2023-10-11 01:05:54 -03:00
|
|
|
"""
|
|
|
|
Tests for the ingredients API.
|
|
|
|
"""
|
2023-10-12 00:44:46 -03:00
|
|
|
from decimal import Decimal
|
|
|
|
|
2023-10-11 01:05:54 -03:00
|
|
|
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
|
|
|
|
|
2023-10-12 00:44:46 -03:00
|
|
|
from core.models import (
|
|
|
|
Ingredient,
|
|
|
|
Recipe,
|
|
|
|
)
|
2023-10-11 01:05:54 -03:00
|
|
|
|
|
|
|
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())
|
2023-10-12 00:44:46 -03:00
|
|
|
|
|
|
|
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)
|