88import org .locationtech .jts .geom .Point ;
99import org .locationtech .jts .geom .Polygon ;
1010import org .rutebanken .tiamat .exporter .params .TopographicPlaceSearch ;
11+ import org .rutebanken .tiamat .model .GroupOfStopPlaces ;
1112import org .rutebanken .tiamat .model .Parking ;
1213import org .rutebanken .tiamat .model .Quay ;
1314import org .rutebanken .tiamat .model .StopPlace ;
2425
2526import static org .hamcrest .MatcherAssert .assertThat ;
2627import static org .hamcrest .Matchers .equalTo ;
27- import static org .mockito .AdditionalMatchers .not ;
2828import static org .mockito .ArgumentMatchers .any ;
2929import static org .mockito .ArgumentMatchers .anyBoolean ;
30- import static org .mockito .ArgumentMatchers .anyString ;
3130import static org .mockito .ArgumentMatchers .eq ;
3231import static org .mockito .ArgumentMatchers .matches ;
3332import static org .mockito .Mockito .mock ;
@@ -93,10 +92,14 @@ class FintrafficAuthorizationServiceTest {
9392 }
9493
9594 private static FintrafficAuthorizationService getAuthorizationService () {
96- return getAuthorizationService (true , true );
95+ return getAuthorizationService (true , true , false );
9796 }
9897
99- private static FintrafficAuthorizationService getAuthorizationService (boolean codespaceEnabled , boolean municipalityEnabled ) {
98+ private static FintrafficAuthorizationService getAuthorizationService (
99+ boolean codespaceEnabled ,
100+ boolean municipalityEnabled ,
101+ boolean multiModalStopPlaceSupportDisabled
102+ ) {
100103 TopographicPlaceRepository topographicPlaceRepositoryMock = mock (TopographicPlaceRepository .class );
101104 TrivoreAuthorizations trivoreAuthorizationsMock = mock (TrivoreAuthorizations .class );
102105
@@ -117,12 +120,14 @@ private static FintrafficAuthorizationService getAuthorizationService(boolean co
117120 when (trivoreAuthorizationsMock .hasAccess (matches ("Parking" ), matches ("\\ {all\\ }" ), eq (TrivorePermission .MANAGE ), anyBoolean ())).thenReturn (true );
118121 when (trivoreAuthorizationsMock .hasAccess (matches ("Quay" ), matches ("\\ {all\\ }" ), eq (TrivorePermission .MANAGE ), anyBoolean ())).thenReturn (true );
119122 when (trivoreAuthorizationsMock .hasAccess (matches ("StopPlace" ), matches ("RAIL" ), eq (TrivorePermission .MANAGE ), anyBoolean ())).thenReturn (false );
123+ when (trivoreAuthorizationsMock .hasAccess (matches ("GroupOfStopPlaces" ), matches ("\\ {all\\ }" ), eq (TrivorePermission .MANAGE ), anyBoolean ())).thenReturn (true );
120124
121125 return new FintrafficAuthorizationService (
122126 trivoreAuthorizationsMock ,
123127 topographicPlaceRepositoryMock ,
124128 codespaceEnabled ,
125- municipalityEnabled
129+ municipalityEnabled ,
130+ multiModalStopPlaceSupportDisabled
126131 );
127132 }
128133
@@ -160,6 +165,69 @@ public void testCanEditEntityParking() {
160165 }
161166
162167
168+ @ Test
169+ public void testCanEditParentStopPlaceAllChildTransportModesAllowed () {
170+ // Parent stop place with children that all have allowed transport modes (BUS)
171+ StopPlace parentStopPlace = getStopPlace ("FSR:StopPlace:100" , null , getPoint (new Coordinate (0.3 , 0.3 )));
172+ parentStopPlace .setParentStopPlace (true );
173+ StopPlace child1 = getStopPlace ("FSR:StopPlace:101" , VehicleModeEnumeration .BUS , getPoint (new Coordinate (0.3 , 0.3 )));
174+ StopPlace child2 = getStopPlace ("FSR:StopPlace:102" , VehicleModeEnumeration .BUS , getPoint (new Coordinate (0.4 , 0.4 )));
175+ parentStopPlace .setChildren (Set .of (child1 , child2 ));
176+
177+ FintrafficAuthorizationService authorizationService = getAuthorizationService ();
178+ assertThat (authorizationService .canEditEntity (parentStopPlace ), equalTo (true ));
179+ }
180+
181+ @ Test
182+ public void testCanEditParentStopPlaceChildTransportModeNotAllowed () {
183+ // Parent stop place with a child that has a forbidden transport mode (RAIL)
184+ StopPlace parentStopPlace = getStopPlace ("FSR:StopPlace:200" , null , getPoint (new Coordinate (0.3 , 0.3 )));
185+ parentStopPlace .setParentStopPlace (true );
186+ StopPlace child = getStopPlace ("FSR:StopPlace:201" , VehicleModeEnumeration .RAIL , getPoint (new Coordinate (0.3 , 0.3 )));
187+ parentStopPlace .setChildren (Set .of (child ));
188+
189+ FintrafficAuthorizationService authorizationService = getAuthorizationService ();
190+ assertThat (authorizationService .canEditEntity (parentStopPlace ), equalTo (false ));
191+ }
192+
193+ @ Test
194+ public void testCanNotEditParentStopPlaceMultiModalSupportDisabled () {
195+ // Parent stop place with children that all have allowed transport modes (BUS)
196+ // Multi-modal stop place support is disabled, so parent stop place should not be editable even if child transport mode is allowed
197+ StopPlace parentStopPlace = getStopPlace ("FSR:StopPlace:100" , null , getPoint (new Coordinate (0.3 , 0.3 )));
198+ parentStopPlace .setParentStopPlace (true );
199+ StopPlace child1 = getStopPlace ("FSR:StopPlace:101" , VehicleModeEnumeration .BUS , getPoint (new Coordinate (0.3 , 0.3 )));
200+ StopPlace child2 = getStopPlace ("FSR:StopPlace:102" , VehicleModeEnumeration .BUS , getPoint (new Coordinate (0.4 , 0.4 )));
201+ parentStopPlace .setChildren (Set .of (child1 , child2 ));
202+
203+ FintrafficAuthorizationService authorizationService = getAuthorizationService (true , true , true );
204+ assertThat (authorizationService .canEditEntity (parentStopPlace ), equalTo (false ));
205+ }
206+
207+ @ Test
208+ public void testCanEditParentStopPlaceWithMixedChildTransportModes () {
209+ // Parent stop place with children of mixed transport modes: one allowed (BUS), one denied (RAIL)
210+ StopPlace parentStopPlace = getStopPlace ("FSR:StopPlace:300" , null , getPoint (new Coordinate (0.3 , 0.3 )));
211+ parentStopPlace .setParentStopPlace (true );
212+ StopPlace childBus = getStopPlace ("FSR:StopPlace:301" , VehicleModeEnumeration .BUS , getPoint (new Coordinate (0.3 , 0.3 )));
213+ StopPlace childRail = getStopPlace ("FSR:StopPlace:302" , VehicleModeEnumeration .RAIL , getPoint (new Coordinate (0.4 , 0.4 )));
214+ parentStopPlace .setChildren (Set .of (childBus , childRail ));
215+
216+ FintrafficAuthorizationService authorizationService = getAuthorizationService ();
217+ assertThat (authorizationService .canEditEntity (parentStopPlace ), equalTo (false ));
218+ }
219+
220+ @ Test
221+ public void testCanEditParentStopPlaceWithNoChildren () {
222+ // Parent stop place with no children
223+ StopPlace parentStopPlace = getStopPlace ("FSR:StopPlace:400" , null , getPoint (new Coordinate (0.3 , 0.3 )));
224+ parentStopPlace .setParentStopPlace (true );
225+ parentStopPlace .setChildren (Set .of ());
226+
227+ FintrafficAuthorizationService authorizationService = getAuthorizationService ();
228+ assertThat (authorizationService .canEditEntity (parentStopPlace ), equalTo (false ));
229+ }
230+
163231 @ Test
164232 public void testCanEditStopPlaceWithNestedEntities () {
165233 StopPlace stopPlaceWithQuayAndNestedStopPlace = getStopPlace ("FSR:StopPlace:1" , VehicleModeEnumeration .BUS , getPoint (new Coordinate (0.3 , 0.3 )));
@@ -212,7 +280,7 @@ public void testCanEditEntityByEitherCodespaceOrMunicipality() {
212280
213281 @ Test
214282 public void testCodespaceOnlyMode () {
215- FintrafficAuthorizationService authorizationService = getAuthorizationService (true , false );
283+ FintrafficAuthorizationService authorizationService = getAuthorizationService (true , false , false );
216284 // Point inside region (codespace) — allowed
217285 assertThat (authorizationService .canEditEntity (getPoint (new Coordinate (0.5 , 0.5 ))), equalTo (true ));
218286 // Point inside municipality area but municipality auth disabled — denied
@@ -221,7 +289,7 @@ public void testCodespaceOnlyMode() {
221289
222290 @ Test
223291 public void testMunicipalityOnlyMode () {
224- FintrafficAuthorizationService authorizationService = getAuthorizationService (false , true );
292+ FintrafficAuthorizationService authorizationService = getAuthorizationService (false , true , false );
225293 // Point inside region but codespace auth disabled — denied
226294 assertThat (authorizationService .canEditEntity (getPoint (new Coordinate (0.5 , 0.5 ))), equalTo (false ));
227295 // Point inside municipality area — allowed
@@ -230,9 +298,18 @@ public void testMunicipalityOnlyMode() {
230298
231299 @ Test
232300 public void testBothAuthorizationMethodsDisabled () {
233- FintrafficAuthorizationService authorizationService = getAuthorizationService (false , false );
301+ FintrafficAuthorizationService authorizationService = getAuthorizationService (false , false , false );
234302 // Both disabled — all geographic edits denied
235303 assertThat (authorizationService .canEditEntity (getPoint (new Coordinate (0.5 , 0.5 ))), equalTo (false ));
236304 assertThat (authorizationService .canEditEntity (getPoint (new Coordinate (2.5 , 2.5 ))), equalTo (false ));
237305 }
306+
307+ @ Test
308+ public void testGroupOfStopPlacesEditable () {
309+ GroupOfStopPlaces groupOfStopPlaces = new GroupOfStopPlaces ();
310+ groupOfStopPlaces .setNetexId ("FSR:GroupOfStopPlaces:1" );
311+
312+ FintrafficAuthorizationService authorizationService = getAuthorizationService ();
313+ assertThat (authorizationService .canEditEntity (groupOfStopPlaces ), equalTo (true ));
314+ }
238315}
0 commit comments