Skip to content

Commit 0528146

Browse files
committed
feat: python unit tests
1 parent 0ff8df5 commit 0528146

9 files changed

+259
-0
lines changed

src/SDK/Language/Python.php

+35
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,11 @@ public function getFiles(): array
124124
'destination' => '{{ spec.title | caseSnake}}/__init__.py',
125125
'template' => 'python/package/__init__.py.twig',
126126
],
127+
[
128+
'scope' => 'default',
129+
'destination' => 'test/__init__.py',
130+
'template' => 'python/test/__init__.py.twig',
131+
],
127132
[
128133
'scope' => 'default',
129134
'destination' => '{{ spec.title | caseSnake}}/client.py',
@@ -134,21 +139,41 @@ public function getFiles(): array
134139
'destination' => '{{ spec.title | caseSnake}}/permission.py',
135140
'template' => 'python/package/permission.py.twig',
136141
],
142+
[
143+
'scope' => 'default',
144+
'destination' => 'test/test_permission.py',
145+
'template' => 'python/test/test_permission.py.twig',
146+
],
137147
[
138148
'scope' => 'default',
139149
'destination' => '{{ spec.title | caseSnake}}/role.py',
140150
'template' => 'python/package/role.py.twig',
141151
],
152+
[
153+
'scope' => 'default',
154+
'destination' => 'test/test_role.py',
155+
'template' => 'python/test/test_role.py.twig',
156+
],
142157
[
143158
'scope' => 'default',
144159
'destination' => '{{ spec.title | caseSnake}}/id.py',
145160
'template' => 'python/package/id.py.twig',
146161
],
162+
[
163+
'scope' => 'default',
164+
'destination' => 'test/test_id.py',
165+
'template' => 'python/test/test_id.py.twig',
166+
],
147167
[
148168
'scope' => 'default',
149169
'destination' => '{{ spec.title | caseSnake}}/query.py',
150170
'template' => 'python/package/query.py.twig',
151171
],
172+
[
173+
'scope' => 'default',
174+
'destination' => 'test/test_query.py',
175+
'template' => 'python/test/test_query.py.twig',
176+
],
152177
[
153178
'scope' => 'default',
154179
'destination' => '{{ spec.title | caseSnake}}/exception.py',
@@ -169,11 +194,21 @@ public function getFiles(): array
169194
'destination' => '{{ spec.title | caseSnake}}/services/__init__.py',
170195
'template' => 'python/package/services/__init__.py.twig',
171196
],
197+
[
198+
'scope' => 'default',
199+
'destination' => 'test/services/__init__.py',
200+
'template' => 'python/test/services/__init__.py.twig',
201+
],
172202
[
173203
'scope' => 'service',
174204
'destination' => '{{ spec.title | caseSnake}}/services/{{service.name | caseSnake}}.py',
175205
'template' => 'python/package/services/service.py.twig',
176206
],
207+
[
208+
'scope' => 'service',
209+
'destination' => 'test/services/test_{{service.name | caseSnake}}.py',
210+
'template' => 'python/test/services/test_service.py.twig',
211+
],
177212
[
178213
'scope' => 'method',
179214
'destination' => 'docs/examples/{{service.name | caseLower}}/{{method.name | caseDash}}.md',
+1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
requests==2.31.0
2+
requests_mock==1.11.0

templates/python/test/__init__.py.twig

Whitespace-only changes.

templates/python/test/services/__init__.py.twig

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import json
2+
import requests_mock
3+
import unittest
4+
5+
from appwrite.client import Client
6+
from appwrite.input_file import InputFile
7+
from appwrite.services.{{ service.name | caseSnake }} import {{ service.name | caseUcfirst }}
8+
9+
10+
class {{ service.name | caseUcfirst }}ServiceTest(unittest.TestCase):
11+
12+
def setUp(self):
13+
self.client = Client()
14+
self.{{ service.name | caseSnake }} = {{ service.name | caseUcfirst }}(self.client)
15+
16+
{% for method in service.methods %}
17+
@requests_mock.Mocker()
18+
def test_{{ method.name | caseSnake }}(self, m):
19+
{%~ if method.type == 'webAuth' %}
20+
data = ''
21+
{%~ elseif method.type == 'location' %}
22+
data = bytearray()
23+
{%~ else %}
24+
{%~ if method.responseModel and method.responseModel != 'any' %}
25+
data = {
26+
{%- for definition in spec.definitions ~%}{%~ if definition.name == method.responseModel -%}{%~ for property in definition.properties | filter((param) => param.required) ~%}
27+
'{{property.name}}': {% if property.type == 'object' %}{}{% elseif property.type == 'array' %}[]{% elseif property.type == 'string' %}'{{property.example | escapeDollarSign}}'{% elseif property.type == 'boolean' %}True{% else %}{{property.example}}{% endif %},{%~ endfor ~%}{% set break = true %}{%- else -%}{% set continue = true %}{%- endif -%}
28+
{%~ endfor ~%}
29+
}
30+
{%~ else %}
31+
data = ''
32+
{%~ endif %}
33+
{%~ endif %}
34+
headers = {'Content-Type': {% if method.type == 'location' %}'application/octet-stream'{% else %}'application/json'{% endif %}}
35+
m.request(requests_mock.ANY, requests_mock.ANY, {% if method.type == 'location' %}body=data{% else %}text=json.dumps(data){% endif %}, headers=headers)
36+
37+
response = self.{{ service.name | caseSnake }}.{{ method.name | caseSnake }}({%~ for parameter in method.parameters.all | filter((param) => param.required) ~%}
38+
{% if parameter.type == 'object' %}{}{% elseif parameter.type == 'array' %}[]{% elseif parameter.type == 'file' %}InputFile.from_bytes(bytearray()){% elseif parameter.type == 'boolean' %}True{% elseif parameter.type == 'string' %}'{% if parameter.example is not empty %}{{parameter.example | escapeDollarSign}}{% endif %}'{% elseif parameter.type == 'integer' and parameter['x-example'] is empty %}1{% elseif parameter.type == 'number' and parameter['x-example'] is empty %}1.0{% else %}{{parameter.example}}{%~ endif ~%},{%~ endfor ~%}
39+
)
40+
41+
self.assertEqual(response, data)
42+
43+
{% endfor %}

templates/python/test/test_id.py.twig

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import unittest
2+
3+
from appwrite.id import ID
4+
5+
6+
class TestIDMethods(unittest.TestCase):
7+
8+
def test_unique(self):
9+
self.assertEqual(ID.unique(), 'unique()')
10+
11+
def test_custom(self):
12+
self.assertEqual(ID.custom('custom'), 'custom')
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import unittest
2+
3+
from appwrite.permission import Permission
4+
from appwrite.role import Role
5+
6+
7+
class TestPermissionMethods(unittest.TestCase):
8+
9+
def test_read(self):
10+
self.assertEqual(Permission.read(Role.any()), 'read("any")')
11+
12+
def test_write(self):
13+
self.assertEqual(Permission.write(Role.any()), 'write("any")')
14+
15+
def test_create(self):
16+
self.assertEqual(Permission.create(Role.any()), 'create("any")')
17+
18+
def test_update(self):
19+
self.assertEqual(Permission.update(Role.any()), 'update("any")')
20+
21+
def test_delete(self):
22+
self.assertEqual(Permission.delete(Role.any()), 'delete("any")')
+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
import unittest
2+
3+
from appwrite.query import Query
4+
5+
6+
class BasicFilterQueryTest:
7+
def __init__(self, description: str, value, expected_values: str):
8+
self.description = description
9+
self.value = value
10+
self.expected_values = expected_values
11+
12+
13+
tests = [
14+
BasicFilterQueryTest('with a string', 's', '["s"]'),
15+
BasicFilterQueryTest('with an integer', 1, '[1]'),
16+
BasicFilterQueryTest('with a double', 1.2, '[1.2]'),
17+
BasicFilterQueryTest('with a whole number double', 1.0, '[1.0]'),
18+
BasicFilterQueryTest('with a bool', False, '[false]'),
19+
BasicFilterQueryTest('with a list', ['a', 'b', 'c'], '["a","b","c"]'),
20+
]
21+
22+
23+
class TestQueryMethods(unittest.TestCase):
24+
25+
def test_equal(self):
26+
for t in tests:
27+
self.assertEqual(
28+
Query.equal('attr', t.value),
29+
f'equal("attr", {t.expected_values})',
30+
t.description
31+
)
32+
33+
def test_not_equal(self):
34+
for t in tests:
35+
self.assertEqual(
36+
Query.not_equal('attr', t.value),
37+
f'notEqual("attr", {t.expected_values})',
38+
t.description
39+
)
40+
41+
def test_less_than(self):
42+
for t in tests:
43+
self.assertEqual(
44+
Query.less_than('attr', t.value),
45+
f'lessThan("attr", {t.expected_values})',
46+
t.description
47+
)
48+
49+
def test_less_than_equal(self):
50+
for t in tests:
51+
self.assertEqual(
52+
Query.less_than_equal('attr', t.value),
53+
f'lessThanEqual("attr", {t.expected_values})',
54+
t.description
55+
)
56+
57+
def test_greater_than(self):
58+
for t in tests:
59+
self.assertEqual(
60+
Query.greater_than('attr', t.value),
61+
f'greaterThan("attr", {t.expected_values})',
62+
t.description
63+
)
64+
65+
def test_greater_than_equal(self):
66+
for t in tests:
67+
self.assertEqual(
68+
Query.greater_than_equal('attr', t.value),
69+
f'greaterThanEqual("attr", {t.expected_values})',
70+
t.description
71+
)
72+
73+
def test_search(self):
74+
self.assertEqual(Query.search('attr', 'keyword1 keyword2'), 'search("attr", ["keyword1 keyword2"])')
75+
76+
def test_is_null(self):
77+
self.assertEqual(Query.is_null('attr'), 'isNull("attr")')
78+
79+
def test_is_not_null(self):
80+
self.assertEqual(Query.is_not_null('attr'), 'isNotNull("attr")')
81+
82+
def test_between_with_integers(self):
83+
self.assertEqual(Query.between('attr', 1, 2), 'between("attr", [1,2])')
84+
85+
def test_between_with_doubles(self):
86+
self.assertEqual(Query.between('attr', 1.0, 2.0), 'between("attr", [1.0,2.0])')
87+
88+
def test_between_with_strings(self):
89+
self.assertEqual(Query.between('attr', 'a', 'z'), 'between("attr", ["a","z"])')
90+
91+
def test_select(self):
92+
self.assertEqual(Query.select(['attr1', 'attr2']), 'select(["attr1","attr2"])')
93+
94+
def test_order_asc(self):
95+
self.assertEqual(Query.order_asc('attr'), 'orderAsc("attr")')
96+
97+
def test_order_desc(self):
98+
self.assertEqual(Query.order_desc('attr'), 'orderDesc("attr")')
99+
100+
def test_cursor_before(self):
101+
self.assertEqual(Query.cursor_before('custom'), 'cursorBefore("custom")')
102+
103+
def test_cursor_after(self):
104+
self.assertEqual(Query.cursor_after('custom'), 'cursorAfter("custom")')
105+
106+
def test_limit(self):
107+
self.assertEqual(Query.limit(1), 'limit(1)')
108+
109+
def test_offset(self):
110+
self.assertEqual(Query.offset(1), 'offset(1)')
+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import unittest
2+
3+
from appwrite.role import Role
4+
5+
6+
class TestRoleMethods(unittest.TestCase):
7+
8+
def test_any(self):
9+
self.assertEqual(Role.any(), 'any')
10+
11+
def test_user_without_status(self):
12+
self.assertEqual(Role.user('custom'), 'user:custom')
13+
14+
def test_user_with_status(self):
15+
self.assertEqual(Role.user('custom', 'verified'), 'user:custom/verified')
16+
17+
def test_users_without_status(self):
18+
self.assertEqual(Role.users(), 'users')
19+
20+
def test_users_with_status(self):
21+
self.assertEqual(Role.users('verified'), 'users/verified')
22+
23+
def test_guests(self):
24+
self.assertEqual(Role.guests(), 'guests')
25+
26+
def test_team_without_role(self):
27+
self.assertEqual(Role.team('custom'), 'team:custom')
28+
29+
def test_team_with_role(self):
30+
self.assertEqual(Role.team('custom', 'owner'), 'team:custom/owner')
31+
32+
def test_member(self):
33+
self.assertEqual(Role.member('custom'), 'member:custom')
34+
35+
def test_label(self):
36+
self.assertEqual(Role.label('admin'), 'label:admin')

0 commit comments

Comments
 (0)