Blame view

flashcards/tests/test_api.py 14.2 KB
4af65c21d   Andrew Buss   Expanded tests so...
1
  from django.core import mail
fca017a2b   Rachel Lee   Tests and code fo...
2
  from flashcards.models import *
54bba1fea   Andrew Buss   enforce enrollmen...
3
  from rest_framework.status import HTTP_204_NO_CONTENT, HTTP_201_CREATED, HTTP_200_OK, HTTP_403_FORBIDDEN
ce17f969f   Andrew Buss   Restructured api,...
4
  from rest_framework.test import APITestCase
b705da3be   Rohan Rangray   Added a password ...
5
  from re import search
2a9edd990   Chung Wang   Flashcard detail ...
6
  from django.utils.timezone import now
a3637e4b2   Andrew Buss   Added some tests ...
7
8
9
  
  
  class LoginTests(APITestCase):
72bf5f00c   Andrew Buss   Falcon puuuuuuuus...
10
      fixtures = ['testusers']
a3637e4b2   Andrew Buss   Added some tests ...
11
12
13
  
      def test_login(self):
          url = '/api/login'
72bf5f00c   Andrew Buss   Falcon puuuuuuuus...
14
          data = {'email': 'none@none.com', 'password': '1234'}
a3637e4b2   Andrew Buss   Added some tests ...
15
16
          response = self.client.post(url, data, format='json')
          self.assertEqual(response.status_code, HTTP_200_OK)
72bf5f00c   Andrew Buss   Falcon puuuuuuuus...
17
          data = {'email': 'none@none.com', 'password': '4321'}
60cf35d28   Andrew Buss   fixed up login tests
18
          response = self.client.post(url, data, format='json')
ce17f969f   Andrew Buss   Restructured api,...
19
          self.assertContains(response, 'Invalid email or password', status_code=403)
60cf35d28   Andrew Buss   fixed up login tests
20

72bf5f00c   Andrew Buss   Falcon puuuuuuuus...
21
          data = {'email': 'bad@none.com', 'password': '1234'}
60cf35d28   Andrew Buss   fixed up login tests
22
          response = self.client.post(url, data, format='json')
ce17f969f   Andrew Buss   Restructured api,...
23
          self.assertContains(response, 'Invalid email or password', status_code=403)
60cf35d28   Andrew Buss   fixed up login tests
24

72bf5f00c   Andrew Buss   Falcon puuuuuuuus...
25
          data = {'password': '4321'}
60cf35d28   Andrew Buss   fixed up login tests
26
          response = self.client.post(url, data, format='json')
ce17f969f   Andrew Buss   Restructured api,...
27
          self.assertContains(response, 'email', status_code=400)
60cf35d28   Andrew Buss   fixed up login tests
28

72bf5f00c   Andrew Buss   Falcon puuuuuuuus...
29
          data = {'email': 'none@none.com'}
4af65c21d   Andrew Buss   Expanded tests so...
30
31
          response = self.client.post(url, data, format='json')
          self.assertContains(response, 'password', status_code=400)
72bf5f00c   Andrew Buss   Falcon puuuuuuuus...
32
          user = User.objects.get(email="none@none.com")
129a6d7b1   Andrew Buss   boosting test cov...
33
34
          user.is_active = False
          user.save()
72bf5f00c   Andrew Buss   Falcon puuuuuuuus...
35
          data = {'email': 'none@none.com', 'password': '1234'}
129a6d7b1   Andrew Buss   boosting test cov...
36
37
38
39
          response = self.client.post(url, data, format='json')
          self.assertContains(response, 'Account is disabled', status_code=403)
  
      def test_logout(self):
72bf5f00c   Andrew Buss   Falcon puuuuuuuus...
40
41
          self.client.login(email='none@none.com', password='1234')
          response = self.client.post('/api/logout')
b9d4dd7cc   Rohan Rangray   Removed test cove...
42
          self.assertEqual(response.status_code, HTTP_204_NO_CONTENT)
dbaa4eb52   Rohan Rangray   Finished writing ...
43

72bf5f00c   Andrew Buss   Falcon puuuuuuuus...
44
45
46
          # since we're not logged in, we should get a 403 response
          response = self.client.get('/api/me', format='json')
          self.assertEqual(response.status_code, HTTP_403_FORBIDDEN)
129a6d7b1   Andrew Buss   boosting test cov...
47

cc832f03e   Andrew Buss   Added dev site fo...
48

b705da3be   Rohan Rangray   Added a password ...
49
  class PasswordResetTest(APITestCase):
72bf5f00c   Andrew Buss   Falcon puuuuuuuus...
50
      fixtures = ['testusers']
b705da3be   Rohan Rangray   Added a password ...
51

ecf3c7d46   Andrew Buss   rename tests so t...
52
      def test_reset_password(self):
dbaa4eb52   Rohan Rangray   Finished writing ...
53
          # submit the request to reset the password
72bf5f00c   Andrew Buss   Falcon puuuuuuuus...
54
55
          url = '/api/request_password_reset'
          post_data = {'email': 'none@none.com'}
cc832f03e   Andrew Buss   Added dev site fo...
56
          self.client.post(url, post_data, format='json')
b705da3be   Rohan Rangray   Added a password ...
57
58
          self.assertEqual(len(mail.outbox), 1)
          self.assertIn('reset your password', mail.outbox[0].body)
dbaa4eb52   Rohan Rangray   Finished writing ...
59
          # capture the reset token from the email
346dc6546   Andrew Buss   fixed reset passw...
60
          capture = search('https://flashy.cards/app/resetpassword/(\d+)/(.*)',
cc832f03e   Andrew Buss   Added dev site fo...
61
                           mail.outbox[0].body)
72bf5f00c   Andrew Buss   Falcon puuuuuuuus...
62
          patch_data = {'new_password': '4321'}
38c977bc0   Rohan Rangray   Fixed typo in tes...
63
          patch_data['uid'] = capture.group(1)
dbaa4eb52   Rohan Rangray   Finished writing ...
64
65
66
67
          reset_token = capture.group(2)
  
          # try to reset the password with the wrong reset token
          patch_data['token'] = 'wrong_token'
72bf5f00c   Andrew Buss   Falcon puuuuuuuus...
68
69
          url = '/api/reset_password'
          response = self.client.post(url, patch_data, format='json')
dbaa4eb52   Rohan Rangray   Finished writing ...
70
71
72
73
          self.assertContains(response, 'Could not verify reset token', status_code=400)
  
          # try to reset the password with the correct token
          patch_data['token'] = reset_token
72bf5f00c   Andrew Buss   Falcon puuuuuuuus...
74
          response = self.client.post(url, patch_data, format='json')
dbaa4eb52   Rohan Rangray   Finished writing ...
75
          self.assertEqual(response.status_code, HTTP_204_NO_CONTENT)
38c977bc0   Rohan Rangray   Fixed typo in tes...
76
77
          user = User.objects.get(id=patch_data['uid'])
          assert user.check_password(patch_data['new_password'])
b705da3be   Rohan Rangray   Added a password ...
78

a3637e4b2   Andrew Buss   Added some tests ...
79
80
81
  
  class RegistrationTest(APITestCase):
      def test_create_account(self):
72bf5f00c   Andrew Buss   Falcon puuuuuuuus...
82
          url = '/api/register'
7aa4b42d3   Andrew Buss   Fixed registratio...
83
84
85
86
87
88
89
90
91
92
93
94
  
          # missing password
          data = {'email': 'none@none.com'}
          response = self.client.post(url, data, format='json')
          self.assertContains(response, 'password', status_code=400)
  
          # missing email
          data = {'password': '1234'}
          response = self.client.post(url, data, format='json')
          self.assertContains(response, 'email', status_code=400)
  
          # create a user
a3637e4b2   Andrew Buss   Added some tests ...
95
96
97
          data = {'email': 'none@none.com', 'password': '1234'}
          response = self.client.post(url, data, format='json')
          self.assertEqual(response.status_code, HTTP_201_CREATED)
7aa4b42d3   Andrew Buss   Fixed registratio...
98
          # user should not be confirmed
4af65c21d   Andrew Buss   Expanded tests so...
99
          user = User.objects.get(email="none@none.com")
7aa4b42d3   Andrew Buss   Fixed registratio...
100
101
102
          self.assertFalse(user.is_confirmed)
  
          # check that the confirmation key was sent
4af65c21d   Andrew Buss   Expanded tests so...
103
104
          self.assertEqual(len(mail.outbox), 1)
          self.assertIn(user.confirmation_key, mail.outbox[0].body)
7aa4b42d3   Andrew Buss   Fixed registratio...
105
          # log the user out
1a3e459bf   Andrew Buss   Switched to local...
106
          self.client.logout()
7aa4b42d3   Andrew Buss   Fixed registratio...
107
108
  
          # log the user in with their registered credentials
1a3e459bf   Andrew Buss   Switched to local...
109
          self.client.login(email='none@none.com', password='1234')
a8906a991   Nam Tran   Added login check...
110

7aa4b42d3   Andrew Buss   Fixed registratio...
111
          # try activating with an invalid key
72bf5f00c   Andrew Buss   Falcon puuuuuuuus...
112
113
  
          url = '/api/me'
7aa4b42d3   Andrew Buss   Fixed registratio...
114
115
          response = self.client.patch(url, {'confirmation_key': 'NOT A KEY'})
          self.assertContains(response, 'confirmation_key is invalid', status_code=400)
d8bcc626c   Nam Tran   More tests for cr...
116

7aa4b42d3   Andrew Buss   Fixed registratio...
117
118
119
          # try activating with the valid key
          response = self.client.patch(url, {'confirmation_key': user.confirmation_key})
          self.assertTrue(response.data['is_confirmed'])
ce17f969f   Andrew Buss   Restructured api,...
120

d8bcc626c   Nam Tran   More tests for cr...
121

a3637e4b2   Andrew Buss   Added some tests ...
122
  class ProfileViewTest(APITestCase):
72bf5f00c   Andrew Buss   Falcon puuuuuuuus...
123
      fixtures = ['testusers']
d38c8b394   Andrew Buss   Made lecture sect...
124

a3637e4b2   Andrew Buss   Added some tests ...
125
      def test_get_me(self):
72bf5f00c   Andrew Buss   Falcon puuuuuuuus...
126
          url = '/api/me'
a3637e4b2   Andrew Buss   Added some tests ...
127
          response = self.client.get(url, format='json')
ce17f969f   Andrew Buss   Restructured api,...
128
          # since we're not logged in, we shouldn't be able to see this
72bf5f00c   Andrew Buss   Falcon puuuuuuuus...
129
          self.assertEqual(response.status_code, 403)
d38c8b394   Andrew Buss   Made lecture sect...
130

72bf5f00c   Andrew Buss   Falcon puuuuuuuus...
131
          self.client.login(email='none@none.com', password='1234')
d38c8b394   Andrew Buss   Made lecture sect...
132
          response = self.client.get(url, format='json')
a3637e4b2   Andrew Buss   Added some tests ...
133
          self.assertEqual(response.status_code, HTTP_200_OK)
d38c8b394   Andrew Buss   Made lecture sect...
134

09446ce20   Andrew Buss   Change password t...
135
136
  
  class PasswordChangeTest(APITestCase):
72bf5f00c   Andrew Buss   Falcon puuuuuuuus...
137
      fixtures = ['testusers']
09446ce20   Andrew Buss   Change password t...
138
139
  
      def test_change_password(self):
72bf5f00c   Andrew Buss   Falcon puuuuuuuus...
140
          url = '/api/me'
09446ce20   Andrew Buss   Change password t...
141
142
          user = User.objects.get(email='none@none.com')
          self.assertTrue(user.check_password('1234'))
129a6d7b1   Andrew Buss   boosting test cov...
143
          response = self.client.patch(url, {'new_password': '4321', 'old_password': '1234'}, format='json')
72bf5f00c   Andrew Buss   Falcon puuuuuuuus...
144
          self.assertEqual(response.status_code, HTTP_403_FORBIDDEN)
09446ce20   Andrew Buss   Change password t...
145
146
147
148
149
150
151
152
153
154
155
156
157
  
          self.client.login(email='none@none.com', password='1234')
          response = self.client.patch(url, {'new_password': '4321'}, format='json')
          self.assertContains(response, 'old_password is required', status_code=400)
  
          response = self.client.patch(url, {'new_password': '4321', 'old_password': '4321'}, format='json')
          self.assertContains(response, 'old_password is incorrect', status_code=400)
  
          response = self.client.patch(url, {'new_password': '4321', 'old_password': '1234'}, format='json')
          self.assertEqual(response.status_code, 200)
          user = User.objects.get(email='none@none.com')
  
          self.assertFalse(user.check_password('1234'))
129a6d7b1   Andrew Buss   boosting test cov...
158
159
160
161
          self.assertTrue(user.check_password('4321'))
  
  
  class DeleteUserTest(APITestCase):
72bf5f00c   Andrew Buss   Falcon puuuuuuuus...
162
      fixtures = ['testusers']
129a6d7b1   Andrew Buss   boosting test cov...
163
164
  
      def test_delete_user(self):
72bf5f00c   Andrew Buss   Falcon puuuuuuuus...
165
          url = '/api/me'
129a6d7b1   Andrew Buss   boosting test cov...
166
167
168
169
          user = User.objects.get(email='none@none.com')
  
          self.client.login(email='none@none.com', password='1234')
          self.client.delete(url)
f5539effb   Rohan Rangray   Fixed a regex gro...
170
          self.assertFalse(User.objects.filter(email='none@none.com').exists())
129a6d7b1   Andrew Buss   boosting test cov...
171

a0e0db361   Andrew Buss   bad merge
172

2a9edd990   Chung Wang   Flashcard detail ...
173
  class FlashcardDetailTest(APITestCase):
ec4e278d0   Andrew Buss   Added tests for s...
174
      fixtures = ['testusers', 'testsections']
72bf5f00c   Andrew Buss   Falcon puuuuuuuus...
175

2a9edd990   Chung Wang   Flashcard detail ...
176
      def setUp(self):
ec4e278d0   Andrew Buss   Added tests for s...
177
178
          section = Section.objects.get(pk=1)
          user = User.objects.get(email='none@none.com')
54bba1fea   Andrew Buss   enforce enrollmen...
179
180
181
182
          section.enroll(user)
          self.inaccessible_flashcard = Flashcard(text="you can't see me!", section=Section.objects.get(pk=2),
                                                  material_date=now(), author=user)
          self.inaccessible_flashcard.save()
a0e0db361   Andrew Buss   bad merge
183
          self.flashcard = Flashcard(text="jason", section=section, material_date=now(), author=user)
2a9edd990   Chung Wang   Flashcard detail ...
184
          self.flashcard.save()
61c43267c   Rohan Rangray   Fixed accidental ...
185
186
187
188
189
190
191
192
193
194
195
196
      def test_edit_flashcard(self):
          self.client.login(email='none@none.com', password='1234')
          user = User.objects.get(email='none@none.com')
          user.sections.add(Section.objects.get(pk=1))
          user.save()
  
      def test_create_flashcard(self):
          self.client.login(email='none@none.com', password='1234')
          user = User.objects.get(email='none@none.com')
          user.sections.add(Section.objects.get(pk=1))
          user.save()
          data = {'text': 'this is a flashcard',
1cc32d8b0   Andrew Buss   fixed test_create...
197
                  'material_date': now(),
61c43267c   Rohan Rangray   Fixed accidental ...
198
199
200
201
202
203
204
                  'mask': '[]',
                  'section': '1',
                  'previous': None}
          response = self.client.post("/api/flashcards/", data, format="json")
          self.assertEqual(response.status_code, HTTP_201_CREATED)
          self.assertEqual(response.data['text'], data['text'])
          self.assertTrue(Flashcard.objects.filter(section__pk=1, text=data['text']).exists())
2a9edd990   Chung Wang   Flashcard detail ...
205
      def test_get_flashcard(self):
ec4e278d0   Andrew Buss   Added tests for s...
206
          self.client.login(email='none@none.com', password='1234')
72bf5f00c   Andrew Buss   Falcon puuuuuuuus...
207
          response = self.client.get("/api/flashcards/%d/" % self.flashcard.id, format="json")
2a9edd990   Chung Wang   Flashcard detail ...
208
209
          self.assertEqual(response.status_code, HTTP_200_OK)
          self.assertEqual(response.data["text"], "jason")
8488fecec   Andrew Buss   try harder
210

ec4e278d0   Andrew Buss   Added tests for s...
211
212
213
214
215
216
217
  
  class SectionViewSetTest(APITestCase):
      fixtures = ['testusers', 'testsections']
  
      def setUp(self):
          self.client.login(email='none@none.com', password='1234')
          self.user = User.objects.get(email='none@none.com')
54bba1fea   Andrew Buss   enforce enrollmen...
218
219
          self.flashcard = Flashcard(text="jason", section=Section.objects.get(pk=1), material_date=now(),
                                     author=self.user)
fca017a2b   Rachel Lee   Tests and code fo...
220
          self.flashcard.save()
fedcc8ded   Rohan Rangray   Wrote tests for F...
221
          self.section = Section.objects.get(pk=1)
ec4e278d0   Andrew Buss   Added tests for s...
222
223
224
225
226
227
  
      def test_list_sections(self):
          response = self.client.get("/api/sections/", format="json")
          self.assertEqual(response.status_code, HTTP_200_OK)
  
      def test_section_enroll(self):
fedcc8ded   Rohan Rangray   Wrote tests for F...
228
          section = self.section
ec4e278d0   Andrew Buss   Added tests for s...
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
          self.assertFalse(self.user.sections.filter(pk=section.pk))
  
          # test enrolling in a section without a whitelist
          response = self.client.post('/api/sections/%d/enroll/' % section.pk)
          self.assertEqual(response.status_code, HTTP_204_NO_CONTENT)
          self.assertTrue(self.user.sections.filter(pk=section.pk).exists())
  
          section = Section.objects.get(pk=2)
          WhitelistedAddress.objects.create(email='bad@none.com', section=section)
  
          # test enrolling in a section when not on the whitelist
          response = self.client.post('/api/sections/%d/enroll/' % section.pk)
          self.assertEqual(response.status_code, HTTP_403_FORBIDDEN)
          self.assertFalse(self.user.sections.filter(pk=section.pk).exists())
  
          WhitelistedAddress.objects.create(email=self.user.email, section=section)
  
          # test enrolling in a section when on the whitelist
          response = self.client.post('/api/sections/%d/enroll/' % section.pk)
          self.assertEqual(response.status_code, HTTP_204_NO_CONTENT)
          self.assertTrue(self.user.sections.filter(pk=section.pk).exists())
  
      def test_section_drop(self):
fedcc8ded   Rohan Rangray   Wrote tests for F...
252
          section = self.section
ec4e278d0   Andrew Buss   Added tests for s...
253
254
255
256
257
258
259
260
261
262
263
  
          # test dropping a section that the user isn't in
          response = self.client.post('/api/sections/%d/drop/' % section.pk)
          self.assertEqual(response.status_code, 400)
  
          self.user.sections.add(section)
          self.assertTrue(self.user.sections.filter(pk=section.pk).exists())
  
          # test dropping a section that the user is in
          response = self.client.post('/api/sections/%d/drop/' % section.pk)
          self.assertEqual(response.status_code, HTTP_204_NO_CONTENT)
c2b6dc852   Rachel Lee   Wrote test for se...
264
265
266
          self.assertFalse(self.user.sections.filter(pk=section.pk).exists())
  
      def test_section_flashcards(self):
fca017a2b   Rachel Lee   Tests and code fo...
267
268
269
270
271
272
273
          # test to get flashcards for section 1
          response = self.client.get('/api/sections/1/flashcards/')
          self.assertEqual(response.status_code, HTTP_200_OK)
  
          # test: Making FlashcardHide object, so no card should be seen.
          flashcard_hide = FlashcardHide(user=self.user, flashcard=self.flashcard)
          flashcard_hide.save()
c2b6dc852   Rachel Lee   Wrote test for se...
274
275
          response = self.client.get('/api/sections/1/flashcards/')
          self.assertEqual(response.status_code, HTTP_200_OK)
fca017a2b   Rachel Lee   Tests and code fo...
276
          self.assertEqual(response.content, '[]')
dc685f192   Andrew Buss   Section search wo...
277
278
279
280
  
      def test_section_search(self):
          response = self.client.get('/api/sections/search/?q=Kramer')
          self.assertEqual(response.status_code, HTTP_200_OK)
3709ee645   Laura Hawkins   working on deck view
281
282
  
      def test_section_deck(self):
fedcc8ded   Rohan Rangray   Wrote tests for F...
283
284
          self.user.sections.add(self.section)
          self.user.save()
5aca59e1e   Andrew Buss   maybe I should le...
285
          response = self.client.get('/api/sections/1/deck/')
3709ee645   Laura Hawkins   working on deck view
286
          self.assertEqual(response.status_code, HTTP_200_OK)
a2d8c4229   Andrew Buss   added feed
287
288
289
290
  
      def test_section_feed(self):
          response = self.client.get('/api/sections/1/feed/')
          self.assertEqual(response.status_code, HTTP_200_OK)
3188404a6   Andrew Buss   feed tests works(?)
291
          self.assertEqual(response.data[0]['id'], 1)
7dbe162dc   Andrew Buss   merge
292

2c52b3c5c   Chung Wang   ordered_deck unde...
293
      def test_section_ordered_deck(self):
ab186354f   Rohan Rangray   Fixed the test fo...
294
295
          self.user.sections.add(self.section)
          self.user.save()
2c52b3c5c   Chung Wang   ordered_deck unde...
296
          response = self.client.get('/api/sections/1/ordered_deck/')
7dbe162dc   Andrew Buss   merge
297
          self.assertEqual(response.status_code, HTTP_200_OK)
29c433096   Andrew Buss   updated readme to...
298

0eff34260   Chung Wang   test hide second ...
299
300
301
302
303
304
305
  
  class FlashcardViewSetTest(APITestCase):
      fixtures = ['testusers', 'testsections']
  
      def setUp(self):
          self.client.login(email='none@none.com', password='1234')
          self.user = User.objects.get(email='none@none.com')
54bba1fea   Andrew Buss   enforce enrollmen...
306
307
308
          self.section = Section.objects.get(pk=1)
          self.section.enroll(self.user)
          self.flashcard = Flashcard(text="jason", section=self.section, material_date=now(),
0eff34260   Chung Wang   test hide second ...
309
310
                                     author=self.user)
          self.flashcard.save()
54bba1fea   Andrew Buss   enforce enrollmen...
311
312
313
          self.inaccessible_flashcard = Flashcard(text="can't touch this", section=Section.objects.get(pk=2),
                                                  material_date=now(), author=self.user)
          self.inaccessible_flashcard.save()
0eff34260   Chung Wang   test hide second ...
314
315
316
  
      def test_hide_flashcard(self):
          url = '/api/flashcards/1/hide/'
54bba1fea   Andrew Buss   enforce enrollmen...
317
          response = self.client.post(url, format='json')
0eff34260   Chung Wang   test hide second ...
318
          self.assertEqual(response.status_code, HTTP_204_NO_CONTENT)
5d1399ce3   Chung Wang   test unhide flash...
319

54bba1fea   Andrew Buss   enforce enrollmen...
320
321
322
          response = self.client.post('/api/flashcards/%d/hide/' % self.inaccessible_flashcard.pk, format='json')
          # This should fail because the user is not enrolled in section id 2
          self.assertEqual(response.status_code, HTTP_403_FORBIDDEN)
5d1399ce3   Chung Wang   test unhide flash...
323
324
325
326
327
328
329
      def test_unhide_flashcard(self):
          url = '/api/flashcards/1/unhide/'
          flashcard_hide = FlashcardHide(user=self.user, flashcard=self.flashcard)
          flashcard_hide.save()
  
          response = self.client.post(url, format='json')
          self.assertEqual(response.status_code, HTTP_204_NO_CONTENT)
54bba1fea   Andrew Buss   enforce enrollmen...
330
331
332
333
          response = self.client.post('/api/flashcards/%d/unhide/' % self.inaccessible_flashcard.pk, format='json')
  
          # This should fail because the user is not enrolled in section id 2
          self.assertEqual(response.status_code, HTTP_403_FORBIDDEN)