Passed
Pull Request — master (#40)
by Paolo
01:44
created

submissions.tests.test_view_new_submission   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 249
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 22
eloc 136
dl 0
loc 249
rs 10
c 0
b 0
f 0

18 Methods

Rating   Name   Duplication   Size   Complexity  
A SuccessfulCreateSubmissionViewTest.test_task_called() 0 3 1
A CreateSubmissionViewTest.test_form_inputs() 0 7 1
A Initialize.get_data() 0 22 1
A SuccessfulCreateSubmissionViewTest.test_redirect() 0 3 1
A Initialize.tearDown() 0 10 3
A SuccessfulCreateSubmissionViewTest.setUp() 0 16 1
A CreateSubmissionViewTest.test_url_resolves_view() 0 3 1
A SuccessfulCreateSubmissionViewTest.test_new_submission_obj() 0 4 1
A SuccessfulCreateSubmissionViewTest.test_different_user() 0 23 1
A Initialize.setUp() 0 7 1
A SuccessfulCreateSubmissionViewTest.tearDown() 0 12 3
A InvalidCreateSubmissionViewTest.test_no_new_obj() 0 2 1
A InvalidCreateSubmissionViewTest.setUp() 0 6 1
A SupportedCreateSubmissionViewTest.test_crb_anim_wrong_columns() 0 16 1
A SupportedCreateSubmissionViewTest.test_template_loading() 0 5 1
A SupportedCreateSubmissionViewTest.test_crb_anim_loading() 0 4 1
A SupportedCreateSubmissionViewTest.file_loading() 0 24 1
A SupportedCreateSubmissionViewTest.test_crb_anim_wrong_encoding() 0 16 1
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
    @patch('submissions.views.ImportCRBAnimTask.delay')
217
    def test_crb_anim_wrong_encoding(self, my_task):
218
        # submit a cryoweb like dictionary
219
        response = self.client.post(
220
            self.url,
221
            self.get_data(ds_file="latin_type"))
222
223
        # check errors
224
        form = response.context.get('form')
225
        self.assertGreater(len(form.errors), 0)
226
227
        # no submissions
228
        self.assertFalse(Submission.objects.exists())
229
230
        # test task
231
        self.assertFalse(my_task.called)
232
233
    @patch('submissions.views.ImportCRBAnimTask.delay')
234
    def test_crb_anim_wrong_columns(self, my_task):
235
        # submit a cryoweb like dictionary
236
        response = self.client.post(
237
            self.url,
238
            self.get_data(ds_file="not_valid_crbanim"))
239
240
        # check errors
241
        form = response.context.get('form')
242
        self.assertGreater(len(form.errors), 0)
243
244
        # no submissions
245
        self.assertFalse(Submission.objects.exists())
246
247
        # test task
248
        self.assertFalse(my_task.called)
249