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

tcms.tests   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 230
Duplicated Lines 14.78 %

Importance

Changes 0
Metric Value
wmc 25
eloc 167
dl 34
loc 230
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A LoggedInTestCase.setUp() 0 7 1
A LoggedInTestCase.setUpTestData() 0 5 1
A LoggedInTestCase.assertJsonResponse() 0 5 1
A LoggedInTestCase.assert404() 0 2 1
B BasePlanCase.setUpTestData() 0 70 1
A BaseCaseRun.setUpTestData() 0 47 3

3 Functions

Rating   Name   Duplication   Size   Complexity  
B user_should_have_perm() 16 16 7
B remove_perm_from_user() 18 18 7
A create_request_user() 0 11 3

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
# -*- coding: utf-8 -*-
2
# pylint: disable=invalid-name
3
4
from http import HTTPStatus
5
6
from django import test
7
from django.conf import settings
8
from django.contrib.auth.models import Permission
9
10
from tcms.testruns.models import TestExecutionStatus
11
from tcms.testcases.models import TestCaseStatus
12
from tcms.tests.factories import ProductFactory
13
from tcms.tests.factories import TestCaseFactory
14
from tcms.tests.factories import TestExecutionFactory
15
from tcms.tests.factories import TestPlanFactory
16
from tcms.tests.factories import TestRunFactory
17
from tcms.tests.factories import UserFactory
18
from tcms.tests.factories import VersionFactory
19
from tcms.tests.factories import BuildFactory
20
21
22 View Code Duplication
def user_should_have_perm(user, perm):
0 ignored issues
show
Duplication introduced by Chenxiong Qi
This code seems to be duplicated in your project.
Loading history...
23
    if isinstance(perm, str):
24
        try:
25
            app_label, codename = perm.split('.')
26
        except ValueError:
27
            raise ValueError('%s is not valid. Should be in format app_label.perm_codename')
28
        else:
29
            if not app_label or not codename:
30
                raise ValueError('Invalid app_label or codename')
31
            get_permission = Permission.objects.get
32
            user.user_permissions.add(
33
                get_permission(content_type__app_label=app_label, codename=codename))
34
    elif isinstance(perm, Permission):
35
        user.user_permissions.add(perm)
36
    else:
37
        raise TypeError('perm should be an instance of either str or Permission')
38
39
40 View Code Duplication
def remove_perm_from_user(user, perm):
0 ignored issues
show
Duplication introduced by Chenxiong Qi
This code seems to be duplicated in your project.
Loading history...
41
    """Remove a permission from an user"""
42
43
    if isinstance(perm, str):
44
        try:
45
            app_label, codename = perm.split('.')
46
        except ValueError:
47
            raise ValueError('%s is not valid. Should be in format app_label.perm_codename')
48
        else:
49
            if not app_label or not codename:
50
                raise ValueError('Invalid app_label or codename')
51
            get_permission = Permission.objects.get
52
            user.user_permissions.remove(
53
                get_permission(content_type__app_label=app_label, codename=codename))
54
    elif isinstance(perm, Permission):
55
        user.user_permissions.remove(perm)
56
    else:
57
        raise TypeError('perm should be an instance of either str or Permission')
58
59
60
def create_request_user(username=None, password=None):
61
    if username:
62
        user = UserFactory(username=username)
63
    else:
64
        user = UserFactory()
65
    if password:
66
        user.set_password(password)
67
    else:
68
        user.set_password('password')
69
    user.save()
70
    return user
71
72
73
class LoggedInTestCase(test.TestCase):
74
    """
75
        Test case class for logged-in users which also provides couple of
76
        helper assertion methods.
77
    """
78
79
    @classmethod
80
    def setUpTestData(cls):
81
        cls.tester = UserFactory()
82
        cls.tester.set_password('password')
83
        cls.tester.save()
84
85
    def setUp(self):
86
        """
87
            Login because by default we have GlobalLoginRequiredMiddleware enabled!
88
        """
89
        super().setUp()
90
        self.client.login(username=self.tester.username,  # nosec:B106:hardcoded_password_funcarg
91
                          password='password')
92
93
    # todo: create a lint plugin for that to enforce using the helper
94
    def assert404(self, response):
95
        self.assertEqual(HTTPStatus.NOT_FOUND, response.status_code)
96
97
    # todo: create a lint plugin for that to enforce using the helper
98
    def assertJsonResponse(self, response, expected, status_code=200):
99
        self.assertEqual(status_code, response.status_code)
100
        self.assertJSONEqual(
101
            str(response.content, encoding=settings.DEFAULT_CHARSET),
102
            expected)
103
104
105
class BasePlanCase(LoggedInTestCase):
106
    """Base test case by providing essential Plan and Case objects used in tests"""
107
108
    @classmethod
109
    def setUpTestData(cls):
110
        super().setUpTestData()
111
112
        cls.case_status_confirmed = TestCaseStatus.objects.get(name='CONFIRMED')
113
        cls.case_status_proposed = TestCaseStatus.objects.get(name='PROPOSED')
114
115
        cls.product = ProductFactory(name='Kiwi')
116
        cls.version = VersionFactory(value='0.1', product=cls.product)
117
118
        cls.plan = TestPlanFactory(
119
            author=cls.tester,
120
            product=cls.product,
121
            product_version=cls.version)
122
123
        cls.case = TestCaseFactory(
124
            author=cls.tester,
125
            default_tester=None,
126
            reviewer=cls.tester,
127
            case_status=cls.case_status_confirmed,
128
            plan=[cls.plan])
129
        cls.case.save()  # will generate history object
130
131
        cls.case_1 = TestCaseFactory(
132
            author=cls.tester,
133
            default_tester=None,
134
            reviewer=cls.tester,
135
            case_status=cls.case_status_confirmed,
136
            plan=[cls.plan])
137
        cls.case_1.save()  # will generate history object
138
139
        cls.case_2 = TestCaseFactory(
140
            author=cls.tester,
141
            default_tester=None,
142
            reviewer=cls.tester,
143
            case_status=cls.case_status_confirmed,
144
            plan=[cls.plan])
145
        cls.case_2.save()  # will generate history object
146
147
        cls.case_3 = TestCaseFactory(
148
            author=cls.tester,
149
            default_tester=None,
150
            reviewer=cls.tester,
151
            case_status=cls.case_status_confirmed,
152
            plan=[cls.plan])
153
        cls.case_3.save()  # will generate history object
154
155
        cls.case_4 = TestCaseFactory(
156
            author=cls.tester,
157
            default_tester=None,
158
            reviewer=cls.tester,
159
            case_status=cls.case_status_confirmed,
160
            plan=[cls.plan])
161
        cls.case_4.save()  # will generate history object
162
163
        cls.case_5 = TestCaseFactory(
164
            author=cls.tester,
165
            default_tester=None,
166
            reviewer=cls.tester,
167
            case_status=cls.case_status_confirmed,
168
            plan=[cls.plan])
169
        cls.case_5.save()  # will generate history object
170
171
        cls.case_6 = TestCaseFactory(
172
            author=cls.tester,
173
            default_tester=None,
174
            reviewer=cls.tester,
175
            case_status=cls.case_status_confirmed,
176
            plan=[cls.plan])
177
        cls.case_6.save()  # will generate history object
178
179
180
class BaseCaseRun(BasePlanCase):
181
    """Base test case containing test run and case runs"""
182
183
    @classmethod
184
    def setUpTestData(cls):
185
        super(BaseCaseRun, cls).setUpTestData()
186
187
        # todo: we need a linter to find all places where we get statuses
188
        # by hard-coded names instead of class based attribute constants!
189
        cls.status_idle = TestExecutionStatus.objects.get(name='IDLE')
190
191
        cls.build = BuildFactory(product=cls.product)
192
193
        cls.test_run = TestRunFactory(product_version=cls.version,
194
                                      plan=cls.plan,
195
                                      build=cls.build,
196
                                      manager=cls.tester,
197
                                      default_tester=cls.tester)
198
199
        executions = []
200
        for i, case in enumerate((cls.case_1, cls.case_2, cls.case_3), 1):
201
            executions.append(TestExecutionFactory(assignee=cls.tester,
202
                                                   run=cls.test_run,
203
                                                   build=cls.build,
204
                                                   status=cls.status_idle,
205
                                                   case=case, sortkey=i * 10))
206
207
        # used in other tests as well
208
        cls.execution_1 = executions[0]
209
        cls.execution_2 = executions[1]
210
        cls.execution_3 = executions[2]
211
212
        cls.test_run_1 = TestRunFactory(product_version=cls.version,
213
                                        plan=cls.plan,
214
                                        build=cls.build,
215
                                        manager=cls.tester,
216
                                        default_tester=cls.tester)
217
218
        # create a few more TestExecution objects
219
        for i, case in enumerate((cls.case_4, cls.case_5, cls.case_6), 1):
220
            executions.append(TestExecutionFactory(assignee=cls.tester,
221
                                                   tested_by=cls.tester,
222
                                                   run=cls.test_run_1,
223
                                                   build=cls.build,
224
                                                   status=cls.status_idle,
225
                                                   case=case, sortkey=i * 10))
226
        # used in other tests as well
227
        cls.execution_4 = executions[3]
228
        cls.execution_5 = executions[4]
229
        cls.execution_6 = executions[5]
230