Passed
Push — master ( 189f04...13283a )
by Alexander
03:44
created

TestCloneCase.test_show_clone_page_with_selected_cases()   A

Complexity

Conditions 2

Size

Total Lines 9
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 9
rs 10
c 0
b 0
f 0
cc 2
nop 1
1
# -*- coding: utf-8 -*-
2
# pylint: disable=invalid-name, too-many-ancestors
3
4
import unittest
5
from http import HTTPStatus
6
from urllib.parse import urlencode
7
8
from django.urls import reverse
9
from django.forms import ValidationError
10
from django.test import RequestFactory
11
from django.utils.translation import override
12
from django.utils.translation import ugettext_lazy as _
13
14
from tcms.testcases.fields import MultipleEmailField
15
from tcms.management.models import Priority, Tag
16
from tcms.testcases.models import TestCase, TestCasePlan
17
from tcms.testcases.views import get_selected_testcases
18
from tcms.testruns.models import TestExecutionStatus
19
from tcms.tests.factories import BugFactory
20
from tcms.tests.factories import TestCaseFactory
21
from tcms.tests import BasePlanCase, BaseCaseRun, remove_perm_from_user
22
from tcms.tests import user_should_have_perm
23
from tcms.utils.permissions import initiate_user_with_default_setups
24
25
26
class TestGetTestCase(BaseCaseRun):
27
    def test_test_case_is_shown(self):
28
        url = reverse('testcases-get', args=[self.case_1.pk])
29
        response = self.client.get(url)
30
31
        # will not fail when running under different locale
32
        self.assertEqual(HTTPStatus.OK, response.status_code)
33
34
35
class TestGetCaseRunDetailsAsDefaultUser(BaseCaseRun):
36
    """Assert what a default user (non-admin) will see"""
37
38
    def test_user_in_default_group_sees_comments(self):
39
        # test for https://github.com/kiwitcms/Kiwi/issues/74
40
        initiate_user_with_default_setups(self.tester)
41
42
        url = reverse('execution-detail-pane', args=[self.execution_1.case_id])
43
        response = self.client.get(
44
            url,
45
            {
46
                'case_run_id': self.execution_1.pk,
47
                'case_text_version': self.execution_1.case.history.latest().history_id,
48
            }
49
        )
50
51
        self.assertEqual(HTTPStatus.OK, response.status_code)
52
53
        self.assertContains(
54
            response,
55
            '<textarea name="comment" cols="40" id="id_comment" maxlength="10000" '
56
            'rows="10">\n</textarea>',
57
            html=True)
58
59
        with override('en'):
60
            for status in TestExecutionStatus.objects.all():
61
                self.assertContains(
62
                    response,
63
                    "<input type=\"submit\" class=\"btn btn_%s btn_status js-status-button\" "
64
                    "title=\"%s\"" % (status.name.lower(), status.name),
65
                    html=False
66
                )
67
68
    def test_user_sees_bugs(self):
69
        bug_1 = BugFactory()
70
        bug_2 = BugFactory()
71
72
        self.execution_1.add_bug(bug_1.bug_id, bug_1.bug_system.pk)
73
        self.execution_1.add_bug(bug_2.bug_id, bug_2.bug_system.pk)
74
75
        url = reverse('execution-detail-pane', args=[self.execution_1.case.pk])
76
        response = self.client.get(
77
            url,
78
            {
79
                'case_run_id': self.execution_1.pk,
80
                'case_text_version': self.execution_1.case.history.latest().history_id,
81
            }
82
        )
83
84
        self.assertEqual(HTTPStatus.OK, response.status_code)
85
        self.assertContains(response, bug_1.get_full_url())
86
        self.assertContains(response, bug_2.get_full_url())
87
88
89
class TestMultipleEmailField(unittest.TestCase):
90
91
    @classmethod
92
    def setUpClass(cls):
93
        super().setUpClass()
94
        cls.field = MultipleEmailField()
95
96
    def test_to_python(self):
97
        value = u'zhangsan@localhost'
98
        pyobj = self.field.to_python(value)
99
        self.assertEqual(pyobj, [value])
100
101
        value = u'zhangsan@localhost,,[email protected],'
102
        pyobj = self.field.to_python(value)
103
        self.assertEqual(pyobj, [u'zhangsan@localhost', u'[email protected]'])
104
105
        for value in ('', None, []):
106
            pyobj = self.field.to_python(value)
107
            self.assertEqual(pyobj, [])
108
109
    def test_clean(self):
110
        value = u'zhangsan@localhost'
111
        data = self.field.clean(value)
112
        self.assertEqual(data, [value])
113
114
        value = u'zhangsan@localhost,[email protected]'
115
        data = self.field.clean(value)
116
        self.assertEqual(data, [u'zhangsan@localhost', u'[email protected]'])
117
118
        value = u',zhangsan@localhost, ,[email protected], \n'
119
        data = self.field.clean(value)
120
        self.assertEqual(data, [u'zhangsan@localhost', '[email protected]'])
121
122
        value = ',zhangsan,zhangsan@localhost, \n,[email protected], '
123
        self.assertRaises(ValidationError, self.field.clean, value)
124
125
        value = ''
126
        self.field.required = True
127
        self.assertRaises(ValidationError, self.field.clean, value)
128
129
        value = ''
130
        self.field.required = False
131
        data = self.field.clean(value)
132
        self.assertEqual(data, [])
133
134
135
class TestNewCase(BasePlanCase):
136
137
    @classmethod
138
    def setUpTestData(cls):
139
        super().setUpTestData()
140
141
        cls.new_case_url = reverse('testcases-new')
142
143
        cls.summary = 'summary'
144
        cls.text = 'some text description'
145
        cls.script = 'some script'
146
        cls.arguments = 'args1, args2, args3'
147
        cls.requirement = 'requirement'
148
        cls.link = 'http://somelink.net'
149
        cls.notes = 'notes'
150
        cls.data = {
151
            'summary': cls.summary,
152
            'default_tester': cls.tester.pk,
153
            'product': cls.case.category.product.pk,
154
            'category': cls.case.category.pk,
155
            'case_status': cls.case_status_confirmed.pk,
156
            'priority': cls.case.priority.pk,
157
            'text': cls.text,
158
            'script': cls.script,
159
            'arguments': cls.arguments,
160
            'requirement': cls.requirement,
161
            'extra_link': cls.link,
162
            'notes': cls.notes
163
        }
164
165
        user_should_have_perm(cls.tester, 'testcases.add_testcase')
166
167
    def test_create_test_case_successfully(self):
168
        response = self.client.post(self.new_case_url, self.data)
169
170
        test_case = TestCase.objects.get(summary=self.summary)
171
        redirect_url = reverse('testcases-get', args=[test_case.pk])
172
173
        self.assertRedirects(response, redirect_url)
174
        self._assertTestCase(test_case)
175
176
    def test_create_test_case_successfully_from_plan(self):
177
        self.data['from_plan'] = self.plan.pk
178
179
        response = self.client.post(self.new_case_url, self.data)
180
181
        test_case = TestCase.objects.get(summary=self.summary)
182
        redirect_url = "{0}?from_plan={1}".format(
183
            reverse('testcases-get', args=[test_case.pk]), self.plan.pk
184
        )
185
186
        self.assertRedirects(response, redirect_url)
187
        self.assertEqual(test_case.plan.get(), self.plan)
188
        self.assertEqual(TestCasePlan.objects.filter(case=test_case, plan=self.plan).count(), 1)
189
        self._assertTestCase(test_case)
190
191
    def test_create_test_case_without_permissions(self):
192
        remove_perm_from_user(self.tester, 'testcases.add_testcase')
193
194
        response = self.client.post(self.new_case_url, self.data)
195
        redirect_url = "{0}?next={1}".format(
196
            reverse('tcms-login'), reverse('testcases-new')
197
        )
198
199
        self.assertRedirects(response, redirect_url)
200
        # assert test case has not been created
201
        self.assertEqual(TestCase.objects.filter(summary=self.summary).count(), 0)
202
203
    def _assertTestCase(self, test_case):
204
        self.assertEqual(test_case.summary, self.summary)
205
        self.assertEqual(test_case.category, self.case.category)
206
        self.assertEqual(test_case.default_tester, self.tester)
207
        self.assertEqual(test_case.case_status, self.case_status_confirmed)
208
        self.assertEqual(test_case.priority, self.case.priority)
209
        self.assertEqual(test_case.text, self.text)
210
        self.assertEqual(test_case.script, self.script)
211
        self.assertEqual(test_case.arguments, self.arguments)
212
        self.assertEqual(test_case.requirement, self.requirement)
213
        self.assertEqual(test_case.extra_link, self.link)
214
        self.assertEqual(test_case.notes, self.notes)
215
216
217
class TestEditCase(BasePlanCase):
218
    """Test edit view method"""
219
220
    @classmethod
221
    def setUpTestData(cls):
222
        super(TestEditCase, cls).setUpTestData()
223
224
        cls.proposed_case = TestCaseFactory(
225
            author=cls.tester,
226
            default_tester=None,
227
            reviewer=cls.tester,
228
            case_status=cls.case_status_proposed,
229
            plan=[cls.plan])
230
231
        # test data for https://github.com/kiwitcms/Kiwi/issues/334
232
        # pylint: disable=objects-update-used
233
        Priority.objects.filter(value='P4').update(is_active=False)
234
235
        user_should_have_perm(cls.tester, 'testcases.change_testcase')
236
        cls.case_edit_url = reverse('testcases-edit', args=[cls.case_1.pk])
237
238
        # Copy, then modify or add new data for specific tests below
239
        cls.edit_data = {
240
            'from_plan': cls.plan.pk,
241
            'summary': cls.case_1.summary,
242
            'product': cls.case_1.category.product.pk,
243
            'category': cls.case_1.category.pk,
244
            'default_tester': '',
245
            'case_status': cls.case_status_confirmed.pk,
246
            'arguments': '',
247
            'extra_link': '',
248
            'notes': '',
249
            'is_automated': '0',
250
            'requirement': '',
251
            'script': '',
252
            'priority': cls.case_1.priority.pk,
253
            'tag': 'RHEL',
254
            'text': 'Given-When-Then',
255
            'cc_list': '',
256
        }
257
258
    def test_404_if_case_id_not_exist(self):
259
        url = reverse('testcases-edit', args=[99999])
260
        response = self.client.get(url)
261
        self.assert404(response)
262
263
    def test_404_if_from_plan_not_exist(self):
264
        response = self.client.get(self.case_edit_url, {'from_plan': 9999})
265
        self.assert404(response)
266
267
    def test_show_edit_page(self):
268
        response = self.client.get(self.case_edit_url)
269
        self.assertEqual(200, response.status_code)
270
        self.assertNotContains(response, ">P4</option")
271
272
    def test_edit_a_case(self):
273
        edit_data = self.edit_data.copy()
274
        new_summary = 'Edited: {0}'.format(self.case_1.summary)
275
        edit_data['summary'] = new_summary
276
277
        response = self.client.post(self.case_edit_url, edit_data)
278
279
        redirect_url = '{0}?from_plan={1}'.format(
280
            reverse('testcases-get', args=[self.case_1.pk]),
281
            self.plan.pk,
282
        )
283
        self.assertRedirects(response, redirect_url)
284
285
        edited_case = TestCase.objects.get(pk=self.case_1.pk)
286
        self.assertEqual(new_summary, edited_case.summary)
287
288
289
class TestPrintablePage(BasePlanCase):
290
    """Test printable page view method"""
291
292
    @classmethod
293
    def setUpTestData(cls):
294
        super().setUpTestData()
295
        cls.printable_url = reverse('testcases-printable')
296
297
    def test_printable_page(self):
298
        # printing only 1 of the cases
299
        response = self.client.post(self.printable_url,
300
                                    {'case': [self.case_1.pk]})
301
302
        # not printing the Test Plan header section
303
        self.assertNotContains(response, 'Test Plan Document')
304
305
        # response contains the first TestCase
306
        self.assertContains(
307
            response,
308
            '<h3>TC-{0}: {1}</h3>'.format(self.case_1.pk, self.case_1.summary),
309
            html=True
310
        )
311
312
        # but not the second TestCase b/c it was not selected
313
        self.assertNotContains(
314
            response,
315
            '<h3>TC-{0}: {1}'.format(self.case_2.pk, self.case_2.summary),
316
            html=True
317
        )
318
319
320
class TestCloneCase(BasePlanCase):
321
    """Test clone view method"""
322
323
    @classmethod
324
    def setUpTestData(cls):
325
        super(TestCloneCase, cls).setUpTestData()
326
327
        user_should_have_perm(cls.tester, 'testcases.add_testcase')
328
        cls.clone_url = reverse('testcases-clone')
329
330
    def test_refuse_if_missing_argument(self):
331
        # Refuse to clone cases if missing selectAll and case arguments
332
        response = self.client.get(self.clone_url, {}, follow=True)
333
334
        self.assertContains(response, _('At least one TestCase is required'))
335
336
    def test_show_clone_page_with_selected_cases(self):
337
        response = self.client.get(self.clone_url,
338
                                   {'case': [self.case_1.pk, self.case_2.pk]})
339
340
        self.assertContains(response, "TP-%s: %s" % (self.plan.pk, self.plan.name))
341
342
        for case in [self.case_1, self.case_2]:
343
            self.assertContains(response,
344
                                "TC-%d: %s" % (case.pk, case.summary))
345
346
347
class TestSearchCases(BasePlanCase):
348
    """Test search view method"""
349
350
    @classmethod
351
    def setUpTestData(cls):
352
        super().setUpTestData()
353
354
        cls.search_url = reverse('testcases-search')
355
356
    def test_page_renders(self):
357
        response = self.client.get(self.search_url, {})
358
        self.assertContains(response, '<option value="">----------</option>', html=True)
359
360
361
class TestGetCasesFromPlan(BasePlanCase):
362
    @classmethod
363
    def setUpTestData(cls):
364
        super().setUpTestData()
365
        initiate_user_with_default_setups(cls.tester)
366
367
    def test_casetags_are_shown_in_template(self):
368
        # pylint: disable=tag-objects-get_or_create
369
        tag, _created = Tag.objects.get_or_create(name='Linux')
370
        self.case.add_tag(tag)
371
372
        url = reverse('testcases-all')
373
        response_data = urlencode({
374
            'from_plan': self.plan.pk,
375
            'template_type': 'case',
376
            'a': 'initial'})
377
        # note: this is how the UI sends the request
378
        response = self.client.post(url, data=response_data,
379
                                    content_type='application/x-www-form-urlencoded; charset=UTF-8',
380
                                    HTTP_X_REQUESTED_WITH='XMLHttpRequest')
381
        self.assertEqual(HTTPStatus.OK, response.status_code)
382
        self.assertContains(response, _('Tags'))
383
        self.assertContains(response, '<a href="#testcases">Linux</a>')
384
385
    def test_disabled_priority_now_shown(self):
386
        # test data for https://github.com/kiwitcms/Kiwi/issues/334
387
        # pylint: disable=objects-update-used
388
        Priority.objects.filter(value='P4').update(is_active=False)
389
390
        url = reverse('testcases-all')
391
        response_data = urlencode({
392
            'from_plan': self.plan.pk,
393
            'template_type': 'case',
394
            'a': 'initial'})
395
        # note: this is how the UI sends the request
396
        response = self.client.post(url, data=response_data,
397
                                    content_type='application/x-www-form-urlencoded; charset=UTF-8',
398
                                    HTTP_X_REQUESTED_WITH='XMLHttpRequest')
399
        self.assertEqual(HTTPStatus.OK, response.status_code)
400
        self.assertContains(response, 'Set P3')
401
        self.assertNotContains(response, 'Set P4')
402
403
404
class TestGetSelectedTestcases(BasePlanCase):
405
    def test_get_selected_testcases_works_with_both_string_and_int_pks(self):
406
        """
407
        Assures that tcms.testcases.views.get_selected_testcases
408
        returns the same results, regardless of whether the
409
        passed request contains the case pks as strings or
410
        integers, as long as they are the same in both occasions.
411
        """
412
413
        case_int_pks = [self.case.pk, self.case_1.pk, self.case_2.pk, self.case_3.pk]
414
        case_str_pks = []
415
416
        for _pk in case_int_pks:
417
            case_str_pks.append(str(_pk))
418
419
        int_pk_query = get_selected_testcases(
420
            RequestFactory().post(
421
                reverse('testcases-clone'),
422
                {'case': case_int_pks}
423
            )
424
        )
425
426
        str_pk_query = get_selected_testcases(
427
            RequestFactory().post(
428
                reverse('testcases-clone'),
429
                {'case': case_str_pks}
430
            )
431
        )
432
433
        for case in TestCase.objects.filter(pk__in=case_int_pks):
434
            self.assertTrue(case in int_pk_query)
435
            self.assertTrue(case in str_pk_query)
436