1
0
Fork 0
mirror of https://github.com/mealie-recipes/mealie.git synced 2025-08-03 12:35:22 +02:00

Feature/restore-recipe-functionality (#810)

* feat(frontend):  add back support for assets

* feat(backend):  add back support for assets

* feat(frontend):  add support for recipe tools

* feat(backend):  add support for recipe tools

* feat(frontend):  add onHand support for recipe toosl

* feat(backend):  add onHand support for backend

* refactor(frontend): ♻️ move items to recipe folder and break apart types

* feat(frontend):  add support for recipe comments

* feat(backend):  Add support for recipe comments

* fix(backend): 💥 disable comments import

* fix(frontend): 🐛 fix rendering issue with titles when moving steps

* add tools to changelog

* fix type errors

Co-authored-by: hay-kot <hay-kot@pm.me>
This commit is contained in:
Hayden 2021-11-22 20:10:48 -09:00 committed by GitHub
parent 912cc6d956
commit 7afdd5b577
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
43 changed files with 1221 additions and 423 deletions

View file

@ -0,0 +1,122 @@
import pytest
from fastapi.testclient import TestClient
from mealie.schema.recipe.recipe import Recipe
from tests.utils.factories import random_string
from tests.utils.fixture_schemas import TestUser
class Routes:
base = "/api/comments"
recipes = "/api/recipes"
def item(item_id: int) -> str:
return f"{Routes.base}/{item_id}"
def recipe(recipe_id: int) -> str:
return f"{Routes.recipes}/{recipe_id}"
def recipe_comments(recipe_slug: str) -> str:
return f"{Routes.recipe(recipe_slug)}/comments"
@pytest.fixture(scope="function")
def unique_recipe(api_client: TestClient, unique_user: TestUser):
payload = {"name": random_string(length=20)}
response = api_client.post(Routes.recipes, json=payload, headers=unique_user.token)
assert response.status_code == 201
response_data = response.json()
recipe_response = api_client.get(Routes.recipe(response_data), headers=unique_user.token)
return Recipe(**recipe_response.json())
def random_comment(recipe_id: int) -> dict:
if recipe_id is None:
raise ValueError("recipe_id is required")
return {
"recipeId": recipe_id,
"text": random_string(length=50),
}
def test_create_comment(api_client: TestClient, unique_recipe: Recipe, unique_user: TestUser):
# Create Comment
create_data = random_comment(unique_recipe.id)
response = api_client.post(Routes.base, json=create_data, headers=unique_user.token)
assert response.status_code == 201
response_data = response.json()
assert response_data["recipeId"] == unique_recipe.id
assert response_data["text"] == create_data["text"]
assert response_data["userId"] == unique_user.user_id
# Check for Proper Association
response = api_client.get(Routes.recipe_comments(unique_recipe.slug), headers=unique_user.token)
assert response.status_code == 200
response_data = response.json()
assert len(response_data) == 1
assert response_data[0]["recipeId"] == unique_recipe.id
assert response_data[0]["text"] == create_data["text"]
assert response_data[0]["userId"] == unique_user.user_id
def test_update_comment(api_client: TestClient, unique_recipe: Recipe, unique_user: TestUser):
# Create Comment
create_data = random_comment(unique_recipe.id)
response = api_client.post(Routes.base, json=create_data, headers=unique_user.token)
assert response.status_code == 201
comment_id = response.json()["id"]
# Update Comment
update_data = random_comment(unique_recipe.id)
update_data["id"] = comment_id
response = api_client.put(Routes.item(comment_id), json=update_data, headers=unique_user.token)
assert response.status_code == 200
response_data = response.json()
assert response_data["recipeId"] == unique_recipe.id
assert response_data["text"] == update_data["text"]
assert response_data["userId"] == unique_user.user_id
def test_delete_comment(api_client: TestClient, unique_recipe: Recipe, unique_user: TestUser):
# Create Comment
create_data = random_comment(unique_recipe.id)
response = api_client.post(Routes.base, json=create_data, headers=unique_user.token)
assert response.status_code == 201
# Delete Comment
comment_id = response.json()["id"]
response = api_client.delete(Routes.item(comment_id), headers=unique_user.token)
assert response.status_code == 200
# Validate Deletion
response = api_client.get(Routes.item(comment_id), headers=unique_user.token)
assert response.status_code == 404
def test_admin_can_delete(api_client: TestClient, unique_recipe: Recipe, unique_user: TestUser, admin_user: TestUser):
# Create Comment
create_data = random_comment(unique_recipe.id)
response = api_client.post(Routes.base, json=create_data, headers=unique_user.token)
assert response.status_code == 201
# Delete Comment
comment_id = response.json()["id"]
response = api_client.delete(Routes.item(comment_id), headers=admin_user.token)
assert response.status_code == 200
# Validate Deletion
response = api_client.get(Routes.item(comment_id), headers=admin_user.token)
assert response.status_code == 404

View file

@ -39,7 +39,6 @@ def test_read_update(
]
recipe["notes"] = test_notes
recipe["tools"] = ["one tool", "two tool"]
test_categories = [
{"name": "one", "slug": "one"},

View file

@ -0,0 +1,104 @@
from dataclasses import dataclass
import pytest
from fastapi.testclient import TestClient
from tests.utils.factories import random_string
from tests.utils.fixture_schemas import TestUser
class Routes:
base = "/api/tools"
recipes = "/api/recipes"
def item(item_id: int) -> str:
return f"{Routes.base}/{item_id}"
def recipe(recipe_id: int) -> str:
return f"{Routes.recipes}/{recipe_id}"
@dataclass
class TestRecipeTool:
id: int
name: str
@pytest.fixture(scope="function")
def tool(api_client: TestClient, unique_user: TestUser) -> TestRecipeTool:
data = {"name": random_string(10)}
response = api_client.post(Routes.base, json=data, headers=unique_user.token)
assert response.status_code == 201
yield TestRecipeTool(id=response.json()["id"], name=data["name"])
try:
response = api_client.delete(Routes.item(response.json()["id"]), headers=unique_user.token)
except Exception:
pass
def test_create_tool(api_client: TestClient, unique_user: TestUser):
data = {"name": random_string(10)}
response = api_client.post(Routes.base, json=data, headers=unique_user.token)
assert response.status_code == 201
def test_read_tool(api_client: TestClient, tool: TestRecipeTool, unique_user: TestUser):
response = api_client.get(Routes.item(tool.id), headers=unique_user.token)
assert response.status_code == 200
as_json = response.json()
assert as_json["id"] == tool.id
assert as_json["name"] == tool.name
def test_update_tool(api_client: TestClient, tool: TestRecipeTool, unique_user: TestUser):
update_data = {"id": tool.id, "name": random_string(10)}
response = api_client.put(Routes.item(tool.id), json=update_data, headers=unique_user.token)
assert response.status_code == 200
as_json = response.json()
assert as_json["id"] == tool.id
assert as_json["name"] == update_data["name"]
def test_delete_tool(api_client: TestClient, tool: TestRecipeTool, unique_user: TestUser):
response = api_client.delete(Routes.item(tool.id), headers=unique_user.token)
assert response.status_code == 200
def test_recipe_tool_association(api_client: TestClient, tool: TestRecipeTool, unique_user: TestUser):
# Setup Recipe
recipe_data = {"name": random_string(10)}
response = api_client.post(Routes.recipes, json=recipe_data, headers=unique_user.token)
slug = response.json()
assert response.status_code == 201
# Get Recipe Data
response = api_client.get(Routes.recipe(slug), headers=unique_user.token)
as_json = response.json()
as_json["tools"] = [{"id": tool.id, "name": tool.name}]
# Update Recipe
response = api_client.put(Routes.recipe(slug), json=as_json, headers=unique_user.token)
assert response.status_code == 200
# Get Recipe Data
response = api_client.get(Routes.recipe(slug), headers=unique_user.token)
as_json = response.json()
assert as_json["tools"][0]["id"] == tool.id