Passed
Push — master ( cddcf6...1d3855 )
by Alexander
01:59
created

TestCaserunCasesMenu.test_add_cases_to_run_without_permission()   A

Complexity

Conditions 1

Size

Total Lines 4
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nop 1
1
# -*- coding: utf-8 -*-
2
# pylint: disable=invalid-name, too-many-ancestors
3
4
from http import HTTPStatus
5
6
from django.utils import formats
7
from django.urls import reverse
8
from django.contrib.auth.models import Permission
9
from django.utils.translation import ugettext_lazy as _
10
11
from tcms.testruns.models import TestExecutionStatus
12
from tcms.testruns.models import TestRun
13
from tcms.utils.permissions import initiate_user_with_default_setups
14
15
from tcms.tests import BaseCaseRun
16
from tcms.tests import BasePlanCase
17
from tcms.tests import remove_perm_from_user
18
from tcms.tests import user_should_have_perm
19
from tcms.tests.factories import BuildFactory
20
from tcms.tests.factories import TagFactory
21
from tcms.tests.factories import TestCaseFactory
22
from tcms.tests.factories import UserFactory
23
24
25
class TestGetRun(BaseCaseRun):
26
    """Test get view method"""
27
28
    @classmethod
29
    def setUpTestData(cls):
30
        super().setUpTestData()
31
        initiate_user_with_default_setups(cls.tester)
32
33
        for _i in range(3):
34
            cls.test_run.add_tag(TagFactory())
35
36
        cls.unauthorized = UserFactory()
37
        cls.unauthorized.set_password('password')
38
        cls.unauthorized.save()
39
40
        cls.unauthorized.user_permissions.add(*Permission.objects.all())
41
        remove_perm_from_user(cls.unauthorized, 'testruns.add_testruntag')
42
        remove_perm_from_user(cls.unauthorized, 'testruns.delete_testruntag')
43
44
    def test_404_if_non_existing_pk(self):
45
        url = reverse('testruns-get', args=[99999999])
46
        response = self.client.get(url)
47
        self.assertEqual(HTTPStatus.NOT_FOUND, response.status_code)
48
49
    def test_get_a_run(self):
50
        url = reverse('testruns-get', args=[self.test_run.pk])
51
        response = self.client.get(url)
52
53
        self.assertEqual(HTTPStatus.OK, response.status_code)
54
        self.assertContains(response, 'Add Tag')
55
        self.assertContains(response, 'js-remove-tag')
56
57
        for i, case_run in enumerate(
58
                (self.execution_1, self.execution_2, self.execution_3), 1):
59
            self.assertContains(
60
                response,
61
                '<a href="#caserun_{0}">#{0}</a>'.format(case_run.pk),
62
                html=True)
63
            self.assertContains(
64
                response,
65
                '<a id="link_{0}" href="#caserun_{1}" title="Expand test case">'
66
                '{2}</a>'.format(i, case_run.pk, case_run.case.summary),
67
                html=True)
68
69
    def test_get_run_without_permissions_to_add_or_remove_tags(self):
70
        self.client.logout()
71
72
        self.client.login(  # nosec:B106:hardcoded_password_funcarg
73
            username=self.unauthorized.username,
74
            password='password')
75
76
        url = reverse('testruns-get', args=[self.test_run.pk])
77
        response = self.client.get(url)
78
79
        self.assertEqual(HTTPStatus.OK, response.status_code)
80
        self.assertNotContains(response, 'Add Tag')
81
        self.assertNotContains(response, 'js-remove-tag')
82
83
84
class TestCreateNewRun(BasePlanCase):
85
    """Test creating new run"""
86
87
    @classmethod
88
    def setUpTestData(cls):
89
        super(TestCreateNewRun, cls).setUpTestData()
90
91
        cls.permission = 'testruns.add_testrun'
92
        user_should_have_perm(cls.tester, cls.permission)
93
        cls.url = reverse('testruns-new')
94
        cls.build_fast = BuildFactory(name='fast', product=cls.product)
95
96
    def test_refuse_if_missing_plan_pk(self):
97
        self.client.login(  # nosec:B106:hardcoded_password_funcarg
98
            username=self.tester.username,
99
            password='password')
100
        response = self.client.post(self.url, {})
101
        self.assertRedirects(response, reverse('plans-search'))
102
103
    def test_refuse_if_missing_cases_pks(self):
104
        self.client.login(  # nosec:B106:hardcoded_password_funcarg
105
            username=self.tester.username,
106
            password='password')
107
        response = self.client.post(self.url, {'from_plan': self.plan.pk}, follow=True)
108
        self.assertContains(response, _('Creating a TestRun requires at least one TestCase'))
109
110
    def test_show_create_new_run_page(self):
111
        self.client.login(  # nosec:B106:hardcoded_password_funcarg
112
            username=self.tester.username,
113
            password='password')
114
115
        response = self.client.post(self.url, {
116
            'from_plan': self.plan.pk,
117
            'case': [self.case_1.pk, self.case_2.pk, self.case_3.pk]
118
        })
119
120
        # Assert listed cases
121
        for _i, case in enumerate((self.case_1, self.case_2, self.case_3), 1):
122
            case_url = reverse('testcases-get', args=[case.pk])
123
            self.assertContains(
124
                response,
125
                '<a href="%s">TC-%d: %s</a>' % (case_url, case.pk, case.summary),
126
                html=True)
127
128
    def test_create_a_new_run(self):
129
        self.client.login(  # nosec:B106:hardcoded_password_funcarg
130
            username=self.tester.username,
131
            password='password')
132
133
        clone_data = {
134
            'summary': self.plan.name,
135
            'from_plan': self.plan.pk,
136
            'build': self.build_fast.pk,
137
            'manager': self.tester.email,
138
            'default_tester': self.tester.email,
139
            'notes': 'Clone new run',
140
            'case': [self.case_1.pk, self.case_2.pk],
141
            'POSTING_TO_CREATE': 'YES',
142
        }
143
144
        url = reverse('testruns-new')
145
        response = self.client.post(url, clone_data)
146
147
        new_run = TestRun.objects.last()
148
149
        self.assertRedirects(
150
            response,
151
            reverse('testruns-get', args=[new_run.pk]))
152
153
        self.assertEqual(self.plan.name, new_run.summary)
154
        self.assertEqual(self.plan, new_run.plan)
155
        self.assertEqual(self.version, new_run.product_version)
156
        self.assertEqual(None, new_run.stop_date)
157
        self.assertEqual('Clone new run', new_run.notes)
158
        self.assertEqual(self.build_fast, new_run.build)
159
        self.assertEqual(self.tester, new_run.manager)
160
        self.assertEqual(self.tester, new_run.default_tester)
161
162
        for case, case_run in zip((self.case_1, self.case_2),
163
                                  new_run.case_run.order_by('case')):
164
            self.assertEqual(case, case_run.case)
165
            self.assertEqual(None, case_run.tested_by)
166
            self.assertEqual(self.tester, case_run.assignee)
167
            self.assertEqual(TestExecutionStatus.objects.get(name='IDLE'),
168
                             case_run.status)
169
            self.assertEqual(case.history.latest().history_id, case_run.case_text_version)
170
            self.assertEqual(new_run.build, case_run.build)
171
            self.assertEqual(None, case_run.close_date)
172
173
174
class CloneRunBaseTest(BaseCaseRun):
175
176
    def assert_one_run_clone_page(self, response):
177
        """Verify clone page for cloning one test run"""
178
179
        self.assertContains(
180
            response,
181
            '<input id="id_summary" class="form-control" name="summary" '
182
            'type="text" value="%s%s" required>' % (_('Clone of '), self.test_run.summary),
183
            html=True)
184
185
        for case_run in (self.execution_1, self.execution_2):
186
            case_url = reverse('testcases-get', args=[case_run.case.pk])
187
188
            self.assertContains(
189
                response,
190
                '<a href="%s">TC-%d: %s</a>' % (case_url, case_run.case.pk, case_run.case.summary),
191
                html=True)
192
193
194
class TestStartCloneRunFromRunPage(CloneRunBaseTest):
195
    """Test case for cloning run from a run page"""
196
197
    @classmethod
198
    def setUpTestData(cls):
199
        super(TestStartCloneRunFromRunPage, cls).setUpTestData()
200
201
        cls.permission = 'testruns.add_testrun'
202
        user_should_have_perm(cls.tester, cls.permission)
203
204
    def test_refuse_without_selecting_case_runs(self):
205
        self.client.login(  # nosec:B106:hardcoded_password_funcarg
206
            username=self.tester.username,
207
            password='password')
208
        url = reverse('testruns-clone', args=[self.test_run.pk])
209
210
        response = self.client.post(url, {}, follow=True)
211
212
        self.assertContains(response, _('At least one TestCase is required'))
213
214
    def test_open_clone_page_by_selecting_case_runs(self):
215
        self.client.login(  # nosec:B106:hardcoded_password_funcarg
216
            username=self.tester.username,
217
            password='password')
218
        url = reverse('testruns-clone', args=[self.test_run.pk])
219
220
        response = self.client.post(url, {'case_run': [self.execution_1.pk, self.execution_2.pk]})
221
222
        self.assert_one_run_clone_page(response)
223
224
    def test_clone_a_run(self):
225
        self.client.login(  # nosec:B106:hardcoded_password_funcarg
226
            username=self.tester.username,
227
            password='password')
228
229
        new_summary = 'Clone {} - {}'.format(self.test_run.pk, self.test_run.summary)
230
231
        clone_data = {
232
            'summary': new_summary,
233
            'from_plan': self.plan.pk,
234
            'product_id': self.test_run.plan.product_id,
235
            'do': 'clone_run',
236
            'orig_run_id': self.test_run.pk,
237
            'POSTING_TO_CREATE': 'YES',
238
            'product': self.test_run.plan.product_id,
239
            'product_version': self.test_run.product_version.pk,
240
            'build': self.test_run.build.pk,
241
            'errata_id': '',
242
            'manager': self.test_run.manager.email,
243
            'default_tester': self.test_run.default_tester.email,
244
            'notes': '',
245
            'case': [self.execution_1.case.pk, self.execution_2.case.pk],
246
            'case_run_id': [self.execution_1.pk, self.execution_2.pk],
247
        }
248
249
        url = reverse('testruns-new')
250
        response = self.client.post(url, clone_data)
251
252
        cloned_run = TestRun.objects.get(summary=new_summary)
253
254
        self.assertRedirects(
255
            response,
256
            reverse('testruns-get', args=[cloned_run.pk]))
257
258
        self.assert_cloned_run(cloned_run)
259
260
    def assert_cloned_run(self, cloned_run):
261
        # Assert clone settings result
262
        for origin_case_run, cloned_case_run in zip((self.execution_1, self.execution_2),
263
                                                    cloned_run.case_run.order_by('pk')):
264
            self.assertEqual(TestExecutionStatus.objects.get(name='IDLE'),
265
                             cloned_case_run.status)
266
            self.assertEqual(origin_case_run.assignee, cloned_case_run.assignee)
267
268
269
class TestSearchRuns(BaseCaseRun):
270
271
    @classmethod
272
    def setUpTestData(cls):
273
        super(TestSearchRuns, cls).setUpTestData()
274
275
        cls.search_runs_url = reverse('testruns-search')
276
277
    def test_search_page_is_shown(self):
278
        response = self.client.get(self.search_runs_url)
279
        self.assertContains(response, '<input id="id_summary" type="text"')
280
281
282
class TestAddRemoveRunCC(BaseCaseRun):
283
    """Test view tcms.testruns.views.cc"""
284
285
    @classmethod
286
    def setUpTestData(cls):
287
        super(TestAddRemoveRunCC, cls).setUpTestData()
288
289
        cls.cc_url = reverse('testruns-cc', args=[cls.test_run.pk])
290
291
        cls.cc_user_1 = UserFactory(username='cc-user-1',
292
                                    email='[email protected]')
293
        cls.cc_user_2 = UserFactory(username='cc-user-2',
294
                                    email='[email protected]')
295
        cls.cc_user_3 = UserFactory(username='cc-user-3',
296
                                    email='[email protected]')
297
298
        cls.test_run.add_cc(cls.cc_user_2)
299
        cls.test_run.add_cc(cls.cc_user_3)
300
301
    def test_404_if_run_not_exist(self):
302
        cc_url = reverse('testruns-cc', args=[999999])
303
        response = self.client.get(cc_url)
304
        self.assert404(response)
305
306
    def assert_cc(self, response, expected_cc):
307
        self.assertEqual(len(expected_cc), self.test_run.cc.count())  # pylint: disable=no-member
308
309
        for cc in expected_cc:
310
            href = reverse('tcms-profile', args=[cc.username])
311
            self.assertContains(
312
                response,
313
                '<a href="%s">%s</a>' % (href, cc.username),
314
                html=True)
315
316
    def test_refuse_if_missing_action(self):
317
        response = self.client.get(self.cc_url,
318
                                   {'user': self.cc_user_1.username})
319
        self.assert_cc(response, [self.cc_user_2, self.cc_user_3])
320
321
    def test_add_cc(self):
322
        response = self.client.get(
323
            self.cc_url,
324
            {'do': 'add', 'user': self.cc_user_1.username})
325
326
        self.assert_cc(response,
327
                       [self.cc_user_2, self.cc_user_3, self.cc_user_1])
328
329
    def test_remove_cc(self):
330
        response = self.client.get(
331
            self.cc_url,
332
            {'do': 'remove', 'user': self.cc_user_2.username})
333
334
        self.assert_cc(response, [self.cc_user_3])
335
336
    def test_refuse_to_remove_if_missing_user(self):
337
        response = self.client.get(self.cc_url, {'do': 'remove'})
338
339
        self.assertContains(
340
            response,
341
            'User name or email is required by this operation')
342
343
        self.assert_cc(response, [self.cc_user_2, self.cc_user_3])
344
345
    def test_refuse_to_add_if_missing_user(self):
346
        response = self.client.get(self.cc_url, {'do': 'add'})
347
348
        self.assertContains(
349
            response,
350
            'User name or email is required by this operation')
351
352
        self.assert_cc(response, [self.cc_user_2, self.cc_user_3])
353
354
    def test_refuse_if_user_not_exist(self):
355
        response = self.client.get(self.cc_url,
356
                                   {'do': 'add', 'user': 'not exist'})
357
358
        self.assertContains(
359
            response,
360
            'The user you typed does not exist in database')
361
362
        self.assert_cc(response, [self.cc_user_2, self.cc_user_3])
363
364
365
class TestRemoveCaseRuns(BaseCaseRun):
366
    """Test remove_case_run view method"""
367
368
    @classmethod
369
    def setUpTestData(cls):
370
        super(TestRemoveCaseRuns, cls).setUpTestData()
371
372
        user_should_have_perm(cls.tester, 'testruns.delete_testexecution')
373
374
        cls.remove_case_run_url = reverse('testruns-remove_case_run',
375
                                          args=[cls.test_run.pk])
376
377
    def test_nothing_change_if_no_case_run_passed(self):
378
        response = self.client.post(self.remove_case_run_url, {})
379
380
        self.assertRedirects(response,
381
                             reverse('testruns-get', args=[self.test_run.pk]))
382
383
    def test_ignore_non_integer_case_run_ids(self):
384
        expected_rest_case_runs_count = self.test_run.case_run.count() - 2
385
386
        self.client.post(self.remove_case_run_url,
387
                         {
388
                             'case_run': [self.execution_1.pk,
389
                                          'a1000',
390
                                          self.execution_2.pk],
391
                         })
392
393
        self.assertEqual(expected_rest_case_runs_count,
394
                         self.test_run.case_run.count())
395
396
    def test_remove_case_runs(self):
397
        expected_rest_case_runs_count = self.test_run.case_run.count() - 1
398
399
        self.client.post(self.remove_case_run_url,
400
                         {'case_run': [self.execution_1.pk]})
401
402
        self.assertEqual(expected_rest_case_runs_count,
403
                         self.test_run.case_run.count())
404
405
    def test_redirect_to_run_if_still_case_runs_exist_after_removal(self):
406
        response = self.client.post(self.remove_case_run_url,
407
                                    {'case_run': [self.execution_1.pk]})
408
409
        self.assertRedirects(response,
410
                             reverse('testruns-get', args=[self.test_run.pk]))
411
412
    def test_redirect_to_add_case_runs_if_all_case_runs_are_removed(self):
413
        case_runs = []
414
415
        for case_run in self.test_run.case_run.all():
416
            case_runs.append(case_run.pk)
417
418
        response = self.client.post(
419
            self.remove_case_run_url,
420
            {
421
                'case_run': case_runs
422
            })
423
424
        self.assertRedirects(response,
425
                             reverse('add-cases-to-run',
426
                                     args=[self.test_run.pk]),
427
                             target_status_code=302)
428
429
430
class TestUpdateCaseRunText(BaseCaseRun):
431
    """Test update_case_run_text view method"""
432
433
    @classmethod
434
    def setUpTestData(cls):
435
        super().setUpTestData()
436
437
        cls.testruns_url = reverse('testruns-get', args=[cls.test_run.pk])
438
        cls.update_url = reverse('testruns-update_case_run_text',
439
                                 args=[cls.test_run.pk])
440
441
        # To increase case text version
442
        cls.execution_1.case.text = "Scenario Version 1"
443
        cls.execution_1.case.save()
444
445
        cls.execution_1.case.text = "Scenario Version 2"
446
        cls.execution_1.case.save()
447
448
    def test_get_update_caserun_text_with_permissions(self):
449
        user_should_have_perm(self.tester, 'testruns.change_testexecution')
450
        response = self.client.get(self.testruns_url)
451
        self.assertContains(response, 'id="update_case_run_text"')
452
453
    def test_update_selected_case_runs_with_permissions(self):
454
        user_should_have_perm(self.tester, 'testruns.change_testexecution')
455
456
        self.assertNotEqual(self.execution_1.case.history.latest().history_id,
457
                            self.execution_1.case_text_version)
458
        response = self.client.post(self.update_url,
459
                                    {'case_run': [self.execution_1.pk]},
460
                                    follow=True)
461
462
        self.assertContains(response, _('%d CaseRun(s) updated:') % 1)
463
464
        self.execution_1.refresh_from_db()
465
466
        self.assertEqual(
467
            self.execution_1.case.get_text_with_version(
468
                self.execution_1.case_text_version
469
            ),
470
            "Scenario Version 2"
471
        )
472
        self.assertEqual(
473
            self.execution_1.case.history.latest().history_id,
474
            self.execution_1.case_text_version
475
        )
476
477
    def test_get_update_caserun_text_without_permissions(self):
478
        remove_perm_from_user(self.tester, 'testruns.change_testexecution')
479
        response = self.client.get(self.testruns_url)
480
        self.assertNotContains(response, 'id="update_case_run_text"')
481
482
    def test_update_selected_case_runs_without_permissions(self):
483
        self.execution_1.case.text = "Scenario Version 3"
484
        self.execution_1.case.save()
485
486
        remove_perm_from_user(self.tester, 'testruns.change_testexecution')
487
488
        self.client.login(  # nosec:B106:hardcoded_password_funcarg
489
            username=self.tester.username,
490
            password='password')
491
492
        self.assertNotEqual(
493
            self.execution_1.case.history.latest().history_id,
494
            self.execution_1.case_text_version
495
        )
496
497
        response = self.client.post(self.update_url,
498
                                    {'case_run': [self.execution_1.pk]},
499
                                    follow=True)
500
501
        self.assertRedirects(
502
            response,
503
            reverse('tcms-login') + '?next=' + self.update_url
504
        )
505
506
        self.execution_1.refresh_from_db()
507
508
        self.assertNotEqual(
509
            self.execution_1.case.get_text_with_version(
510
                self.execution_1.case_text_version
511
            ),
512
            "Scenario Version 3"
513
        )
514
515
        self.assertNotEqual(
516
            self.execution_1.case.history.latest().history_id,
517
            self.execution_1.case_text_version
518
        )
519
520
521
class TestEditRun(BaseCaseRun):
522
    """Test edit view method"""
523
524
    @classmethod
525
    def setUpTestData(cls):
526
        super(TestEditRun, cls).setUpTestData()
527
528
        user_should_have_perm(cls.tester, 'testruns.change_testrun')
529
        cls.edit_url = reverse('testruns-edit', args=[cls.test_run.pk])
530
531
        cls.new_build = BuildFactory(name='FastTest',
532
                                     product=cls.test_run.plan.product)
533
        cls.intern = UserFactory(username='intern',
534
                                 email='[email protected]')
535
536
    def test_404_if_edit_non_existing_run(self):
537
        url = reverse('testruns-edit', args=[9999])
538
        response = self.client.get(url)
539
540
        self.assert404(response)
541
542
    def test_edit_run(self):
543
544
        post_data = {
545
            'summary': 'New run summary',
546
            'build': self.new_build.pk,
547
            'manager': self.test_run.manager.email,
548
            'default_tester': self.intern.email,
549
            'notes': 'easytest',
550
        }
551
552
        response = self.client.post(self.edit_url, post_data)
553
554
        run = TestRun.objects.get(pk=self.test_run.pk)
555
        self.assertEqual('New run summary', run.summary)
556
        self.assertEqual(self.new_build, run.build)
557
558
        self.assertRedirects(response, reverse('testruns-get', args=[run.pk]))
559
560
561
class TestAddCasesToRun(BaseCaseRun):
562
    """Test AddCasesToRunView"""
563
564
    @classmethod
565
    def setUpTestData(cls):
566
        super(TestAddCasesToRun, cls).setUpTestData()
567
568
        cls.proposed_case = TestCaseFactory(
569
            author=cls.tester,
570
            default_tester=None,
571
            reviewer=cls.tester,
572
            case_status=cls.case_status_proposed,
573
            plan=[cls.plan])
574
575
        user_should_have_perm(cls.tester, 'testruns.add_testexecution')
576
577
    def test_show_add_cases_to_run(self):
578
        url = reverse('add-cases-to-run', args=[self.test_run.pk])
579
        response = self.client.get(url)
580
581
        self.assertNotContains(
582
            response,
583
            '<a href="{0}">{1}</a>'.format(
584
                reverse('testcases-get',
585
                        args=[self.proposed_case.pk]),
586
                self.proposed_case.pk),
587
            html=True
588
        )
589
590
        confirmed_cases = [self.case, self.case_1, self.case_2, self.case_3]
591
592
        # Check selected and unselected case id checkboxes
593
        # cls.case is not added to cls.test_run, so it should not be checked.
594
        self.assertContains(
595
            response,
596
            '<td align="left">'
597
            '<input type="checkbox" name="case" value="{0}">'
598
            '</td>'.format(self.case.pk),
599
            html=True)
600
601
        # other cases are added to cls.test_run, so must be checked.
602
        for case in confirmed_cases[1:]:
603
            self.assertContains(
604
                response,
605
                '<td align="left">'
606
                '<input type="checkbox" name="case" value="{0}" '
607
                'disabled="true" checked="true">'
608
                '</td>'.format(case.pk),
609
                html=True)
610
611
        # Check listed case properties
612
        # note: the response is ordered by 'case'
613
        for loop_counter, case in enumerate(confirmed_cases, 1):
614
            html_pieces = [
615
                '<a href="{0}">{1}</a>'.format(
616
                    reverse('testcases-get', args=[case.pk]),
617
                    case.pk),
618
619
                '<td class="js-case-summary" data-param="{0}">'
620
                '<a id="link_{0}" class="blind_title_link" '
621
                'href="javascript:void(0);">{1}</a></td>'.format(loop_counter,
622
                                                                 case.summary),
623
624
                '<td>{0}</td>'.format(case.author.username),
625
                '<td>{0}</td>'.format(
626
                    formats.date_format(case.create_date, 'DATETIME_FORMAT')),
627
                '<td>{0}</td>'.format(case.category.name),
628
                '<td>{0}</td>'.format(case.priority.value),
629
            ]
630
            for html in html_pieces:
631
                self.assertContains(response, html, html=True)
632
633
634
class TestCaserunCasesMenu(BaseCaseRun):
635
    @classmethod
636
    def setUpTestData(cls):
637
        super().setUpTestData()
638
639
        cls.url = reverse('testruns-get', args=[cls.test_run.pk])
640
641
        cls.add_cases_html = \
642
            '<a href="{0}" class="addBlue9">{1}</a>' \
643
            .format(
644
                reverse('add-cases-to-run', args=[cls.test_run.pk]),
645
                _('Add')
646
            )
647
648
        cls.remove_cases_html = \
649
            '<a href="#" title="{0}" data-param="{1}" \
650
            class="removeBlue9 js-del-case">{2}</a>' \
651
            .format(
652
                _('Remove selected cases form this test run'),
653
                cls.test_run.pk,
654
                _('Remove')
655
            )
656
657
        cls.update_case_run_text_html = \
658
            '<a href="#" title="{0}" \
659
            href="javascript:void(0)" data-param="{1}" \
660
            class="updateBlue9 js-update-case" id="update_case_run_text">{2}</a>' \
661
            .format(
662
                _('Update the IDLE case runs to newest case text'),
663
                reverse('testruns-update_case_run_text', args=[cls.test_run.pk]),
664
                _('Update')
665
            )
666
667
        cls.change_assignee_html = \
668
            '<a href="#" title="{0}" \
669
            class="assigneeBlue9 js-change-assignee">{1}</a>' \
670
            .format(
671
                _('Assign this case(s) to other people'),
672
                _('Assignee')
673
            )
674
675
    def test_add_cases_to_run_with_permission(self):
676
        user_should_have_perm(self.tester, 'testruns.add_testexecution')
677
        response = self.client.get(self.url)
678
        self.assertContains(response, self.add_cases_html, html=True)
679
680
    def test_remove_cases_from_run_with_permission(self):
681
        user_should_have_perm(self.tester, 'testruns.delete_testexecution')
682
        response = self.client.get(self.url)
683
        self.assertContains(response, self.remove_cases_html, html=True)
684
685
    def test_update_caserun_text_with_permission(self):
686
        user_should_have_perm(self.tester, 'testruns.change_testexecution')
687
        response = self.client.get(self.url)
688
        self.assertContains(response, self.update_case_run_text_html, html=True)
689
690
    def test_change_assignee_with_permission(self):
691
        user_should_have_perm(self.tester, 'testruns.change_testexecution')
692
        response = self.client.get(self.url)
693
        self.assertContains(response, self.change_assignee_html, html=True)
694
695
    def test_add_cases_to_run_without_permission(self):
696
        remove_perm_from_user(self.tester, 'testruns.add_testexecution')
697
        response = self.client.get(self.url)
698
        self.assertNotContains(response, self.add_cases_html, html=True)
699
700
    def test_remove_cases_from_run_without_permission(self):
701
        remove_perm_from_user(self.tester, 'testruns.delete_testexecution')
702
        response = self.client.get(self.url)
703
        self.assertNotContains(response, self.remove_cases_html, html=True)
704
705
    def test_update_caserun_text_without_permission(self):
706
        remove_perm_from_user(self.tester, 'testruns.change_testexecution')
707
        response = self.client.get(self.url)
708
        self.assertNotContains(response, self.update_case_run_text_html, html=True)
709
710
    def test_change_assignee_without_permission(self):
711
        remove_perm_from_user(self.tester, 'testruns.change_testexecution')
712
        response = self.client.get(self.url)
713
        self.assertNotContains(response, self.change_assignee_html, html=True)
714