cornflow 1.1.2__py3-none-any.whl → 1.1.5a1__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.
@@ -1,5 +1,17 @@
1
1
  """
2
- Unit test for the data check endpoint
2
+ Unit tests for the data check endpoints.
3
+
4
+ This module contains tests for data validation functionality, including:
5
+
6
+ - Execution data checks
7
+ - Instance data validation
8
+ - Case data verification
9
+ - Airflow integration testing
10
+ - Run and no-run scenarios
11
+ - Response validation
12
+
13
+ The tests verify both successful validation operations and proper error handling
14
+ for various data check scenarios.
3
15
  """
4
16
 
5
17
  # Import from libraries
@@ -11,7 +23,6 @@ from cornflow.models import ExecutionModel, InstanceModel, CaseModel
11
23
  from cornflow.tests.const import (
12
24
  INSTANCE_PATH,
13
25
  EXECUTION_PATH,
14
- EXECUTION_URL,
15
26
  CASE_PATH,
16
27
  EXECUTION_URL_NORUN,
17
28
  DATA_CHECK_EXECUTION_URL,
@@ -25,7 +36,28 @@ from cornflow.tests.unit.tools import patch_af_client
25
36
 
26
37
 
27
38
  class TestDataChecksExecutionEndpoint(CustomTestCase):
39
+ """
40
+ Test suite for execution data check endpoints.
41
+
42
+ This class tests data validation for executions:
43
+
44
+ - Direct execution checks
45
+ - Run and no-run validation scenarios
46
+ - Response structure validation
47
+ - Airflow integration testing
48
+ """
49
+
28
50
  def setUp(self):
51
+ """
52
+ Set up test environment before each test.
53
+
54
+ Initializes:
55
+
56
+ - Base test configuration
57
+ - Test instance data
58
+ - Execution model
59
+ - Test payload
60
+ """
29
61
  super().setUp()
30
62
 
31
63
  with open(INSTANCE_PATH) as f:
@@ -42,6 +74,16 @@ class TestDataChecksExecutionEndpoint(CustomTestCase):
42
74
  self.payload = load_file_fk(EXECUTION_PATH)
43
75
 
44
76
  def test_check_execution(self):
77
+ """
78
+ Test execution data check without running.
79
+
80
+ Verifies:
81
+
82
+ - Successful data check creation
83
+ - Correct response status
84
+ - Proper ID assignment
85
+ - Data consistency
86
+ """
45
87
  exec_to_check_id = self.create_new_row(
46
88
  EXECUTION_URL_NORUN, self.model, payload=self.payload
47
89
  )
@@ -61,6 +103,16 @@ class TestDataChecksExecutionEndpoint(CustomTestCase):
61
103
 
62
104
  @patch("cornflow.endpoints.data_check.Airflow")
63
105
  def test_check_execution_run(self, af_client_class):
106
+ """
107
+ Test execution data check with Airflow integration.
108
+
109
+ Verifies:
110
+
111
+ - Successful data check creation
112
+ - Airflow client interaction
113
+ - Response validation
114
+ - Data consistency
115
+ """
64
116
  patch_af_client(af_client_class)
65
117
 
66
118
  exec_to_check_id = self.create_new_row(
@@ -83,7 +135,28 @@ class TestDataChecksExecutionEndpoint(CustomTestCase):
83
135
 
84
136
 
85
137
  class TestDataChecksInstanceEndpoint(CustomTestCase):
138
+ """
139
+ Test suite for instance data check endpoints.
140
+
141
+ This class tests data validation for instances:
142
+
143
+ - Instance data validation
144
+ - Run and no-run scenarios
145
+ - Configuration verification
146
+ - Response structure validation
147
+ """
148
+
86
149
  def setUp(self):
150
+ """
151
+ Set up test environment before each test.
152
+
153
+ Initializes:
154
+
155
+ - Base test configuration
156
+ - Test instance data
157
+ - Instance ID reference
158
+ - Execution model
159
+ """
87
160
  super().setUp()
88
161
 
89
162
  with open(INSTANCE_PATH) as f:
@@ -93,7 +166,16 @@ class TestDataChecksInstanceEndpoint(CustomTestCase):
93
166
  self.model = ExecutionModel
94
167
 
95
168
  def test_new_data_check_execution(self):
169
+ """
170
+ Test instance data check without running.
171
+
172
+ Verifies:
96
173
 
174
+ - Successful data check creation
175
+ - Correct response status
176
+ - Instance ID association
177
+ - Configuration settings
178
+ """
97
179
  url = DATA_CHECK_INSTANCE_URL + self.instance_id + "/?run=0"
98
180
  response = self.client.post(
99
181
  url,
@@ -112,6 +194,16 @@ class TestDataChecksInstanceEndpoint(CustomTestCase):
112
194
 
113
195
  @patch("cornflow.endpoints.data_check.Airflow")
114
196
  def test_new_data_check_execution_run(self, af_client_class):
197
+ """
198
+ Test instance data check with Airflow integration.
199
+
200
+ Verifies:
201
+
202
+ - Successful data check creation
203
+ - Airflow client interaction
204
+ - Instance association
205
+ - Configuration validation
206
+ """
115
207
  patch_af_client(af_client_class)
116
208
 
117
209
  url = DATA_CHECK_INSTANCE_URL + self.instance_id + "/"
@@ -132,7 +224,28 @@ class TestDataChecksInstanceEndpoint(CustomTestCase):
132
224
 
133
225
 
134
226
  class TestDataChecksCaseEndpoint(CustomTestCase):
227
+ """
228
+ Test suite for case data check endpoints.
229
+
230
+ This class tests data validation for cases:
231
+
232
+ - Case data validation
233
+ - Run and no-run scenarios
234
+ - Configuration verification
235
+ - Response structure validation
236
+ """
237
+
135
238
  def setUp(self):
239
+ """
240
+ Set up test environment before each test.
241
+
242
+ Initializes:
243
+
244
+ - Base test configuration
245
+ - Test case data
246
+ - Case ID reference
247
+ - Execution model
248
+ """
136
249
  super().setUp()
137
250
 
138
251
  with open(CASE_PATH) as f:
@@ -142,7 +255,16 @@ class TestDataChecksCaseEndpoint(CustomTestCase):
142
255
  self.model = ExecutionModel
143
256
 
144
257
  def test_new_data_check_execution(self):
258
+ """
259
+ Test case data check without running.
145
260
 
261
+ Verifies:
262
+
263
+ - Successful data check creation
264
+ - Correct response status
265
+ - Configuration settings
266
+ - Response validation
267
+ """
146
268
  url = DATA_CHECK_CASE_URL + str(self.case_id) + "/?run=0"
147
269
  response = self.client.post(
148
270
  url,
@@ -159,6 +281,16 @@ class TestDataChecksCaseEndpoint(CustomTestCase):
159
281
 
160
282
  @patch("cornflow.endpoints.data_check.Airflow")
161
283
  def test_new_data_check_execution_run(self, af_client_class):
284
+ """
285
+ Test case data check with Airflow integration.
286
+
287
+ Verifies:
288
+
289
+ - Successful data check creation
290
+ - Airflow client interaction
291
+ - Configuration validation
292
+ - Response structure
293
+ """
162
294
  patch_af_client(af_client_class)
163
295
 
164
296
  url = DATA_CHECK_CASE_URL + str(self.case_id) + "/"
@@ -2,13 +2,21 @@
2
2
  Unit test for the log in endpoint
3
3
  """
4
4
 
5
- # Import from libraries
5
+ import json
6
+ import logging as log
7
+ from unittest import mock
8
+
6
9
  from flask import current_app
7
10
 
8
- # Import from internal modules
11
+
12
+ from cornflow.app import create_app
13
+ from cornflow.commands.access import access_init_command
14
+ from cornflow.commands.dag import register_deployed_dags_command_test
9
15
  from cornflow.models import UserModel
10
16
  from cornflow.shared import db
11
- from cornflow.tests.custom_test_case import LoginTestCases
17
+ from cornflow.shared.const import SERVICE_ROLE, OID_GOOGLE, OID_AZURE, OID_NONE
18
+ from cornflow.tests.const import LOGIN_URL
19
+ from cornflow.tests.custom_test_case import CustomTestCase, LoginTestCases
12
20
 
13
21
 
14
22
  class TestLogIn(LoginTestCases.LoginEndpoint):
@@ -29,5 +37,475 @@ class TestLogIn(LoginTestCases.LoginEndpoint):
29
37
  self.idx = UserModel.query.filter_by(username="testname").first().id
30
38
 
31
39
  def test_successful_log_in(self):
40
+ """
41
+ Test the successful log in
42
+ """
32
43
  super().test_successful_log_in()
33
44
  self.assertEqual(self.idx, self.response.json["id"])
45
+
46
+ @mock.patch("cornflow.endpoints.login.Auth.generate_token")
47
+ def test_exception_on_token_generation(self, mock_generate_token):
48
+ # Simulate an exception when generate_token is called
49
+ mock_generate_token.side_effect = Exception("Custom exception")
50
+
51
+ # Prepare login payload
52
+ payload = self.data
53
+
54
+ # Make a login request
55
+ response = self.client.post(
56
+ LOGIN_URL,
57
+ data=json.dumps(payload),
58
+ follow_redirects=True,
59
+ headers={"Content-Type": "application/json"},
60
+ )
61
+
62
+ # Assert that the response is a 400 error
63
+ self.assertEqual(400, response.status_code)
64
+ # Assert that the error message contains the expected text
65
+ self.assertIn("Error in generating user token", response.json["error"])
66
+
67
+
68
+ class TestLogInOpenAuthNoConfig(CustomTestCase):
69
+ def create_app(self):
70
+ """
71
+ Creates and configures a Flask application for testing.
72
+
73
+ :returns: A configured Flask application instance
74
+ :rtype: Flask
75
+ """
76
+ app = create_app("testing-oauth")
77
+ app.config["SERVICE_USER_ALLOW_PASSWORD_LOGIN"] = 0
78
+ return app
79
+
80
+ def setUp(self):
81
+ log.root.setLevel(current_app.config["LOG_LEVEL"])
82
+ db.create_all()
83
+ access_init_command(verbose=False)
84
+ register_deployed_dags_command_test(verbose=False)
85
+ self.user_data = {
86
+ "username": "testname",
87
+ "email": "test@test.com",
88
+ "password": "Testpassword1!",
89
+ }
90
+
91
+ test_user = UserModel(data=self.user_data)
92
+ test_user.save()
93
+
94
+ self.user_data.pop("email")
95
+
96
+ self.test_user_id = test_user.id
97
+
98
+ self.service_data = {
99
+ "username": "service_user",
100
+ "email": "service@test.com",
101
+ "password": "Testpassword1!",
102
+ }
103
+
104
+ service_user = UserModel(data=self.service_data)
105
+ service_user.save()
106
+
107
+ self.service_data.pop("email")
108
+ self.service_user_id = service_user.id
109
+
110
+ self.assign_role(self.service_user_id, SERVICE_ROLE)
111
+
112
+ def test_service_user_login(self):
113
+ """
114
+ Tests that a service user can not log in with username and password
115
+ """
116
+ response = self.client.post(
117
+ LOGIN_URL,
118
+ data=json.dumps(self.service_data),
119
+ headers={"Content-Type": "application/json"},
120
+ )
121
+
122
+ self.assertEqual(400, response.status_code)
123
+ self.assertEqual(response.json["error"], "Invalid request")
124
+
125
+ def test_other_user_password(self):
126
+ """
127
+ Tests that a user can not log in with username and password
128
+ """
129
+ response = self.client.post(
130
+ LOGIN_URL,
131
+ data=json.dumps(self.user_data),
132
+ headers={"Content-Type": "application/json"},
133
+ )
134
+
135
+ self.assertEqual(400, response.status_code)
136
+ self.assertEqual(response.json["error"], "Invalid request")
137
+
138
+
139
+ class TestLogInOpenAuthAzure(CustomTestCase):
140
+ def create_app(self):
141
+ """
142
+ Creates and configures a Flask application for testing.
143
+
144
+ :returns: A configured Flask application instance
145
+ :rtype: Flask
146
+ """
147
+ app = create_app("testing-oauth")
148
+ app.config["SERVICE_USER_ALLOW_PASSWORD_LOGIN"] = 0
149
+ app.config["OID_PROVIDER"] = OID_AZURE
150
+ app.config["OID_CLIENT_ID"] = "SOME_SECRET"
151
+ app.config["OID_TENANT_ID"] = "SOME_SECRET"
152
+ app.config["OID_ISSUER"] = "SOME_SECRET"
153
+ return app
154
+
155
+ def setUp(self):
156
+ log.root.setLevel(current_app.config["LOG_LEVEL"])
157
+ db.create_all()
158
+ access_init_command(verbose=False)
159
+ register_deployed_dags_command_test(verbose=False)
160
+
161
+ self.service_data = {
162
+ "username": "service_user",
163
+ "email": "service@test.com",
164
+ "password": "Testpassword1!",
165
+ }
166
+
167
+ service_user = UserModel(data=self.service_data)
168
+ service_user.save()
169
+
170
+ self.service_data.pop("email")
171
+ self.service_user_id = service_user.id
172
+
173
+ self.assign_role(self.service_user_id, SERVICE_ROLE)
174
+
175
+ def test_service_user_login_first_fail(self):
176
+ """
177
+ Tests that a service user can not log in with username and password
178
+ """
179
+ response = self.client.post(
180
+ LOGIN_URL,
181
+ data=json.dumps({"token": "some_token"}),
182
+ headers={"Content-Type": "application/json"},
183
+ )
184
+
185
+ self.assertEqual(400, response.status_code)
186
+ self.assertEqual(response.json["error"], "Token is not valid")
187
+
188
+ @mock.patch("cornflow.shared.authentication.auth.jwt")
189
+ def test_service_user_login_second_fail(self, mock_header):
190
+ """
191
+ Tests second exit point on token validation
192
+ """
193
+ mock_header.get_unverified_header.return_value = None
194
+ response = self.client.post(
195
+ LOGIN_URL,
196
+ data=json.dumps({"token": "some_token"}),
197
+ headers={"Content-Type": "application/json"},
198
+ )
199
+
200
+ self.assertEqual(400, response.status_code)
201
+ self.assertEqual(response.json["error"], "Token is missing the headers")
202
+
203
+ @mock.patch("cornflow.shared.authentication.auth.jwt")
204
+ def test_service_user_login_third_fail(self, mock_header):
205
+ """
206
+ Tests third exit point on token validation
207
+ """
208
+ mock_header.get_unverified_header.return_value = {"kid": "some_value"}
209
+ response = self.client.post(
210
+ LOGIN_URL,
211
+ data=json.dumps({"token": "some_token"}),
212
+ headers={"Content-Type": "application/json"},
213
+ )
214
+
215
+ self.assertEqual(400, response.status_code)
216
+ self.assertIn(
217
+ "Error getting issuer discovery meta from", response.json["error"]
218
+ )
219
+
220
+ @mock.patch("cornflow.endpoints.login.Auth.validate_oid_token")
221
+ def test_service_user_login_no_fail(self, mock_auth):
222
+ mock_auth.return_value = {"preferred_username": "service_user"}
223
+ response = self.client.post(
224
+ LOGIN_URL,
225
+ data=json.dumps({"token": "some_token"}),
226
+ headers={"Content-Type": "application/json"},
227
+ )
228
+
229
+ print(response.json)
230
+
231
+ self.assertEqual(200, response.status_code)
232
+ self.assertEqual(self.service_user_id, response.json["id"])
233
+
234
+ @mock.patch("cornflow.endpoints.login.Auth.validate_oid_token")
235
+ def test_new_user_login_no_fail(self, mock_auth):
236
+ mock_auth.return_value = {"preferred_username": "test_user"}
237
+ response = self.client.post(
238
+ LOGIN_URL,
239
+ data=json.dumps({"token": "some_token"}),
240
+ headers={"Content-Type": "application/json"},
241
+ )
242
+
243
+ self.assertEqual(200, response.status_code)
244
+ self.assertEqual(self.service_user_id + 1, response.json["id"])
245
+
246
+
247
+ class TestLogInOpenAuthGoogle(CustomTestCase):
248
+ def create_app(self):
249
+ """
250
+ Creates and configures a Flask application for testing.
251
+
252
+ :returns: A configured Flask application instance
253
+ :rtype: Flask
254
+ """
255
+ app = create_app("testing-oauth")
256
+ app.config["SERVICE_USER_ALLOW_PASSWORD_LOGIN"] = 0
257
+ app.config["OID_PROVIDER"] = OID_GOOGLE
258
+ app.config["OID_CLIENT_ID"] = "SOME_SECRET"
259
+ app.config["OID_TENANT_ID"] = "SOME_SECRET"
260
+ app.config["OID_ISSUER"] = "SOME_SECRET"
261
+ return app
262
+
263
+ def setUp(self):
264
+ log.root.setLevel(current_app.config["LOG_LEVEL"])
265
+ db.create_all()
266
+ access_init_command(verbose=False)
267
+ register_deployed_dags_command_test(verbose=False)
268
+
269
+ self.service_data = {
270
+ "username": "service_user",
271
+ "email": "service@test.com",
272
+ "password": "Testpassword1!",
273
+ }
274
+
275
+ service_user = UserModel(data=self.service_data)
276
+ service_user.save()
277
+
278
+ self.service_data.pop("email")
279
+ self.service_user_id = service_user.id
280
+
281
+ self.assign_role(self.service_user_id, SERVICE_ROLE)
282
+
283
+ def test_service_user_login(self):
284
+ """
285
+ Tests that a service user can not log in with username and password
286
+ """
287
+ response = self.client.post(
288
+ LOGIN_URL,
289
+ data=json.dumps({"token": "some_token"}),
290
+ headers={"Content-Type": "application/json"},
291
+ )
292
+
293
+ self.assertEqual(501, response.status_code)
294
+ self.assertEqual(
295
+ response.json["error"], "The selected OID provider is not implemented"
296
+ )
297
+
298
+
299
+ class TestLogInOpenAuthNone(CustomTestCase):
300
+ def create_app(self):
301
+ """
302
+ Creates and configures a Flask application for testing.
303
+
304
+ :returns: A configured Flask application instance
305
+ :rtype: Flask
306
+ """
307
+ app = create_app("testing-oauth")
308
+ app.config["SERVICE_USER_ALLOW_PASSWORD_LOGIN"] = 0
309
+ app.config["OID_PROVIDER"] = OID_NONE
310
+ app.config["OID_CLIENT_ID"] = "SOME_SECRET"
311
+ app.config["OID_TENANT_ID"] = "SOME_SECRET"
312
+ app.config["OID_ISSUER"] = "SOME_SECRET"
313
+ return app
314
+
315
+ def setUp(self):
316
+ log.root.setLevel(current_app.config["LOG_LEVEL"])
317
+ db.create_all()
318
+ access_init_command(verbose=False)
319
+ register_deployed_dags_command_test(verbose=False)
320
+
321
+ self.service_data = {
322
+ "username": "service_user",
323
+ "email": "service@test.com",
324
+ "password": "Testpassword1!",
325
+ }
326
+
327
+ service_user = UserModel(data=self.service_data)
328
+ service_user.save()
329
+
330
+ self.service_data.pop("email")
331
+ self.service_user_id = service_user.id
332
+
333
+ self.assign_role(self.service_user_id, SERVICE_ROLE)
334
+
335
+ def test_service_user_login(self):
336
+ """
337
+ Tests that a service user can not log in with username and password
338
+ """
339
+ response = self.client.post(
340
+ LOGIN_URL,
341
+ data=json.dumps({"token": "some_token"}),
342
+ headers={"Content-Type": "application/json"},
343
+ )
344
+
345
+ self.assertEqual(501, response.status_code)
346
+ self.assertEqual(
347
+ response.json["error"], "The OID provider configuration is not valid"
348
+ )
349
+
350
+
351
+ class TestLogInOpenAuthOther(CustomTestCase):
352
+ def create_app(self):
353
+ """
354
+ Creates and configures a Flask application for testing.
355
+
356
+ :returns: A configured Flask application instance
357
+ :rtype: Flask
358
+ """
359
+ app = create_app("testing-oauth")
360
+ app.config["SERVICE_USER_ALLOW_PASSWORD_LOGIN"] = 0
361
+ app.config["OID_PROVIDER"] = 3
362
+ app.config["OID_CLIENT_ID"] = "SOME_SECRET"
363
+ app.config["OID_TENANT_ID"] = "SOME_SECRET"
364
+ app.config["OID_ISSUER"] = "SOME_SECRET"
365
+ return app
366
+
367
+ def setUp(self):
368
+ log.root.setLevel(current_app.config["LOG_LEVEL"])
369
+ db.create_all()
370
+ access_init_command(verbose=False)
371
+ register_deployed_dags_command_test(verbose=False)
372
+
373
+ self.service_data = {
374
+ "username": "service_user",
375
+ "email": "service@test.com",
376
+ "password": "Testpassword1!",
377
+ }
378
+
379
+ service_user = UserModel(data=self.service_data)
380
+ service_user.save()
381
+
382
+ self.service_data.pop("email")
383
+ self.service_user_id = service_user.id
384
+
385
+ self.assign_role(self.service_user_id, SERVICE_ROLE)
386
+
387
+ def test_service_user_login(self):
388
+ """
389
+ Tests that a service user can not log in with username and password
390
+ """
391
+ response = self.client.post(
392
+ LOGIN_URL,
393
+ data=json.dumps({"token": "some_token"}),
394
+ headers={"Content-Type": "application/json"},
395
+ )
396
+
397
+ self.assertEqual(501, response.status_code)
398
+ self.assertEqual(
399
+ response.json["error"], "The OID provider configuration is not valid"
400
+ )
401
+
402
+
403
+ class TestLogInOpenAuthService(CustomTestCase):
404
+
405
+ def create_app(self):
406
+ """
407
+ Creates and configures a Flask application for testing.
408
+
409
+ :returns: A configured Flask application instance
410
+ :rtype: Flask
411
+ """
412
+ app = create_app("testing-oauth")
413
+ return app
414
+
415
+ def setUp(self):
416
+ log.root.setLevel(current_app.config["LOG_LEVEL"])
417
+ db.create_all()
418
+ access_init_command(verbose=False)
419
+ register_deployed_dags_command_test(verbose=False)
420
+ self.user_data = {
421
+ "username": "testname",
422
+ "email": "test@test.com",
423
+ "password": "Testpassword1!",
424
+ }
425
+
426
+ test_user = UserModel(data=self.user_data)
427
+ test_user.save()
428
+
429
+ self.user_data.pop("email")
430
+
431
+ self.test_user_id = test_user.id
432
+
433
+ self.service_data = {
434
+ "username": "service_user",
435
+ "email": "service@test.com",
436
+ "password": "Testpassword1!",
437
+ }
438
+
439
+ service_user = UserModel(data=self.service_data)
440
+ service_user.save()
441
+
442
+ self.service_data.pop("email")
443
+ self.service_user_id = service_user.id
444
+
445
+ self.assign_role(self.service_user_id, SERVICE_ROLE)
446
+
447
+ def test_service_user_login(self):
448
+ """
449
+ Tests that a service user can log in with username and password
450
+ """
451
+
452
+ response = self.client.post(
453
+ LOGIN_URL,
454
+ data=json.dumps(self.service_data),
455
+ headers={"Content-Type": "application/json"},
456
+ )
457
+
458
+ self.assertEqual(200, response.status_code)
459
+ self.assertEqual(self.service_user_id, response.json["id"])
460
+
461
+ def test_validation_error(self):
462
+ """
463
+ Tests that a user can not log in without token or username and password
464
+ """
465
+ response = self.client.post(
466
+ LOGIN_URL,
467
+ data=json.dumps({}),
468
+ headers={"Content-Type": "application/json"},
469
+ )
470
+
471
+ self.assertEqual(400, response.status_code)
472
+
473
+ def test_other_user_password(self):
474
+ """
475
+ Tests that a user can not log in with username and password
476
+ """
477
+ response = self.client.post(
478
+ LOGIN_URL,
479
+ data=json.dumps(self.user_data),
480
+ headers={"Content-Type": "application/json"},
481
+ )
482
+
483
+ self.assertEqual(400, response.status_code)
484
+ self.assertEqual(response.json["error"], "Invalid request")
485
+
486
+ def test_token_login(self):
487
+ """
488
+ Tests that a user can log in with a token
489
+ """
490
+ response = self.client.post(
491
+ LOGIN_URL,
492
+ data=json.dumps({"token": "test"}),
493
+ headers={"Content-Type": "application/json"},
494
+ )
495
+
496
+ self.assertEqual(501, response.status_code)
497
+ self.assertEqual(
498
+ response.json["error"], "The OID provider configuration is not valid"
499
+ )
500
+
501
+ def test_log_in_with_all_fields(self):
502
+ """
503
+ Tests that a user can not log in with username and password and a token
504
+ """
505
+ response = self.client.post(
506
+ LOGIN_URL,
507
+ data=json.dumps({**self.service_data, "token": "test"}),
508
+ headers={"Content-Type": "application/json"},
509
+ )
510
+
511
+ self.assertEqual(400, response.status_code)