152 lines
5.0 KiB
Python
152 lines
5.0 KiB
Python
"""
|
|
Tests for the user API.
|
|
"""
|
|
from django.test import TestCase
|
|
from django.contrib.auth import get_user_model
|
|
from django.urls import reverse
|
|
|
|
from rest_framework.test import APIClient
|
|
from rest_framework import status
|
|
|
|
CREATE_USER_URL = reverse('user:create')
|
|
TOKEN_URL = reverse('user:token')
|
|
ME_URL = reverse('user:me')
|
|
|
|
def create_user(**params):
|
|
"""Create and return a new user."""
|
|
return get_user_model().objects.create_user(**params)
|
|
|
|
|
|
class PublicUserApiTest(TestCase):
|
|
"""Test the public features of the user API."""
|
|
|
|
def setUp(self):
|
|
self.client = APIClient()
|
|
|
|
def test_create_user_success(self):
|
|
"""Tests creating a user is successful."""
|
|
payload = {
|
|
'email': 'test@example.com',
|
|
'password':'testpass123',
|
|
'name': 'TestName',
|
|
}
|
|
res = self.client.post(CREATE_USER_URL, payload)
|
|
|
|
self.assertEqual(res.status_code, status.HTTP_201_CREATED)
|
|
user = get_user_model().objects.get(email=payload['email'])
|
|
self.assertTrue(user.check_password(payload['password']))
|
|
self.assertNotIn('password', res.data)
|
|
|
|
def test_user_with_email_exists_error(self):
|
|
"""Test error returned if user with email exists."""
|
|
payload = {
|
|
'email': 'test@example.com',
|
|
'password':'testpass123',
|
|
'name': 'Test Name',
|
|
}
|
|
create_user(**payload)
|
|
res = self.client.post(CREATE_USER_URL, payload)
|
|
|
|
self.assertEqual(res.status_code, status.HTTP_400_BAD_REQUEST)
|
|
|
|
def test_password_too_short_error(self):
|
|
"""Test an error is returned if password less than 5 chars."""
|
|
payload = {
|
|
'email': 'test@example.com',
|
|
'password':'pw',
|
|
'name': 'Test Name',
|
|
}
|
|
res = self.client.post(CREATE_USER_URL, payload)
|
|
|
|
self.assertEqual(res.status_code, status.HTTP_400_BAD_REQUEST)
|
|
user_exists = get_user_model().objects.filter(
|
|
email=payload['email']
|
|
).exists()
|
|
self.assertFalse(user_exists)
|
|
|
|
def test_create_token_for_user(self):
|
|
"""Test generate token for valid credentials."""
|
|
user_details = {
|
|
'name': 'Test Name',
|
|
'email': 'test@example.com',
|
|
'password':'test-user-password123',
|
|
}
|
|
create_user(**user_details)
|
|
|
|
payload = {
|
|
'email': user_details['email'],
|
|
'password': user_details['password'],
|
|
}
|
|
res = self.client.post(TOKEN_URL, payload)
|
|
|
|
self.assertIn('token', res.data)
|
|
self.assertEqual(res.status_code, status.HTTP_200_OK)
|
|
|
|
def test_create_token_bad_credentials(self):
|
|
"""Test returns error if credentials invalid."""
|
|
create_user(email='test@example.com', password='goodpass')
|
|
|
|
payload = {'email': 'test@example.com' ,'password': 'badpass'}
|
|
res = self.client.post(TOKEN_URL, payload)
|
|
|
|
self.assertNotIn('token', res.data)
|
|
self.assertEqual(res.status_code, status.HTTP_400_BAD_REQUEST)
|
|
|
|
def test_create_token_blank_password(self):
|
|
"""Test posting a blank password returns an error."""
|
|
payload = {'email': 'test@example.com' , 'password': ''}
|
|
res = self.client.post(TOKEN_URL, payload)
|
|
|
|
self.assertNotIn('token', res.data)
|
|
self.assertEqual(res.status_code, status.HTTP_400_BAD_REQUEST)
|
|
|
|
def test_retrive_user_unauthorized(self):
|
|
"""Test authentication is required for users."""
|
|
res = self.client.get(ME_URL)
|
|
|
|
self.assertEqual(res.status_code, status.HTTP_401_UNAUTHORIZED)
|
|
|
|
|
|
class PrivateUserApiTests(TestCase):
|
|
"""Test API requests that require authentication."""
|
|
|
|
def setUp(self):
|
|
self.user = create_user(
|
|
email='test@example.com',
|
|
password='testpass123',
|
|
name='Test Name',
|
|
)
|
|
self.client = APIClient()
|
|
self.client.force_authenticate(user=self.user)
|
|
|
|
def test_retrive_profile_success(self):
|
|
"""Test retrieving profile for logged in user."""
|
|
res = self.client.get(ME_URL)
|
|
|
|
self.assertEqual(res.status_code, status.HTTP_200_OK)
|
|
self.assertEqual(
|
|
res.data, {
|
|
'name': self.user.name,
|
|
'email': self.user.email,
|
|
})
|
|
|
|
def test_post_me_not_allowed(self):
|
|
"""Test POST is not allowed for the 'me' endpoint."""
|
|
res = self.client.post(ME_URL, {})
|
|
|
|
self.assertAlmostEqual(
|
|
res.status_code,
|
|
status.HTTP_405_METHOD_NOT_ALLOWED
|
|
)
|
|
|
|
def test_update_user_profile(self):
|
|
"""Test updating the user profile for the autenticated user."""
|
|
payload = { 'name': 'Updated Name', 'password': 'newpassword123' }
|
|
|
|
res = self.client.patch(ME_URL, payload)
|
|
|
|
self.user.refresh_from_db()
|
|
self.assertEqual(self.user.name, payload['name'])
|
|
self.assertTrue(self.user.check_password(payload['password']))
|
|
self.assertEqual(res.status_code, status.HTTP_200_OK)
|