Completed
Pull Request — master (#47)
by Paolo
11:49 queued 10:21
created

submissions.tests.test_view_reload_submission   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 271
Duplicated Lines 19.93 %

Importance

Changes 0
Metric Value
wmc 23
eloc 155
dl 54
loc 271
rs 10
c 0
b 0
f 0

21 Methods

Rating   Name   Duplication   Size   Complexity  
A TestBase.tearDown() 0 13 3
A ReloadSubmissionViewTest.test_contains_navigation_links() 0 5 1
A SuccessfulReloadMixin.test_redirect() 0 3 1
A ReloadSubmissionViewTest.setUp() 0 5 1
A InvalidReloadSubmissionViewTest.setUp() 0 7 1
A TestBase.get_data() 0 14 1
A SuccessfulReloadSubmissionViewTest.setUp() 0 16 1
A TestBase.setUp() 0 9 1
A SuccessfulReloadMixin.test_task_called() 0 2 1
A ReloadSubmissionViewTest.test_form_inputs() 0 8 1
A InvalidReloadSubmissionViewTest.test_task_called() 0 2 1
A SuccessfulReloadMixin.test_submission_status() 0 6 1
A ReloadSubmissionViewTest.test_url_resolves_view() 0 3 1
A ReloadSubmissionViewTest.test_reload_not_found_status_code() 0 4 1
A ReloadValidationTest.common_check() 7 7 1
A ReloadValidationTest.test_crb_anim_wrong_columns() 9 9 1
A ReloadValidationTest.test_template_issues_in_sheets() 12 12 1
A TemplateReloadSubmissionViewTest.setUp() 0 20 1
A ReloadValidationTest.test_crb_anim_wrong_encoding() 9 9 1
A ReloadValidationTest.test_template_issues_in_columns() 12 12 1
A CRBAnimReloadSubmissionViewTest.setUp() 0 20 1

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
#!/usr/bin/env python3
2
# -*- coding: utf-8 -*-
3
"""
4
Created on Thu Nov  8 16:35:48 2018
5
6
@author: Paolo Cozzi <[email protected]>
7
"""
8
9
import os
10
11
from unittest.mock import patch
12
13
from django.test import TestCase, Client
14
from django.urls import resolve, reverse
15
16
from common.tests import (
17
    FormMixinTestCase, OwnerMixinTestCase, InvalidFormMixinTestCase,
18
    StatusMixinTestCase)
19
from common.constants import (
20
    CRB_ANIM_TYPE, CRYOWEB_TYPE, TEMPLATE_TYPE, WAITING)
21
from image_app.models import Submission
22
from image_app.tests import DataSourceMixinTestCase
23
24
from .common import SubmissionFormMixin
25
from ..views import ReloadSubmissionView
26
from ..forms import ReloadForm
27
28
29
class TestBase(SubmissionFormMixin, DataSourceMixinTestCase, TestCase):
30
    fixtures = [
31
        "image_app/user",
32
        "image_app/dictcountry",
33
        "image_app/dictrole",
34
        "image_app/organization",
35
        "image_app/submission"
36
    ]
37
38
    def setUp(self):
39
        # call base method
40
        super().setUp()
41
42
        # login a test user (defined in fixture)
43
        self.client = Client()
44
        self.client.login(username='test', password='test')
45
46
        self.url = reverse('submissions:reload', kwargs={'pk': 1})
47
48
    def tearDown(self):
49
        if hasattr(self, "submission"):
50
            # read written file
51
            self.submission.refresh_from_db()
52
53
            # delete uploaded file if exists
54
            fullpath = self.submission.uploaded_file.path
55
56
            if os.path.exists(fullpath):
57
                os.remove(fullpath)
58
59
        # call super method
60
        super().tearDown()
61
62
    def get_data(self, ds_file=CRYOWEB_TYPE):
63
        """Get data dictionary"""
64
65
        ds_type, ds_path = super().get_data(ds_file)
66
67
        # define test data
68
        data = {
69
            'uploaded_file': open(ds_path, "rb"),
70
            'datasource_type': ds_type,
71
            'datasource_version': "reload",
72
            'agree_reload': True
73
        }
74
75
        return data
76
77
78
class ReloadSubmissionViewTest(
79
        FormMixinTestCase, OwnerMixinTestCase, TestBase):
80
81
    form_class = ReloadForm
82
83
    def setUp(self):
84
        # call base method
85
        super().setUp()
86
87
        self.response = self.client.get(self.url)
88
89
    def test_url_resolves_view(self):
90
        view = resolve('/submissions/1/reload/')
91
        self.assertIsInstance(view.func.view_class(), ReloadSubmissionView)
92
93
    def test_form_inputs(self):
94
95
        # total input is n of form fields + (CSRF) + 1 file + 1 checkbox
96
        # +1 select + text
97
        self.assertContains(self.response, '<input', 4)
98
        self.assertContains(self.response, '<select', 1)
99
        self.assertContains(self.response, 'type="file"', 1)
100
        self.assertContains(self.response, 'type="checkbox"', 1)
101
102
    def test_reload_not_found_status_code(self):
103
        url = reverse('submissions:reload', kwargs={'pk': 99})
104
        response = self.client.get(url)
105
        self.assertEqual(response.status_code, 404)
106
107
    def test_contains_navigation_links(self):
108
        """Contain links to DetailSubmissionView"""
109
110
        link = reverse('submissions:detail', kwargs={'pk': 1})
111
        self.assertContains(self.response, 'href="{0}"'.format(link))
112
113
114
class SuccessfulReloadMixin(StatusMixinTestCase):
115
    def test_redirect(self):
116
        url = reverse('submissions:detail', kwargs={'pk': 1})
117
        self.assertRedirects(self.response, url)
118
119
    def test_task_called(self):
120
        self.assertTrue(self.my_task.called)
121
122
    def test_submission_status(self):
123
        self.submission.refresh_from_db()
124
        self.assertEqual(self.submission.status, WAITING)
125
        self.assertEqual(
126
            self.submission.message,
127
            "waiting for data loading")
128
129
130
class SuccessfulReloadSubmissionViewTest(
131
        SuccessfulReloadMixin, OwnerMixinTestCase, TestBase):
132
    # patch to simulate data load
133
    @patch('cryoweb.tasks.import_from_cryoweb.delay')
134
    def setUp(self, my_task):
135
        # call base method
136
        super().setUp()
137
138
        # this post request create a new data_source file
139
        self.response = self.client.post(
140
            self.url,
141
            self.get_data(),
142
            follow=True)
143
144
        # setting task
145
        self.my_task = my_task
146
147
        # get submission, with the new data_source file
148
        self.submission = Submission.objects.get(pk=1)
149
150
151
class InvalidReloadSubmissionViewTest(
152
        InvalidFormMixinTestCase, OwnerMixinTestCase, TestBase):
153
154
    # patch to simulate data load
155
    @patch('cryoweb.tasks.import_from_cryoweb.delay')
156
    def setUp(self, my_task):
157
        # call base method
158
        super().setUp()
159
160
        self.response = self.client.post(self.url, {})
161
        self.my_task = my_task
162
163
    def test_task_called(self):
164
        self.assertFalse(self.my_task.called)
165
166
167 View Code Duplication
class ReloadValidationTest(TestBase):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
168
    def common_check(self, response, my_task):
169
        # check errors
170
        form = response.context.get('form')
171
        self.assertGreater(len(form.errors), 0)
172
173
        # test task
174
        self.assertFalse(my_task.called)
175
176
    @patch('submissions.views.ImportCRBAnimTask.delay')
177
    def test_crb_anim_wrong_encoding(self, my_task):
178
        # submit a cryoweb like dictionary
179
        response = self.client.post(
180
            self.url,
181
            self.get_data(ds_file="latin_type"))
182
183
        # check errors
184
        self.common_check(response, my_task)
185
186
    @patch('submissions.views.ImportCRBAnimTask.delay')
187
    def test_crb_anim_wrong_columns(self, my_task):
188
        # submit a cryoweb like dictionary
189
        response = self.client.post(
190
            self.url,
191
            self.get_data(ds_file="not_valid_crbanim"))
192
193
        # check errors
194
        self.common_check(response, my_task)
195
196
    @patch('xlrd.book.Book.sheet_names', return_value=['animal', 'sample'])
197
    @patch('submissions.views.ImportTemplateTask.delay')
198
    def test_template_issues_in_sheets(self, my_task, my_excel):
199
        # submit a template file
200
        response = self.client.post(
201
            self.url,
202
            self.get_data(ds_file=TEMPLATE_TYPE))
203
204
        # check errors
205
        self.common_check(response, my_task)
206
207
        self.assertTrue(my_excel.called)
208
209
    @patch.dict(
210
            "excel.helpers.exceltemplate.TEMPLATE_COLUMNS",
211
            {'breed': ["a column"]})
212
    @patch('submissions.views.ImportTemplateTask.delay')
213
    def test_template_issues_in_columns(self, my_task):
214
        # submit a template file
215
        response = self.client.post(
216
            self.url,
217
            self.get_data(ds_file=TEMPLATE_TYPE))
218
219
        # check errors
220
        self.common_check(response, my_task)
221
222
223
class CRBAnimReloadSubmissionViewTest(
224
        SuccessfulReloadMixin, TestBase):
225
226
    @patch('submissions.views.ImportCRBAnimTask.delay')
227
    def setUp(self, my_task):
228
        # call base method
229
        super().setUp()
230
231
        # get a submission object
232
        self.submission = Submission.objects.get(pk=1)
233
234
        # change template type
235
        self.submission.datasource_type = CRB_ANIM_TYPE
236
        self.submission.save()
237
238
        # this post request create a new data_source file
239
        self.response = self.client.post(
240
            self.url,
241
            self.get_data(ds_file=CRB_ANIM_TYPE),
242
            follow=True)
243
244
        # track task
245
        self.my_task = my_task
246
247
248
class TemplateReloadSubmissionViewTest(
249
        SuccessfulReloadMixin, TestBase):
250
251
    @patch('submissions.views.ImportTemplateTask.delay')
252
    def setUp(self, my_task):
253
        # call base method
254
        super().setUp()
255
256
        # get a submission object
257
        self.submission = Submission.objects.get(pk=1)
258
259
        # change template type
260
        self.submission.datasource_type = TEMPLATE_TYPE
261
        self.submission.save()
262
263
        # this post request create a new data_source file
264
        self.response = self.client.post(
265
            self.url,
266
            self.get_data(ds_file=TEMPLATE_TYPE),
267
            follow=True)
268
269
        # track task
270
        self.my_task = my_task
271