package com.recipeapp.common; import com.recipeapp.recipe.HouseholdResolver; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.method.HandlerMethod; import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; @ExtendWith(MockitoExtension.class) class HouseholdRoleInterceptorTest { @Mock private HouseholdResolver householdResolver; @Mock private HttpServletRequest request; @Mock private HttpServletResponse response; @InjectMocks private HouseholdRoleInterceptor interceptor; @AfterEach void clearContext() { SecurityContextHolder.clearContext(); } private void authenticateAs(String email) { SecurityContextHolder.getContext().setAuthentication( new UsernamePasswordAuthenticationToken(email, null)); } @Test void shouldAllowWhenUserHasRequiredRole() throws Exception { authenticateAs("planner@example.com"); when(householdResolver.resolveRole("planner@example.com")).thenReturn("planner"); var handlerMethod = mock(HandlerMethod.class); var annotation = mock(RequiresHouseholdRole.class); when(annotation.value()).thenReturn("planner"); when(handlerMethod.getMethodAnnotation(RequiresHouseholdRole.class)).thenReturn(annotation); boolean result = interceptor.preHandle(request, response, handlerMethod); assertThat(result).isTrue(); } @Test void shouldThrowForbiddenWhenUserLacksRequiredRole() { authenticateAs("member@example.com"); when(householdResolver.resolveRole("member@example.com")).thenReturn("member"); var handlerMethod = mock(HandlerMethod.class); var annotation = mock(RequiresHouseholdRole.class); when(annotation.value()).thenReturn("planner"); when(handlerMethod.getMethodAnnotation(RequiresHouseholdRole.class)).thenReturn(annotation); assertThatThrownBy(() -> interceptor.preHandle(request, response, handlerMethod)) .isInstanceOf(ForbiddenException.class) .hasMessage("Insufficient permissions"); } @Test void shouldPassThroughWhenNoAnnotation() throws Exception { var handlerMethod = mock(HandlerMethod.class); when(handlerMethod.getMethodAnnotation(RequiresHouseholdRole.class)).thenReturn(null); boolean result = interceptor.preHandle(request, response, handlerMethod); assertThat(result).isTrue(); } @Test void shouldPassThroughWhenNotHandlerMethod() throws Exception { boolean result = interceptor.preHandle(request, response, new Object()); assertThat(result).isTrue(); } }