Completed
Push — master ( 35953d...7928c8 )
by Alexander
114:44 queued 112:42
created

TestExecutionAddLinkPermissions.verify_api_without_permission()   A

Complexity

Conditions 2

Size

Total Lines 7
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 2
nop 1
1
# -*- coding: utf-8 -*-
2
# pylint: disable=invalid-name, attribute-defined-outside-init, objects-update-used
3
4
from xmlrpc.client import Fault as XmlRPCFault
5
from xmlrpc.client import ProtocolError
6
7
from django.test import override_settings
8
from django.utils import timezone
9
10
from tcms.core.contrib.linkreference.models import LinkReference
11
from tcms.core.helpers.comments import get_comments
12
from tcms.rpc.tests.utils import APITestCase, APIPermissionsTestCase
13
from tcms.testruns.models import TestExecutionStatus
14
from tcms.tests.factories import (BuildFactory,
15
                                  TestCaseFactory, TestExecutionFactory,
16
                                  TestPlanFactory, TestRunFactory, UserFactory,
17
                                  VersionFactory, LinkReferenceFactory)
18
19
20
@override_settings(LANGUAGE_CODE='en')
21
class TestExecutionCreate(APITestCase):  # pylint: disable=too-many-instance-attributes
22
    """Test TestExecution.create"""
23
24
    def _fixture_setup(self):
25
        super()._fixture_setup()
26
27
        self.staff = UserFactory()
28
29
        self.version = VersionFactory()
30
        self.build = self.version.product.build.first()
31
        self.plan = TestPlanFactory(author=self.api_user, product=self.version.product)
32
        self.test_run = TestRunFactory(product_version=self.version, build=self.build,
33
                                       default_tester=None, plan=self.plan)
34
        self.status = TestExecutionStatus.objects.filter(weight=0).first()
35
        self.case = TestCaseFactory(author=self.api_user, default_tester=None, plan=[self.plan])
36
37
    def test_create_with_no_required_fields(self):
38
        values = [
39
            {
40
                "assignee": self.staff.pk,
41
                "status": self.status.pk,
42
            },
43
            {
44
                "build": self.build.pk,
45
                "assignee": self.staff.pk,
46
                "status": 1,
47
            },
48
            {
49
                "run": self.test_run.pk,
50
                "build": self.build.pk,
51
                "assignee": self.staff.pk,
52
                "status": self.status.pk,
53
            },
54
        ]
55
        for value in values:
56
            with self.assertRaisesRegex(XmlRPCFault, 'This field is required'):
57
                self.rpc_client.TestExecution.create(value)
58
59
    def test_create_with_required_fields(self):
60
        execution = self.rpc_client.TestExecution.create({
61
            "run": self.test_run.pk,
62
            "build": self.build.pk,
63
            "case": self.case.pk,
64
            "case_text_version": 15,
65
        })
66
        self.assertIsNotNone(execution)
67
        self.assertIsNotNone(execution['id'])
68
        self.assertEqual(execution['build_id'], self.build.pk)
69
        self.assertEqual(execution['case_id'], self.case.pk)
70
        self.assertEqual(execution['run_id'], self.test_run.pk)
71
72
    def test_create_with_all_fields(self):
73
        execution = self.rpc_client.TestExecution.create({
74
            "run": self.test_run.pk,
75
            "build": self.build.pk,
76
            "case": self.case.pk,
77
            "assignee": self.api_user.pk,
78
            "sortkey": 90,
79
            "status": self.status.pk,
80
            "case_text_version": 3,
81
        })
82
        self.assertIsNotNone(execution)
83
        self.assertIsNotNone(execution['id'])
84
        self.assertEqual(execution['build_id'], self.build.pk)
85
        self.assertEqual(execution['case_id'], self.case.pk)
86
        self.assertEqual(execution['assignee_id'], self.api_user.pk)
87
        self.assertEqual(execution['sortkey'], 90)
88
        self.assertEqual(execution['status'], self.status.name)
89
        self.assertEqual(execution['case_text_version'], 3)
90
91
    def test_create_with_non_exist_fields(self):
92
        values = [
93
            {
94
                "run": self.test_run.pk,
95
                "build": self.build.pk,
96
                "case": 111111,
97
            },
98
            {
99
                "run": 11111,
100
                "build": self.build.pk,
101
                "case": self.case.pk,
102
            },
103
            {
104
                "run": self.test_run.pk,
105
                "build": 11222222,
106
                "case": self.case.pk,
107
            },
108
        ]
109
        for value in values:
110
            with self.assertRaisesRegex(XmlRPCFault, 'Select a valid choice'):
111
                self.rpc_client.TestExecution.create(value)
112
113
    def test_create_with_no_perm(self):
114
        values = {
115
            "run": self.test_run.pk,
116
            "build": self.build.pk,
117
            "case": self.case.pk,
118
            "assignee": self.api_user.pk,
119
            "sortkey": 2,
120
            "status": self.status.pk,
121
        }
122
        self.rpc_client.Auth.logout()
123
        with self.assertRaisesRegex(ProtocolError, '403 Forbidden'):
124
            self.rpc_client.TestExecution.create(values)
125
126
127
class TestExecutionAddComment(APITestCase):
128
    """Test TestExecution.add_comment"""
129
130
    def _fixture_setup(self):
131
        super()._fixture_setup()
132
133
        self.execution_1 = TestExecutionFactory()
134
        self.execution_2 = TestExecutionFactory()
135
136
    def test_add_comment_with_pk_as_int(self):
137
        self.rpc_client.TestExecution.add_comment(self.execution_2.pk,
138
                                                  "Hello World!")
139
        comments = get_comments(self.execution_2)
140
        self.assertEqual(1, comments.count())
141
142
        first_comment = comments.first()
143
        self.assertEqual("Hello World!", first_comment.comment)
144
145
146
@override_settings(LANGUAGE_CODE='en')
147
class TestExecutionAddLink(APITestCase):
148
    """Test TestExecution.add_link"""
149
150
    def _fixture_setup(self):
151
        super()._fixture_setup()
152
153
        self.case_run = TestExecutionFactory()
154
155
    def test_attach_log_with_non_existing_id(self):
156
        with self.assertRaisesRegex(XmlRPCFault, 'constraint fail|violates foreign key'):
157
            self.rpc_client.TestExecution.add_link({
158
                'execution_id': -5,
159
                'name': 'A test log',
160
                'url': 'http://example.com'})
161
162
    def test_attach_log(self):
163
        url = "http://127.0.0.1/test/test-log.log"
164
        result = self.rpc_client.TestExecution.add_link({
165
            'execution_id': self.case_run.pk,
166
            'name': 'UT test logs',
167
            'url': url})
168
        self.assertGreater(result['id'], 0)
169
        self.assertEqual(result['url'], url)
170
171
172
class TestExecutionAddLinkPermissions(APIPermissionsTestCase):
173
    """Test permissions of TestExecution.add_link"""
174
175
    permission_label = 'linkreference.add_linkreference'
176
177
    def _fixture_setup(self):
178
        super()._fixture_setup()
179
180
        self.execution = TestExecutionFactory()
181
182
    def verify_api_with_permission(self):
183
        links = self.execution.links()
184
        self.assertFalse(links.exists())
185
186
        url = 'http://example.com'
187
        result = self.rpc_client.TestExecution.add_link({
188
            'execution_id': self.execution.pk,
189
            'url': url})
190
191
        links = self.execution.links()
192
        self.assertEqual(self.execution.pk, result['execution'])
193
        self.assertEqual(url, result['url'])
194
        self.assertEqual(1, links.count())
195
        self.assertEqual(url, links.first().url)
196
197
    def verify_api_without_permission(self):
198
        url = 'http://127.0.0.1/test/test-log.log'
199
        with self.assertRaisesRegex(ProtocolError, '403 Forbidden'):
200
            self.rpc_client.TestExecution.add_link({
201
                'execution_id': self.execution.pk,
202
                'name': 'UT test logs',
203
                'url': url})
204
205
206
class TestExecutionRemoveLink(APITestCase):
207
208
    def _fixture_setup(self):
209
        super()._fixture_setup()
210
211
        self.status_idle = TestExecutionStatus.objects.filter(weight=0).first()
212
        self.tester = UserFactory()
213
        self.case_run = TestExecutionFactory(assignee=self.tester, tested_by=None,
214
                                             sortkey=10,
215
                                             status=self.status_idle)
216
217
    def setUp(self):
218
        super().setUp()
219
220
        self.rpc_client.TestExecution.add_link({
221
            'execution_id': self.case_run.pk,
222
            'name': 'Related issue',
223
            'url': 'https://localhost/issue/1'})
224
        self.link = self.case_run.links()[0]
225
226
    def test_doesnt_raise_with_non_existing_id(self):
227
        self.rpc_client.TestExecution.remove_link({'execution_id': -9})
228
        links = self.case_run.links()
229
        self.assertEqual(1, links.count())
230
        self.assertEqual(self.link.pk, links[0].pk)
231
232
    def test_detach_log_with_non_exist_log(self):
233
        self.rpc_client.TestExecution.remove_link({'pk': 999999999})
234
        links = self.case_run.links()
235
        self.assertEqual(1, links.count())
236
        self.assertEqual(self.link.pk, links[0].pk)
237
238
    def test_detach_log(self):
239
        self.rpc_client.TestExecution.remove_link({'execution_id': self.case_run.pk,
240
                                                   'pk': self.link.pk})
241
        self.assertEqual([], list(self.case_run.links()))
242
243
244
class TestExecutionRemoveLinkPermissions(APIPermissionsTestCase):
245
    """Test permissions of TestExecution.remove_link"""
246
247
    permission_label = 'linkreference.delete_linkreference'
248
249
    def _fixture_setup(self):
250
        super()._fixture_setup()
251
252
        self.execution = TestExecutionFactory()
253
        self.link = LinkReferenceFactory(execution=self.execution)
254
        self.another_link = LinkReferenceFactory(execution=self.execution)
255
256
    def verify_api_with_permission(self):
257
        links = self.execution.links()
258
        self.assertEqual(2, links.count())
259
        self.assertIn(self.link, links)
260
        self.assertIn(self.another_link, links)
261
262
        self.rpc_client.TestExecution.remove_link({'pk': self.link.pk})
263
264
        links = self.execution.links()
265
        self.assertEqual(1, links.count())
266
        self.assertIn(self.another_link, links)
267
        self.assertNotIn(self.link, links)
268
269
    def verify_api_without_permission(self):
270
        with self.assertRaisesRegex(ProtocolError, '403 Forbidden'):
271
            self.rpc_client.TestExecution.remove_link({'pk': self.another_link.pk})
272
273
274
class TestExecutionFilter(APITestCase):
275
276
    def _fixture_setup(self):
277
        super()._fixture_setup()
278
279
        self.status_idle = TestExecutionStatus.objects.filter(weight=0).first()
280
        self.tester = UserFactory()
281
        self.case_run = TestExecutionFactory(assignee=self.tester, tested_by=None,
282
                                             sortkey=10,
283
                                             status=self.status_idle)
284
285
    def test_with_non_exist_id(self):
286
        found = self.rpc_client.TestExecution.filter({'pk': -1})
287
        self.assertEqual(0, len(found))
288
289
    def test_filter_by_id(self):
290
        execution = self.rpc_client.TestExecution.filter({'pk': self.case_run.pk})[0]
291
        self.assertIsNotNone(execution)
292
        self.assertEqual(execution['build_id'], self.case_run.build.pk)
293
        self.assertEqual(execution['case_id'], self.case_run.case.pk)
294
        self.assertEqual(execution['assignee_id'], self.tester.pk)
295
        self.assertEqual(execution['tested_by_id'], None)
296
        self.assertEqual(execution['sortkey'], 10)
297
        self.assertEqual(execution['status'], self.status_idle.name)
298
        self.assertEqual(execution['status_id'], self.status_idle.pk)
299
300
301
class TestExecutionGetLinks(APITestCase):
302
303
    def _fixture_setup(self):
304
        super()._fixture_setup()
305
306
        self.case_run_1 = TestExecutionFactory()
307
        self.case_run_2 = TestExecutionFactory()
308
309
        self.rpc_client.TestExecution.add_link({
310
            'execution_id': self.case_run_1.pk,
311
            'name': 'Test logs',
312
            'url': 'http://kiwitcms.org'})
313
314
    def test_get_links_with_non_exist_id(self):
315
        result = self.rpc_client.TestExecution.get_links({'execution': -9})
316
        self.assertEqual([], result)
317
318
    def test_get_empty_logs(self):
319
        logs = self.rpc_client.TestExecution.get_links({'execution': self.case_run_2.pk})
320
        self.assertIsInstance(logs, list)
321
        self.assertEqual(len(logs), 0)
322
323
    def test_get_links(self):
324
        execution_log = LinkReference.objects.get(execution=self.case_run_1.pk)
325
        logs = self.rpc_client.TestExecution.get_links({'execution': self.case_run_1.pk})
326
        self.assertIsInstance(logs, list)
327
        self.assertEqual(len(logs), 1)
328
        self.assertEqual(logs[0]['id'], execution_log.pk)
329
        self.assertEqual(logs[0]['name'], "Test logs")
330
        self.assertEqual(logs[0]['url'], 'http://kiwitcms.org')
331
332
333
@override_settings(LANGUAGE_CODE='en')
334
class TestExecutionUpdate(APITestCase):
335
336
    def _fixture_setup(self):
337
        super()._fixture_setup()
338
339
        self.user = UserFactory()
340
        self.build = BuildFactory()
341
        self.case_run_1 = TestExecutionFactory()
342
        self.case_run_2 = TestExecutionFactory()
343
        self.status_positive = TestExecutionStatus.objects.filter(weight__gt=0).last()
344
345
    def test_update_with_single_caserun(self):
346
        execution = self.rpc_client.TestExecution.update(self.case_run_1.pk, {
347
            "build": self.build.pk,
348
            "assignee": self.user.pk,
349
            "status": self.status_positive.pk,
350
            "sortkey": 90
351
        })
352
        self.assertEqual(execution['build'], self.build.name)
353
        self.assertEqual(execution['assignee'], self.user.username)
354
        self.assertEqual(execution['status'], self.status_positive.name)
355
        self.assertEqual(execution['sortkey'], 90)
356
357
    def test_update_with_assignee_id(self):
358
        self.assertNotEqual(self.case_run_1.assignee, self.user.pk)
359
        execution = self.rpc_client.TestExecution.update(self.case_run_1.pk, {
360
            "assignee": self.user.pk
361
        })
362
        self.assertEqual(execution['assignee'], self.user.username)
363
364
    def test_update_with_assignee_email(self):
365
        self.assertNotEqual(self.case_run_1.assignee, self.user.email)
366
        execution = self.rpc_client.TestExecution.update(self.case_run_1.pk, {
367
            "assignee": self.user.email
368
        })
369
        self.assertEqual(execution['assignee'], self.user.username)
370
371
    def test_update_with_assignee_username(self):
372
        self.assertNotEqual(self.case_run_1.assignee, self.user.username)
373
        execution = self.rpc_client.TestExecution.update(self.case_run_1.pk, {
374
            "assignee": self.user.username
375
        })
376
        self.assertEqual(execution['assignee'], self.user.username)
377
378
    def test_update_with_non_existing_build(self):
379
        with self.assertRaisesRegex(XmlRPCFault, 'Select a valid choice'):
380
            self.rpc_client.TestExecution.update(self.case_run_1.pk, {"build": 1111111})
381
382
    def test_update_with_non_existing_assignee_id(self):
383
        with self.assertRaisesRegex(XmlRPCFault, 'Unknown user_id'):
384
            self.rpc_client.TestExecution.update(self.case_run_1.pk, {
385
                "assignee": 1111111
386
            })
387
388
    def test_update_with_non_existing_assignee_email(self):
389
        with self.assertRaisesRegex(XmlRPCFault, 'Unknown user'):
390
            self.rpc_client.TestExecution.update(self.case_run_1.pk, {
391
                "assignee": '[email protected]'
392
            })
393
394
    def test_update_with_non_existing_assignee_username(self):
395
        with self.assertRaisesRegex(XmlRPCFault, 'Unknown user:'):
396
            self.rpc_client.TestExecution.update(self.case_run_1.pk, {
397
                "assignee": 'nonExistentUsername'
398
            })
399
400
    def test_update_when_case_text_version_is_integer(self):
401
        initial_case_text_version = self.case_run_1.case_text_version
402
        self.update_test_case_text()
403
404
        execution = self.rpc_client.TestExecution.update(self.case_run_1.pk, {
405
            "case_text_version": str(self.case_run_1.case.history.latest().history_id)
406
        })
407
        self.case_run_1.refresh_from_db()
408
409
        latest_case_text_version = self.case_run_1.case_text_version
410
        self.assertNotEqual(initial_case_text_version, latest_case_text_version)
411
        self.assertEqual(execution["case_text_version"], latest_case_text_version)
412
        self.assertEqual(self.case_run_1.case.history.latest().history_id, latest_case_text_version)
413
414
    def test_update_when_case_text_version_is_string_latest(self):
415
        initial_case_text_version = self.case_run_1.case_text_version
416
        self.update_test_case_text()
417
418
        execution = self.rpc_client.TestExecution.update(self.case_run_1.pk, {
419
            "case_text_version": 'latest'
420
        })
421
        self.case_run_1.refresh_from_db()
422
423
        latest_case_text_version = self.case_run_1.case_text_version
424
        self.assertNotEqual(initial_case_text_version, latest_case_text_version)
425
        self.assertEqual(execution["case_text_version"], latest_case_text_version)
426
        self.assertEqual(self.case_run_1.case.history.latest().history_id, latest_case_text_version)
427
428
    def update_test_case_text(self):
429
        self.case_run_1.case.summary = "Summary Updated"
430
        self.case_run_1.case.text = "Text Updated"
431
        self.case_run_1.case.save()
432
433
    def test_update_with_non_existing_status(self):
434
        with self.assertRaisesRegex(XmlRPCFault, 'Select a valid choice'):
435
            self.rpc_client.TestExecution.update(self.case_run_1.pk,
436
                                                 {"status": 1111111})
437
438
    def test_update_with_no_perm(self):
439
        self.rpc_client.Auth.logout()
440
        with self.assertRaisesRegex(ProtocolError, '403 Forbidden'):
441
            self.rpc_client.TestExecution.update(self.case_run_1.pk,
442
                                                 {"close_date": timezone.now()})
443