recipes_api/app/recipe/tests/test_ingredients_api.py

147 lines
4.8 KiB
Python

"""
Tests for the ingredients API.
"""
from decimal import Decimal
from django.contrib.auth import get_user_model
from django.urls import reverse
from django.test import TestCase
from rest_framework import status
from rest_framework.test import APIClient
from core.models import (
Ingredient,
Recipe,
)
from recipe.serializers import IngredientSerializer
INGREDIENTS_URL = reverse('recipe:ingredient-list')
def detail_url(ingredient_id):
"""Create and return an ingredient detail URL."""
return reverse('recipe:ingredient-detail', args=[ingredient_id])
def create_user(email='user@example.com', password='testpass123'):
"""Create and return user."""
return get_user_model().objects.create_user(email=email, password=password)
class PublicIngredientsApiTests(TestCase):
"""Test unanthenticated API requests."""
def setUp(self):
self.client = APIClient()
def test_auth_required(self):
"""Test auth is required for retrieving ingredients."""
res = self.client.get(INGREDIENTS_URL)
self.assertEqual(res.status_code, status.HTTP_401_UNAUTHORIZED)
class PrivateIngredientsApiTests(TestCase):
"""Test authenticated API requests."""
def setUp(self):
self.user = create_user()
self.client = APIClient()
self.client.force_authenticate(self.user)
def test_retrieve_ingredients(self):
"""Test retrieving a list of ingredients."""
Ingredient.objects.create(user=self.user, name='Harina')
Ingredient.objects.create(user=self.user, name='Panela')
res = self.client.get(INGREDIENTS_URL)
ingredients = Ingredient.objects.all().order_by('-name')
serializer = IngredientSerializer(ingredients, many=True)
self.assertEqual(res.status_code, status.HTTP_200_OK)
self.assertEqual(res.data, serializer.data)
def test_ingredients_limited_to_user(self):
"""Test list of ingredients is limited to authenticated user."""
user2 = create_user(email='user2@example.com')
Ingredient.objects.create(user=user2, name='Sal')
ingredient = Ingredient.objects.create(user=self.user, name='Pimienta')
res = self.client.get(INGREDIENTS_URL)
self.assertEqual(res.status_code, status.HTTP_200_OK)
self.assertEqual(len(res.data), 1)
self.assertEqual(res.data[0]['name'], ingredient.name)
self.assertEqual(res.data[0]['id'], ingredient.id)
def test_update_ingredient(self):
"""Test updating an ingredient."""
ingredient = Ingredient.objects.create(
user=self.user, name='Coriandro'
)
payload = {'name': 'Cilantro'}
url = detail_url(ingredient.id)
res = self.client.patch(url, payload)
self.assertEqual(res.status_code, status.HTTP_200_OK)
ingredient.refresh_from_db()
self.assertEqual(ingredient.name, payload['name'])
def test_delete_ingredient(self):
"""Test deleting an ingredient."""
ingredient = Ingredient.objects.create(user=self.user, name='Lechuga')
url = detail_url(ingredient.id)
res = self.client.delete(url)
self.assertEqual(res.status_code, status.HTTP_204_NO_CONTENT)
ingredients = Ingredient.objects.filter(user=self.user)
self.assertFalse(ingredients.exists())
def test_filter_ingredients_assigned_to_recipes(self):
"""Test listing ingredients by those assigned to recipes."""
in1 = Ingredient.objects.create(user=self.user, name='Manzana')
in2 = Ingredient.objects.create(user=self.user, name='Pavo')
recipe = Recipe.objects.create(
title='Pure de Manzana',
time_minutes=5,
price=Decimal('4.5'),
user=self.user,
)
recipe.ingredients.add(in1)
res = self.client.get(INGREDIENTS_URL, {'assigned_only': 1})
s1 = IngredientSerializer(in1)
s2 = IngredientSerializer(in2)
self.assertIn(s1.data, res.data)
self.assertNotIn(s2.data, res.data)
def test_filtered_ingredients_unique(self):
"""Test filtered ingredients returns a unique list."""
ing = Ingredient.objects.create(user=self.user, name='Huevo')
Ingredient.objects.create(user=self.user, name='Lentejas')
recipe1 = Recipe.objects.create(
title='Huevos a la copa',
time_minutes=4,
price=Decimal('1.0'),
user=self.user,
)
recipe2 = Recipe.objects.create(
title='Huevos a cocidos',
time_minutes=5,
price=Decimal('1.0'),
user=self.user,
)
recipe1.ingredients.add(ing)
recipe2.ingredients.add(ing)
res = self.client.get(INGREDIENTS_URL, {'assigned_only': 1})
self.assertEqual(len(res.data), 1)