tcms.rpc.tests.test_testrun   B
last analyzed

Complexity

Total Complexity 49

Size/Duplication

Total Lines 594
Duplicated Lines 8.25 %

Importance

Changes 0
Metric Value
wmc 49
eloc 442
dl 49
loc 594
rs 8.48
c 0
b 0
f 0

37 Methods

Rating   Name   Duplication   Size   Complexity  
A TestAddCase._fixture_setup() 0 13 1
A TestRemovesCase._fixture_setup() 0 14 1
A TestFilter.test_filter() 0 25 1
A TestCreatePermission.verify_api_without_permission() 0 3 2
A TestFilter._fixture_setup() 0 10 1
A TestRemovesCase.test_remove_case_without_permissions() 0 21 2
A TestRemoveTag.test_remove_tag() 0 17 1
A TestRemovesCase.test_nothing_change_if_invalid_case_passed() 0 7 1
A TestAddCase.test_add_case() 0 20 2
A TestAddTag._fixture_setup() 0 21 1
A TestFilter.test_empty_query() 0 5 1
A TestRemovesCase.test_nothing_change_if_invalid_run_passed() 0 7 1
A TestGetCasesPermission.verify_api_with_permission() 0 3 1
A TestAddTag.test_add_tag_without_permissions() 22 22 2
A TestRemoveTag.test_remove_tag_without_permissions() 27 27 2
A TestUpdateTestRun.test_wrong_date_format() 0 27 2
A TestUpdatePermission.verify_api_without_permission() 0 3 2
A TestGetCasesPermission._fixture_setup() 0 4 1
A TestAddCase.test_add_case_without_permissions() 0 21 2
A TestUpdatePermission.verify_api_with_permission() 0 8 1
A TestFilterPermission.verify_api_without_permission() 0 3 2
A TestGetCasesPermission.verify_api_without_permission() 0 3 2
A TestUpdateTestRun._fixture_setup() 0 13 1
A TestGetCases.test_get_empty_result_if_no_case_added() 0 3 1
A TestGetCases.test_get_cases() 0 26 1
A TestRemoveTag._fixture_setup() 0 27 2
A TestUpdateTestRun.test_update_with_product() 0 25 1
A TestRunCreate.test_create_with_invalid_value() 0 10 2
A TestCreatePermission.verify_api_with_permission() 0 17 1
A TestGetCases._fixture_setup() 0 9 1
A TestRemovesCase.test_should_remove_an_execution() 0 4 1
A TestRunCreate._fixture_setup() 0 5 1
A TestAddTag.test_add_tag() 0 10 1
A TestUpdateTestRun.test_successful_update() 0 33 1
A TestFilterPermission.verify_api_with_permission() 0 3 1
A TestUpdatePermission._fixture_setup() 0 9 1
A TestCreatePermission._fixture_setup() 0 17 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complexity

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like tcms.rpc.tests.test_testrun often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
# -*- coding: utf-8 -*-
2
# pylint: disable=attribute-defined-outside-init, objects-update-used
3
from datetime import datetime
4
from xmlrpc.client import Fault as XmlRPCFault
5
from xmlrpc.client import ProtocolError
6
7
from django.contrib.auth.models import Permission
8
from django.utils.translation import gettext_lazy as _
9
from tcms_api import xmlrpc
10
11
from tcms.rpc.tests.utils import APIPermissionsTestCase, APITestCase
12
from tcms.testcases.models import TestCaseStatus
13
from tcms.testruns.models import TestExecution, TestRun
14
from tcms.tests import remove_perm_from_user
15
from tcms.tests.factories import (
16
    BuildFactory,
17
    ProductFactory,
18
    TagFactory,
19
    TestCaseFactory,
20
    TestExecutionFactory,
21
    TestPlanFactory,
22
    TestRunFactory,
23
    UserFactory,
24
    VersionFactory,
25
)
26
27
28
class TestAddCase(APITestCase):
29
    def _fixture_setup(self):
30
        super()._fixture_setup()
31
32
        self.plan = TestPlanFactory(author=self.api_user)
33
34
        self.test_case = TestCaseFactory()
35
        self.test_case.case_status = TestCaseStatus.objects.filter(
36
            is_confirmed=True
37
        ).first()
38
        self.test_case.save()  # generate history object
39
        self.plan.add_case(self.test_case)
40
41
        self.test_run = TestRunFactory(plan=self.plan)
42
43
    def test_add_case(self):
44
        executions = self.rpc_client.TestRun.add_case(
45
            self.test_run.pk, self.test_case.pk
46
        )
47
        self.assertIsInstance(executions, list)
48
49
        for result in executions:
50
            self.assertIn("id", result)
51
            self.assertIn("assignee", result)
52
            self.assertEqual(result["tested_by"], None)
53
            self.assertIn("case_text_version", result)
54
            self.assertIn("start_date", result)
55
            self.assertIn("stop_date", result)
56
            self.assertIn("sortkey", result)
57
            self.assertEqual(result["run"], self.test_run.pk)
58
            self.assertEqual(result["case"], self.test_case.pk)
59
            self.assertIn("build", result)
60
            self.assertIn("status", result)
61
            self.assertIn("properties", result)
62
            self.assertIsInstance(result["properties"], list)
63
64
    def test_add_case_without_permissions(self):
65
        unauthorized_user = UserFactory()
66
        unauthorized_user.set_password("api-testing")
67
        unauthorized_user.save()
68
69
        unauthorized_user.user_permissions.add(*Permission.objects.all())
70
        remove_perm_from_user(unauthorized_user, "testruns.add_testexecution")
71
72
        rpc_client = xmlrpc.TCMSXmlrpc(
73
            unauthorized_user.username,
74
            "api-testing",
75
            f"{self.live_server_url}/xml-rpc/",
76
        ).server
77
78
        with self.assertRaisesRegex(ProtocolError, "403 Forbidden"):
79
            rpc_client.TestRun.add_case(self.test_run.pk, self.test_case.pk)
80
81
        exists = TestExecution.objects.filter(
82
            run=self.test_run.pk, case=self.test_case.pk
83
        ).exists()
84
        self.assertFalse(exists)
85
86
87
class TestRemovesCase(APITestCase):
88
    def _fixture_setup(self):
89
        super()._fixture_setup()
90
91
        self.plan = TestPlanFactory(author=self.api_user)
92
93
        self.test_case = TestCaseFactory()
94
        self.test_case.save()  # generate history object
95
        self.plan.add_case(self.test_case)
96
97
        self.test_run = TestRunFactory(plan=self.plan)
98
        self.test_execution = TestExecutionFactory(
99
            run=self.test_run, case=self.test_case
100
        )
101
        self.test_execution.save()
102
103
    def test_nothing_change_if_invalid_case_passed(self):
104
        self.rpc_client.TestRun.remove_case(self.test_run.pk, 999999)
105
        self.test_execution.refresh_from_db()
106
        self.assertTrue(
107
            TestExecution.objects.filter(pk=self.test_execution.pk).exists()
108
        )
109
        self.assertEqual(1, TestExecution.objects.count())
110
111
    def test_nothing_change_if_invalid_run_passed(self):
112
        self.rpc_client.TestRun.remove_case(99999, self.test_case.pk)
113
        self.test_execution.refresh_from_db()
114
        self.assertTrue(
115
            TestExecution.objects.filter(pk=self.test_execution.pk).exists()
116
        )
117
        self.assertEqual(1, TestExecution.objects.count())
118
119
    def test_remove_case_without_permissions(self):
120
        unauthorized_user = UserFactory()
121
        unauthorized_user.set_password("api-testing")
122
        unauthorized_user.save()
123
124
        unauthorized_user.user_permissions.add(*Permission.objects.all())
125
        remove_perm_from_user(unauthorized_user, "testruns.delete_testexecution")
126
127
        rpc_client = xmlrpc.TCMSXmlrpc(
128
            unauthorized_user.username,
129
            "api-testing",
130
            f"{self.live_server_url}/xml-rpc/",
131
        ).server
132
133
        with self.assertRaisesRegex(ProtocolError, "403 Forbidden"):
134
            rpc_client.TestRun.remove_case(self.test_run.pk, self.test_case.pk)
135
136
        exists = TestExecution.objects.filter(
137
            run=self.test_run.pk, case=self.test_case.pk
138
        ).exists()
139
        self.assertTrue(exists)
140
141
    def test_should_remove_an_execution(self):
142
        self.rpc_client.TestRun.remove_case(self.test_run.pk, self.test_case.pk)
143
        self.assertFalse(
144
            TestExecution.objects.filter(pk=self.test_execution.pk).exists()
145
        )
146
147
148
class TestGetCases(APITestCase):
149
    def _fixture_setup(self):
150
        super()._fixture_setup()
151
152
        self.test_case = TestCaseFactory()
153
        self.test_case.case_status = TestCaseStatus.objects.filter(
154
            is_confirmed=True
155
        ).first()
156
        self.test_case.save()
157
        self.test_run = TestRunFactory()
158
159
    def test_get_empty_result_if_no_case_added(self):
160
        result = self.rpc_client.TestRun.get_cases(self.test_run.pk)
161
        self.assertEqual(0, len(result))
162
163
    def test_get_cases(self):
164
        self.test_run.create_execution(case=self.test_case)
165
        result = self.rpc_client.TestRun.get_cases(self.test_run.pk)
166
        self.assertEqual(1, len(result))
167
168
        case = result[0]
169
170
        self.assertEqual(case["id"], self.test_case.pk)
171
        self.assertIn("execution_id", case)
172
        self.assertIn("status", case)
173
174
        self.assertIn("create_date", case)
175
        self.assertIn("is_automated", case)
176
        self.assertIn("script", case)
177
        self.assertIn("arguments", case)
178
        self.assertIn("extra_link", case)
179
        self.assertIn("summary", case)
180
        self.assertIn("requirement", case)
181
        self.assertIn("notes", case)
182
        self.assertIn("text", case)
183
        self.assertIn("case_status", case)
184
        self.assertIn("category", case)
185
        self.assertIn("priority", case)
186
        self.assertIn("author", case)
187
        self.assertIn("default_tester", case)
188
        self.assertIn("reviewer", case)
189
190
191
class TestGetCasesPermission(APIPermissionsTestCase):
192
    permission_label = "testruns.view_testrun"
193
194
    def _fixture_setup(self):
195
        super()._fixture_setup()
196
197
        self.test_run = TestRunFactory()
198
199
    def verify_api_with_permission(self):
200
        result = self.rpc_client.TestRun.get_cases(self.test_run.pk)
201
        self.assertTrue(isinstance(result, list))
202
203
    def verify_api_without_permission(self):
204
        with self.assertRaisesRegex(ProtocolError, "403 Forbidden"):
205
            self.rpc_client.TestRun.get_cases(self.test_run.pk)
206
207
208
class TestAddTag(APITestCase):
209
    def _fixture_setup(self):
210
        super()._fixture_setup()
211
212
        self.plan = TestPlanFactory(author=self.api_user)
213
        self.build = BuildFactory(version=self.plan.product_version)
214
215
        self.test_runs = [
216
            TestRunFactory(
217
                build=self.build,
218
                default_tester=None,
219
                plan=self.plan,
220
            ),
221
            TestRunFactory(
222
                build=self.build,
223
                default_tester=None,
224
                plan=self.plan,
225
            ),
226
        ]
227
228
        self.tag0 = TagFactory(name="xmlrpc_test_tag_0")
229
        self.tag1 = TagFactory(name="xmlrpc_test_tag_1")
230
231
    def test_add_tag(self):
232
        result = self.rpc_client.TestRun.add_tag(self.test_runs[0].pk, self.tag0.name)
233
        self.assertEqual(len(result), 1)
234
        self.assertEqual(result[0]["id"], self.tag0.pk)
235
        self.assertEqual(result[0]["name"], self.tag0.name)
236
237
        tag_exists = TestRun.objects.filter(
238
            pk=self.test_runs[0].pk, tag__pk=self.tag0.pk
239
        ).exists()
240
        self.assertTrue(tag_exists)
241
242 View Code Duplication
    def test_add_tag_without_permissions(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
243
        unauthorized_user = UserFactory()
244
        unauthorized_user.set_password("api-testing")
245
        unauthorized_user.save()
246
247
        unauthorized_user.user_permissions.add(*Permission.objects.all())
248
        remove_perm_from_user(unauthorized_user, "testruns.add_testruntag")
249
250
        rpc_client = xmlrpc.TCMSXmlrpc(
251
            unauthorized_user.username,
252
            "api-testing",
253
            f"{self.live_server_url}/xml-rpc/",
254
        ).server
255
256
        with self.assertRaisesRegex(ProtocolError, "403 Forbidden"):
257
            rpc_client.TestRun.add_tag(self.test_runs[0].pk, self.tag0.name)
258
259
        # tags were not modified
260
        tag_exists = TestRun.objects.filter(
261
            pk=self.test_runs[0].pk, tag__pk=self.tag0.pk
262
        ).exists()
263
        self.assertFalse(tag_exists)
264
265
266
class TestRemoveTag(APITestCase):
267
    def _fixture_setup(self):
268
        super()._fixture_setup()
269
270
        self.product = ProductFactory()
271
        self.version = VersionFactory(product=self.product)
272
        self.build = BuildFactory(version=self.version)
273
        self.plan = TestPlanFactory(author=self.api_user, product=self.product)
274
275
        self.test_runs = [
276
            TestRunFactory(
277
                build=self.build,
278
                default_tester=None,
279
                plan=self.plan,
280
            ),
281
            TestRunFactory(
282
                build=self.build,
283
                default_tester=None,
284
                plan=self.plan,
285
            ),
286
        ]
287
288
        self.tag0 = TagFactory(name="xmlrpc_test_tag_0")
289
        self.tag1 = TagFactory(name="xmlrpc_test_tag_1")
290
291
        for tag in [self.tag0, self.tag1]:
292
            self.test_runs[0].add_tag(tag)
293
            self.test_runs[1].add_tag(tag)
294
295
    def test_remove_tag(self):
296
        result = self.rpc_client.TestRun.remove_tag(
297
            self.test_runs[0].pk, self.tag0.name
298
        )
299
        self.assertEqual(len(result), 1)
300
        self.assertEqual(result[0]["id"], self.tag1.pk)
301
        self.assertEqual(result[0]["name"], self.tag1.name)
302
303
        tag_exists = TestRun.objects.filter(
304
            pk=self.test_runs[0].pk, tag__pk=self.tag0.pk
305
        ).exists()
306
        self.assertFalse(tag_exists)
307
308
        tag_exists = TestRun.objects.filter(
309
            pk=self.test_runs[0].pk, tag__pk=self.tag1.pk
310
        ).exists()
311
        self.assertTrue(tag_exists)
312
313 View Code Duplication
    def test_remove_tag_without_permissions(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
314
        unauthorized_user = UserFactory()
315
        unauthorized_user.set_password("api-testing")
316
        unauthorized_user.save()
317
318
        unauthorized_user.user_permissions.add(*Permission.objects.all())
319
        remove_perm_from_user(unauthorized_user, "testruns.delete_testruntag")
320
321
        rpc_client = xmlrpc.TCMSXmlrpc(
322
            unauthorized_user.username,
323
            "api-testing",
324
            f"{self.live_server_url}/xml-rpc/",
325
        ).server
326
327
        with self.assertRaisesRegex(ProtocolError, "403 Forbidden"):
328
            rpc_client.TestRun.remove_tag(self.test_runs[0].pk, self.tag0.name)
329
330
        # tags were not modified
331
        tag_exists = TestRun.objects.filter(
332
            pk=self.test_runs[0].pk, tag__pk=self.tag0.pk
333
        ).exists()
334
        self.assertTrue(tag_exists)
335
336
        tag_exists = TestRun.objects.filter(
337
            pk=self.test_runs[0].pk, tag__pk=self.tag1.pk
338
        ).exists()
339
        self.assertTrue(tag_exists)
340
341
342
class TestRunCreate(APITestCase):
343
    def _fixture_setup(self):
344
        super()._fixture_setup()
345
346
        self.plan = TestPlanFactory(author=self.api_user)
347
        self.build = BuildFactory(version=self.plan.product_version)
348
349
    def test_create_with_invalid_value(self):
350
        test_run_fields = {
351
            "plan": self.plan.pk,
352
            "build": self.build.pk,
353
            "summary": "TR without version",
354
            "manager": "manager",
355
        }
356
357
        with self.assertRaisesRegex(XmlRPCFault, 'Unknown user: "manager"'):
358
            self.rpc_client.TestRun.create(test_run_fields)
359
360
361
class TestCreatePermission(APIPermissionsTestCase):
362
    permission_label = "testruns.add_testrun"
363
364
    def _fixture_setup(self):
365
        super()._fixture_setup()
366
367
        self.plan = TestPlanFactory()
368
        self.build = BuildFactory(version=self.plan.product_version)
369
370
        self.test_run_fields = {
371
            "plan": self.plan.pk,
372
            "build": self.build.pk,
373
            "summary": "TR created",
374
            "manager": UserFactory().pk,
375
            "start_date": datetime.strptime("2020-05-05", "%Y-%m-%d"),
376
            "stop_date": datetime.strptime("2020-05-05 00:00:00", "%Y-%m-%d %H:%M:%S"),
377
            "planned_start": datetime.strptime(
378
                "2020-05-05 09:00:00", "%Y-%m-%d %H:%M:%S"
379
            ),
380
            "planned_stop": datetime.strptime("2020-05-06", "%Y-%m-%d"),
381
        }
382
383
    def verify_api_with_permission(self):
384
        result = self.rpc_client.TestRun.create(self.test_run_fields)
385
386
        run_id = result["id"]
387
        test_run = TestRun.objects.get(pk=run_id)
388
389
        self.assertIn("id", result)
390
        self.assertEqual(result["summary"], self.test_run_fields["summary"])
391
        self.assertIn("notes", result)
392
        self.assertEqual(result["stop_date"], test_run.stop_date)
393
        self.assertEqual(result["start_date"], test_run.start_date)
394
        self.assertEqual(result["planned_start"], test_run.planned_start)
395
        self.assertEqual(result["planned_stop"], test_run.planned_stop)
396
        self.assertEqual(result["plan"], self.plan.pk)
397
        self.assertEqual(result["build"], self.build.pk)
398
        self.assertEqual(result["manager"], self.test_run_fields["manager"])
399
        self.assertIn("default_tester", result)
400
401
    def verify_api_without_permission(self):
402
        with self.assertRaisesRegex(ProtocolError, "403 Forbidden"):
403
            self.rpc_client.TestRun.create(self.test_run_fields)
404
405
406
class TestFilter(APITestCase):
407
    def _fixture_setup(self):
408
        super()._fixture_setup()
409
410
        self.plan = TestPlanFactory()
411
412
        self.test_case = TestCaseFactory()
413
        self.test_case.save()
414
        self.plan.add_case(self.test_case)
415
416
        self.test_run = TestRunFactory(plan=self.plan)
417
418
    def test_empty_query(self):
419
        result = self.rpc_client.TestRun.filter()
420
        self.assertTrue(isinstance(result, list))
421
        self.assertEqual(1, len(result))
422
        self.assertEqual(self.test_run.pk, result[0]["id"])
423
424
    def test_filter(self):
425
        _ = TestRunFactory()
426
        result = self.rpc_client.TestRun.filter({"plan": self.plan.pk})
427
        self.assertEqual(1, len(result))
428
429
        result = result[0]
430
431
        self.assertEqual(result["id"], self.test_run.pk)
432
        self.assertEqual(
433
            result["plan__product_version"], self.test_run.plan.product_version.pk
434
        )
435
        self.assertEqual(
436
            result["plan__product_version__value"],
437
            self.test_run.plan.product_version.value,
438
        )
439
        self.assertEqual(result["start_date"], self.test_run.start_date)
440
        self.assertEqual(result["stop_date"], self.test_run.stop_date)
441
        self.assertEqual(result["planned_start"], self.test_run.planned_start)
442
        self.assertEqual(result["planned_stop"], self.test_run.planned_stop)
443
        self.assertEqual(result["summary"], self.test_run.summary)
444
        self.assertEqual(result["notes"], self.test_run.notes)
445
        self.assertEqual(result["plan"], self.test_run.plan.pk)
446
        self.assertEqual(result["build"], self.test_run.build.pk)
447
        self.assertEqual(result["manager"], self.test_run.manager.pk)
448
        self.assertEqual(result["default_tester"], self.test_run.default_tester.pk)
449
450
451
class TestFilterPermission(APIPermissionsTestCase):
452
    permission_label = "testruns.view_testrun"
453
454
    def verify_api_with_permission(self):
455
        result = self.rpc_client.TestRun.filter()
456
        self.assertTrue(isinstance(result, list))
457
458
    def verify_api_without_permission(self):
459
        with self.assertRaisesRegex(ProtocolError, "403 Forbidden"):
460
            self.rpc_client.TestRun.filter(None)
461
462
463
class TestUpdateTestRun(APITestCase):
464
    def _fixture_setup(self):
465
        super()._fixture_setup()
466
467
        self.test_run = TestRunFactory()
468
469
        self.updated_test_plan = TestPlanFactory()
470
        self.updated_build = BuildFactory()
471
        self.updated_summary = "Updated summary."
472
        self.updated_stop_date = datetime.strptime("2020-05-05", "%Y-%m-%d")
473
        self.updated_planned_start = datetime.strptime(
474
            "2020-05-05 09:00:00", "%Y-%m-%d %H:%M:%S"
475
        )
476
        self.updated_planned_stop = datetime.strptime("2020-05-06", "%Y-%m-%d")
477
478
    def test_successful_update(self):
479
        update_fields = {
480
            "plan": self.updated_test_plan.pk,
481
            "build": self.updated_build.pk,
482
            "summary": self.updated_summary,
483
            "stop_date": self.updated_stop_date,
484
            "planned_start": self.updated_planned_start,
485
            "planned_stop": self.updated_planned_stop,
486
        }
487
488
        # assert test run is not updated yet
489
        self.assertNotEqual(self.updated_test_plan, self.test_run.plan.name)
490
        self.assertNotEqual(self.updated_build, self.test_run.build.name)
491
        self.assertNotEqual(self.updated_summary, self.test_run.summary)
492
        self.assertNotEqual(self.updated_stop_date, self.test_run.stop_date)
493
        self.assertNotEqual(self.updated_planned_start, self.test_run.planned_start)
494
        self.assertNotEqual(self.updated_planned_stop, self.test_run.planned_stop)
495
496
        result = self.rpc_client.TestRun.update(self.test_run.pk, update_fields)
497
        self.test_run.refresh_from_db()
498
499
        # compare result, returned from API call with test run from DB
500
        self.assertEqual(result["id"], self.test_run.pk)
501
        self.assertEqual(result["start_date"], self.test_run.start_date)
502
        self.assertEqual(result["stop_date"], self.test_run.stop_date)
503
        self.assertEqual(result["planned_start"], self.test_run.planned_start)
504
        self.assertEqual(result["planned_stop"], self.test_run.planned_stop)
505
        self.assertEqual(result["summary"], self.test_run.summary)
506
        self.assertEqual(result["notes"], self.test_run.notes)
507
        self.assertEqual(result["plan"], self.test_run.plan.pk)
508
        self.assertEqual(result["build"], self.test_run.build.pk)
509
        self.assertEqual(result["manager"], self.test_run.manager.pk)
510
        self.assertEqual(result["default_tester"], self.test_run.default_tester.pk)
511
512
    def test_wrong_date_format(self):
513
        test_run = TestRunFactory()
514
        update_fields = {
515
            "plan": self.updated_test_plan.pk,
516
            "build": self.updated_build.pk,
517
            "summary": self.updated_summary,
518
            "stop_date": "10-10-2010",
519
            "planned_stop": "11-10-2010",
520
        }
521
522
        with self.assertRaisesMessage(
523
            Exception, str(_("Invalid date format. Expected YYYY-MM-DD [HH:MM:SS]."))
524
        ):
525
            self.rpc_client.TestRun.update(test_run.pk, update_fields)
526
527
        # assert test run fields have not been updated
528
        test_run.refresh_from_db()
529
        self.assertNotEqual(update_fields["plan"], test_run.plan.pk)
530
        self.assertNotEqual(update_fields["build"], test_run.build.pk)
531
        self.assertNotEqual(update_fields["summary"], test_run.summary)
532
        self.assertNotEqual(
533
            datetime.strptime(update_fields["stop_date"], "%d-%m-%Y"),
534
            test_run.stop_date,
535
        )
536
        self.assertNotEqual(
537
            datetime.strptime(update_fields["planned_stop"], "%d-%m-%Y"),
538
            test_run.planned_stop,
539
        )
540
541
    def test_update_with_product(self):
542
        test_run = TestRunFactory()
543
        product = ProductFactory()
544
        updated_test_plan = TestPlanFactory(product=product)
545
        updated_build = BuildFactory(version=product.version.first())
546
        updated_summary = "Updated summary."
547
        updated_stop_date = "2020-05-05 00:00:00"
548
549
        updated_test_run = self.rpc_client.TestRun.update(
550
            test_run.pk,
551
            {
552
                "plan": updated_test_plan.pk,
553
                "product": product.id,
554
                "build": updated_build.pk,
555
                "summary": updated_summary,
556
                "stop_date": updated_stop_date,
557
            },
558
        )
559
560
        test_run.refresh_from_db()
561
562
        self.assertEqual(updated_test_run["plan"], updated_test_plan.pk)
563
        self.assertEqual(updated_test_run["build"], updated_build.pk)
564
        self.assertEqual(updated_test_run["summary"], updated_summary)
565
        self.assertEqual(updated_test_run["stop_date"], test_run.stop_date)
566
567
568
class TestUpdatePermission(APIPermissionsTestCase):
569
    permission_label = "testruns.change_testrun"
570
571
    def _fixture_setup(self):
572
        super()._fixture_setup()
573
574
        self.test_run = TestRunFactory()
575
        self.update_fields = {
576
            "plan": TestPlanFactory().pk,
577
            "build": BuildFactory().pk,
578
            "summary": "Updated summary.",
579
            "stop_date": "2020-05-05 00:00:00",
580
        }
581
582
    def verify_api_with_permission(self):
583
        updated_test_run = self.rpc_client.TestRun.update(
584
            self.test_run.pk, self.update_fields
585
        )
586
        self.test_run.refresh_from_db()
587
588
        self.assertEqual(updated_test_run["summary"], self.update_fields["summary"])
589
        self.assertEqual(updated_test_run["stop_date"], self.test_run.stop_date)
590
591
    def verify_api_without_permission(self):
592
        with self.assertRaisesRegex(ProtocolError, "403 Forbidden"):
593
            self.rpc_client.TestRun.update(self.test_run.pk, self.update_fields)
594