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

IssuesWithFilesTest.common_check()   A

Complexity

Conditions 1

Size

Total Lines 10
Code Lines 5

Duplication

Lines 10
Ratio 100 %

Importance

Changes 0
Metric Value
eloc 5
dl 10
loc 10
rs 10
c 0
b 0
f 0
cc 1
nop 3
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 image_app.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
        "image_app/user",
30
        "image_app/dictrole",
31
        "image_app/dictcountry",
32
        "image_app/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('cryoweb.tasks.import_from_cryoweb.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('cryoweb.tasks.import_from_cryoweb.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
164
class InvalidCreateSubmissionViewTest(InvalidFormMixinTestCase, Initialize):
165
166
    def setUp(self):
167
        # create a test user
168
        super().setUp()
169
170
        # submit an empty dictionary
171
        self.response = self.client.post(self.url, {})
172
173
    def test_no_new_obj(self):
174
        self.assertFalse(Submission.objects.exists())
175
176
177
class SupportedCreateSubmissionViewTest(Initialize):
178
    # a generic function for data loading
179
    def file_loading(self, my_task, ds_type):
180
        # submit a cryoweb like dictionary
181
        response = self.client.post(
182
            self.url,
183
            self.get_data(ds_file=ds_type),
184
            follow=True)
185
186
        # get the submission object
187
        self.assertEqual(Submission.objects.count(), 1)
188
        self.submission = Submission.objects.first()
189
190
        # test redirect
191
        url = reverse('submissions:detail', kwargs={'pk': self.submission.pk})
192
        self.assertRedirects(response, url)
193
194
        # test status
195
        self.assertEqual(self.submission.status, WAITING)
196
197
        # test message
198
        message = "waiting for data loading"
199
        self.assertEqual(self.submission.message, message)
200
201
        # test task
202
        self.assertTrue(my_task.called)
203
204
    # patch to simulate data load
205
    @patch('submissions.views.ImportCRBAnimTask.delay')
206
    def test_crb_anim_loading(self, my_task):
207
        # submit a cryoweb like dictionary
208
        self.file_loading(my_task, CRB_ANIM_TYPE)
209
210
    @patch('submissions.views.ImportTemplateTask.delay')
211
    def test_template_loading(self, my_task):
212
        # submit a template file
213
        # submit a cryoweb like dictionary
214
        self.file_loading(my_task, TEMPLATE_TYPE)
215
216
217 View Code Duplication
class IssuesWithFilesTest(Initialize):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
218
    """A class to test errors in file during uploads"""
219
220
    def common_check(self, response, my_task):
221
        # check errors
222
        form = response.context.get('form')
223
        self.assertGreater(len(form.errors), 0)
224
225
        # no submissions
226
        self.assertFalse(Submission.objects.exists())
227
228
        # test task
229
        self.assertFalse(my_task.called)
230
231
    @patch('submissions.views.ImportCRBAnimTask.delay')
232
    def test_crb_anim_wrong_encoding(self, my_task):
233
        # submit a crbanim with wrong encoding
234
        response = self.client.post(
235
            self.url,
236
            self.get_data(ds_file="latin_type"))
237
238
        # check errors
239
        self.common_check(response, my_task)
240
241
    @patch('submissions.views.ImportCRBAnimTask.delay')
242
    def test_crb_anim_wrong_columns(self, my_task):
243
        # submit a crbanim with wrong column
244
        response = self.client.post(
245
            self.url,
246
            self.get_data(ds_file="not_valid_crbanim"))
247
248
        # check errors
249
        self.common_check(response, my_task)
250
251
    @patch('xlrd.book.Book.sheet_names', return_value=['animal', 'sample'])
252
    @patch('submissions.views.ImportTemplateTask.delay')
253
    def test_template_issues_in_sheets(self, my_task, my_excel):
254
        # submit a template file
255
        response = self.client.post(
256
            self.url,
257
            self.get_data(ds_file=TEMPLATE_TYPE))
258
259
        # check errors
260
        self.common_check(response, my_task)
261
262
        self.assertTrue(my_excel.called)
263
264
    @patch.dict(
265
            "excel.helpers.exceltemplate.TEMPLATE_COLUMNS",
266
            {'breed': ["a column"]})
267
    @patch('submissions.views.ImportTemplateTask.delay')
268
    def test_template_issues_in_columns(self, my_task):
269
        # submit a template file
270
        response = self.client.post(
271
            self.url,
272
            self.get_data(ds_file=TEMPLATE_TYPE))
273
274
        # check errors
275
        self.common_check(response, my_task)
276