mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-08-03 04:25:24 +02:00
feat: Cross-Household Recipes (#4089)
This commit is contained in:
parent
7ef2e91ecf
commit
9acf9ec27c
16 changed files with 545 additions and 92 deletions
|
@ -124,3 +124,20 @@ def test_admin_can_delete(
|
|||
response = api_client.get(api_routes.comments_item_id(comment_id), headers=admin_user.token)
|
||||
|
||||
assert response.status_code == 404
|
||||
|
||||
|
||||
def test_user_can_comment_on_other_household(api_client: TestClient, unique_recipe: Recipe, h2_user: TestUser):
|
||||
# Create Comment
|
||||
create_data = random_comment(unique_recipe.id)
|
||||
response = api_client.post(api_routes.comments, json=create_data, headers=h2_user.token)
|
||||
assert response.status_code == 201
|
||||
|
||||
# Delete Comment
|
||||
comment_id = response.json()["id"]
|
||||
response = api_client.delete(api_routes.comments_item_id(comment_id), headers=h2_user.token)
|
||||
assert response.status_code == 200
|
||||
|
||||
# Validate Deletion
|
||||
response = api_client.get(api_routes.comments_item_id(comment_id), headers=h2_user.token)
|
||||
|
||||
assert response.status_code == 404
|
||||
|
|
|
@ -0,0 +1,186 @@
|
|||
from datetime import datetime, timezone
|
||||
|
||||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from tests.utils import api_routes
|
||||
from tests.utils.factories import random_string
|
||||
from tests.utils.fixture_schemas import TestUser
|
||||
|
||||
|
||||
@pytest.mark.parametrize("is_private_household", [True, False])
|
||||
def test_duplicate_recipe_changes_household(
|
||||
api_client: TestClient, unique_user: TestUser, h2_user: TestUser, is_private_household: bool
|
||||
):
|
||||
household = unique_user.repos.households.get_one(h2_user.household_id)
|
||||
assert household and household.preferences
|
||||
household.preferences.private_household = is_private_household
|
||||
unique_user.repos.household_preferences.update(household.id, household.preferences)
|
||||
|
||||
source_recipe_name = random_string()
|
||||
duplicate_recipe_name = random_string()
|
||||
|
||||
response = api_client.post(api_routes.recipes, json={"name": source_recipe_name}, headers=unique_user.token)
|
||||
assert response.status_code == 201
|
||||
recipe = unique_user.repos.recipes.get_one(response.json())
|
||||
assert recipe
|
||||
assert recipe.name == source_recipe_name
|
||||
assert str(recipe.household_id) == unique_user.household_id
|
||||
|
||||
response = api_client.post(
|
||||
api_routes.recipes_slug_duplicate(recipe.slug), json={"name": duplicate_recipe_name}, headers=h2_user.token
|
||||
)
|
||||
assert response.status_code == 201
|
||||
duplicate_recipe = h2_user.repos.recipes.get_one(response.json()["slug"])
|
||||
assert duplicate_recipe
|
||||
assert duplicate_recipe.name == duplicate_recipe_name
|
||||
assert str(duplicate_recipe.household_id) == h2_user.household_id != unique_user.household_id
|
||||
|
||||
|
||||
@pytest.mark.parametrize("is_private_household", [True, False])
|
||||
def test_get_all_recipes_includes_all_households(
|
||||
api_client: TestClient, unique_user: TestUser, h2_user: TestUser, is_private_household: bool
|
||||
):
|
||||
household = unique_user.repos.households.get_one(h2_user.household_id)
|
||||
assert household and household.preferences
|
||||
household.preferences.private_household = is_private_household
|
||||
unique_user.repos.household_preferences.update(household.id, household.preferences)
|
||||
|
||||
response = api_client.post(api_routes.recipes, json={"name": random_string()}, headers=unique_user.token)
|
||||
assert response.status_code == 201
|
||||
recipe = unique_user.repos.recipes.get_one(response.json())
|
||||
assert recipe and recipe.id
|
||||
recipe_id = recipe.id
|
||||
|
||||
response = api_client.post(api_routes.recipes, json={"name": random_string()}, headers=h2_user.token)
|
||||
assert response.status_code == 201
|
||||
h2_recipe = h2_user.repos.recipes.get_one(response.json())
|
||||
assert h2_recipe and h2_recipe.id
|
||||
h2_recipe_id = h2_recipe.id
|
||||
|
||||
response = api_client.get(api_routes.recipes, params={"page": 1, "perPage": -1}, headers=unique_user.token)
|
||||
assert response.status_code == 200
|
||||
response_ids = {recipe["id"] for recipe in response.json()["items"]}
|
||||
assert str(recipe_id) in response_ids
|
||||
assert str(h2_recipe_id) in response_ids
|
||||
|
||||
|
||||
@pytest.mark.parametrize("is_private_household", [True, False])
|
||||
def test_get_one_recipe_from_another_household(
|
||||
api_client: TestClient, unique_user: TestUser, h2_user: TestUser, is_private_household: bool
|
||||
):
|
||||
household = unique_user.repos.households.get_one(h2_user.household_id)
|
||||
assert household and household.preferences
|
||||
household.preferences.private_household = is_private_household
|
||||
unique_user.repos.household_preferences.update(household.id, household.preferences)
|
||||
|
||||
response = api_client.post(api_routes.recipes, json={"name": random_string()}, headers=h2_user.token)
|
||||
assert response.status_code == 201
|
||||
h2_recipe = h2_user.repos.recipes.get_one(response.json())
|
||||
assert h2_recipe and h2_recipe.id
|
||||
h2_recipe_id = h2_recipe.id
|
||||
|
||||
response = api_client.get(api_routes.recipes_slug(h2_recipe_id), headers=unique_user.token)
|
||||
assert response.status_code == 200
|
||||
assert response.json()["id"] == str(h2_recipe_id)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("is_private_household", [True, False])
|
||||
@pytest.mark.parametrize("use_patch", [True, False])
|
||||
def test_prevent_updates_to_recipes_from_other_households(
|
||||
api_client: TestClient, unique_user: TestUser, h2_user: TestUser, is_private_household: bool, use_patch: bool
|
||||
):
|
||||
household = unique_user.repos.households.get_one(h2_user.household_id)
|
||||
assert household and household.preferences
|
||||
household.preferences.private_household = is_private_household
|
||||
unique_user.repos.household_preferences.update(household.id, household.preferences)
|
||||
|
||||
original_name = random_string()
|
||||
response = api_client.post(api_routes.recipes, json={"name": original_name}, headers=h2_user.token)
|
||||
assert response.status_code == 201
|
||||
h2_recipe = h2_user.repos.recipes.get_one(response.json())
|
||||
assert h2_recipe and h2_recipe.id
|
||||
h2_recipe_id = h2_recipe.id
|
||||
|
||||
response = api_client.get(api_routes.recipes_slug(h2_recipe_id), headers=unique_user.token)
|
||||
assert response.status_code == 200
|
||||
recipe = response.json()
|
||||
assert recipe["id"] == str(h2_recipe_id)
|
||||
|
||||
updated_name = random_string()
|
||||
recipe["name"] = updated_name
|
||||
client_func = api_client.patch if use_patch else api_client.put
|
||||
response = client_func(api_routes.recipes_slug(recipe["slug"]), json=recipe, headers=unique_user.token)
|
||||
assert response.status_code == 403
|
||||
|
||||
# confirm the recipe is unchanged
|
||||
response = api_client.get(api_routes.recipes_slug(recipe["slug"]), headers=unique_user.token)
|
||||
assert response.status_code == 200
|
||||
updated_recipe = response.json()
|
||||
assert updated_recipe["name"] == original_name != updated_name
|
||||
|
||||
|
||||
@pytest.mark.parametrize("is_private_household", [True, False])
|
||||
def test_prevent_deletes_to_recipes_from_other_households(
|
||||
api_client: TestClient, unique_user: TestUser, h2_user: TestUser, is_private_household: bool
|
||||
):
|
||||
household = unique_user.repos.households.get_one(h2_user.household_id)
|
||||
assert household and household.preferences
|
||||
household.preferences.private_household = is_private_household
|
||||
unique_user.repos.household_preferences.update(household.id, household.preferences)
|
||||
|
||||
response = api_client.post(api_routes.recipes, json={"name": random_string()}, headers=h2_user.token)
|
||||
assert response.status_code == 201
|
||||
h2_recipe = h2_user.repos.recipes.get_one(response.json())
|
||||
assert h2_recipe and h2_recipe.id
|
||||
h2_recipe_id = str(h2_recipe.id)
|
||||
|
||||
response = api_client.get(api_routes.recipes_slug(h2_recipe_id), headers=unique_user.token)
|
||||
assert response.status_code == 200
|
||||
recipe_json = response.json()
|
||||
assert recipe_json["id"] == h2_recipe_id
|
||||
|
||||
response = api_client.delete(api_routes.recipes_slug(recipe_json["slug"]), headers=unique_user.token)
|
||||
assert response.status_code == 403
|
||||
|
||||
# confirm the recipe still exists
|
||||
response = api_client.get(api_routes.recipes_slug(h2_recipe_id), headers=unique_user.token)
|
||||
assert response.status_code == 200
|
||||
assert response.json()["id"] == h2_recipe_id
|
||||
|
||||
|
||||
@pytest.mark.parametrize("is_private_household", [True, False])
|
||||
def test_user_can_update_last_made_on_other_household(
|
||||
api_client: TestClient, unique_user: TestUser, h2_user: TestUser, is_private_household: bool
|
||||
):
|
||||
household = unique_user.repos.households.get_one(h2_user.household_id)
|
||||
assert household and household.preferences
|
||||
household.preferences.private_household = is_private_household
|
||||
unique_user.repos.household_preferences.update(household.id, household.preferences)
|
||||
|
||||
response = api_client.post(api_routes.recipes, json={"name": random_string()}, headers=h2_user.token)
|
||||
assert response.status_code == 201
|
||||
h2_recipe = h2_user.repos.recipes.get_one(response.json())
|
||||
assert h2_recipe and h2_recipe.id
|
||||
h2_recipe_id = h2_recipe.id
|
||||
h2_recipe_slug = h2_recipe.slug
|
||||
|
||||
response = api_client.get(api_routes.recipes_slug(h2_recipe_slug), headers=unique_user.token)
|
||||
assert response.status_code == 200
|
||||
recipe = response.json()
|
||||
assert recipe["id"] == str(h2_recipe_id)
|
||||
old_last_made = recipe["lastMade"]
|
||||
|
||||
now = datetime.now(timezone.utc).isoformat().replace("+00:00", "Z")
|
||||
response = api_client.patch(
|
||||
api_routes.recipes_slug_last_made(h2_recipe_slug), json={"timestamp": now}, headers=unique_user.token
|
||||
)
|
||||
assert response.status_code == 200
|
||||
|
||||
# confirm the last made date was updated
|
||||
response = api_client.get(api_routes.recipes_slug(h2_recipe_slug), headers=unique_user.token)
|
||||
assert response.status_code == 200
|
||||
recipe = response.json()
|
||||
assert recipe["id"] == str(h2_recipe_id)
|
||||
new_last_made = recipe["lastMade"]
|
||||
assert new_last_made == now != old_last_made
|
|
@ -368,3 +368,47 @@ def test_recipe_rating_is_readonly(
|
|||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["rating"] == rating.rating
|
||||
|
||||
|
||||
def test_user_can_rate_recipes_in_other_households(api_client: TestClient, unique_user: TestUser, h2_user: TestUser):
|
||||
response = api_client.post(api_routes.recipes, json={"name": random_string()}, headers=unique_user.token)
|
||||
assert response.status_code == 201
|
||||
recipe = unique_user.repos.recipes.get_one(response.json())
|
||||
assert recipe and recipe.id
|
||||
|
||||
rating = UserRatingUpdate(rating=random.uniform(1, 5), is_favorite=True)
|
||||
response = api_client.post(
|
||||
api_routes.users_id_ratings_slug(h2_user.user_id, recipe.slug),
|
||||
json=rating.model_dump(),
|
||||
headers=h2_user.token,
|
||||
)
|
||||
assert response.status_code == 200
|
||||
|
||||
response = api_client.get(api_routes.users_self_ratings_recipe_id(recipe.id), headers=h2_user.token)
|
||||
data = response.json()
|
||||
assert data["recipeId"] == str(recipe.id)
|
||||
assert data["rating"] == rating.rating
|
||||
assert data["isFavorite"] is True
|
||||
|
||||
|
||||
def test_average_recipe_rating_includes_all_households(
|
||||
api_client: TestClient, unique_user: TestUser, h2_user: TestUser
|
||||
):
|
||||
response = api_client.post(api_routes.recipes, json={"name": random_string()}, headers=unique_user.token)
|
||||
assert response.status_code == 201
|
||||
recipe = unique_user.repos.recipes.get_one(response.json())
|
||||
assert recipe
|
||||
|
||||
user_ratings = (UserRatingUpdate(rating=5), UserRatingUpdate(rating=2))
|
||||
for i, user in enumerate([unique_user, h2_user]):
|
||||
response = api_client.post(
|
||||
api_routes.users_id_ratings_slug(user.user_id, recipe.slug),
|
||||
json=user_ratings[i].model_dump(),
|
||||
headers=user.token,
|
||||
)
|
||||
assert response.status_code == 200
|
||||
|
||||
response = api_client.get(api_routes.recipes_slug(recipe.slug), headers=unique_user.token)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["rating"] == 3.5
|
||||
|
|
|
@ -35,11 +35,19 @@ def recipes(api_client: TestClient, unique_user: TestUser):
|
|||
response = api_client.delete(f"{api_routes.recipes}/{slug}", headers=unique_user.token)
|
||||
|
||||
|
||||
def test_create_timeline_event(api_client: TestClient, unique_user: TestUser, recipes: list[Recipe]):
|
||||
@pytest.mark.parametrize("use_other_household_user", [True, False])
|
||||
def test_create_timeline_event(
|
||||
api_client: TestClient,
|
||||
unique_user: TestUser,
|
||||
recipes: list[Recipe],
|
||||
h2_user: TestUser,
|
||||
use_other_household_user: bool,
|
||||
):
|
||||
user = h2_user if use_other_household_user else unique_user
|
||||
recipe = recipes[0]
|
||||
new_event = {
|
||||
"recipe_id": str(recipe.id),
|
||||
"user_id": str(unique_user.user_id),
|
||||
"user_id": str(user.user_id),
|
||||
"subject": random_string(),
|
||||
"event_type": "info",
|
||||
"message": random_string(),
|
||||
|
@ -48,41 +56,53 @@ def test_create_timeline_event(api_client: TestClient, unique_user: TestUser, re
|
|||
event_response = api_client.post(
|
||||
api_routes.recipes_timeline_events,
|
||||
json=new_event,
|
||||
headers=unique_user.token,
|
||||
headers=user.token,
|
||||
)
|
||||
assert event_response.status_code == 201
|
||||
|
||||
event = RecipeTimelineEventOut.model_validate(event_response.json())
|
||||
assert event.recipe_id == recipe.id
|
||||
assert str(event.user_id) == str(unique_user.user_id)
|
||||
assert str(event.user_id) == str(user.user_id)
|
||||
|
||||
|
||||
def test_get_all_timeline_events(api_client: TestClient, unique_user: TestUser, recipes: list[Recipe]):
|
||||
@pytest.mark.parametrize("use_other_household_user", [True, False])
|
||||
def test_get_all_timeline_events(
|
||||
api_client: TestClient,
|
||||
unique_user: TestUser,
|
||||
recipes: list[Recipe],
|
||||
h2_user: TestUser,
|
||||
use_other_household_user: bool,
|
||||
):
|
||||
user = h2_user if use_other_household_user else unique_user
|
||||
# create some events
|
||||
recipe = recipes[0]
|
||||
events_data = [
|
||||
{
|
||||
"recipe_id": str(recipe.id),
|
||||
"user_id": str(unique_user.user_id),
|
||||
"subject": random_string(),
|
||||
"event_type": "info",
|
||||
"message": random_string(),
|
||||
}
|
||||
for _ in range(10)
|
||||
]
|
||||
events_data: list[dict] = []
|
||||
for user in [unique_user, h2_user]:
|
||||
events_data.extend(
|
||||
[
|
||||
{
|
||||
"recipe_id": str(recipe.id),
|
||||
"user_id": str(user.user_id),
|
||||
"subject": random_string(),
|
||||
"event_type": "info",
|
||||
"message": random_string(),
|
||||
}
|
||||
for _ in range(10)
|
||||
]
|
||||
)
|
||||
|
||||
events: list[RecipeTimelineEventOut] = []
|
||||
for event_data in events_data:
|
||||
params: dict = {"queryFilter": f"recipe_id={event_data['recipe_id']}"}
|
||||
event_response = api_client.post(
|
||||
api_routes.recipes_timeline_events, params=params, json=event_data, headers=unique_user.token
|
||||
api_routes.recipes_timeline_events, params=params, json=event_data, headers=user.token
|
||||
)
|
||||
events.append(RecipeTimelineEventOut.model_validate(event_response.json()))
|
||||
|
||||
# check that we see them all
|
||||
params = {"page": 1, "perPage": -1}
|
||||
|
||||
events_response = api_client.get(api_routes.recipes_timeline_events, params=params, headers=unique_user.token)
|
||||
events_response = api_client.get(api_routes.recipes_timeline_events, params=params, headers=user.token)
|
||||
events_pagination = RecipeTimelineEventPagination.model_validate(events_response.json())
|
||||
|
||||
event_ids = [event.id for event in events]
|
||||
|
@ -93,12 +113,20 @@ def test_get_all_timeline_events(api_client: TestClient, unique_user: TestUser,
|
|||
assert event_id in paginated_event_ids
|
||||
|
||||
|
||||
def test_get_timeline_event(api_client: TestClient, unique_user: TestUser, recipes: list[Recipe]):
|
||||
@pytest.mark.parametrize("use_other_household_user", [True, False])
|
||||
def test_get_timeline_event(
|
||||
api_client: TestClient,
|
||||
unique_user: TestUser,
|
||||
recipes: list[Recipe],
|
||||
h2_user: TestUser,
|
||||
use_other_household_user: bool,
|
||||
):
|
||||
user = h2_user if use_other_household_user else unique_user
|
||||
# create an event
|
||||
recipe = recipes[0]
|
||||
new_event_data = {
|
||||
"recipe_id": str(recipe.id),
|
||||
"user_id": str(unique_user.user_id),
|
||||
"user_id": str(user.user_id),
|
||||
"subject": random_string(),
|
||||
"event_type": "info",
|
||||
"message": random_string(),
|
||||
|
@ -107,19 +135,27 @@ def test_get_timeline_event(api_client: TestClient, unique_user: TestUser, recip
|
|||
event_response = api_client.post(
|
||||
api_routes.recipes_timeline_events,
|
||||
json=new_event_data,
|
||||
headers=unique_user.token,
|
||||
headers=user.token,
|
||||
)
|
||||
new_event = RecipeTimelineEventOut.model_validate(event_response.json())
|
||||
|
||||
# fetch the new event
|
||||
event_response = api_client.get(api_routes.recipes_timeline_events_item_id(new_event.id), headers=unique_user.token)
|
||||
event_response = api_client.get(api_routes.recipes_timeline_events_item_id(new_event.id), headers=user.token)
|
||||
assert event_response.status_code == 200
|
||||
|
||||
event = RecipeTimelineEventOut.model_validate(event_response.json())
|
||||
assert event == new_event
|
||||
|
||||
|
||||
def test_update_timeline_event(api_client: TestClient, unique_user: TestUser, recipes: list[Recipe]):
|
||||
@pytest.mark.parametrize("use_other_household_user", [True, False])
|
||||
def test_update_timeline_event(
|
||||
api_client: TestClient,
|
||||
unique_user: TestUser,
|
||||
recipes: list[Recipe],
|
||||
h2_user: TestUser,
|
||||
use_other_household_user: bool,
|
||||
):
|
||||
user = h2_user if use_other_household_user else unique_user
|
||||
old_subject = random_string()
|
||||
new_subject = random_string()
|
||||
|
||||
|
@ -127,12 +163,12 @@ def test_update_timeline_event(api_client: TestClient, unique_user: TestUser, re
|
|||
recipe = recipes[0]
|
||||
new_event_data = {
|
||||
"recipe_id": str(recipe.id),
|
||||
"user_id": str(unique_user.user_id),
|
||||
"user_id": str(user.user_id),
|
||||
"subject": old_subject,
|
||||
"event_type": "info",
|
||||
}
|
||||
|
||||
event_response = api_client.post(api_routes.recipes_timeline_events, json=new_event_data, headers=unique_user.token)
|
||||
event_response = api_client.post(api_routes.recipes_timeline_events, json=new_event_data, headers=user.token)
|
||||
new_event = RecipeTimelineEventOut.model_validate(event_response.json())
|
||||
assert new_event.subject == old_subject
|
||||
|
||||
|
@ -142,7 +178,7 @@ def test_update_timeline_event(api_client: TestClient, unique_user: TestUser, re
|
|||
event_response = api_client.put(
|
||||
api_routes.recipes_timeline_events_item_id(new_event.id),
|
||||
json=updated_event_data,
|
||||
headers=unique_user.token,
|
||||
headers=user.token,
|
||||
)
|
||||
assert event_response.status_code == 200
|
||||
|
||||
|
@ -152,42 +188,54 @@ def test_update_timeline_event(api_client: TestClient, unique_user: TestUser, re
|
|||
assert updated_event.timestamp == new_event.timestamp
|
||||
|
||||
|
||||
def test_delete_timeline_event(api_client: TestClient, unique_user: TestUser, recipes: list[Recipe]):
|
||||
@pytest.mark.parametrize("use_other_household_user", [True, False])
|
||||
def test_delete_timeline_event(
|
||||
api_client: TestClient,
|
||||
unique_user: TestUser,
|
||||
recipes: list[Recipe],
|
||||
h2_user: TestUser,
|
||||
use_other_household_user: bool,
|
||||
):
|
||||
user = h2_user if use_other_household_user else unique_user
|
||||
# create an event
|
||||
recipe = recipes[0]
|
||||
new_event_data = {
|
||||
"recipe_id": str(recipe.id),
|
||||
"user_id": str(unique_user.user_id),
|
||||
"user_id": str(user.user_id),
|
||||
"subject": random_string(),
|
||||
"event_type": "info",
|
||||
"message": random_string(),
|
||||
}
|
||||
|
||||
event_response = api_client.post(api_routes.recipes_timeline_events, json=new_event_data, headers=unique_user.token)
|
||||
event_response = api_client.post(api_routes.recipes_timeline_events, json=new_event_data, headers=user.token)
|
||||
new_event = RecipeTimelineEventOut.model_validate(event_response.json())
|
||||
|
||||
# delete the event
|
||||
event_response = api_client.delete(
|
||||
api_routes.recipes_timeline_events_item_id(new_event.id), headers=unique_user.token
|
||||
)
|
||||
event_response = api_client.delete(api_routes.recipes_timeline_events_item_id(new_event.id), headers=user.token)
|
||||
assert event_response.status_code == 200
|
||||
|
||||
deleted_event = RecipeTimelineEventOut.model_validate(event_response.json())
|
||||
assert deleted_event.id == new_event.id
|
||||
|
||||
# try to get the event
|
||||
event_response = api_client.get(
|
||||
api_routes.recipes_timeline_events_item_id(deleted_event.id), headers=unique_user.token
|
||||
)
|
||||
event_response = api_client.get(api_routes.recipes_timeline_events_item_id(deleted_event.id), headers=user.token)
|
||||
assert event_response.status_code == 404
|
||||
|
||||
|
||||
def test_timeline_event_message_alias(api_client: TestClient, unique_user: TestUser, recipes: list[Recipe]):
|
||||
@pytest.mark.parametrize("use_other_household_user", [True, False])
|
||||
def test_timeline_event_message_alias(
|
||||
api_client: TestClient,
|
||||
unique_user: TestUser,
|
||||
recipes: list[Recipe],
|
||||
h2_user: TestUser,
|
||||
use_other_household_user: bool,
|
||||
):
|
||||
user = h2_user if use_other_household_user else unique_user
|
||||
# create an event using aliases
|
||||
recipe = recipes[0]
|
||||
new_event_data = {
|
||||
"recipeId": str(recipe.id),
|
||||
"userId": str(unique_user.user_id),
|
||||
"userId": str(user.user_id),
|
||||
"subject": random_string(),
|
||||
"eventType": "info",
|
||||
"eventMessage": random_string(), # eventMessage is the correct alias for the message
|
||||
|
@ -196,7 +244,7 @@ def test_timeline_event_message_alias(api_client: TestClient, unique_user: TestU
|
|||
event_response = api_client.post(
|
||||
api_routes.recipes_timeline_events,
|
||||
json=new_event_data,
|
||||
headers=unique_user.token,
|
||||
headers=user.token,
|
||||
)
|
||||
new_event = RecipeTimelineEventOut.model_validate(event_response.json())
|
||||
assert str(new_event.user_id) == new_event_data["userId"]
|
||||
|
@ -204,7 +252,7 @@ def test_timeline_event_message_alias(api_client: TestClient, unique_user: TestU
|
|||
assert new_event.message == new_event_data["eventMessage"]
|
||||
|
||||
# fetch the new event
|
||||
event_response = api_client.get(api_routes.recipes_timeline_events_item_id(new_event.id), headers=unique_user.token)
|
||||
event_response = api_client.get(api_routes.recipes_timeline_events_item_id(new_event.id), headers=user.token)
|
||||
assert event_response.status_code == 200
|
||||
|
||||
event = RecipeTimelineEventOut.model_validate(event_response.json())
|
||||
|
@ -218,7 +266,7 @@ def test_timeline_event_message_alias(api_client: TestClient, unique_user: TestU
|
|||
event_response = api_client.put(
|
||||
api_routes.recipes_timeline_events_item_id(new_event.id),
|
||||
json=updated_event_data,
|
||||
headers=unique_user.token,
|
||||
headers=user.token,
|
||||
)
|
||||
assert event_response.status_code == 200
|
||||
|
||||
|
@ -227,20 +275,27 @@ def test_timeline_event_message_alias(api_client: TestClient, unique_user: TestU
|
|||
assert updated_event.message == new_message
|
||||
|
||||
|
||||
@pytest.mark.parametrize("use_other_household_user", [True, False])
|
||||
def test_timeline_event_update_image(
|
||||
api_client: TestClient, unique_user: TestUser, recipes: list[Recipe], test_image_jpg: str
|
||||
api_client: TestClient,
|
||||
unique_user: TestUser,
|
||||
recipes: list[Recipe],
|
||||
test_image_jpg: str,
|
||||
h2_user: TestUser,
|
||||
use_other_household_user: bool,
|
||||
):
|
||||
user = h2_user if use_other_household_user else unique_user
|
||||
# create an event
|
||||
recipe = recipes[0]
|
||||
new_event_data = {
|
||||
"recipe_id": str(recipe.id),
|
||||
"user_id": str(unique_user.user_id),
|
||||
"user_id": str(user.user_id),
|
||||
"subject": random_string(),
|
||||
"message": random_string(),
|
||||
"event_type": "info",
|
||||
}
|
||||
|
||||
event_response = api_client.post(api_routes.recipes_timeline_events, json=new_event_data, headers=unique_user.token)
|
||||
event_response = api_client.post(api_routes.recipes_timeline_events, json=new_event_data, headers=user.token)
|
||||
new_event = RecipeTimelineEventOut.model_validate(event_response.json())
|
||||
assert new_event.image == TimelineEventImage.does_not_have_image.value
|
||||
|
||||
|
@ -249,7 +304,7 @@ def test_timeline_event_update_image(
|
|||
api_routes.recipes_timeline_events_item_id_image(new_event.id),
|
||||
files={"image": ("test_image_jpg.jpg", f, "image/jpeg")},
|
||||
data={"extension": "jpg"},
|
||||
headers=unique_user.token,
|
||||
headers=user.token,
|
||||
)
|
||||
r.raise_for_status()
|
||||
|
||||
|
@ -258,7 +313,7 @@ def test_timeline_event_update_image(
|
|||
|
||||
event_response = api_client.get(
|
||||
api_routes.recipes_timeline_events_item_id(new_event.id),
|
||||
headers=unique_user.token,
|
||||
headers=user.token,
|
||||
)
|
||||
assert event_response.status_code == 200
|
||||
|
||||
|
@ -269,23 +324,35 @@ def test_timeline_event_update_image(
|
|||
assert updated_event.image == TimelineEventImage.has_image.value
|
||||
|
||||
|
||||
def test_create_recipe_with_timeline_event(api_client: TestClient, unique_user: TestUser, recipes: list[Recipe]):
|
||||
@pytest.mark.parametrize("use_other_household_user", [True, False])
|
||||
def test_create_recipe_with_timeline_event(
|
||||
api_client: TestClient,
|
||||
unique_user: TestUser,
|
||||
recipes: list[Recipe],
|
||||
h2_user: TestUser,
|
||||
use_other_household_user: bool,
|
||||
):
|
||||
user = h2_user if use_other_household_user else unique_user
|
||||
# make sure when the recipes fixture was created that all recipes have at least one event
|
||||
for recipe in recipes:
|
||||
params = {"queryFilter": f"recipe_id={recipe.id}"}
|
||||
events_response = api_client.get(api_routes.recipes_timeline_events, params=params, headers=unique_user.token)
|
||||
events_response = api_client.get(api_routes.recipes_timeline_events, params=params, headers=user.token)
|
||||
events_pagination = RecipeTimelineEventPagination.model_validate(events_response.json())
|
||||
assert events_pagination.items
|
||||
|
||||
|
||||
def test_invalid_recipe_id(api_client: TestClient, unique_user: TestUser):
|
||||
@pytest.mark.parametrize("use_other_household_user", [True, False])
|
||||
def test_invalid_recipe_id(
|
||||
api_client: TestClient, unique_user: TestUser, h2_user: TestUser, use_other_household_user: bool
|
||||
):
|
||||
user = h2_user if use_other_household_user else unique_user
|
||||
new_event_data = {
|
||||
"recipe_id": str(uuid4()),
|
||||
"user_id": str(unique_user.user_id),
|
||||
"user_id": str(user.user_id),
|
||||
"subject": random_string(),
|
||||
"event_type": "info",
|
||||
"message": random_string(),
|
||||
}
|
||||
|
||||
event_response = api_client.post(api_routes.recipes_timeline_events, json=new_event_data, headers=unique_user.token)
|
||||
event_response = api_client.post(api_routes.recipes_timeline_events, json=new_event_data, headers=user.token)
|
||||
assert event_response.status_code == 404
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue