Commit 389089b58816cabb22097b9526fff628dd4753e1
Exists in
master
Merge branch 'master' of git.ucsd.edu:110swag/flashy-backend
Showing 6 changed files Side-by-side Diff
flashcards/.api.py.swo
View file @
389089b
flashcards/models.py
View file @
389089b
flashcards/tests/test_api.py
View file @
389089b
1 | 1 | from django.core import mail |
2 | 2 | from flashcards.models import User |
3 | -from rest_framework.status import HTTP_201_CREATED, HTTP_200_OK, HTTP_401_UNAUTHORIZED | |
3 | +from rest_framework.status import HTTP_204_NO_CONTENT, HTTP_201_CREATED, HTTP_200_OK, HTTP_401_UNAUTHORIZED | |
4 | 4 | from rest_framework.test import APITestCase |
5 | 5 | from re import search |
6 | 6 | |
7 | 7 | |
8 | 8 | |
9 | 9 | |
10 | 10 | |
11 | 11 | |
12 | 12 | |
13 | 13 | |
14 | 14 | |
... | ... | @@ -41,32 +41,48 @@ |
41 | 41 | self.assertContains(response, 'Account is disabled', status_code=403) |
42 | 42 | |
43 | 43 | def test_logout(self): |
44 | - self.client.login(email='none@none.com', password='1234') | |
45 | - self.client.post('/api/logout') | |
44 | + url = '/api/login' | |
45 | + data = {'email': 'test@flashy.cards', 'password': '1234'} | |
46 | + response = self.client.post(url, data, format='json') | |
47 | + self.assertEqual(response.status_code, HTTP_200_OK) | |
46 | 48 | |
49 | + p = self.client.post('/api/logout') | |
50 | + self.assertEqual(p.status_code, HTTP_204_NO_CONTENT) | |
47 | 51 | response = self.client.get('/api/users/me', format='json') |
52 | + | |
48 | 53 | # since we're not logged in, we shouldn't be able to see this |
49 | 54 | self.assertEqual(response.status_code, HTTP_401_UNAUTHORIZED) |
50 | 55 | |
51 | 56 | class PasswordResetTest(APITestCase): |
52 | 57 | def setUp(self): |
58 | + # create a user to test things with | |
53 | 59 | email = "test@flashy.cards" |
54 | 60 | User.objects.create_user(email=email, password="12345") |
55 | 61 | |
56 | 62 | def test_reset_password(self): |
63 | + # submit the request to reset the password | |
57 | 64 | url = '/api/reset_password' |
58 | 65 | post_data = {'email': 'test@flashy.cards'} |
59 | - patch_data = {'new_password': '54321', | |
60 | - 'uid': '', 'token': ''} | |
61 | 66 | self.client.post(url, post_data, format='json') |
62 | 67 | self.assertEqual(len(mail.outbox), 1) |
63 | 68 | self.assertIn('reset your password', mail.outbox[0].body) |
64 | 69 | |
70 | + # capture the reset token from the email | |
65 | 71 | capture = search('https://flashy.cards/app/reset_password/(\d+)/(.*)', |
66 | 72 | mail.outbox[0].body) |
73 | + patch_data = {'new_password': '54321'} | |
67 | 74 | patch_data['uid'] = capture.group(1) |
68 | - patch_data['token'] = capture.group(2) | |
69 | - self.client.patch(url, patch_data, format='json') | |
75 | + reset_token = capture.group(2) | |
76 | + | |
77 | + # try to reset the password with the wrong reset token | |
78 | + patch_data['token'] = 'wrong_token' | |
79 | + response = self.client.patch(url, patch_data, format='json') | |
80 | + self.assertContains(response, 'Could not verify reset token', status_code=400) | |
81 | + | |
82 | + # try to reset the password with the correct token | |
83 | + patch_data['token'] = reset_token | |
84 | + response = self.client.patch(url, patch_data, format='json') | |
85 | + self.assertEqual(response.status_code, HTTP_204_NO_CONTENT) | |
70 | 86 | user = User.objects.get(id=patch_data['uid']) |
71 | 87 | assert user.check_password(patch_data['new_password']) |
72 | 88 |
flashcards/views.py
View file @
389089b
... | ... | @@ -3,7 +3,7 @@ |
3 | 3 | from flashcards.serializers import SectionSerializer, UserUpdateSerializer, RegistrationSerializer, UserSerializer, \ |
4 | 4 | PasswordResetSerializer, PasswordResetRequestSerializer, EmailPasswordSerializer |
5 | 5 | from rest_framework.permissions import IsAuthenticated |
6 | -from rest_framework.viewsets import ReadOnlyModelViewSet | |
6 | +from rest_framework.viewsets import ReadOnlyModelViewSet, ModelViewSet | |
7 | 7 | from django.core.mail import send_mail |
8 | 8 | from django.contrib.auth import authenticate, login, logout |
9 | 9 | from django.contrib.auth.tokens import default_token_generator |
10 | 10 | |
11 | 11 | |
... | ... | @@ -12,13 +12,20 @@ |
12 | 12 | from rest_framework.response import Response |
13 | 13 | from rest_framework.exceptions import AuthenticationFailed, NotAuthenticated, ValidationError |
14 | 14 | from simple_email_confirmation import EmailAddress |
15 | +from rest_framework import filters | |
15 | 16 | |
16 | - | |
17 | 17 | class SectionViewSet(ReadOnlyModelViewSet): |
18 | 18 | queryset = Section.objects.all() |
19 | 19 | serializer_class = SectionSerializer |
20 | 20 | pagination_class = StandardResultsSetPagination |
21 | 21 | |
22 | +class UserSectionViewSet(ModelViewSet): | |
23 | + serializer_class = SectionSerializer | |
24 | + permission_classes = [IsAuthenticated] | |
25 | + def get_queryset(self): | |
26 | + return self.request.user.sections.all() | |
27 | + | |
28 | + def paginate_queryset(self, queryset): return None | |
22 | 29 | |
23 | 30 | class UserDetail(APIView): |
24 | 31 | def patch(self, request, format=None): |
flashy/settings.py
View file @
389089b
... | ... | @@ -10,7 +10,9 @@ |
10 | 10 | ALLOWED_HOSTS = ['127.0.0.1', 'flashy.cards'] |
11 | 11 | |
12 | 12 | AUTH_USER_MODEL = 'flashcards.User' |
13 | - | |
13 | +REST_FRAMEWORK = { | |
14 | + 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination' | |
15 | +} | |
14 | 16 | INSTALLED_APPS = ( |
15 | 17 | 'simple_email_confirmation', |
16 | 18 | 'flashcards', |
flashy/urls.py
View file @
389089b
1 | 1 | from django.conf.urls import include, url |
2 | 2 | from django.contrib import admin |
3 | -from flashcards.views import SectionViewSet, UserDetail, UserLogin, UserLogout, PasswordReset | |
3 | +from flashcards.views import SectionViewSet, UserDetail, UserLogin, UserLogout, PasswordReset, UserSectionViewSet | |
4 | 4 | from rest_framework.routers import DefaultRouter |
5 | 5 | from flashcards.api import * |
6 | 6 | |
7 | 7 | router = DefaultRouter() |
8 | 8 | router.register(r'sections', SectionViewSet) |
9 | 9 | |
10 | +router.register(r'users/me/sections', UserSectionViewSet, base_name = 'usersection') | |
11 | + | |
10 | 12 | urlpatterns = [ |
11 | 13 | url(r'^api/docs/', include('rest_framework_swagger.urls')), |
12 | 14 | url(r'^api/users/me$', UserDetail.as_view()), |
... | ... | @@ -16,7 +18,8 @@ |
16 | 18 | url(r'^api/', include(router.urls)), |
17 | 19 | url(r'^admin/doc/', include('django.contrib.admindocs.urls')), |
18 | 20 | url(r'^admin/', include(admin.site.urls)), |
19 | - url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')) | |
21 | + url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework' | |
22 | +)) | |
20 | 23 | ] |
21 | 24 | |
22 | 25 | urlpatterns += (url(r'^admin/django-ses/', include('django_ses.urls')),) |