diff --git a/lastleg-service/src/test/java/com/baiyue/lastleg/fleet/trip/FleetTripApiContractTest.java b/lastleg-service/src/test/java/com/baiyue/lastleg/fleet/trip/FleetTripApiContractTest.java index faddeed17..7fdff6ed5 100644 --- a/lastleg-service/src/test/java/com/baiyue/lastleg/fleet/trip/FleetTripApiContractTest.java +++ b/lastleg-service/src/test/java/com/baiyue/lastleg/fleet/trip/FleetTripApiContractTest.java @@ -46,7 +46,7 @@ class FleetTripApiContractTest { count++; } } - assertThat(count).isEqualTo(52); + assertThat(count).isEqualTo(53); verifyRefs(document, document); verifyRefs(preparation, preparation); verifyRefs(pool, pool); diff --git a/lastleg-service/src/test/java/com/baiyue/lastleg/fleet/trip/FleetTripAuthorizationTest.java b/lastleg-service/src/test/java/com/baiyue/lastleg/fleet/trip/FleetTripAuthorizationTest.java index a7e68abb8..a3d714739 100644 --- a/lastleg-service/src/test/java/com/baiyue/lastleg/fleet/trip/FleetTripAuthorizationTest.java +++ b/lastleg-service/src/test/java/com/baiyue/lastleg/fleet/trip/FleetTripAuthorizationTest.java @@ -12,6 +12,24 @@ import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; class FleetTripAuthorizationTest { + @Test void calendarRequiresTripReadPermissionThroughMethodSecurity() { + try (var context = new AnnotationConfigApplicationContext(Config.class)) { + var controller = context.getBean(PlatformFleetTripController.class); + var calendar = context.getBean(FleetTripCalendarService.class); + var from = java.time.Instant.parse("2026-10-01T00:00:00Z"); + var to = from.plusSeconds(86400); + var user = new com.baiyue.common.security.AuthenticatedUser(1L, 0L, 0L, 1L, + "platform", "PLATFORM", "WEB", java.util.Set.of("platform:fleet:trip:list")); + SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken( + user, "unused", List.of(new SimpleGrantedAuthority("platform:appointment:list")))); + assertThatThrownBy(() -> controller.calendar(user, from, to)).isInstanceOf(AccessDeniedException.class); + verifyNoInteractions(calendar); + SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken( + user, "unused", List.of(new SimpleGrantedAuthority("platform:fleet:trip:list")))); + controller.calendar(user, from, to); + verify(calendar).calendar(from, to); + } finally { SecurityContextHolder.clearContext(); } + } @Test void bookingQuoteCandidatesRequireBothTripAndQuoteReadPermissions() { try(var context=new AnnotationConfigApplicationContext(Config.class)) { var controller=context.getBean(PlatformFleetBookingController.class); @@ -69,6 +87,7 @@ class FleetTripAuthorizationTest { } @Configuration @EnableMethodSecurity static class Config { + @Bean FleetTripCalendarService calendar() { return mock(FleetTripCalendarService.class); } @Bean FleetCapacityOfferCommandMapper commands() { return mock(FleetCapacityOfferCommandMapper.class); } @Bean FleetDispatchPlanningGateway planning() { return mock(FleetDispatchPlanningGateway.class); } @Bean FleetTripPreparationService preparation() { return mock(FleetTripPreparationService.class); }