|
1
|
1 |
|
import json |
|
2
|
|
|
|
|
3
|
1 |
|
from django.core import mail |
|
4
|
|
|
|
|
5
|
1 |
|
from rest_framework import status |
|
6
|
1 |
|
from rest_framework.test import APITestCase, force_authenticate |
|
7
|
|
|
|
|
8
|
1 |
|
from sigma_core.tests.factories import UserFactory, AdminUserFactory, GroupMemberFactory, GroupFactory |
|
9
|
1 |
|
from sigma_core.serializers.user import DetailedUserSerializer as UserSerializer |
|
10
|
|
|
from sigma_core.models.group import Group |
|
11
|
|
|
from sigma_core.models.group_member import GroupMember |
|
12
|
1 |
|
|
|
13
|
1 |
|
class UserTests(APITestCase): |
|
14
|
|
|
@classmethod |
|
15
|
1 |
|
def setUpTestData(self): |
|
16
|
|
|
super(UserTests, self).setUpTestData() |
|
17
|
1 |
|
|
|
18
|
1 |
|
self.user = UserFactory() |
|
19
|
1 |
|
self.user2 = UserFactory() |
|
20
|
|
|
self.user3 = UserFactory() |
|
21
|
1 |
|
self.group23 = GroupFactory() |
|
22
|
1 |
|
GroupMemberFactory(group=self.group23, user=self.user2, perm_rank=0) |
|
23
|
1 |
|
GroupMemberFactory(group=self.group23, user=self.user3, perm_rank=1) |
|
24
|
|
|
self.group23_bis = GroupFactory() |
|
25
|
1 |
|
GroupMemberFactory(group=self.group23_bis, user=self.user2, perm_rank=1) |
|
26
|
|
|
GroupMemberFactory(group=self.group23_bis, user=self.user3, perm_rank=1) |
|
27
|
1 |
|
self.admin_user = AdminUserFactory() |
|
28
|
|
|
|
|
29
|
|
|
serializer = UserSerializer(self.user) |
|
30
|
1 |
|
self.user_data = serializer.data |
|
31
|
|
|
self.user_url = '/user/%d/' % self.user.id |
|
32
|
1 |
|
|
|
33
|
1 |
|
self.users_list = [self.user, self.user2, self.admin_user] |
|
34
|
|
|
self.users_list_for_user3 = [self.user2, self.user3] |
|
35
|
|
|
|
|
36
|
|
|
self.new_user_data = {'lastname': 'Doe', 'firstname': 'John', 'email': '[email protected]', 'password': 'password'} |
|
37
|
|
|
|
|
38
|
|
|
#### List requests |
|
39
|
|
|
def test_get_users_list_unauthed(self): |
|
40
|
|
|
# Client not authenticated |
|
41
|
1 |
|
response = self.client.get('/user/') |
|
42
|
|
|
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) |
|
43
|
1 |
|
|
|
44
|
1 |
|
# def test_get_users_list_forbidden(self): |
|
45
|
1 |
|
# # Client authenticated but has no permission |
|
46
|
1 |
|
# self.client.force_authenticate(user=self.user) |
|
47
|
|
|
# response = self.client.get('/user/') |
|
48
|
|
|
# self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) |
|
49
|
1 |
|
|
|
50
|
|
|
def test_get_users_list_ok(self): |
|
51
|
1 |
|
# Client has permissions |
|
52
|
1 |
|
self.client.force_authenticate(user=self.user3) |
|
53
|
|
|
response = self.client.get('/user/') |
|
54
|
|
|
self.assertEqual(response.status_code, status.HTTP_200_OK) |
|
55
|
|
|
self.assertEqual(len(response.data), len(self.users_list_for_user3)) |
|
56
|
|
|
|
|
57
|
|
|
#### Get requests |
|
58
|
|
|
def test_get_user_unauthed(self): |
|
59
|
|
|
# Client is not authenticated |
|
60
|
1 |
|
response = self.client.get(self.user_url) |
|
61
|
|
|
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) |
|
62
|
1 |
|
|
|
63
|
1 |
|
def test_get_user_forbidden_no_common_group(self): |
|
64
|
1 |
|
# Client authenticated but has no group in common |
|
65
|
1 |
|
self.client.force_authenticate(user=self.user) |
|
66
|
1 |
|
response = self.client.get("/user/%d/" % self.user3.id) |
|
67
|
|
|
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) |
|
68
|
|
|
|
|
69
|
1 |
|
def test_get_user_forbidden_common_group_not_accepted(self): |
|
70
|
|
|
# Client authenticated, group in common, but not accepted in this Group |
|
71
|
1 |
|
user4 = UserFactory() |
|
72
|
1 |
|
GroupMemberFactory(group=self.group23, user=user4, perm_rank=0) |
|
73
|
|
|
self.client.force_authenticate(user=user4) |
|
74
|
1 |
|
response = self.client.get("/user/%d/" % self.user2.id) |
|
75
|
|
|
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) |
|
76
|
1 |
|
|
|
77
|
1 |
|
def test_get_user_ok_same_group(self): |
|
78
|
1 |
|
self.client.force_authenticate(user=self.user3) |
|
79
|
1 |
|
response = self.client.get("/user/%d/" % self.user2.id) |
|
80
|
|
|
self.assertEqual(response.status_code, status.HTTP_200_OK) |
|
81
|
|
|
|
|
82
|
1 |
|
def test_get_user_ok(self): |
|
83
|
|
|
# Client has permissions |
|
84
|
1 |
|
self.client.force_authenticate(user=self.user) |
|
85
|
1 |
|
response = self.client.get(self.user_url) |
|
86
|
|
|
self.assertEqual(response.status_code, status.HTTP_200_OK) |
|
87
|
1 |
|
response.data.pop('permissions', None) # Workaround because DRY rest permissions needs a request |
|
88
|
|
|
self.assertEqual(response.data, self.user_data) |
|
89
|
1 |
|
|
|
90
|
1 |
|
def test_get_user_memberships_all_visible(self): |
|
91
|
1 |
|
# User3 is in both groups |
|
92
|
|
|
self.client.force_authenticate(user=self.user3) |
|
93
|
1 |
|
response = self.client.get('/user/%d/' % self.user2.id) |
|
94
|
|
|
self.assertEqual(response.status_code, status.HTTP_200_OK) |
|
95
|
1 |
|
self.assertEqual(len(response.data['memberships']), 2) |
|
96
|
1 |
|
|
|
97
|
1 |
|
def test_get_user_memberships_only_one_visible(self): |
|
98
|
1 |
|
# User2 is in both groups, but not accepted in the first group |
|
99
|
|
|
self.client.force_authenticate(user=self.user2) |
|
100
|
|
|
response = self.client.get('/user/%d/' % self.user3.id) |
|
101
|
1 |
|
self.assertEqual(response.status_code, status.HTTP_200_OK) |
|
102
|
|
|
self.assertEqual(len(response.data['memberships']), 1) |
|
103
|
1 |
|
|
|
104
|
1 |
|
#### "Get my data" requests |
|
105
|
1 |
|
def test_get_my_data_unauthed(self): |
|
106
|
1 |
|
# Client is not authenticated |
|
107
|
1 |
|
response = self.client.get('/user/me/') |
|
108
|
|
|
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) |
|
109
|
1 |
|
|
|
110
|
|
|
def test_get_my_data_ok(self): |
|
111
|
1 |
|
# Client is authenticated |
|
112
|
1 |
|
self.client.force_authenticate(user=self.user) |
|
113
|
1 |
|
response = self.client.get('/user/me/') |
|
114
|
1 |
|
self.assertEqual(response.status_code, status.HTTP_200_OK) |
|
115
|
1 |
|
self.assertEqual(response.data['id'], self.user.id) |
|
116
|
|
|
|
|
117
|
1 |
|
#### Create requests |
|
118
|
|
|
def test_create_user_unauthed(self): |
|
119
|
1 |
|
# Client is not authenticated |
|
120
|
1 |
|
response = self.client.post('/user/', self.new_user_data) |
|
121
|
1 |
|
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) |
|
122
|
1 |
|
|
|
123
|
1 |
|
def test_create_user_forbidden(self): |
|
124
|
1 |
|
# Client has no permission |
|
125
|
|
|
self.client.force_authenticate(user=self.user) |
|
126
|
1 |
|
response = self.client.post('/user/', self.new_user_data) |
|
127
|
1 |
|
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) |
|
128
|
|
|
|
|
129
|
1 |
|
def test_create_user_ok(self): |
|
130
|
|
|
# Client has permissions |
|
131
|
1 |
|
self.client.force_authenticate(user=self.admin_user) |
|
132
|
1 |
|
response = self.client.post('/user/', self.new_user_data) |
|
133
|
1 |
|
self.assertEqual(response.status_code, status.HTTP_201_CREATED) |
|
134
|
1 |
|
self.assertEqual(response.data['lastname'], self.new_user_data['lastname']) |
|
135
|
1 |
|
|
|
136
|
|
|
#### Modification requests |
|
137
|
1 |
|
def test_edit_email_wrong_permission(self): |
|
138
|
|
|
# Client wants to change another user's email |
|
139
|
1 |
|
self.client.force_authenticate(user=self.user) |
|
140
|
1 |
|
user_data = UserSerializer(self.user2).data |
|
141
|
1 |
|
user_data['email'] = "[email protected]" |
|
142
|
1 |
|
response = self.client.put("/user/%d/" % self.user2.id, user_data) |
|
143
|
1 |
|
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) |
|
144
|
1 |
|
|
|
145
|
|
|
def test_edit_is_superuser_no_permission(self): |
|
146
|
1 |
|
# Client can't set himself as administrator ! |
|
147
|
1 |
|
self.client.force_authenticate(user=self.user) |
|
148
|
|
|
user_data = UserSerializer(self.user).data |
|
149
|
1 |
|
user_data['is_superuser'] = True |
|
150
|
|
|
response = self.client.put("/user/%d/" % self.user.id, user_data) |
|
151
|
1 |
|
self.assertFalse(self.user.is_superuser); |
|
152
|
1 |
|
|
|
153
|
1 |
|
def test_edit_email_nonvalid_email(self): |
|
154
|
1 |
|
# Client wants to change his email with a non valid value |
|
155
|
1 |
|
self.client.force_authenticate(user=self.user) |
|
156
|
|
|
user_data = self.user_data.copy() |
|
157
|
1 |
|
user_data['email'] = "ThisIsNotAnEmail" |
|
158
|
|
|
response = self.client.put("/user/%d/" % self.user.id, user_data) |
|
159
|
1 |
|
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) |
|
160
|
1 |
|
|
|
161
|
1 |
|
def test_edit_email_ok(self): |
|
|
|
|
|
|
162
|
1 |
|
# Client wants to change his email and succeed in |
|
163
|
1 |
|
self.client.force_authenticate(user=self.user) |
|
164
|
1 |
|
user_data = self.user_data.copy() |
|
165
|
|
|
user_data['email'] = "[email protected]" |
|
166
|
1 |
|
response = self.client.put("/user/%d/" % self.user.id, user_data) |
|
167
|
1 |
|
self.assertEqual(response.status_code, status.HTTP_200_OK) |
|
168
|
|
|
self.assertEqual(response.data['email'], user_data['email']) |
|
169
|
|
|
# Guarantee that tests are independant |
|
170
|
|
|
self.user.email = self.user_data['email'] |
|
171
|
1 |
|
self.user.save() |
|
172
|
|
|
|
|
173
|
1 |
|
def test_edit_profile_wrong_permission(self): |
|
174
|
1 |
|
# Client wants to change another user's phone number |
|
175
|
1 |
|
self.client.force_authenticate(user=self.user) |
|
176
|
1 |
|
user_data = UserSerializer(self.user2).data |
|
177
|
|
|
user_data['phone'] = "0123456789" |
|
178
|
1 |
|
response = self.client.put("/user/%d/" % self.user2.id, user_data) |
|
179
|
|
|
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) |
|
180
|
1 |
|
|
|
181
|
1 |
|
def test_edit_profile_ok(self): |
|
|
|
|
|
|
182
|
1 |
|
# Client wants to change his phone number |
|
183
|
1 |
|
self.client.force_authenticate(user=self.user) |
|
184
|
|
|
user_data = self.user_data.copy() |
|
185
|
1 |
|
user_data['phone'] = "0123456789" |
|
186
|
|
|
response = self.client.put("/user/%d/" % self.user.id, user_data) |
|
187
|
1 |
|
self.assertEqual(response.status_code, status.HTTP_200_OK) |
|
188
|
1 |
|
self.assertEqual(response.data['phone'], user_data['phone']) |
|
189
|
1 |
|
# Guarantee that tests are independant |
|
190
|
1 |
|
self.user.phone = self.user_data['phone'] |
|
191
|
|
|
self.user.save() |
|
192
|
|
|
|
|
193
|
1 |
|
def test_edit_lastname_wrong_permission(self): |
|
194
|
|
|
# Client wants to change his lastname |
|
195
|
1 |
|
self.client.force_authenticate(user=self.user) |
|
196
|
1 |
|
user_data = self.user_data.copy() |
|
197
|
|
|
user_data['lastname'] = "Daudet" |
|
198
|
1 |
|
response = self.client.put("/user/%d/" % self.user.id, user_data) |
|
199
|
|
|
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) |
|
200
|
1 |
|
|
|
201
|
1 |
|
def test_edit_lastname_ok(self): |
|
|
|
|
|
|
202
|
|
|
# Admin wants to change an user's lastname |
|
203
|
1 |
|
self.client.force_authenticate(user=self.admin_user) |
|
204
|
|
|
user_data = self.user_data.copy() |
|
205
|
1 |
|
user_data['lastname'] = "Daudet" |
|
206
|
1 |
|
response = self.client.put("/user/%d/" % self.user.id, user_data) |
|
207
|
1 |
|
self.assertEqual(response.status_code, status.HTTP_200_OK) |
|
208
|
1 |
|
self.assertEqual(response.data['lastname'], user_data['lastname']) |
|
209
|
1 |
|
# Guarantee that tests are independant |
|
210
|
|
|
self.user.lastname = self.user_data['lastname'] |
|
211
|
|
|
self.user.save() |
|
212
|
|
|
|
|
213
|
|
|
|
|
214
|
|
|
#### "Change password" requests |
|
215
|
|
|
def test_change_pwd_wrong_pwd(self): |
|
216
|
|
|
# Client gives a wrong old password |
|
217
|
|
|
self.user.set_password('old_pwd') |
|
218
|
|
|
self.client.force_authenticate(user=self.user) |
|
219
|
|
|
response = self.client.put('/user/change_password/', {'old_password': 'wrong', 'password': 'new_pwd'}) |
|
220
|
|
|
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) |
|
221
|
|
|
|
|
222
|
|
|
def test_change_pwd_no_pwd(self): |
|
223
|
|
|
# Client gives no new password |
|
224
|
|
|
self.user.set_password('old_pwd') |
|
225
|
|
|
self.client.force_authenticate(user=self.user) |
|
226
|
|
|
response = self.client.put('/user/change_password/', {'old_password': 'old_pwd', 'password': ''}) |
|
227
|
|
|
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) |
|
228
|
|
|
|
|
229
|
|
|
def test_change_pwd_ok(self): |
|
230
|
|
|
# Client successfully changes his password |
|
231
|
|
|
self.user.set_password('old_pwd') |
|
232
|
|
|
self.client.force_authenticate(user=self.user) |
|
233
|
|
|
response = self.client.put('/user/change_password/', {'old_password': 'old_pwd', 'password': 'new_strong_pwd'}) |
|
234
|
|
|
self.assertEqual(response.status_code, status.HTTP_200_OK) |
|
235
|
|
|
|
|
236
|
|
|
#### "Reset password" requests |
|
237
|
|
|
def test_reset_pwd_no_email(self): |
|
238
|
|
|
# Client gives no email |
|
239
|
|
|
response = self.client.post('/user/reset_password/', {'email': ''}) |
|
240
|
|
|
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) |
|
241
|
|
|
|
|
242
|
|
|
def test_reset_pwd_no_user(self): |
|
243
|
|
|
# Client's email is not found |
|
244
|
|
|
response = self.client.post('/user/reset_password/', {'email': '[email protected]'}) |
|
245
|
|
|
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) |
|
246
|
|
|
|
|
247
|
|
|
def test_reset_pwd_ok(self): |
|
248
|
|
|
# Client successfully resets his password |
|
249
|
|
|
response = self.client.post('/user/reset_password/', {'email': self.user.email}) |
|
250
|
|
|
self.assertEqual(response.status_code, status.HTTP_200_OK) |
|
251
|
|
|
self.assertEqual(len(mail.outbox), 1) |
|
252
|
|
|
from sigma_core.views.user import reset_mail |
|
253
|
|
|
self.assertEqual(mail.outbox[0].subject, reset_mail['subject']) |
|
254
|
|
|
|
|
255
|
|
|
#### "Add photo" requests |
|
256
|
|
|
def test_addphoto_ok(self): |
|
257
|
|
|
self.client.force_authenticate(user=self.user) |
|
258
|
|
|
with open("sigma_files/test_img.png", "rb") as img: |
|
259
|
|
|
response = self.client.post(self.user_url + "addphoto/", {'file': img}, format='multipart') |
|
260
|
|
|
self.assertEqual(response.status_code, status.HTTP_201_CREATED) |
|
261
|
|
|
|
|
262
|
|
|
#### Deletion requests |
|
263
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.