karrio-server-graph 2025.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- karrio/server/graph/__init__.py +1 -0
- karrio/server/graph/admin.py +3 -0
- karrio/server/graph/apps.py +5 -0
- karrio/server/graph/forms.py +57 -0
- karrio/server/graph/management/__init__.py +0 -0
- karrio/server/graph/management/commands/__init__.py +0 -0
- karrio/server/graph/management/commands/export_schema.py +9 -0
- karrio/server/graph/migrations/0001_initial.py +37 -0
- karrio/server/graph/migrations/0002_auto_20210512_1353.py +22 -0
- karrio/server/graph/migrations/__init__.py +0 -0
- karrio/server/graph/models.py +44 -0
- karrio/server/graph/schema.py +44 -0
- karrio/server/graph/schemas/__init__.py +2 -0
- karrio/server/graph/schemas/base/__init__.py +385 -0
- karrio/server/graph/schemas/base/inputs.py +612 -0
- karrio/server/graph/schemas/base/mutations.py +1033 -0
- karrio/server/graph/schemas/base/types.py +1406 -0
- karrio/server/graph/serializers.py +388 -0
- karrio/server/graph/templates/graphql/graphiql.html +142 -0
- karrio/server/graph/templates/karrio/email_change_email.html +13 -0
- karrio/server/graph/templates/karrio/email_change_email.txt +13 -0
- karrio/server/graph/templates/karrio/password_reset_email.html +14 -0
- karrio/server/graph/tests/__init__.py +9 -0
- karrio/server/graph/tests/base.py +153 -0
- karrio/server/graph/tests/test_carrier_connections.py +239 -0
- karrio/server/graph/tests/test_metafield.py +404 -0
- karrio/server/graph/tests/test_partial_shipments.py +603 -0
- karrio/server/graph/tests/test_rate_sheets.py +354 -0
- karrio/server/graph/tests/test_registration.py +209 -0
- karrio/server/graph/tests/test_templates.py +677 -0
- karrio/server/graph/tests/test_user_info.py +71 -0
- karrio/server/graph/urls.py +10 -0
- karrio/server/graph/utils.py +308 -0
- karrio/server/graph/views.py +91 -0
- karrio/server/settings/graph.py +7 -0
- karrio_server_graph-2025.5.dist-info/METADATA +29 -0
- karrio_server_graph-2025.5.dist-info/RECORD +39 -0
- karrio_server_graph-2025.5.dist-info/WHEEL +5 -0
- karrio_server_graph-2025.5.dist-info/top_level.txt +2 -0
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
import karrio.lib as lib
|
|
2
|
+
from unittest.mock import ANY
|
|
3
|
+
from karrio.server.graph.tests.base import GraphTestCase
|
|
4
|
+
import karrio.server.providers.models as providers
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class TestRateSheets(GraphTestCase):
|
|
8
|
+
def setUp(self):
|
|
9
|
+
super().setUp()
|
|
10
|
+
|
|
11
|
+
# Create a test rate sheet
|
|
12
|
+
self.rate_sheet = providers.RateSheet.objects.create(
|
|
13
|
+
name="Test Rate Sheet",
|
|
14
|
+
carrier_name="ups",
|
|
15
|
+
slug="test_rate_sheet",
|
|
16
|
+
created_by=self.user,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
# Create a test service
|
|
20
|
+
self.service = providers.ServiceLevel.objects.create(
|
|
21
|
+
service_name="UPS Standard",
|
|
22
|
+
service_code="ups_standard",
|
|
23
|
+
carrier_service_code="11",
|
|
24
|
+
currency="USD",
|
|
25
|
+
active=True,
|
|
26
|
+
zones=[
|
|
27
|
+
{
|
|
28
|
+
"rate": 10.00,
|
|
29
|
+
"label": "Zone 1",
|
|
30
|
+
"cities": ["New York", "Los Angeles"],
|
|
31
|
+
}
|
|
32
|
+
],
|
|
33
|
+
created_by=self.user,
|
|
34
|
+
)
|
|
35
|
+
self.rate_sheet.services.add(self.service)
|
|
36
|
+
|
|
37
|
+
def test_query_rate_sheets(self):
|
|
38
|
+
response = self.query(
|
|
39
|
+
"""
|
|
40
|
+
query get_rate_sheets {
|
|
41
|
+
rate_sheets {
|
|
42
|
+
edges {
|
|
43
|
+
node {
|
|
44
|
+
id
|
|
45
|
+
name
|
|
46
|
+
carrier_name
|
|
47
|
+
slug
|
|
48
|
+
services {
|
|
49
|
+
id
|
|
50
|
+
service_name
|
|
51
|
+
service_code
|
|
52
|
+
carrier_service_code
|
|
53
|
+
active
|
|
54
|
+
currency
|
|
55
|
+
zones {
|
|
56
|
+
rate
|
|
57
|
+
label
|
|
58
|
+
cities
|
|
59
|
+
postal_codes
|
|
60
|
+
country_codes
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
""",
|
|
68
|
+
operation_name="get_rate_sheets",
|
|
69
|
+
)
|
|
70
|
+
response_data = response.data
|
|
71
|
+
|
|
72
|
+
self.assertResponseNoErrors(response)
|
|
73
|
+
self.assertDictEqual(
|
|
74
|
+
lib.to_dict(response_data),
|
|
75
|
+
RATE_SHEETS_RESPONSE,
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
def test_create_rate_sheet(self):
|
|
79
|
+
response = self.query(
|
|
80
|
+
"""
|
|
81
|
+
mutation create_rate_sheet($data: CreateRateSheetMutationInput!) {
|
|
82
|
+
create_rate_sheet(input: $data) {
|
|
83
|
+
rate_sheet {
|
|
84
|
+
id
|
|
85
|
+
name
|
|
86
|
+
carrier_name
|
|
87
|
+
services {
|
|
88
|
+
id
|
|
89
|
+
service_name
|
|
90
|
+
service_code
|
|
91
|
+
currency
|
|
92
|
+
zones {
|
|
93
|
+
rate
|
|
94
|
+
label
|
|
95
|
+
postal_codes
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
""",
|
|
102
|
+
operation_name="create_rate_sheet",
|
|
103
|
+
variables=CREATE_RATE_SHEET_DATA,
|
|
104
|
+
)
|
|
105
|
+
response_data = response.data
|
|
106
|
+
|
|
107
|
+
self.assertResponseNoErrors(response)
|
|
108
|
+
self.assertDictEqual(response_data, CREATE_RATE_SHEET_RESPONSE)
|
|
109
|
+
|
|
110
|
+
def test_update_rate_sheet(self):
|
|
111
|
+
response = self.query(
|
|
112
|
+
"""
|
|
113
|
+
mutation update_rate_sheet($data: UpdateRateSheetMutationInput!) {
|
|
114
|
+
update_rate_sheet(input: $data) {
|
|
115
|
+
rate_sheet {
|
|
116
|
+
id
|
|
117
|
+
name
|
|
118
|
+
services {
|
|
119
|
+
id
|
|
120
|
+
service_name
|
|
121
|
+
zones {
|
|
122
|
+
rate
|
|
123
|
+
label
|
|
124
|
+
country_codes
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
""",
|
|
131
|
+
operation_name="update_rate_sheet",
|
|
132
|
+
variables={
|
|
133
|
+
"data": {
|
|
134
|
+
"id": self.rate_sheet.id,
|
|
135
|
+
"name": "Updated Rate Sheet",
|
|
136
|
+
"services": [
|
|
137
|
+
{
|
|
138
|
+
"id": self.service.id,
|
|
139
|
+
"service_name": "Updated Service",
|
|
140
|
+
"zones": [
|
|
141
|
+
{
|
|
142
|
+
"rate": 20.0,
|
|
143
|
+
"label": "Updated Zone",
|
|
144
|
+
"country_codes": ["US", "CA"],
|
|
145
|
+
}
|
|
146
|
+
],
|
|
147
|
+
}
|
|
148
|
+
],
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
)
|
|
152
|
+
response_data = response.data
|
|
153
|
+
|
|
154
|
+
self.assertResponseNoErrors(response)
|
|
155
|
+
self.assertDictEqual(
|
|
156
|
+
lib.to_dict(response_data),
|
|
157
|
+
UPDATE_RATE_SHEET_RESPONSE,
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
def test_update_service_zone(self):
|
|
161
|
+
response = self.query(
|
|
162
|
+
"""
|
|
163
|
+
mutation update_zone($data: UpdateServiceZoneMutationInput!) {
|
|
164
|
+
update_service_zone(input: $data) {
|
|
165
|
+
rate_sheet {
|
|
166
|
+
id
|
|
167
|
+
services {
|
|
168
|
+
id
|
|
169
|
+
zones {
|
|
170
|
+
rate
|
|
171
|
+
label
|
|
172
|
+
country_codes
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
""",
|
|
179
|
+
operation_name="update_zone",
|
|
180
|
+
variables={
|
|
181
|
+
"data": {
|
|
182
|
+
"id": self.rate_sheet.id,
|
|
183
|
+
"service_id": self.service.id,
|
|
184
|
+
**UPDATE_ZONE_DATA["data"],
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
)
|
|
188
|
+
response_data = response.data
|
|
189
|
+
|
|
190
|
+
self.assertResponseNoErrors(response)
|
|
191
|
+
self.assertDictEqual(
|
|
192
|
+
lib.to_dict(response_data),
|
|
193
|
+
UPDATE_ZONE_RESPONSE,
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
RATE_SHEETS_RESPONSE = {
|
|
198
|
+
"data": {
|
|
199
|
+
"rate_sheets": {
|
|
200
|
+
"edges": [
|
|
201
|
+
{
|
|
202
|
+
"node": {
|
|
203
|
+
"carrier_name": "ups",
|
|
204
|
+
"id": ANY,
|
|
205
|
+
"name": "Test Rate Sheet",
|
|
206
|
+
"services": [
|
|
207
|
+
{
|
|
208
|
+
"active": True,
|
|
209
|
+
"carrier_service_code": "11",
|
|
210
|
+
"currency": "USD",
|
|
211
|
+
"id": ANY,
|
|
212
|
+
"service_code": "ups_standard",
|
|
213
|
+
"service_name": "UPS Standard",
|
|
214
|
+
"zones": [
|
|
215
|
+
{
|
|
216
|
+
"cities": ["New York", "Los Angeles"],
|
|
217
|
+
"label": "Zone 1",
|
|
218
|
+
"rate": 10.0,
|
|
219
|
+
}
|
|
220
|
+
],
|
|
221
|
+
}
|
|
222
|
+
],
|
|
223
|
+
"slug": "test_rate_sheet",
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
]
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
CREATE_RATE_SHEET_DATA = {
|
|
232
|
+
"data": {
|
|
233
|
+
"name": "New Rate Sheet",
|
|
234
|
+
"carrier_name": "fedex",
|
|
235
|
+
"services": [
|
|
236
|
+
{
|
|
237
|
+
"service_name": "FedEx Ground",
|
|
238
|
+
"service_code": "fedex_ground",
|
|
239
|
+
"carrier_service_code": "FEDEX_GROUND",
|
|
240
|
+
"currency": "USD",
|
|
241
|
+
"zones": [
|
|
242
|
+
{
|
|
243
|
+
"rate": 15.0,
|
|
244
|
+
"label": "Zone A",
|
|
245
|
+
"postal_codes": ["12345", "67890"],
|
|
246
|
+
}
|
|
247
|
+
],
|
|
248
|
+
}
|
|
249
|
+
],
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
CREATE_RATE_SHEET_RESPONSE = {
|
|
254
|
+
"data": {
|
|
255
|
+
"create_rate_sheet": {
|
|
256
|
+
"rate_sheet": {
|
|
257
|
+
"id": ANY,
|
|
258
|
+
"name": "New Rate Sheet",
|
|
259
|
+
"carrier_name": "fedex",
|
|
260
|
+
"services": [
|
|
261
|
+
{
|
|
262
|
+
"id": ANY,
|
|
263
|
+
"service_name": "FedEx Ground",
|
|
264
|
+
"service_code": "fedex_ground",
|
|
265
|
+
"currency": "USD",
|
|
266
|
+
"zones": [
|
|
267
|
+
{
|
|
268
|
+
"rate": 15.0,
|
|
269
|
+
"label": "Zone A",
|
|
270
|
+
"postal_codes": ["12345", "67890"],
|
|
271
|
+
}
|
|
272
|
+
],
|
|
273
|
+
}
|
|
274
|
+
],
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
UPDATE_RATE_SHEET_DATA = {
|
|
281
|
+
"data": {
|
|
282
|
+
"name": "Updated Rate Sheet",
|
|
283
|
+
"services": [
|
|
284
|
+
{
|
|
285
|
+
"id": ANY, # Will be replaced with actual service ID in test
|
|
286
|
+
"service_name": "Updated Service",
|
|
287
|
+
"zones": [
|
|
288
|
+
{
|
|
289
|
+
"rate": 20.0,
|
|
290
|
+
"label": "Updated Zone",
|
|
291
|
+
"country_codes": ["US", "CA"],
|
|
292
|
+
}
|
|
293
|
+
],
|
|
294
|
+
}
|
|
295
|
+
],
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
UPDATE_RATE_SHEET_RESPONSE = {
|
|
300
|
+
"data": {
|
|
301
|
+
"update_rate_sheet": {
|
|
302
|
+
"rate_sheet": {
|
|
303
|
+
"id": ANY,
|
|
304
|
+
"name": "Updated Rate Sheet",
|
|
305
|
+
"services": [
|
|
306
|
+
{
|
|
307
|
+
"id": ANY,
|
|
308
|
+
"service_name": "Updated Service",
|
|
309
|
+
"zones": [
|
|
310
|
+
{
|
|
311
|
+
"country_codes": ["US", "CA"],
|
|
312
|
+
"label": "Updated Zone",
|
|
313
|
+
"rate": 20.0,
|
|
314
|
+
}
|
|
315
|
+
],
|
|
316
|
+
}
|
|
317
|
+
],
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
UPDATE_ZONE_DATA = {
|
|
324
|
+
"data": {
|
|
325
|
+
"zone_index": 0,
|
|
326
|
+
"zone": {
|
|
327
|
+
"rate": 25.0,
|
|
328
|
+
"label": "Modified Zone",
|
|
329
|
+
"country_codes": ["MX"],
|
|
330
|
+
},
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
UPDATE_ZONE_RESPONSE = {
|
|
335
|
+
"data": {
|
|
336
|
+
"update_service_zone": {
|
|
337
|
+
"rate_sheet": {
|
|
338
|
+
"id": ANY,
|
|
339
|
+
"services": [
|
|
340
|
+
{
|
|
341
|
+
"id": ANY,
|
|
342
|
+
"zones": [
|
|
343
|
+
{
|
|
344
|
+
"rate": 25.0,
|
|
345
|
+
"label": "Modified Zone",
|
|
346
|
+
"country_codes": ["MX"],
|
|
347
|
+
}
|
|
348
|
+
],
|
|
349
|
+
}
|
|
350
|
+
],
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
from unittest.mock import patch, MagicMock
|
|
2
|
+
from karrio.server.graph.tests.base import GraphTestCase
|
|
3
|
+
from django.contrib.auth import get_user_model
|
|
4
|
+
|
|
5
|
+
User = get_user_model()
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class TestUserRegistration(GraphTestCase):
|
|
9
|
+
|
|
10
|
+
@patch("karrio.server.conf.settings.ALLOW_SIGNUP", True)
|
|
11
|
+
@patch("karrio.server.conf.settings.EMAIL_ENABLED", False)
|
|
12
|
+
def test_register_user_mutation(self):
|
|
13
|
+
"""Test successful user registration"""
|
|
14
|
+
# Ensure user doesn't exist
|
|
15
|
+
User.objects.filter(email="newuser@example.com").delete()
|
|
16
|
+
|
|
17
|
+
response = self.query(
|
|
18
|
+
"""
|
|
19
|
+
mutation register_user($data: RegisterUserMutationInput!) {
|
|
20
|
+
register_user(input: $data) {
|
|
21
|
+
user {
|
|
22
|
+
email
|
|
23
|
+
full_name
|
|
24
|
+
is_active
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
""",
|
|
29
|
+
operation_name="register_user",
|
|
30
|
+
variables={
|
|
31
|
+
"data": {
|
|
32
|
+
"email": "newuser@example.com",
|
|
33
|
+
"full_name": "New Test User",
|
|
34
|
+
"password1": "TestPassword123!",
|
|
35
|
+
"password2": "TestPassword123!",
|
|
36
|
+
"redirect_url": "http://example.com/email",
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
self.assertResponseNoErrors(response)
|
|
42
|
+
self.assertIsNotNone(response.data["data"]["register_user"]["user"])
|
|
43
|
+
self.assertEqual(
|
|
44
|
+
response.data["data"]["register_user"]["user"]["email"],
|
|
45
|
+
"newuser@example.com",
|
|
46
|
+
)
|
|
47
|
+
self.assertEqual(
|
|
48
|
+
response.data["data"]["register_user"]["user"]["full_name"], "New Test User"
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
# Verify user was created in database
|
|
52
|
+
user = User.objects.get(email="newuser@example.com")
|
|
53
|
+
self.assertEqual(user.full_name, "New Test User")
|
|
54
|
+
|
|
55
|
+
@patch("karrio.server.conf.settings.ALLOW_SIGNUP", True)
|
|
56
|
+
def test_register_user_password_mismatch(self):
|
|
57
|
+
"""Test registration fails with mismatched passwords"""
|
|
58
|
+
response = self.query(
|
|
59
|
+
"""
|
|
60
|
+
mutation register_user($data: RegisterUserMutationInput!) {
|
|
61
|
+
register_user(input: $data) {
|
|
62
|
+
user {
|
|
63
|
+
email
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
""",
|
|
68
|
+
operation_name="register_user",
|
|
69
|
+
variables={
|
|
70
|
+
"data": {
|
|
71
|
+
"email": "mismatch@example.com",
|
|
72
|
+
"full_name": "Mismatch User",
|
|
73
|
+
"password1": "TestPassword123!",
|
|
74
|
+
"password2": "DifferentPassword123!",
|
|
75
|
+
"redirect_url": "http://example.com/email",
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
# Should have errors
|
|
81
|
+
self.assertIsNotNone(response.data.get("errors"))
|
|
82
|
+
self.assertIn("password", str(response.data["errors"][0]))
|
|
83
|
+
|
|
84
|
+
@patch("karrio.server.conf.settings.ALLOW_SIGNUP", True)
|
|
85
|
+
def test_register_user_duplicate_email(self):
|
|
86
|
+
"""Test registration fails with duplicate email"""
|
|
87
|
+
# First create a user
|
|
88
|
+
User.objects.create_user(
|
|
89
|
+
email="existing@example.com",
|
|
90
|
+
password="ExistingPass123!",
|
|
91
|
+
full_name="Existing User",
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
response = self.query(
|
|
95
|
+
"""
|
|
96
|
+
mutation register_user($data: RegisterUserMutationInput!) {
|
|
97
|
+
register_user(input: $data) {
|
|
98
|
+
user {
|
|
99
|
+
email
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
""",
|
|
104
|
+
operation_name="register_user",
|
|
105
|
+
variables={
|
|
106
|
+
"data": {
|
|
107
|
+
"email": "existing@example.com",
|
|
108
|
+
"full_name": "Duplicate User",
|
|
109
|
+
"password1": "TestPassword123!",
|
|
110
|
+
"password2": "TestPassword123!",
|
|
111
|
+
"redirect_url": "http://example.com/email",
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
# Should have errors about duplicate email
|
|
117
|
+
self.assertIsNotNone(response.data.get("errors"))
|
|
118
|
+
|
|
119
|
+
@patch("karrio.server.conf.settings.ALLOW_SIGNUP", False)
|
|
120
|
+
def test_register_user_signup_disabled(self):
|
|
121
|
+
"""Test registration fails when signup is disabled"""
|
|
122
|
+
response = self.query(
|
|
123
|
+
"""
|
|
124
|
+
mutation register_user($data: RegisterUserMutationInput!) {
|
|
125
|
+
register_user(input: $data) {
|
|
126
|
+
user {
|
|
127
|
+
email
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
""",
|
|
132
|
+
operation_name="register_user",
|
|
133
|
+
variables={
|
|
134
|
+
"data": {
|
|
135
|
+
"email": "disabled@example.com",
|
|
136
|
+
"full_name": "Disabled User",
|
|
137
|
+
"password1": "TestPassword123!",
|
|
138
|
+
"password2": "TestPassword123!",
|
|
139
|
+
"redirect_url": "http://example.com/email",
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
# Should have errors about signup not allowed
|
|
145
|
+
self.assertIsNotNone(response.data.get("errors"))
|
|
146
|
+
self.assertIn("Signup is not allowed", str(response.data["errors"][0]))
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
class TestPasswordReset(GraphTestCase):
|
|
150
|
+
|
|
151
|
+
def setUp(self):
|
|
152
|
+
super().setUp()
|
|
153
|
+
# Create a test user for password reset
|
|
154
|
+
self.reset_user = User.objects.create_user(
|
|
155
|
+
email="resetuser@example.com",
|
|
156
|
+
password="OldPassword123!",
|
|
157
|
+
full_name="Reset User",
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
@patch("django.core.mail.send_mail")
|
|
161
|
+
def test_request_password_reset(self, mock_send_mail):
|
|
162
|
+
"""Test requesting a password reset"""
|
|
163
|
+
response = self.query(
|
|
164
|
+
"""
|
|
165
|
+
mutation request_password_reset($data: RequestPasswordResetMutationInput!) {
|
|
166
|
+
request_password_reset(input: $data) {
|
|
167
|
+
email
|
|
168
|
+
redirect_url
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
""",
|
|
172
|
+
operation_name="request_password_reset",
|
|
173
|
+
variables={
|
|
174
|
+
"data": {
|
|
175
|
+
"email": "resetuser@example.com",
|
|
176
|
+
"redirect_url": "http://example.com/password/reset",
|
|
177
|
+
}
|
|
178
|
+
},
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
self.assertResponseNoErrors(response)
|
|
182
|
+
self.assertEqual(
|
|
183
|
+
response.data["data"]["request_password_reset"]["email"],
|
|
184
|
+
"resetuser@example.com",
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
class TestEmailConfirmation(GraphTestCase):
|
|
189
|
+
|
|
190
|
+
@patch("karrio.server.graph.schemas.base.mutations.email_verification.verify_token")
|
|
191
|
+
def test_confirm_email(self, mock_verify):
|
|
192
|
+
"""Test email confirmation"""
|
|
193
|
+
mock_verify.return_value = (True, None)
|
|
194
|
+
|
|
195
|
+
response = self.query(
|
|
196
|
+
"""
|
|
197
|
+
mutation confirm_email($data: ConfirmEmailMutationInput!) {
|
|
198
|
+
confirm_email(input: $data) {
|
|
199
|
+
success
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
""",
|
|
203
|
+
operation_name="confirm_email",
|
|
204
|
+
variables={"data": {"token": "test-confirmation-token"}},
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
self.assertResponseNoErrors(response)
|
|
208
|
+
self.assertTrue(response.data["data"]["confirm_email"]["success"])
|
|
209
|
+
mock_verify.assert_called_once_with("test-confirmation-token")
|