Skip to content

Commit 616b1e6

Browse files
committed
Add unittests
1 parent 3e5f794 commit 616b1e6

17 files changed

+859
-1
lines changed

.gitignore

+4-1
Original file line numberDiff line numberDiff line change
@@ -86,4 +86,7 @@ htmlcov/
8686

8787
# bunq specific
8888
bunq.conf
89-
**/tmp/
89+
bunq-test.conf
90+
**/tmp
91+
config.json
92+
tests/connectQr.png

.idea/inspectionProfiles/Project_Default.xml

+42
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/api_context_handler.py

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
from tests.config import Config
2+
from bunq.sdk.context import ApiContext
3+
from bunq.sdk.context import ApiEnvironmentType
4+
from bunq.sdk.model.generated import endpoint
5+
from bunq.sdk.exception import ApiException
6+
7+
8+
class ApiContextHandler:
9+
# Config values
10+
_API_KEY = Config.get_api_key()
11+
_BUNQ_CONFIG_FILE = "bunq-test.conf"
12+
_DEVICE_DESCRIPTION = 'Python test device'
13+
14+
@classmethod
15+
def get_api_context(cls):
16+
"""
17+
Calls IsSessionActive to check if the session token is still active
18+
and returns the ApiContext.
19+
20+
:rtype: ApiContext
21+
"""
22+
23+
if cls._is_session_active():
24+
return ApiContext.restore(cls._BUNQ_CONFIG_FILE)
25+
else:
26+
api_context = ApiContext(ApiEnvironmentType.SANDBOX, cls._API_KEY,
27+
cls._DEVICE_DESCRIPTION, [])
28+
api_context.save(cls._BUNQ_CONFIG_FILE)
29+
30+
return api_context
31+
32+
@classmethod
33+
def _is_session_active(cls):
34+
"""
35+
Catches ApiExceptoin if the session is inactive.
36+
Catches BunqEception if the conf file does not exist.
37+
38+
:rtype: bool
39+
:return: True If exception is not called, otherwise False.
40+
41+
"""
42+
try:
43+
api_context = ApiContext.restore(cls._BUNQ_CONFIG_FILE)
44+
endpoint.User.list(api_context)
45+
46+
return True
47+
except ApiException:
48+
return False
49+
except FileNotFoundError:
50+
return False

tests/assets/[email protected]

9.62 KB
Loading

tests/assets/config.example.json

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"API_KEY": "<API KEY>",
3+
"USER_ID": "xxxx",
4+
"MA_ID": "xxxx",
5+
"MA_ID2": "xxxx",
6+
"ipAddress": "<Ip address>",
7+
"AttachmentPublicTest":{
8+
"CONTENT_TYPE": "image/png",
9+
"DESCRIPTION": "TEST PNG PHP",
10+
"PATH_IN": "/[email protected]"
11+
},
12+
"TabUsageSingleTest": {
13+
"CASH_REGISTER_ID": "xxx"
14+
},
15+
"CounterPartySelf": {
16+
"Alias": "<Email address>",
17+
"Type": "EMAIL"
18+
},
19+
"CounterPartyOther": {
20+
"Alias": "<Email address>",
21+
"Type": "EMAIL"
22+
}
23+
}

tests/config.py

+134
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
import json
2+
import os
3+
4+
from bunq.sdk.model.generated.object_ import Pointer
5+
6+
7+
class Config:
8+
_FIELD_IP_ADDRESS_ALLOWED = "ipAddress"
9+
_FIELD_COUNTER_PARTY_OTHER = "CounterPartyOther"
10+
_FIELD_COUNTER_PARTY_SELF = "CounterPartySelf"
11+
_FIELD_TYPE = "Type"
12+
_FIELD_ALIAS = "Alias"
13+
_FIELD_TAB_USAGE = "TabUsageSingleTest"
14+
_FIELD_CASH_REGISTER_ID = "CASH_REGISTER_ID"
15+
_FIELD_MONETARY_ACCOUNT_ID_1 = "MA_ID"
16+
_FIELD_MONETARY_ACCOUNT_ID_2 = "MA_ID2"
17+
_FIELD_USER_ID = "USER_ID"
18+
_FIELD_API_KEY = "API_KEY"
19+
_FIELD_ATTACHMENT_PUBLIC = "AttachmentPublicTest"
20+
_FIELD_ATTACHMENT_PATH_IN = "PATH_IN"
21+
_FIELD_ATTACHMENT_DESCRIPTION = "DESCRIPTION"
22+
_FIELD_ATTACHMENT_CONTENT_TYPE = "CONTENT_TYPE"
23+
24+
@classmethod
25+
def get_attachment_content_type(cls):
26+
"""
27+
:rtype: str
28+
"""
29+
30+
return cls._get_config_file()[cls._FIELD_ATTACHMENT_PUBLIC][
31+
cls._FIELD_ATTACHMENT_CONTENT_TYPE]
32+
33+
@classmethod
34+
def get_attachment_description(cls):
35+
"""
36+
:rtype: str
37+
"""
38+
39+
return cls._get_config_file()[cls._FIELD_ATTACHMENT_PUBLIC][
40+
cls._FIELD_ATTACHMENT_DESCRIPTION]
41+
42+
@classmethod
43+
def get_attachment_path_in(cls):
44+
"""
45+
:rtype: str
46+
"""
47+
48+
return cls._get_config_file()[cls._FIELD_ATTACHMENT_PUBLIC][
49+
cls._FIELD_ATTACHMENT_PATH_IN]
50+
51+
@classmethod
52+
def get_api_key(cls):
53+
"""
54+
:rtype: str
55+
"""
56+
57+
return cls._get_config_file()[cls._FIELD_API_KEY]
58+
59+
@classmethod
60+
def get_user_id(cls):
61+
"""
62+
:rtype: int
63+
"""
64+
65+
return int(cls._get_config_file()[cls._FIELD_USER_ID])
66+
67+
@classmethod
68+
def get_monetary_account_id_2(cls):
69+
"""
70+
:rtype: int
71+
"""
72+
73+
return int(cls._get_config_file()[cls._FIELD_MONETARY_ACCOUNT_ID_2])
74+
75+
@classmethod
76+
def get_monetary_account_id_1(cls):
77+
"""
78+
:rtype: int
79+
"""
80+
81+
return int(cls._get_config_file()[cls._FIELD_MONETARY_ACCOUNT_ID_1])
82+
83+
@classmethod
84+
def get_cash_register_id(cls):
85+
"""
86+
:rtype str
87+
"""
88+
89+
return cls._get_config_file()[cls._FIELD_TAB_USAGE][
90+
cls._FIELD_CASH_REGISTER_ID]
91+
92+
@classmethod
93+
def get_pointer_counter_party_self(cls):
94+
"""
95+
:rtype: Pointer
96+
"""
97+
98+
type_ = cls._get_config_file()[cls._FIELD_COUNTER_PARTY_SELF][
99+
cls._FIELD_TYPE]
100+
alias = cls._get_config_file()[cls._FIELD_COUNTER_PARTY_SELF][
101+
cls._FIELD_ALIAS]
102+
103+
return Pointer(type_, alias)
104+
105+
@classmethod
106+
def get_pointer_counter_party_other(cls):
107+
"""
108+
:rtype: Pointer
109+
"""
110+
111+
type_ = cls._get_config_file()[cls._FIELD_COUNTER_PARTY_OTHER][
112+
cls._FIELD_TYPE]
113+
alias = cls._get_config_file()[cls._FIELD_COUNTER_PARTY_OTHER][
114+
cls._FIELD_ALIAS]
115+
116+
return Pointer(type_, alias)
117+
118+
@classmethod
119+
def get_ip_address(cls):
120+
"""
121+
:rtype: str
122+
"""
123+
124+
return cls._get_config_file()[cls._FIELD_IP_ADDRESS_ALLOWED]
125+
126+
@classmethod
127+
def _get_config_file(cls):
128+
"""
129+
:rtype: json.load
130+
"""
131+
132+
file_path = os.path.dirname(os.path.realpath(__file__))
133+
with open(file_path + "/assets/config.json", "r") as f:
134+
return json.load(f)

tests/model/__init__.py

Whitespace-only changes.

tests/model/generated/__init__.py

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import unittest
2+
3+
from tests.api_context_handler import ApiContextHandler
4+
from tests.config import Config
5+
from bunq.sdk.model.generated.endpoint import AttachmentPublic
6+
from bunq.sdk.model.generated.endpoint import AttachmentPublicContent
7+
from bunq.sdk.client import ApiClient
8+
9+
10+
class TestAttachmentPublic(unittest.TestCase):
11+
"""
12+
Tests:
13+
AttachmentPublic
14+
AttachmentPublicContent
15+
"""
16+
17+
@classmethod
18+
def setUpClass(cls):
19+
# config values
20+
cls._PATH_TO_ATTACHMENT = '/Users/khellemun/bunq/sdk_python/tests/' \
21+
'assets'
22+
cls._READ_BYTES = "rb"
23+
cls._CONTENT_TYPE = Config.get_attachment_content_type()
24+
cls._ATTACHMENT_DESCRIPTION = Config.get_attachment_description()
25+
cls._ATTACHMENT_PATH_IN = Config.get_attachment_path_in()
26+
cls._API_CONTEXT = ApiContextHandler.get_api_context()
27+
28+
def test_file_upload_and_retrieval(self):
29+
"""
30+
Tests uploading an attachment, retrieves it and compare them to see
31+
if the uploaded attachment is indeed the attachment we are getting
32+
back.
33+
"""
34+
35+
custom_headers = {
36+
ApiClient.HEADER_CONTENT_TYPE: self._CONTENT_TYPE,
37+
ApiClient.HEADER_ATTACHMENT_DESCRIPTION:
38+
self._ATTACHMENT_DESCRIPTION,
39+
}
40+
41+
attachment_uuid = AttachmentPublic.create(self._API_CONTEXT,
42+
self.attachment_contents,
43+
custom_headers)
44+
45+
contents_from_response = AttachmentPublicContent.list(self._API_CONTEXT,
46+
attachment_uuid)
47+
48+
self.assertEqual(self.attachment_contents, contents_from_response)
49+
50+
@property
51+
def attachment_contents(self):
52+
"""
53+
:rtype: bytes
54+
"""
55+
56+
with open(self._PATH_TO_ATTACHMENT + self._ATTACHMENT_PATH_IN,
57+
self._READ_BYTES) as f:
58+
return f.read()

tests/model/generated/test_avatar.py

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import unittest
2+
3+
from bunq.sdk.client import ApiClient
4+
from bunq.sdk.model.generated.endpoint import Avatar
5+
from bunq.sdk.model.generated.endpoint import AttachmentPublic
6+
from bunq.sdk.model.generated.endpoint import AttachmentPublicContent
7+
from tests.api_context_handler import ApiContextHandler
8+
from tests.config import Config
9+
10+
11+
class AvatarTest(unittest.TestCase):
12+
"""
13+
Tests:
14+
Avatar
15+
AttachmentPublic
16+
AttachmentPublicContent
17+
"""
18+
19+
@classmethod
20+
def setUpClass(cls):
21+
cls._FIRST_INDEX = 0
22+
cls._PATH_TO_ATTACHMENT = '/Users/khellemun/bunq/sdk_python/tests' \
23+
'/assets'
24+
cls._READ_FILE_BYTES = 'rb'
25+
cls._CONTENT_TYPE = Config.get_attachment_content_type()
26+
cls._ATTACHMENT_DESCRIPTION = Config.get_attachment_description()
27+
cls._ATTACHMENT_PATH_IN = Config.get_attachment_path_in()
28+
cls._API_CONTEXT = ApiContextHandler.get_api_context()
29+
30+
def test_avatar_creation(self):
31+
"""
32+
Tests the creation of an avatar by uploading a picture via
33+
AttachmentPublic and setting it as avatar via the uuid
34+
"""
35+
36+
custom_header = {
37+
ApiClient.HEADER_ATTACHMENT_DESCRIPTION:
38+
self._ATTACHMENT_DESCRIPTION,
39+
ApiClient.HEADER_CONTENT_TYPE: self._CONTENT_TYPE
40+
}
41+
attachment_public_uuid = AttachmentPublic \
42+
.create(self._API_CONTEXT, self.attachment_contents, custom_header)
43+
44+
avatar_map = {
45+
Avatar.FIELD_ATTACHMENT_PUBLIC_UUID: attachment_public_uuid
46+
}
47+
avatar_uuid = Avatar.create(self._API_CONTEXT, avatar_map)
48+
attachment_uuid_after = Avatar.get(self._API_CONTEXT, avatar_uuid) \
49+
.image[self._FIRST_INDEX].attachment_public_uuid
50+
51+
file_contents_received = AttachmentPublicContent.list(
52+
self._API_CONTEXT, attachment_uuid_after
53+
)
54+
self.assertEqual(self.attachment_contents, file_contents_received)
55+
56+
@property
57+
def attachment_contents(self):
58+
"""
59+
:rtype: bytes
60+
"""
61+
62+
with open(self._PATH_TO_ATTACHMENT + self._ATTACHMENT_PATH_IN,
63+
self._READ_FILE_BYTES) as f:
64+
return f.read()

0 commit comments

Comments
 (0)