Completed
Push — master ( 8a2447...e2760f )
by Paolo
06:42
created

SuccessfulCreateSubmissionViewTest.test_same_submission()   A

Complexity

Conditions 1

Size

Total Lines 21
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 11
dl 0
loc 21
rs 9.85
c 0
b 0
f 0
cc 1
nop 2
1
#!/usr/bin/env python3
2
# -*- coding: utf-8 -*-
3
"""
4
Created on Tue Jul 24 16:58:41 2018
5
6
@author: Paolo Cozzi <[email protected]>
7
"""
8
9
import os
10
from unittest.mock import patch
11
12
from django.test import Client, TestCase
13
from django.urls import resolve, reverse
14
15
from common.constants import (
16
    CRYOWEB_TYPE, CRB_ANIM_TYPE, TEMPLATE_TYPE, WAITING)
17
from uid.models import DictCountry, Organization, Submission
18
from common.tests import FormMixinTestCase, InvalidFormMixinTestCase
19
20
from .common import SubmissionFormMixin
21
from ..forms import SubmissionForm
22
from ..views import CreateSubmissionView
23
24
25
class Initialize(SubmissionFormMixin, TestCase):
26
    """Does the common stuff when testing cases are run"""
27
28
    fixtures = [
29
        "uid/user",
30
        "uid/dictrole",
31
        "uid/dictcountry",
32
        "uid/organization",
33
    ]
34
35
    def setUp(self):
36
        # login as a test user (defined in fixture)
37
        self.client = Client()
38
        self.client.login(username='test', password='test')
39
40
        self.url = reverse('submissions:create')
41
        self.response = self.client.get(self.url)
42
43
    def tearDown(self):
44
        if hasattr(self, "submission"):
45
            # delete uploaded file if exists
46
            fullpath = self.submission.uploaded_file.path
47
48
            if os.path.exists(fullpath):
49
                os.remove(fullpath)
50
51
        # call super method
52
        super().tearDown()
53
54
    def get_data(self, ds_file=CRYOWEB_TYPE):
55
        """Get data dictionary"""
56
57
        ds_type, ds_path = super().get_data(ds_file)
58
59
        # get required objects object
60
        self.country = DictCountry.objects.get(pk=1)
61
        self.organization = Organization.objects.get(pk=1)
62
63
        # define test data
64
        data = {
65
            'title': "Submission",
66
            'description': "Test Submission",
67
            'gene_bank_name': 'test',
68
            'gene_bank_country': self.country.id,
69
            'organization': self.organization.id,
70
            'datasource_type': ds_type,
71
            'datasource_version': '0.1',
72
            'uploaded_file': open(ds_path, "rb"),
73
        }
74
75
        return data
76
77
78
class CreateSubmissionViewTest(FormMixinTestCase, Initialize):
79
    form_class = SubmissionForm
80
81
    def test_url_resolves_view(self):
82
        view = resolve('/submissions/create/')
83
        self.assertIsInstance(view.func.view_class(), CreateSubmissionView)
84
85
    def test_form_inputs(self):
86
87
        # total input is n of form fields + (CSRF) + file
88
        self.assertContains(self.response, '<input', 6)
89
        self.assertContains(self.response, 'type="text"', 4)
90
        self.assertContains(self.response, 'type="file"', 1)
91
        self.assertContains(self.response, '<select', 3)
92
93
94
class SuccessfulCreateSubmissionViewTest(Initialize):
95
    # patch to simulate data load
96
    @patch('submissions.views.ImportCryowebTask.delay')
97
    def setUp(self, my_task):
98
        # create a test user
99
        super().setUp()
100
101
        # submit a cryoweb like dictionary
102
        self.response = self.client.post(
103
            self.url,
104
            self.get_data(ds_file=CRYOWEB_TYPE),
105
            follow=True)
106
107
        # get the submission object
108
        self.submission = self.response.context['submission']
109
110
        # track mocked object
111
        self.my_task = my_task
112
113
    def tearDown(self):
114
        """Override Initialize.tearDown to erase all submission objects"""
115
116
        # delete uploaded file if exists
117
        for submission in Submission.objects.all():
118
            fullpath = submission.uploaded_file.path
119
120
            if os.path.exists(fullpath):
121
                os.remove(fullpath)
122
123
        # call super method
124
        super().tearDown()
125
126
    def test_new_submission_obj(self):
127
        self.submission.refresh_from_db()
128
        self.assertEqual(Submission.objects.count(), 1)
129
        self.assertEqual(self.submission.status, WAITING)
130
131
    def test_redirect(self):
132
        url = reverse('submissions:detail', kwargs={'pk': self.submission.pk})
133
        self.assertRedirects(self.response, url)
134
135
    def test_task_called(self):
136
        self.assertTrue(self.my_task.called)
137
        self.my_task.assert_called_with(self.submission.pk)
138
139
    @patch('submissions.views.ImportCryowebTask.delay')
140
    def test_different_user(self, my_task):
141
        """Create a new submission with the same data for a different user"""
142
143
        # login as a different user
144
        client = Client()
145
        client.login(username='test2', password='test2')
146
147
        response = client.post(
148
            self.url,
149
            self.get_data(),
150
            follow=True)
151
152
        # get this new submission object
153
        self.assertEqual(Submission.objects.count(), 2)
154
        submission = Submission.objects.filter(owner__username="test2").first()
155
156
        # assert redirects
157
        url = reverse('submissions:detail', kwargs={'pk': submission.pk})
158
        self.assertRedirects(response, url)
159
160
        # test called task
161
        self.assertTrue(my_task.called)
162
163
    @patch('submissions.views.ImportCryowebTask.delay')
164
    def test_same_submission(self, my_task):
165
        """Create a new submission with the same data for same user"""
166
167
        response = self.client.post(
168
            self.url,
169
            self.get_data(),
170
            follow=True)
171
172
        # no objects created
173
        self.assertEqual(Submission.objects.count(), 1)
174
175
        # assert status code (no redirect)
176
        self.assertEqual(response.status_code, 200)
177
178
        # check errors
179
        form = response.context.get('form')
180
        self.assertGreater(len(form.errors), 0)
181
182
        # test called task
183
        self.assertFalse(my_task.called)
184
185
186
class InvalidCreateSubmissionViewTest(InvalidFormMixinTestCase, Initialize):
187
188
    def setUp(self):
189
        # create a test user
190
        super().setUp()
191
192
        # submit an empty dictionary
193
        self.response = self.client.post(self.url, {})
194
195
    def test_no_new_obj(self):
196
        self.assertFalse(Submission.objects.exists())
197
198
199
class SupportedCreateSubmissionViewTest(Initialize):
200
    # a generic function for data loading
201
    def file_loading(self, my_task, ds_type):
202
        # submit a cryoweb like dictionary
203
        response = self.client.post(
204
            self.url,
205
            self.get_data(ds_file=ds_type),
206
            follow=True)
207
208
        # get the submission object
209
        self.assertEqual(Submission.objects.count(), 1)
210
        self.submission = Submission.objects.first()
211
212
        # test redirect
213
        url = reverse('submissions:detail', kwargs={'pk': self.submission.pk})
214
        self.assertRedirects(response, url)
215
216
        # test status
217
        self.assertEqual(self.submission.status, WAITING)
218
219
        # test message
220
        message = "waiting for data loading"
221
        self.assertEqual(self.submission.message, message)
222
223
        # test task
224
        self.assertTrue(my_task.called)
225
226
    # patch to simulate data load
227
    @patch('submissions.views.ImportCRBAnimTask.delay')
228
    def test_crb_anim_loading(self, my_task):
229
        # submit a crbanim like dictionary
230
        self.file_loading(my_task, CRB_ANIM_TYPE)
231
232
    @patch('submissions.views.ImportTemplateTask.delay')
233
    def test_template_loading(self, my_task):
234
        # submit a template file
235
        # submit a cryoweb like dictionary
236
        self.file_loading(my_task, TEMPLATE_TYPE)
237
238
239
class IssuesWithFilesTest(Initialize):
240
    """A class to test errors in file during uploads"""
241
242
    def common_check(self, response, my_task):
243
        # check errors
244
        form = response.context.get('form')
245
        self.assertGreater(len(form.errors), 0)
246
247
        # no submissions
248
        self.assertFalse(Submission.objects.exists())
249
250
        # test task
251
        self.assertFalse(my_task.called)
252
253
    @patch('submissions.views.ImportCRBAnimTask.delay')
254
    def test_crb_anim_wrong_encoding(self, my_task):
255
        # submit a crbanim with wrong encoding
256
        response = self.client.post(
257
            self.url,
258
            self.get_data(ds_file="latin_type"))
259
260
        # check errors
261
        self.common_check(response, my_task)
262
263
    @patch('submissions.views.ImportCRBAnimTask.delay')
264
    def test_crb_anim_wrong_columns(self, my_task):
265
        # submit a crbanim with wrong column
266
        response = self.client.post(
267
            self.url,
268
            self.get_data(ds_file="not_valid_crbanim"))
269
270
        # check errors
271
        self.common_check(response, my_task)
272
273
    @patch('xlrd.book.Book.sheet_names', return_value=['animal', 'sample'])
274
    @patch('submissions.views.ImportTemplateTask.delay')
275
    def test_template_issues_in_sheets(self, my_task, my_excel):
276
        # submit a template file
277
        response = self.client.post(
278
            self.url,
279
            self.get_data(ds_file=TEMPLATE_TYPE))
280
281
        # check errors
282
        self.common_check(response, my_task)
283
284
        self.assertTrue(my_excel.called)
285
286 View Code Duplication
    @patch.dict(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
287
            "excel.helpers.exceltemplate.TEMPLATE_COLUMNS",
288
            {'breed': ["a column"]})
289
    @patch('submissions.views.ImportTemplateTask.delay')
290
    def test_template_issues_in_columns(self, my_task):
291
        # submit a template file
292
        response = self.client.post(
293
            self.url,
294
            self.get_data(ds_file=TEMPLATE_TYPE))
295
296
        # check errors
297
        self.common_check(response, my_task)
298
299
    @patch('submissions.views.ImportCRBAnimTask.delay')
300
    @patch('submissions.views.ImportTemplateTask.delay')
301
    def test_template_issues_in_file(self, my_task, my_crbanim):
302
        # get data for CRB_ANIM
303
        data = self.get_data(ds_file=CRB_ANIM_TYPE)
304
305
        # override datasource type
306
        data['datasource_type'] = TEMPLATE_TYPE
307
308
        # submit a template file with a CRBanim
309
        response = self.client.post(
310
            self.url,
311
            data)
312
313
        # check errors and assert my_task not called
314
        self.common_check(response, my_task)
315
316
        # assert not calling also CRBanim
317
        self.assertFalse(my_crbanim.called)
318