Passed
Push — master ( e9ad8a...f58c94 )
by Alexander
03:37
created

TestSearchCases.test_get_parameter_should_be_accepted_for_a_product()   A

Complexity

Conditions 1

Size

Total Lines 6
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 6
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
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 = reverse('testcases-get', args=[test_case.pk])
183
184
        self.assertRedirects(response, redirect_url)
185
        self.assertEqual(test_case.plan.get(), self.plan)
186
        self.assertEqual(TestCasePlan.objects.filter(case=test_case, plan=self.plan).count(), 1)
187
        self._assertTestCase(test_case)
188
189
    def test_create_test_case_without_permissions(self):
190
        remove_perm_from_user(self.tester, 'testcases.add_testcase')
191
192
        response = self.client.post(self.new_case_url, self.data)
193
        redirect_url = "{0}?next={1}".format(
194
            reverse('tcms-login'), reverse('testcases-new')
195
        )
196
197
        self.assertRedirects(response, redirect_url)
198
        # assert test case has not been created
199
        self.assertEqual(TestCase.objects.filter(summary=self.summary).count(), 0)
200
201
    def _assertTestCase(self, test_case):
202
        self.assertEqual(test_case.summary, self.summary)
203
        self.assertEqual(test_case.category, self.case.category)
204
        self.assertEqual(test_case.default_tester, self.tester)
205
        self.assertEqual(test_case.case_status, self.case_status_confirmed)
206
        self.assertEqual(test_case.priority, self.case.priority)
207
        self.assertEqual(test_case.text, self.text)
208
        self.assertEqual(test_case.script, self.script)
209
        self.assertEqual(test_case.arguments, self.arguments)
210
        self.assertEqual(test_case.requirement, self.requirement)
211
        self.assertEqual(test_case.extra_link, self.link)
212
        self.assertEqual(test_case.notes, self.notes)
213
214
215
class TestEditCase(BasePlanCase):
216
    """Test edit view method"""
217
218
    @classmethod
219
    def setUpTestData(cls):
220
        super(TestEditCase, cls).setUpTestData()
221
222
        cls.proposed_case = TestCaseFactory(
223
            author=cls.tester,
224
            default_tester=None,
225
            reviewer=cls.tester,
226
            case_status=cls.case_status_proposed,
227
            plan=[cls.plan])
228
229
        # test data for https://github.com/kiwitcms/Kiwi/issues/334
230
        # pylint: disable=objects-update-used
231
        Priority.objects.filter(value='P4').update(is_active=False)
232
233
        user_should_have_perm(cls.tester, 'testcases.change_testcase')
234
        cls.case_edit_url = reverse('testcases-edit', args=[cls.case_1.pk])
235
236
        # Copy, then modify or add new data for specific tests below
237
        cls.edit_data = {
238
            'from_plan': cls.plan.pk,
239
            'summary': cls.case_1.summary,
240
            'product': cls.case_1.category.product.pk,
241
            'category': cls.case_1.category.pk,
242
            'default_tester': '',
243
            'case_status': cls.case_status_confirmed.pk,
244
            'arguments': '',
245
            'extra_link': '',
246
            'notes': '',
247
            'is_automated': '0',
248
            'requirement': '',
249
            'script': '',
250
            'priority': cls.case_1.priority.pk,
251
            'tag': 'RHEL',
252
            'text': 'Given-When-Then',
253
            'cc_list': '',
254
        }
255
256
    def test_404_if_case_id_not_exist(self):
257
        url = reverse('testcases-edit', args=[99999])
258
        response = self.client.get(url)
259
        self.assert404(response)
260
261
    def test_404_if_from_plan_not_exist(self):
262
        response = self.client.get(self.case_edit_url, {'from_plan': 9999})
263
        self.assert404(response)
264
265
    def test_show_edit_page(self):
266
        response = self.client.get(self.case_edit_url)
267
        self.assertEqual(200, response.status_code)
268
        self.assertNotContains(response, ">P4</option")
269
270
    def test_edit_a_case(self):
271
        edit_data = self.edit_data.copy()
272
        new_summary = 'Edited: {0}'.format(self.case_1.summary)
273
        edit_data['summary'] = new_summary
274
275
        response = self.client.post(self.case_edit_url, edit_data)
276
277
        redirect_url = reverse('testcases-get', args=[self.case_1.pk])
278
        self.assertRedirects(response, redirect_url)
279
280
        edited_case = TestCase.objects.get(pk=self.case_1.pk)
281
        self.assertEqual(new_summary, edited_case.summary)
282
283
284
class TestPrintablePage(BasePlanCase):
285
    """Test printable page view method"""
286
287
    @classmethod
288
    def setUpTestData(cls):
289
        super().setUpTestData()
290
        cls.printable_url = reverse('testcases-printable')
291
292
    def test_printable_page(self):
293
        # printing only 1 of the cases
294
        response = self.client.post(self.printable_url,
295
                                    {'case': [self.case_1.pk]})
296
297
        # not printing the Test Plan header section
298
        self.assertNotContains(response, 'Test Plan Document')
299
300
        # response contains the first TestCase
301
        self.assertContains(
302
            response,
303
            '<h3>TC-{0}: {1}</h3>'.format(self.case_1.pk, self.case_1.summary),
304
            html=True
305
        )
306
307
        # but not the second TestCase b/c it was not selected
308
        self.assertNotContains(
309
            response,
310
            '<h3>TC-{0}: {1}'.format(self.case_2.pk, self.case_2.summary),
311
            html=True
312
        )
313
314
315
class TestCloneCase(BasePlanCase):
316
    """Test clone view method"""
317
318
    @classmethod
319
    def setUpTestData(cls):
320
        super(TestCloneCase, cls).setUpTestData()
321
322
        user_should_have_perm(cls.tester, 'testcases.add_testcase')
323
        cls.clone_url = reverse('testcases-clone')
324
325
    def test_refuse_if_missing_argument(self):
326
        # Refuse to clone cases if missing selectAll and case arguments
327
        response = self.client.get(self.clone_url, {}, follow=True)
328
329
        self.assertContains(response, _('At least one TestCase is required'))
330
331
    def test_show_clone_page_with_selected_cases(self):
332
        response = self.client.get(self.clone_url,
333
                                   {'case': [self.case_1.pk, self.case_2.pk]})
334
335
        self.assertContains(response, "TP-%s: %s" % (self.plan.pk, self.plan.name))
336
337
        for case in [self.case_1, self.case_2]:
338
            self.assertContains(response,
339
                                "TC-%d: %s" % (case.pk, case.summary))
340
341
    def test_user_without_permission_should_not_be_able_to_clone_a_case(self):
342
        remove_perm_from_user(self.tester, 'testcases.add_testcase')
343
        base_url = reverse('tcms-login') + '?next='
344
        expected = base_url + reverse('testcases-clone') + "?case=%d" % self.case_1.pk
345
        response = self.client.get(self.clone_url, {'case': [self.case_1.pk, ]})
346
347
        self.assertRedirects(
348
            response,
349
            expected
350
        )
351
352
353
class TestSearchCases(BasePlanCase):
354
    """Test search view method"""
355
356
    @classmethod
357
    def setUpTestData(cls):
358
        super().setUpTestData()
359
360
        cls.search_url = reverse('testcases-search')
361
362
    def test_page_renders(self):
363
        response = self.client.get(self.search_url, {})
364
        self.assertContains(response, '<option value="">----------</option>', html=True)
365
366
    def test_get_parameter_should_be_accepted_for_a_product(self):
367
        response = self.client.get(self.search_url, {'product': self.product.pk})
368
        self.assertContains(response,
369
                            '<option value="%d" selected>%s</option>' % (self.product.pk,
370
                                                                         self.product.name),
371
                            html=True)
372
373
374
class TestGetCasesFromPlan(BasePlanCase):
375
    @classmethod
376
    def setUpTestData(cls):
377
        super().setUpTestData()
378
        initiate_user_with_default_setups(cls.tester)
379
380
    def test_casetags_are_shown_in_template(self):
381
        # pylint: disable=tag-objects-get_or_create
382
        tag, _created = Tag.objects.get_or_create(name='Linux')
383
        self.case.add_tag(tag)
384
385
        url = reverse('testcases-all')
386
        response_data = urlencode({
387
            'from_plan': self.plan.pk,
388
            'template_type': 'case',
389
            'a': 'initial'})
390
        # note: this is how the UI sends the request
391
        response = self.client.post(url, data=response_data,
392
                                    content_type='application/x-www-form-urlencoded; charset=UTF-8',
393
                                    HTTP_X_REQUESTED_WITH='XMLHttpRequest')
394
        self.assertEqual(HTTPStatus.OK, response.status_code)
395
        self.assertContains(response, _('Tags'))
396
        self.assertContains(response, '<a href="#testcases">Linux</a>')
397
398
    def test_disabled_priority_now_shown(self):
399
        # test data for https://github.com/kiwitcms/Kiwi/issues/334
400
        # pylint: disable=objects-update-used
401
        Priority.objects.filter(value='P4').update(is_active=False)
402
403
        url = reverse('testcases-all')
404
        response_data = urlencode({
405
            'from_plan': self.plan.pk,
406
            'template_type': 'case',
407
            'a': 'initial'})
408
        # note: this is how the UI sends the request
409
        response = self.client.post(url, data=response_data,
410
                                    content_type='application/x-www-form-urlencoded; charset=UTF-8',
411
                                    HTTP_X_REQUESTED_WITH='XMLHttpRequest')
412
        self.assertEqual(HTTPStatus.OK, response.status_code)
413
        self.assertContains(response, 'Set P3')
414
        self.assertNotContains(response, 'Set P4')
415
416
417
class TestGetSelectedTestcases(BasePlanCase):
418
    def test_get_selected_testcases_works_with_both_string_and_int_pks(self):
419
        """
420
        Assures that tcms.testcases.views.get_selected_testcases
421
        returns the same results, regardless of whether the
422
        passed request contains the case pks as strings or
423
        integers, as long as they are the same in both occasions.
424
        """
425
426
        case_int_pks = [self.case.pk, self.case_1.pk, self.case_2.pk, self.case_3.pk]
427
        case_str_pks = []
428
429
        for _pk in case_int_pks:
430
            case_str_pks.append(str(_pk))
431
432
        int_pk_query = get_selected_testcases(
433
            RequestFactory().post(
434
                reverse('testcases-clone'),
435
                {'case': case_int_pks}
436
            )
437
        )
438
439
        str_pk_query = get_selected_testcases(
440
            RequestFactory().post(
441
                reverse('testcases-clone'),
442
                {'case': case_str_pks}
443
            )
444
        )
445
446
        for case in TestCase.objects.filter(pk__in=case_int_pks):
447
            self.assertTrue(case in int_pk_query)
448
            self.assertTrue(case in str_pk_query)
449