TestSearchRuns.setUpTestData()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 6
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 6
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.contrib.auth.models import Permission
7
from django.urls import reverse
8
from django.utils.translation import gettext_lazy as _
9
10
from tcms.testruns.models import TestExecutionStatus, TestRun
11
from tcms.tests import (
12
    BaseCaseRun,
13
    BasePlanCase,
14
    PermissionsTestCase,
15
    remove_perm_from_user,
16
    user_should_have_perm,
17
)
18
from tcms.tests.factories import (
19
    BuildFactory,
20
    TagFactory,
21
    TestExecutionFactory,
22
    TestRunFactory,
23
    UserFactory,
24
)
25
from tcms.utils.permissions import initiate_user_with_default_setups
26
27
28
class TestGetRun(BaseCaseRun):
29
    """Test get view method"""
30
31
    @classmethod
32
    def setUpTestData(cls):
33
        super().setUpTestData()
34
        initiate_user_with_default_setups(cls.tester)
35
36
        for _i in range(3):
37
            cls.test_run.add_tag(TagFactory())
38
39
        cls.unauthorized = UserFactory()
40
        cls.unauthorized.set_password("password")
41
        cls.unauthorized.save()
42
43
        cls.unauthorized.user_permissions.add(*Permission.objects.all())
44
        remove_perm_from_user(cls.unauthorized, "testruns.add_testruntag")
45
        remove_perm_from_user(cls.unauthorized, "testruns.delete_testruntag")
46
47
    def test_404_if_non_existing_pk(self):
48
        url = reverse("testruns-get", args=[99999999])
49
        response = self.client.get(url)
50
        self.assertEqual(HTTPStatus.NOT_FOUND, response.status_code)
51
52
    def test_get_a_run(self):
53
        url = reverse("testruns-get", args=[self.test_run.pk])
54
        response = self.client.get(url)
55
56
        self.assertEqual(HTTPStatus.OK, response.status_code)
57
        _tags = _("Tags")
58
        self.assertContains(
59
            response,
60
            f'<h2 class="card-pf-title"><span class="fa fa-tags"></span>{_tags}</h2>',
61
            html=True,
62
        )
63
64
    def test_get_run_without_permissions_to_add_or_remove_tags(self):
65
        self.client.logout()
66
67
        self.client.login(  # nosec:B106:hardcoded_password_funcarg
68
            username=self.unauthorized.username, password="password"
69
        )
70
71
        url = reverse("testruns-get", args=[self.test_run.pk])
72
        response = self.client.get(url)
73
74
        self.assertEqual(HTTPStatus.OK, response.status_code)
75
        self.assertNotContains(response, "Add Tag")
76
        self.assertNotContains(response, "js-remove-tag")
77
78
79
class TestCreateNewRun(BasePlanCase):
80
    """Test creating new run"""
81
82
    @classmethod
83
    def setUpTestData(cls):
84
        super().setUpTestData()
85
86
        cls.build = BuildFactory(version=cls.plan.product_version)
87
88
        user_should_have_perm(cls.tester, "testruns.add_testrun")
89
        user_should_have_perm(cls.tester, "testruns.view_testrun")
90
        cls.url = reverse("testruns-new")
91
92
    def test_get_shows_selected_cases(self):
93
        self.client.login(  # nosec:B106:hardcoded_password_funcarg
94
            username=self.tester.username, password="password"
95
        )
96
97
        response = self.client.get(
98
            self.url,
99
            {"p": self.plan.pk, "c": [self.case_1.pk, self.case_2.pk, self.case_3.pk]},
100
        )
101
102
        # Assert listed cases
103
        for _i, case in enumerate((self.case_1, self.case_2, self.case_3), 1):
104
            case_url = reverse("testcases-get", args=[case.pk])
105
            self.assertContains(
106
                response,
107
                f'<a href="{case_url}">TC-{case.pk}: {case.summary}</a>',
108
                html=True,
109
            )
110
111
    def test_post_creates_new_run(self):
112
        new_run_summary = "TestRun summary"
113
114
        post_data = {
115
            "summary": new_run_summary,
116
            "plan": self.plan.pk,
117
            "product_id": self.plan.product_id,
118
            "product": self.plan.product_id,
119
            "build": self.build.pk,
120
            "manager": self.tester.email,
121
            "default_tester": self.tester.email,
122
            "notes": "",
123
            "case": [self.case_1.pk, self.case_2.pk],
124
        }
125
126
        url = reverse("testruns-new")
127
        response = self.client.post(url, post_data)
128
129
        new_run = TestRun.objects.last()
130
131
        self.assertRedirects(response, reverse("testruns-get", args=[new_run.pk]))
132
133
        for case, execution in zip(
134
            (self.case_1, self.case_2), new_run.executions.order_by("case")
135
        ):
136
            self.assertEqual(case, execution.case)
137
            self.assertIsNone(execution.tested_by)
138
            self.assertEqual(self.tester, execution.assignee)
139
            self.assertEqual(
140
                case.history.latest().history_id, execution.case_text_version
141
            )
142
            self.assertEqual(new_run.build, execution.build)
143
            self.assertIsNone(execution.stop_date)
144
145
146
class TestCloneRunView(PermissionsTestCase):
147
    permission_label = "testruns.add_testrun"
148
    http_method_names = ["get"]
149
150
    @classmethod
151
    def setUpTestData(cls):
152
        cls.test_run = TestRunFactory()
153
        cls.execution_1 = TestExecutionFactory(run=cls.test_run)
154
        cls.execution_2 = TestExecutionFactory(run=cls.test_run)
155
156
        cls.url = reverse("testruns-clone", args=[cls.test_run.pk])
157
158
        super().setUpTestData()
159
160
    def verify_get_with_permission(self):
161
        response = self.client.get(self.url)
162
163
        self.assertContains(response, _("Clone TestRun"))
164
165
        _clone_of = _("Clone of ")
166
        self.assertContains(
167
            response,
168
            '<input id="id_summary" class="form-control" name="summary" '
169
            f'type="text" value="{_clone_of}{self.test_run.summary}" required>',
170
            html=True,
171
        )
172
173
        for execution in (self.execution_1, self.execution_2):
174
            case_url = reverse("testcases-get", args=[execution.case.pk])
175
176
            self.assertContains(
177
                response,
178
                f'<a href="{case_url}">TC-{execution.case.pk}: {execution.case.summary}</a>',
179
                html=True,
180
            )
181
182
183
class TestSearchRuns(BaseCaseRun):
184
    @classmethod
185
    def setUpTestData(cls):
186
        super(TestSearchRuns, cls).setUpTestData()
187
188
        cls.search_runs_url = reverse("testruns-search")
189
        user_should_have_perm(cls.tester, "testruns.view_testrun")
190
191
    def test_search_page_is_shown(self):
192
        response = self.client.get(self.search_runs_url)
193
        self.assertContains(response, '<input id="id_summary" type="text"')
194
195
    def test_search_page_is_shown_with_get_parameter_used(self):
196
        response = self.client.get(self.search_runs_url, {"product": self.product.pk})
197
        self.assertContains(
198
            response,
199
            f'<option value="{self.product.pk}" selected>{self.product.name}</option>',
200
            html=True,
201
        )
202
203
204
class TestRunCasesMenu(BaseCaseRun):
205
    @classmethod
206
    def setUpTestData(cls):
207
        super().setUpTestData()
208
        user_should_have_perm(cls.tester, "testruns.view_testrun")
209
210
        cls.url = reverse("testruns-get", args=[cls.test_run.pk])
211
212
        _update_text_version = _("Update text version")
213
        cls.update_text_version_html = f"""
214
            <a href="#" class="update-case-text-bulk">
215
                <span class="fa fa-refresh"></span>{_update_text_version}
216
            </a>
217
        """
218
219
        _assignee = _("Assignee")
220
        cls.change_assignee_html = f"""
221
            <a class="change-assignee-bulk" href="#">
222
                <span class="fa pficon-user"></span>
223
                {_assignee}
224
            </a>
225
        """
226
227
        _delete = _("Delete")
228
        cls.remove_executions_html = f"""
229
            <a class="bg-danger remove-execution-bulk" href="#">
230
                <span class="fa fa-trash-o"></span>
231
                {_delete}
232
            </a>
233
        """
234
235
    def test_add_cases_to_run_with_permission(self):
236
        user_should_have_perm(self.tester, "testruns.add_testexecution")
237
        response = self.client.get(self.url)
238
        self.assertContains(response, _("Search and add test cases"))
239
        self.assertContains(response, _("Advanced search"))
240
241
    def test_add_cases_to_run_without_permission(self):
242
        remove_perm_from_user(self.tester, "testruns.add_testexecution")
243
        response = self.client.get(self.url)
244
        self.assertNotContains(response, _("Search and add test cases"))
245
        self.assertNotContains(response, _("Advanced search"))
246
247
    def test_change_assignee_with_permission(self):
248
        user_should_have_perm(self.tester, "testruns.change_testexecution")
249
        response = self.client.get(self.url)
250
        self.assertContains(response, self.change_assignee_html, html=True)
251
252
    def test_change_assignee_without_permission(self):
253
        remove_perm_from_user(self.tester, "testruns.change_testexecution")
254
        response = self.client.get(self.url)
255
        self.assertNotContains(response, self.change_assignee_html, html=True)
256
257
    def test_update_text_version_with_permission(self):
258
        user_should_have_perm(self.tester, "testruns.change_testexecution")
259
        response = self.client.get(self.url)
260
        self.assertContains(response, self.update_text_version_html, html=True)
261
262
    def test_update_text_version_without_permission(self):
263
        remove_perm_from_user(self.tester, "testruns.change_testexecution")
264
        response = self.client.get(self.url)
265
        self.assertNotContains(response, self.update_text_version_html, html=True)
266
267
    def test_remove_executions_with_permission(self):
268
        user_should_have_perm(self.tester, "testruns.delete_testexecution")
269
        response = self.client.get(self.url)
270
        self.assertContains(response, self.remove_executions_html, html=True)
271
272
    def test_remove_executions_without_permission(self):
273
        remove_perm_from_user(self.tester, "testruns.delete_testexecution")
274
        response = self.client.get(self.url)
275
        self.assertNotContains(response, self.remove_executions_html, html=True)
276
277
278
class TestRunStatusMenu(BaseCaseRun):
279
    @classmethod
280
    def setUpTestData(cls):
281
        super().setUpTestData()
282
        cls.url = reverse("testruns-get", args=[cls.test_run.pk])
283
        user_should_have_perm(cls.tester, "testruns.view_testrun")
284
        cls.status_menu_html = []
285
286
    def test_get_status_options_with_permission(self):
287
        user_should_have_perm(self.tester, "testruns.change_testexecution")
288
        response = self.client.get(self.url)
289
        self.assertEqual(HTTPStatus.OK, response.status_code)
290
291
        for execution_status in TestExecutionStatus.objects.all():
292
            self.assertContains(
293
                response,
294
                f'<span class="{execution_status.icon}"></span>{execution_status.name}',
295
                html=True,
296
            )
297
298
    def test_get_status_options_without_permission(self):
299
        remove_perm_from_user(self.tester, "testruns.change_testexecution")
300
        response = self.client.get(self.url)
301
        self.assertEqual(HTTPStatus.OK, response.status_code)
302
303
        for execution_status in TestExecutionStatus.objects.all():
304
            self.assertNotContains(
305
                response,
306
                f'<span class="{execution_status.icon}"></span>{execution_status.name}',
307
                html=True,
308
            )
309