def test_tags_limited_to_user(self):
        """Test that tags returned are for the authenticated user"""
        tag = utils.create_tag(self.user, "Comfort food")
        utils.create_tag(self.user2, "Fruity")

        res = self.client.get(utils.TAGS_URL)

        self.assertEqual(res.status_code, status.HTTP_200_OK)
        self.assertEqual(len(res.data), 1)
        self.assertEqual(res.data[0]["name"], tag.name)
    def test_retrieve_tags(self):
        """Test retrieving tags"""
        utils.create_tag(self.user, "Vegan")
        utils.create_tag(self.user, "Dessert")

        res = self.client.get(utils.TAGS_URL)

        serializer = TagSerializer(utils.all_tags(), many=True)
        self.assertEqual(res.status_code, status.HTTP_200_OK)
        self.assertEqual(res.data, serializer.data)
    def test_retrieve_tags_assigned_unique(self):
        """Test filtering tags by assigned returns unique items"""
        tag = utils.create_tag(self.user, "Vegan")
        utils.create_tag(self.user, "Lunch")

        recipe1 = utils.create_recipe(self.user, **utils.RECIPE_PAYLOAD)
        recipe2 = utils.create_recipe(self.user, **utils.RECIPE_PAYLOAD_UPDATE)

        recipe1.tags.add(tag)
        recipe2.tags.add(tag)

        res = self.client.get(utils.TAGS_URL, {"assigned_only": 1})

        self.assertEqual(len(res.data), 1)
    def test_retrieve_tags_assigned_to_recipes(self):
        """Test filtering tags by those assigned to recipes"""
        tag1 = utils.create_tag(self.user, "Vegan")
        tag2 = utils.create_tag(self.user, "Lunch")

        recipe = utils.create_recipe(self.user)
        recipe.tags.add(tag1)

        res = self.client.get(utils.TAGS_URL, {"assigned_only": 1})

        serializer1 = TagSerializer(tag1)
        serializer2 = TagSerializer(tag2)

        self.assertIn(serializer1.data, res.data)
        self.assertNotIn(serializer2.data, res.data)
    def test_create_recipe_with_tags(self):
        """Test creating a recipe with tags"""
        tag1 = utils.create_tag(self.user, "Vegan")
        tag2 = utils.create_tag(self.user, "Dessert")
        payload = deepcopy(utils.RECIPE_PAYLOAD)
        payload.update({"tags": [tag1.id, tag2.id]})
        res = self.client.post(utils.RECIPES_URL, payload)

        self.assertEqual(res.status_code, status.HTTP_201_CREATED)

        recipe = Recipe.objects.get(id=res.data["id"])
        tags = recipe.tags.all()

        self.assertEqual(tags.count(), 2)
        self.assertIn(tag1, tags)
        self.assertIn(tag2, tags)
    def test_partial_update_recipe(self):
        """Test updating a recipe with patch"""
        recipe = utils.create_recipe(self.user)
        recipe.tags.add(utils.create_tag(self.user, "Spicy"))
        new_tag = utils.create_tag(self.user, "Curry")

        payload = deepcopy(utils.RECIPE_PAYLOAD)
        payload.update({"tags": [new_tag.id]})

        url = utils.recipe_detail_url(recipe.id)
        res = self.client.patch(url, payload)

        self.assertEqual(res.status_code, status.HTTP_200_OK)

        recipe.refresh_from_db()
        self.assertEqual(recipe.title, payload["title"])
        tags = recipe.tags.all()
        self.assertEqual(len(tags), 1)
        self.assertIn(new_tag, tags)
    def test_view_recipe_detail(self):
        """Test viewing a recipe detial"""
        recipe = utils.create_recipe(self.user)
        recipe.tags.add(utils.create_tag(self.user, "Vegan"))
        recipe.ingredients.add(utils.create_ingredent(self.user, "Salt"))

        res = self.client.get(utils.recipe_detail_url(recipe.id))

        serializer = RecipeDetailSerializer(recipe)

        self.assertEqual(res.data, serializer.data)
    def test_filter_recipes_by_tags(self):
        """Test returning recipes with specific tags"""
        recipe1 = utils.create_recipe(self.user)
        recipe2 = utils.create_recipe(self.user)
        recipe3 = utils.create_recipe(self.user)

        tag1 = utils.create_tag(self.user, "Vegan")
        tag2 = utils.create_tag(self.user, "Vegetatian")

        recipe1.tags.add(tag1)
        recipe2.tags.add(tag2)

        res = self.client.get(
            utils.RECIPES_URL,
            {"tags": f"{tag1.id}, {tag2.id}"},
        )

        serializer1 = RecipeSerializer(recipe1)
        serializer2 = RecipeSerializer(recipe2)
        serializer3 = RecipeSerializer(recipe3)

        self.assertIn(serializer1.data, res.data)
        self.assertIn(serializer2.data, res.data)
        self.assertNotIn(serializer3.data, res.data)
    def test_full_update_recipe(self):
        """Test updating a recipe with put"""
        recipe = utils.create_recipe(self.user)
        recipe.tags.add(utils.create_tag(self.user, "Spicy"))
        url = utils.recipe_detail_url(recipe.id)
        payload = deepcopy(utils.RECIPE_PAYLOAD)
        res = self.client.put(url, payload)

        self.assertEqual(res.status_code, status.HTTP_200_OK)

        recipe.refresh_from_db()
        self.assertEqual(recipe.title, payload["title"])
        self.assertEqual(recipe.time_minutes, payload["time_minutes"])
        self.assertEqual(recipe.price, payload["price"])
        tags = recipe.tags.all()
        self.assertEqual(len(tags), 0)
    def test_tag_str(self):
        """Test the tag string represention"""
        tag = utils.create_tag(self.user, "Vegan")

        self.assertEqual(str(tag), tag.name)