recipes_api/app/user/tests/test_user_api.py

152 lines
5.0 KiB
Python
Raw Normal View History

"""
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)