From c26c2e1973b85e8c3c6714d7463e0b1593d55145 Mon Sep 17 00:00:00 2001 From: Marcel Raddatz Date: Sat, 4 Apr 2026 18:30:41 +0200 Subject: [PATCH] feat(shopping): add getByWeekStart to ShoppingService Returns the shopping list for a given week, defaulting to the current week's Monday when no weekStart is provided. Returns null when no list exists. Co-Authored-By: Claude Sonnet 4.6 --- .../recipeapp/shopping/ShoppingService.java | 17 +++++++- .../shopping/ShoppingServiceTest.java | 40 +++++++++++++++++++ 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/backend/src/main/java/com/recipeapp/shopping/ShoppingService.java b/backend/src/main/java/com/recipeapp/shopping/ShoppingService.java index ab33398..26d16cb 100644 --- a/backend/src/main/java/com/recipeapp/shopping/ShoppingService.java +++ b/backend/src/main/java/com/recipeapp/shopping/ShoppingService.java @@ -18,10 +18,11 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; +import java.time.DayOfWeek; +import java.time.LocalDate; +import java.time.temporal.TemporalAdjusters; import java.util.*; import java.util.stream.Collectors; -import java.util.Set; -import java.util.Map; @Service @Transactional @@ -52,6 +53,18 @@ public class ShoppingService { } + @Transactional(readOnly = true) + public ShoppingListResponse getByWeekStart(UUID householdId, LocalDate weekStart) { + if (weekStart == null) { + weekStart = LocalDate.now().with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)); + } + + return shoppingListRepository.findByHouseholdIdAndWeekPlanWeekStart(householdId, weekStart) + .map(this::toResponse) + .orElse(null); + } + + public ShoppingListResponse generateFromPlan(UUID householdId, UUID weekPlanId) { WeekPlan weekPlan = weekPlanRepository.findById(weekPlanId) .orElseThrow(() -> new ResourceNotFoundException("Week plan not found")); diff --git a/backend/src/test/java/com/recipeapp/shopping/ShoppingServiceTest.java b/backend/src/test/java/com/recipeapp/shopping/ShoppingServiceTest.java index e374c07..d5ce705 100644 --- a/backend/src/test/java/com/recipeapp/shopping/ShoppingServiceTest.java +++ b/backend/src/test/java/com/recipeapp/shopping/ShoppingServiceTest.java @@ -92,6 +92,46 @@ class ShoppingServiceTest { } catch (Exception e) { throw new RuntimeException(e); } } + // ── Get by week start ── + + @Test + void getByWeekStartShouldReturnListForGivenWeek() { + var household = testHousehold(); + var plan = testWeekPlan(household); + var list = testShoppingList(household, plan); + + when(shoppingListRepository.findByHouseholdIdAndWeekPlanWeekStart(HOUSEHOLD_ID, WEEK_START)) + .thenReturn(Optional.of(list)); + + ShoppingListResponse result = shoppingService.getByWeekStart(HOUSEHOLD_ID, WEEK_START); + + assertThat(result.id()).isEqualTo(list.getId()); + } + + @Test + void getByWeekStartShouldDefaultToCurrentWeekWhenNull() { + var household = testHousehold(); + var plan = testWeekPlan(household); + var list = testShoppingList(household, plan); + + when(shoppingListRepository.findByHouseholdIdAndWeekPlanWeekStart(eq(HOUSEHOLD_ID), any(LocalDate.class))) + .thenReturn(Optional.of(list)); + + ShoppingListResponse result = shoppingService.getByWeekStart(HOUSEHOLD_ID, null); + + assertThat(result).isNotNull(); + } + + @Test + void getByWeekStartShouldReturnNullWhenNoListExists() { + when(shoppingListRepository.findByHouseholdIdAndWeekPlanWeekStart(HOUSEHOLD_ID, WEEK_START)) + .thenReturn(Optional.empty()); + + ShoppingListResponse result = shoppingService.getByWeekStart(HOUSEHOLD_ID, WEEK_START); + + assertThat(result).isNull(); + } + // ── Generate ── @Test