44import org .locationtech .jts .geom .Coordinate ;
55import org .locationtech .jts .geom .GeometryFactory ;
66import org .locationtech .jts .geom .LinearRing ;
7+ import org .locationtech .jts .geom .MultiPolygon ;
78import org .locationtech .jts .geom .Point ;
89import org .locationtech .jts .geom .Polygon ;
910import org .rutebanken .tiamat .exporter .params .TopographicPlaceSearch ;
@@ -52,6 +53,18 @@ class FintrafficAuthorizationServiceTest {
5253 return place ;
5354 }
5455
56+ private static @ Nonnull TopographicPlace getMunicipalityTopographicPlace (String municipalityCode ,
57+ Coordinate [] coordinates ) {
58+ TopographicPlace place = new TopographicPlace ();
59+ GeometryFactory fact = new GeometryFactory ();
60+ LinearRing ring = fact .createLinearRing (coordinates );
61+ Polygon polygon = new Polygon (ring , null , fact );
62+ place .setMultiSurface (new MultiPolygon (new Polygon []{polygon }, fact ));
63+ place .setTopographicPlaceType (TopographicPlaceTypeEnumeration .MUNICIPALITY );
64+ place .setPrivateCode (new org .rutebanken .tiamat .model .PrivateCodeStructure (municipalityCode , "type" ));
65+ return place ;
66+ }
67+
5568 private static @ Nonnull Point getPoint (Coordinate coordinate ) {
5669 GeometryFactory fact = new GeometryFactory ();
5770 return fact .createPoint (coordinate );
@@ -80,12 +93,25 @@ class FintrafficAuthorizationServiceTest {
8093 }
8194
8295 private static FintrafficAuthorizationService getAuthorizationService () {
96+ return getAuthorizationService (true , true );
97+ }
98+
99+ private static FintrafficAuthorizationService getAuthorizationService (boolean codespaceEnabled , boolean municipalityEnabled ) {
83100 TopographicPlaceRepository topographicPlaceRepositoryMock = mock (TopographicPlaceRepository .class );
84101 TrivoreAuthorizations trivoreAuthorizationsMock = mock (TrivoreAuthorizations .class );
85102
86- TopographicPlace place = getTopographicPlace ();
87- when (topographicPlaceRepositoryMock .findTopographicPlace (any (TopographicPlaceSearch .class ))).thenReturn (List .of (place ));
103+ TopographicPlace regionPlace = getTopographicPlace ();
104+ TopographicPlace municipalityPlace = getMunicipalityTopographicPlace ("091" , new Coordinate [] {
105+ new Coordinate (2 , 2 ),
106+ new Coordinate (3 , 2 ),
107+ new Coordinate (3 , 3 ),
108+ new Coordinate (2 , 3 ),
109+ new Coordinate (2 , 2 ),
110+ });
111+ when (topographicPlaceRepositoryMock .findTopographicPlace (any (TopographicPlaceSearch .class )))
112+ .thenReturn (List .of (regionPlace , municipalityPlace ));
88113 when (trivoreAuthorizationsMock .getAccessibleCodespaces ()).thenReturn (Set .of ("ABC" , "XYZ" ));
114+ when (trivoreAuthorizationsMock .getAccessibleMunicipalityCodes ()).thenReturn (Set .of ("091" ));
89115
90116 when (trivoreAuthorizationsMock .hasAccess (matches ("StopPlace" ), matches ("BUS" ), eq (TrivorePermission .MANAGE ), anyBoolean ())).thenReturn (true );
91117 when (trivoreAuthorizationsMock .hasAccess (matches ("Parking" ), matches ("\\ {all\\ }" ), eq (TrivorePermission .MANAGE ), anyBoolean ())).thenReturn (true );
@@ -94,7 +120,9 @@ private static FintrafficAuthorizationService getAuthorizationService() {
94120
95121 return new FintrafficAuthorizationService (
96122 trivoreAuthorizationsMock ,
97- topographicPlaceRepositoryMock
123+ topographicPlaceRepositoryMock ,
124+ codespaceEnabled ,
125+ municipalityEnabled
98126 );
99127 }
100128
@@ -153,4 +181,58 @@ public void testCanEditStopPlaceWithNestedEntitiesNotAllowed() {
153181 FintrafficAuthorizationService authorizationService = getAuthorizationService ();
154182 assertThat (authorizationService .canEditEntity (stopPlaceWithQuayAndNestedStopPlace ), equalTo (false ));
155183 }
184+
185+ @ Test
186+ public void testCanEditEntityByMunicipalityCodes () {
187+ // Point (2.5, 2.5) is inside municipality polygon (2,2)-(3,3) but outside region polygon (0,0)-(1,1)
188+ StopPlace stopPlace = getStopPlace ("FSR:StopPlace:10" , VehicleModeEnumeration .BUS , getPoint (new Coordinate (2.5 , 2.5 )));
189+ FintrafficAuthorizationService authorizationService = getAuthorizationService ();
190+ assertThat (authorizationService .canEditEntity (stopPlace ), equalTo (true ));
191+ }
192+
193+ @ Test
194+ public void testCanEditEntityByMunicipalityCodesOutOfBounds () {
195+ // Point (5, 5) is outside both region and municipality polygons
196+ StopPlace stopPlace = getStopPlace ("FSR:StopPlace:11" , VehicleModeEnumeration .BUS , getPoint (new Coordinate (5 , 5 )));
197+ FintrafficAuthorizationService authorizationService = getAuthorizationService ();
198+ assertThat (authorizationService .canEditEntity (stopPlace ), equalTo (false ));
199+ }
200+
201+ @ Test
202+ public void testCanEditEntityByEitherCodespaceOrMunicipality () {
203+ // Point (0.5, 0.5) is inside region polygon — should pass via codespace check
204+ StopPlace stopPlaceInRegion = getStopPlace ("FSR:StopPlace:12" , VehicleModeEnumeration .BUS , getPoint (new Coordinate (0.5 , 0.5 )));
205+ // Point (2.5, 2.5) is inside municipality polygon — should pass via municipality check
206+ StopPlace stopPlaceInMunicipality = getStopPlace ("FSR:StopPlace:13" , VehicleModeEnumeration .BUS , getPoint (new Coordinate (2.5 , 2.5 )));
207+
208+ FintrafficAuthorizationService authorizationService = getAuthorizationService ();
209+ assertThat (authorizationService .canEditEntity (stopPlaceInRegion ), equalTo (true ));
210+ assertThat (authorizationService .canEditEntity (stopPlaceInMunicipality ), equalTo (true ));
211+ }
212+
213+ @ Test
214+ public void testCodespaceOnlyMode () {
215+ FintrafficAuthorizationService authorizationService = getAuthorizationService (true , false );
216+ // Point inside region (codespace) — allowed
217+ assertThat (authorizationService .canEditEntity (getPoint (new Coordinate (0.5 , 0.5 ))), equalTo (true ));
218+ // Point inside municipality area but municipality auth disabled — denied
219+ assertThat (authorizationService .canEditEntity (getPoint (new Coordinate (2.5 , 2.5 ))), equalTo (false ));
220+ }
221+
222+ @ Test
223+ public void testMunicipalityOnlyMode () {
224+ FintrafficAuthorizationService authorizationService = getAuthorizationService (false , true );
225+ // Point inside region but codespace auth disabled — denied
226+ assertThat (authorizationService .canEditEntity (getPoint (new Coordinate (0.5 , 0.5 ))), equalTo (false ));
227+ // Point inside municipality area — allowed
228+ assertThat (authorizationService .canEditEntity (getPoint (new Coordinate (2.5 , 2.5 ))), equalTo (true ));
229+ }
230+
231+ @ Test
232+ public void testBothAuthorizationMethodsDisabled () {
233+ FintrafficAuthorizationService authorizationService = getAuthorizationService (false , false );
234+ // Both disabled — all geographic edits denied
235+ assertThat (authorizationService .canEditEntity (getPoint (new Coordinate (0.5 , 0.5 ))), equalTo (false ));
236+ assertThat (authorizationService .canEditEntity (getPoint (new Coordinate (2.5 , 2.5 ))), equalTo (false ));
237+ }
156238}
0 commit comments