diff --git a/backend/src/test/java/com/recipeapp/shopping/ShoppingListControllerTest.java b/backend/src/test/java/com/recipeapp/shopping/ShoppingListControllerTest.java index 95197ab..c19151c 100644 --- a/backend/src/test/java/com/recipeapp/shopping/ShoppingListControllerTest.java +++ b/backend/src/test/java/com/recipeapp/shopping/ShoppingListControllerTest.java @@ -3,8 +3,10 @@ package com.recipeapp.shopping; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.recipeapp.common.GlobalExceptionHandler; +import com.recipeapp.common.HouseholdRoleInterceptor; import com.recipeapp.recipe.HouseholdResolver; import com.recipeapp.shopping.dto.*; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -12,6 +14,8 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.http.MediaType; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; @@ -49,6 +53,11 @@ class ShoppingListControllerTest { .build(); } + @AfterEach + void clearSecurityContext() { + SecurityContextHolder.clearContext(); + } + @Test void getByWeekStartShouldReturn200() throws Exception { var response = new ShoppingListResponse(LIST_ID, PLAN_ID, Instant.now(), 3, List.of()); @@ -169,4 +178,20 @@ class ShoppingListControllerTest { new AddItemRequest(null, " ", new BigDecimal("1"), "")))) .andExpect(status().isBadRequest()); } + + @Test + void generateFromPlanShouldReturn403ForNonPlanner() throws Exception { + SecurityContextHolder.getContext().setAuthentication( + new UsernamePasswordAuthenticationToken("member@example.com", null)); + when(householdResolver.resolveRole("member@example.com")).thenReturn("member"); + + MockMvc mockMvcWithInterceptor = MockMvcBuilders.standaloneSetup(shoppingListController) + .setControllerAdvice(new GlobalExceptionHandler()) + .addInterceptors(new HouseholdRoleInterceptor(householdResolver)) + .build(); + + mockMvcWithInterceptor.perform(post("/v1/week-plans/{id}/shopping-list", PLAN_ID) + .principal(() -> "member@example.com")) + .andExpect(status().isForbidden()); + } }