Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Bulk Update Owner Removes Some Recipe Data #4393

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions frontend/lib/api/user/recipes/recipe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,10 @@ export class RecipeAPI extends BaseCRUDAPI<CreateRecipe, Recipe, Recipe> {
return await this.requests.put<Recipe[]>(routes.recipesBase, payload);
}

async patchMany(payload: Recipe[]) {
return await this.requests.patch<Recipe[]>(routes.recipesBase, payload);
}

async updateLastMade(recipeSlug: string, timestamp: string) {
return await this.requests.patch<Recipe, RecipeLastMade>(routes.recipesSlugLastMade(recipeSlug), { timestamp })
}
Expand Down
2 changes: 1 addition & 1 deletion frontend/pages/group/data/recipes.vue
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ export default defineComponent({
});

loading.value = true;
await api.recipes.updateMany(selected.value);
await api.recipes.patchMany(selected.value);

await refreshRecipes();
resetAll();
Expand Down
25 changes: 25 additions & 0 deletions mealie/routes/recipe/recipe_crud_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,31 @@ def patch_one(self, slug: str, data: Recipe):

return recipe

@router.patch("")
def patch_many(self, data: list[Recipe]):
updated_by_group_and_household: defaultdict[UUID4, defaultdict[UUID4, list[Recipe]]] = defaultdict(
lambda: defaultdict(list)
)
for recipe in data:
r = self.service.patch_one(recipe.id, recipe) # type: ignore
updated_by_group_and_household[r.group_id][r.household_id].append(r)

all_updated: list[Recipe] = []
if updated_by_group_and_household:
for group_id, household_dict in updated_by_group_and_household.items():
for household_id, updated_recipes in household_dict.items():
all_updated.extend(updated_recipes)
self.publish_event(
event_type=EventTypes.recipe_updated,
document_data=EventRecipeBulkData(
operation=EventOperation.update, recipe_slugs=[r.slug for r in updated_recipes]
),
group_id=group_id,
household_id=household_id,
)

return all_updated

@router.patch("/{slug}/last-made")
def update_last_made(self, slug: str, data: RecipeLastMade):
"""Update a recipe's last made timestamp"""
Expand Down
9 changes: 7 additions & 2 deletions tests/integration_tests/user_recipe_tests/test_recipe_crud.py
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like we expect a different end result from patch, compared to put. Could be good to add validation of that difference in the test?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately this is a frontend issue, not backend, so I can't really write a test for it. The frontend is sending a valid payload to the backend, which is accepted. It's just missing data

Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,8 @@ def test_read_update(
assert cats[0]["name"] in test_name


def test_update_many(api_client: TestClient, unique_user: TestUser):
@pytest.mark.parametrize("use_patch", [True, False])
def test_update_many(api_client: TestClient, unique_user: TestUser, use_patch: bool):
recipe_slugs = [random_string() for _ in range(3)]
for slug in recipe_slugs:
api_client.post(api_routes.recipes, json={"name": slug}, headers=unique_user.token)
Expand All @@ -498,7 +499,11 @@ def test_update_many(api_client: TestClient, unique_user: TestUser):
recipe_data["name"] = new_slug_by_id[recipe_data["id"]]
recipe_data["slug"] = new_slug_by_id[recipe_data["id"]]

response = api_client.put(api_routes.recipes, json=recipes_data, headers=unique_user.token)
if use_patch:
api_client_func = api_client.patch
else:
api_client_func = api_client.put
response = api_client_func(api_routes.recipes, json=recipes_data, headers=unique_user.token)
assert response.status_code == 200
for updated_recipe_data in response.json():
assert updated_recipe_data["slug"] == new_slug_by_id[updated_recipe_data["id"]]
Expand Down
Loading