Completed
Push — master ( ba462b...d97c8b )
by Paolo
27s queued 13s
created

biosample.tests.test_create.Basetest.setUp()   A

Complexity

Conditions 1

Size

Total Lines 15
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 10
dl 0
loc 15
rs 9.9
c 0
b 0
f 0
cc 1
nop 1
1
#!/usr/bin/env python3
2
# -*- coding: utf-8 -*-
3
"""
4
Created on Tue Jul 10 14:55:11 2018
5
6
@author: Paolo Cozzi <[email protected]>
7
"""
8
9
from unittest.mock import patch
10
11
from django.contrib.auth import get_user_model
12
from django.contrib.messages import get_messages
13
from django.core import mail
14
from django.test import Client, TestCase
15
from django.urls import resolve, reverse
16
17
from image_app.models import Organization
18
from pyUSIrest.auth import Auth
19
20
from ..forms import CreateUserForm
21
from ..views import CreateUserView
22
from .test_token import generate_token
23
24
25
class Basetest(TestCase):
26
    def setUp(self):
27
        User = get_user_model()
28
29
        # create a testuser
30
        User.objects.create_user(
31
            username='test',
32
            password='test',
33
            email="[email protected]")
34
35
        self.client = Client()
36
        self.client.login(username='test', password='test')
37
38
        # get the url for dashboard
39
        self.url = reverse('biosample:create')
40
        self.response = self.client.get(self.url)
41
42 View Code Duplication
    def check_messages(self, response, tag, message_text):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
43
        """Check that a response has warnings"""
44
45
        # each element is an instance
46
        # of django.contrib.messages.storage.base.Message
47
        all_messages = [msg for msg in get_messages(response.wsgi_request)]
48
49
        found = False
50
51
        # I can have moltiple message, and maybe I need to find a specific one
52
        for message in all_messages:
53
            if tag in message.tags and message_text in message.message:
54
                found = True
55
56
        self.assertTrue(found)
57
58
59
class CreateUserViewTest(Basetest):
60
    def test_redirection(self):
61
        '''Non Authenticated user are directed to login page'''
62
63
        login_url = reverse("login")
64
        client = Client()
65
        response = client.get(self.url)
66
67
        self.assertRedirects(
68
            response, '{login_url}?next={url}'.format(
69
                login_url=login_url, url=self.url)
70
        )
71
72
    def test_status_code(self):
73
        self.assertEqual(self.response.status_code, 200)
74
75
    def test_url_resolves_view(self):
76
        view = resolve('/biosample/create/')
77
        self.assertIsInstance(view.func.view_class(), CreateUserView)
78
79
    def test_csrf(self):
80
        self.assertContains(self.response, 'csrfmiddlewaretoken')
81
82
    def test_contains_form(self):
83
        form = self.response.context.get('form')
84
85
        self.assertIsInstance(form, CreateUserForm)
86
87
    def test_form_inputs(self):
88
        '''
89
        The view must contain eleven inputs: csrf, username, first_name,
90
        last_name, email, password1, password2, affiliation, role,
91
        organization and agree_gdpr checkbox
92
        '''
93
94
        # total input is n of form fields + (CSRF)
95
        self.assertContains(self.response, '<input', 3)
96
        self.assertContains(self.response, 'type="password"', 2)
97
98
99
class SuccessfulCreateUserViewTest(Basetest):
100
    fixtures = [
101
        "image_app/dictcountry.json",
102
        "image_app/dictrole.json",
103
        "image_app/organization.json"
104
    ]
105
106
    def setUp(self):
107
        User = get_user_model()
108
109
        # create a testuser
110
        user = User.objects.create_user(
111
            username='test',
112
            password='test',
113
            email="[email protected]")
114
115
        # add organization (affiliation) to user
116
        affiliation = Organization.objects.first()
117
        user.person.affiliation = affiliation
118
119
        # add other infor to user
120
        user.first_name = "Foo"
121
        user.last_name = "Bar"
122
123
        # saving updated object
124
        user.save()
125
126
        # those will be POST parameters
127
        self.data = {
128
            'password1': 'image-password',
129
            'password2': 'image-password',
130
        }
131
132
        # this is django.test.Client
133
        self.client = Client()
134
        self.client.login(username='test', password='test')
135
136
        # get the url for dashboard
137
        self.url = reverse('biosample:create')
138
        self.response = self.client.get(self.url)
139
140
        # patching object
141
        self.create_user_patcher = patch('pyUSIrest.client.User.create_user')
142
        self.create_user = self.create_user_patcher.start()
143
        self.create_user.return_value = (
144
            "usr-2a28ca65-2c2f-41e7-9aa5-e829830c6c71")
145
146
        def mocked_auth():
147
            token = generate_token(
148
                domains=['subs.test-team-1', 'subs.test-team-3'])
149
            return Auth(token=token)
150
151
        self.get_auth_patcher = patch('biosample.views.get_manager_auth')
152
        self.get_auth = self.get_auth_patcher.start()
153
        self.get_auth.return_value = mocked_auth()
154
155
        self.create_team_patcher = patch('pyUSIrest.client.User.create_team')
156
        self.create_team = self.create_team_patcher.start()
157
        self.create_team.return_value.name = "subs.test-team-3"
158
159
        self.get_domain_patcher = patch(
160
            'pyUSIrest.client.User.get_domain_by_name')
161
        self.get_domain = self.get_domain_patcher.start()
162
        self.get_domain.return_value.domainReference = (
163
                "dom-41fd3271-d14b-47ff-8de1-e3f0a6d0a693")
164
165
        self.add_user_patcher = patch('pyUSIrest.client.User.add_user_to_team')
166
        self.add_user = self.add_user_patcher.start()
167
168
    def tearDown(self):
169
        self.create_user_patcher.stop()
170
        self.get_auth_patcher.stop()
171
        self.create_team_patcher.stop()
172
        self.get_domain_patcher.stop()
173
        self.add_user_patcher.stop()
174
175
        super().tearDown()
176
177
    def test_deal_with_errors(self):
178
        """Testing deal with errors method"""
179
180
        # change create user reply
181
        self.create_user.side_effect = ConnectionError("test")
182
183
        response = self.client.post(self.url, self.data)
184
        self.assertEqual(response.status_code, 200)
185
186
        # assert mail sent
187
        self.assertGreater(len(mail.outbox), 0)
188
189
        self.assertTrue(self.create_user.called)
190
        self.assertFalse(self.get_auth.called)
191
        self.assertFalse(self.create_team.called)
192
        self.assertFalse(self.get_domain.called)
193
        self.assertFalse(self.add_user.called)
194
195
    def test_user_create(self):
196
        """Testing create user"""
197
198
        # posting user and password to generate a new user
199
        response = self.client.post(self.url, self.data)
200
        dashboard_url = reverse('image_app:dashboard')
201
202
        self.assertRedirects(response, dashboard_url)
203
        self.check_messages(response, "success", "Account created")
204
205
        self.assertTrue(self.create_user.called)
206
        self.assertTrue(self.get_auth.called)
207
        self.assertTrue(self.create_team.called)
208
        self.assertTrue(self.get_domain.called)
209
        self.assertTrue(self.add_user.called)
210
211
    def check_message(self, message):
212
        """assert a non ridirect and a message"""
213
214
        response = self.client.post(self.url, self.data)
215
        self.assertEqual(response.status_code, 200)
216
        self.check_messages(response, "error", message)
217
218
    def test_error_with_create_user(self):
219
        """Testing create user with biosample errors"""
220
221
        # setting mock objects
222
        self.create_user.side_effect = ConnectionError("test")
223
224
        message = "Problem in creating user"
225
        self.check_message(message)
226
227
        self.assertTrue(self.create_user.called)
228
        self.assertFalse(self.get_auth.called)
229
        self.assertFalse(self.create_team.called)
230
        self.assertFalse(self.get_domain.called)
231
        self.assertFalse(self.add_user.called)
232
233
    def mock_create_team_error(self):
234
        """Raise a custom exception when creating team"""
235
236
        msg = (
237
            '{"timestamp":1569592802046,"status":500,"error":"Internal Server '
238
            'Error","exception":"org.springframework.web.client.ResourceAccess'
239
            'Exception","message":"I/O error on POST request for \"https://'
240
            'explore.api.aai.ebi.ac.uk/domains/\": No content to map due '
241
            'to end-of-input\n at [Source: ; line: 1, column: 0]; nested '
242
            'exception is com.fasterxml.jackson.databind.JsonMappingException:'
243
            ' No content to map due to end-of-input\n at [Source: ; line: 1, '
244
            'column: 0]","path":"/api/user/teams"}')
245
246
        return ConnectionError(msg)
247
248
    def test_error_with_create_team(self):
249
        """Testing create user"""
250
251
        # setting mock objects
252
        self.create_team.side_effect = self.mock_create_team_error()
253
254
        message = "Problem in creating team"
255
        self.check_message(message)
256
257
        self.assertTrue(self.create_user.called)
258
        self.assertTrue(self.get_auth.called)
259
        self.assertTrue(self.create_team.called)
260
        self.assertFalse(self.get_domain.called)
261
        self.assertFalse(self.add_user.called)
262
263
    def test_error_with_add_user_to_team(self):
264
        """Testing a generic error during user creation step"""
265
266
        # setting mock objects
267
        self.add_user.side_effect = ConnectionError("test")
268
269
        message = "Problem in adding user"
270
        self.check_message(message)
271
272
        self.assertTrue(self.create_user.called)
273
        self.assertTrue(self.get_auth.called)
274
        self.assertTrue(self.create_team.called)
275
        self.assertTrue(self.get_domain.called)
276
        self.assertTrue(self.add_user.called)
277
278
    def test_generic_error(self):
279
        """Testing a generic error during user creation step"""
280
281
        # setting mock objects
282
        self.get_auth.side_effect = ConnectionError("test")
283
284
        message = "Problem with EBI-AAP endoints. Please contact IMAGE team"
285
        self.check_message(message)
286
287
        # the first manager auth called is in create user
288
        self.assertTrue(self.create_user.called)
289
        self.assertTrue(self.get_auth.called)
290
        self.assertFalse(self.create_team.called)
291
        self.assertFalse(self.get_domain.called)
292
        self.assertFalse(self.add_user.called)
293
294
295
class InvalidCreateUserViewTests(Basetest):
296
    def setUp(self):
297
        # create a test user
298
        super().setUp()
299
300
        # submit an empty dictionary
301
        self.response = self.client.post(self.url, {})
302
303
    def test_signup_status_code(self):
304
        '''
305
        An invalid form submission should return to the same page
306
        '''
307
        self.assertEqual(self.response.status_code, 200)
308
309
    def test_form_errors(self):
310
        form = self.response.context.get('form')
311
        self.assertGreater(len(form.errors), 0)
312