Commit a55a90018e1925b55dc0ed69b94e80ef99baeca9

Authored by Andrew Buss
Exists in master

Merge branch 'master' of git.ucsd.edu:110swag/flashy-backend

Showing 3 changed files Inline Diff

flashcards/tests/test_api.py View file @ a55a900
from django.core import mail 1 1 from django.core import mail
from flashcards.models import User, Section, Flashcard 2 2 from flashcards.models import User, Section, Flashcard
from rest_framework.status import HTTP_204_NO_CONTENT, HTTP_201_CREATED, HTTP_200_OK, HTTP_401_UNAUTHORIZED 3 3 from rest_framework.status import HTTP_204_NO_CONTENT, HTTP_201_CREATED, HTTP_200_OK, HTTP_401_UNAUTHORIZED
from rest_framework.test import APITestCase 4 4 from rest_framework.test import APITestCase
from re import search 5 5 from re import search
from django.utils.timezone import now 6 6 from django.utils.timezone import now
7 7
8 8
class LoginTests(APITestCase): 9 9 class LoginTests(APITestCase):
def setUp(self): 10 10 def setUp(self):
email = "test@flashy.cards" 11 11 email = "test@flashy.cards"
User.objects.create_user(email=email, password="1234") 12 12 User.objects.create_user(email=email, password="1234")
13 13
def test_login(self): 14 14 def test_login(self):
url = '/api/login' 15 15 url = '/api/login'
data = {'email': 'test@flashy.cards', 'password': '1234'} 16 16 data = {'email': 'test@flashy.cards', 'password': '1234'}
response = self.client.post(url, data, format='json') 17 17 response = self.client.post(url, data, format='json')
self.assertEqual(response.status_code, HTTP_200_OK) 18 18 self.assertEqual(response.status_code, HTTP_200_OK)
19 19
data = {'email': 'test@flashy.cards', 'password': '54321'} 20 20 data = {'email': 'test@flashy.cards', 'password': '54321'}
response = self.client.post(url, data, format='json') 21 21 response = self.client.post(url, data, format='json')
self.assertContains(response, 'Invalid email or password', status_code=403) 22 22 self.assertContains(response, 'Invalid email or password', status_code=403)
23 23
data = {'email': 'none@flashy.cards', 'password': '54321'} 24 24 data = {'email': 'none@flashy.cards', 'password': '54321'}
response = self.client.post(url, data, format='json') 25 25 response = self.client.post(url, data, format='json')
self.assertContains(response, 'Invalid email or password', status_code=403) 26 26 self.assertContains(response, 'Invalid email or password', status_code=403)
27 27
data = {'password': '54321'} 28 28 data = {'password': '54321'}
response = self.client.post(url, data, format='json') 29 29 response = self.client.post(url, data, format='json')
self.assertContains(response, 'email', status_code=400) 30 30 self.assertContains(response, 'email', status_code=400)
31 31
data = {'email': 'none@flashy.cards'} 32 32 data = {'email': 'none@flashy.cards'}
response = self.client.post(url, data, format='json') 33 33 response = self.client.post(url, data, format='json')
self.assertContains(response, 'password', status_code=400) 34 34 self.assertContains(response, 'password', status_code=400)
35 35
user = User.objects.get(email="test@flashy.cards") 36 36 user = User.objects.get(email="test@flashy.cards")
user.is_active = False 37 37 user.is_active = False
user.save() 38 38 user.save()
39 39
data = {'email': 'test@flashy.cards', 'password': '1234'} 40 40 data = {'email': 'test@flashy.cards', 'password': '1234'}
response = self.client.post(url, data, format='json') 41 41 response = self.client.post(url, data, format='json')
self.assertContains(response, 'Account is disabled', status_code=403) 42 42 self.assertContains(response, 'Account is disabled', status_code=403)
43 43
def test_logout(self): 44 44 def test_logout(self):
url = '/api/login' 45 45 url = '/api/logout'
data = {'email': 'test@flashy.cards', 'password': '1234'} 46 46 self.client.login(email='test@flashy.cards', password='1234')
response = self.client.post(url, data, format='json') 47 47 response = self.client.post(url)
self.assertEqual(response.status_code, HTTP_200_OK) 48 48 self.assertEqual(response.status_code, HTTP_204_NO_CONTENT)
49 49
p = self.client.post('/api/logout') 50 50 # since we're not logged in, we should get a 401 response
self.assertEqual(p.status_code, HTTP_204_NO_CONTENT) 51
response = self.client.get('/api/users/me', format='json') 52 51 response = self.client.get('/api/users/me', format='json')
53
# since we're not logged in, we shouldn't be able to see this 54
self.assertEqual(response.status_code, HTTP_401_UNAUTHORIZED) 55 52 self.assertEqual(response.status_code, HTTP_401_UNAUTHORIZED)
56 53
57 54
class PasswordResetTest(APITestCase): 58 55 class PasswordResetTest(APITestCase):
def setUp(self): 59 56 def setUp(self):
# create a user to test things with 60 57 # create a user to test things with
email = "test@flashy.cards" 61 58 email = "test@flashy.cards"
User.objects.create_user(email=email, password="12345") 62 59 User.objects.create_user(email=email, password="12345")
63 60
def test_reset_password(self): 64 61 def test_reset_password(self):
# submit the request to reset the password 65 62 # submit the request to reset the password
url = '/api/reset_password' 66 63 url = '/api/reset_password'
post_data = {'email': 'test@flashy.cards'} 67 64 post_data = {'email': 'test@flashy.cards'}
self.client.post(url, post_data, format='json') 68 65 self.client.post(url, post_data, format='json')
self.assertEqual(len(mail.outbox), 1) 69 66 self.assertEqual(len(mail.outbox), 1)
self.assertIn('reset your password', mail.outbox[0].body) 70 67 self.assertIn('reset your password', mail.outbox[0].body)
71 68
# capture the reset token from the email 72 69 # capture the reset token from the email
capture = search('https://flashy.cards/app/reset_password/(\d+)/(.*)', 73 70 capture = search('https://flashy.cards/app/reset_password/(\d+)/(.*)',
mail.outbox[0].body) 74 71 mail.outbox[0].body)
patch_data = {'new_password': '54321'} 75 72 patch_data = {'new_password': '54321'}
patch_data['uid'] = capture.group(1) 76 73 patch_data['uid'] = capture.group(1)
reset_token = capture.group(2) 77 74 reset_token = capture.group(2)
78 75
# try to reset the password with the wrong reset token 79 76 # try to reset the password with the wrong reset token
patch_data['token'] = 'wrong_token' 80 77 patch_data['token'] = 'wrong_token'
response = self.client.patch(url, patch_data, format='json') 81 78 response = self.client.patch(url, patch_data, format='json')
self.assertContains(response, 'Could not verify reset token', status_code=400) 82 79 self.assertContains(response, 'Could not verify reset token', status_code=400)
83 80
# try to reset the password with the correct token 84 81 # try to reset the password with the correct token
patch_data['token'] = reset_token 85 82 patch_data['token'] = reset_token
response = self.client.patch(url, patch_data, format='json') 86 83 response = self.client.patch(url, patch_data, format='json')
self.assertEqual(response.status_code, HTTP_204_NO_CONTENT) 87 84 self.assertEqual(response.status_code, HTTP_204_NO_CONTENT)
user = User.objects.get(id=patch_data['uid']) 88 85 user = User.objects.get(id=patch_data['uid'])
assert user.check_password(patch_data['new_password']) 89 86 assert user.check_password(patch_data['new_password'])
90 87
91 88
class RegistrationTest(APITestCase): 92 89 class RegistrationTest(APITestCase):
def test_create_account(self): 93 90 def test_create_account(self):
url = '/api/users/me' 94 91 url = '/api/users/me'
95 92
# missing password 96 93 # missing password
data = {'email': 'none@none.com'} 97 94 data = {'email': 'none@none.com'}
response = self.client.post(url, data, format='json') 98 95 response = self.client.post(url, data, format='json')
self.assertContains(response, 'password', status_code=400) 99 96 self.assertContains(response, 'password', status_code=400)
100 97
# missing email 101 98 # missing email
data = {'password': '1234'} 102 99 data = {'password': '1234'}
response = self.client.post(url, data, format='json') 103 100 response = self.client.post(url, data, format='json')
self.assertContains(response, 'email', status_code=400) 104 101 self.assertContains(response, 'email', status_code=400)
105 102
# create a user 106 103 # create a user
data = {'email': 'none@none.com', 'password': '1234'} 107 104 data = {'email': 'none@none.com', 'password': '1234'}
response = self.client.post(url, data, format='json') 108 105 response = self.client.post(url, data, format='json')
self.assertEqual(response.status_code, HTTP_201_CREATED) 109 106 self.assertEqual(response.status_code, HTTP_201_CREATED)
110 107
# user should not be confirmed 111 108 # user should not be confirmed
user = User.objects.get(email="none@none.com") 112 109 user = User.objects.get(email="none@none.com")
self.assertFalse(user.is_confirmed) 113 110 self.assertFalse(user.is_confirmed)
114 111
# check that the confirmation key was sent 115 112 # check that the confirmation key was sent
self.assertEqual(len(mail.outbox), 1) 116 113 self.assertEqual(len(mail.outbox), 1)
self.assertIn(user.confirmation_key, mail.outbox[0].body) 117 114 self.assertIn(user.confirmation_key, mail.outbox[0].body)
118 115
# log the user out 119 116 # log the user out
self.client.logout() 120 117 self.client.logout()
121 118
# log the user in with their registered credentials 122 119 # log the user in with their registered credentials
self.client.login(email='none@none.com', password='1234') 123 120 self.client.login(email='none@none.com', password='1234')
124 121
# try activating with an invalid key 125 122 # try activating with an invalid key
response = self.client.patch(url, {'confirmation_key': 'NOT A KEY'}) 126 123 response = self.client.patch(url, {'confirmation_key': 'NOT A KEY'})
self.assertContains(response, 'confirmation_key is invalid', status_code=400) 127 124 self.assertContains(response, 'confirmation_key is invalid', status_code=400)
128 125
# try activating with the valid key 129 126 # try activating with the valid key
response = self.client.patch(url, {'confirmation_key': user.confirmation_key}) 130 127 response = self.client.patch(url, {'confirmation_key': user.confirmation_key})
self.assertTrue(response.data['is_confirmed']) 131 128 self.assertTrue(response.data['is_confirmed'])
132 129
133 130
class ProfileViewTest(APITestCase): 134 131 class ProfileViewTest(APITestCase):
def setUp(self): 135 132 def setUp(self):
email = "profileviewtest@flashy.cards" 136 133 email = "profileviewtest@flashy.cards"
User.objects.create_user(email=email, password="1234") 137 134 User.objects.create_user(email=email, password="1234")
138 135
def test_get_me(self): 139 136 def test_get_me(self):
url = '/api/users/me' 140 137 url = '/api/users/me'
response = self.client.get(url, format='json') 141 138 response = self.client.get(url, format='json')
# since we're not logged in, we shouldn't be able to see this 142 139 # since we're not logged in, we shouldn't be able to see this
self.assertEqual(response.status_code, HTTP_401_UNAUTHORIZED) 143 140 self.assertEqual(response.status_code, HTTP_401_UNAUTHORIZED)
144 141
self.client.login(email='profileviewtest@flashy.cards', password='1234') 145 142 self.client.login(email='profileviewtest@flashy.cards', password='1234')
response = self.client.get(url, format='json') 146 143 response = self.client.get(url, format='json')
self.assertEqual(response.status_code, HTTP_200_OK) 147 144 self.assertEqual(response.status_code, HTTP_200_OK)
148 145
149 146
class PasswordChangeTest(APITestCase): 150 147 class PasswordChangeTest(APITestCase):
def setUp(self): 151 148 def setUp(self):
email = "none@none.com" 152 149 email = "none@none.com"
User.objects.create_user(email=email, password="1234") 153 150 User.objects.create_user(email=email, password="1234")
154 151
def test_change_password(self): 155 152 def test_change_password(self):
url = '/api/users/me' 156 153 url = '/api/users/me'
user = User.objects.get(email='none@none.com') 157 154 user = User.objects.get(email='none@none.com')
self.assertTrue(user.check_password('1234')) 158 155 self.assertTrue(user.check_password('1234'))
159 156
response = self.client.patch(url, {'new_password': '4321', 'old_password': '1234'}, format='json') 160 157 response = self.client.patch(url, {'new_password': '4321', 'old_password': '1234'}, format='json')
self.assertContains(response, 'You must be logged in to change your password', status_code=403) 161 158 self.assertContains(response, 'You must be logged in to change your password', status_code=403)
162 159
requirements.txt View file @ a55a900
#beautifulsoup4 1 1 #beautifulsoup4
Django>=1.8 2 2 Django>=1.8
#django-websocket-redis==0.4.3 3 3 #django-websocket-redis==0.4.3
#gevent==1.0.1 4 4 #gevent==1.0.1
#greenlet==0.4.5 5 5 #greenlet==0.4.5
#redis==2.10.3 6 6 #redis==2.10.3
six==1.9.0 7 7 six==1.9.0
djangorestframework 8 8 djangorestframework
docutils 9 9 docutils
django-simple-email-confirmation 10 10 django-simple-email-confirmation
django-ses 11 11 django-ses
coverage 12 12 coverage
django-rest-swagger 13 13 django-rest-swagger
14 newrelic
scripts/run_production.sh View file @ a55a900
#!/bin/bash -xe 1 1 #!/bin/bash -xe
source secrets.sh 2 2 source secrets.sh
source venv/bin/activate 3 3 source venv/bin/activate
/srv/flashy-backend/venv/bin/gunicorn --pid /run/flashy/gunicorn.pid -w 6 -n flashy -b 127.0.0.1:7002 flashy.wsgi 4 4 newrelic-admin run-program /srv/flashy-backend/venv/bin/gunicorn --pid /run/flashy/gunicorn.pid -w 6 -n flashy -b 127.0.0.1:7002 flashy.wsgi
5 5