44import static org .junit .jupiter .api .Assertions .assertArrayEquals ;
55import static org .junit .jupiter .api .Assertions .assertDoesNotThrow ;
66import static org .junit .jupiter .api .Assertions .assertFalse ;
7+ import static org .junit .jupiter .api .Assertions .assertInstanceOf ;
78import static org .junit .jupiter .api .Assertions .assertNotNull ;
89import static org .junit .jupiter .api .Assertions .assertNull ;
910import static org .junit .jupiter .api .Assertions .assertTrue ;
1011
11- import javax .imageio .ImageIO ;
12- import javax .swing .Action ;
13- import javax .swing .ImageIcon ;
14-
1512import java .awt .image .BufferedImage ;
1613import java .io .ByteArrayOutputStream ;
1714import java .io .IOException ;
1815import java .util .ArrayList ;
1916import java .util .HashMap ;
2017import java .util .List ;
2118import java .util .Map ;
22- import java .util .concurrent .ExecutionException ;
2319import java .util .logging .Handler ;
2420import java .util .logging .LogRecord ;
2521import java .util .stream .Collectors ;
2622
27- import org .awaitility .Awaitility ;
28- import org .awaitility .Durations ;
23+ import javax .imageio .ImageIO ;
24+ import javax .swing .Action ;
25+ import javax .swing .ImageIcon ;
26+
27+ import org .junit .jupiter .api .BeforeEach ;
2928import org .junit .jupiter .api .Test ;
29+ import org .junit .jupiter .api .extension .RegisterExtension ;
3030import org .openstreetmap .josm .data .Bounds ;
3131import org .openstreetmap .josm .data .DataSource ;
3232import org .openstreetmap .josm .data .osm .DataSet ;
3333import org .openstreetmap .josm .gui .MainApplication ;
3434import org .openstreetmap .josm .gui .layer .OsmDataLayer ;
35- import org .openstreetmap .josm .gui .util .GuiHelper ;
3635import org .openstreetmap .josm .plugins .mapwithai .backend .MapWithAIDataUtils ;
3736import org .openstreetmap .josm .plugins .mapwithai .backend .MapWithAILayer ;
3837import org .openstreetmap .josm .plugins .mapwithai .data .mapwithai .MapWithAIInfo ;
4140import org .openstreetmap .josm .plugins .mapwithai .testutils .annotations .MapWithAISources ;
4241import org .openstreetmap .josm .plugins .mapwithai .testutils .annotations .NoExceptions ;
4342import org .openstreetmap .josm .testutils .annotations .BasicPreferences ;
43+ import org .openstreetmap .josm .testutils .annotations .BasicWiremock ;
4444import org .openstreetmap .josm .testutils .annotations .Projection ;
45+ import org .openstreetmap .josm .testutils .annotations .ThreadSync ;
4546import org .openstreetmap .josm .tools .ImageProvider ;
4647import org .openstreetmap .josm .tools .Logging ;
4748
4849import com .github .tomakehurst .wiremock .WireMockServer ;
4950import com .github .tomakehurst .wiremock .client .WireMock ;
50- import com .github .tomakehurst .wiremock .core .WireMockConfiguration ;
5151import com .github .tomakehurst .wiremock .matching .AnythingPattern ;
5252import com .github .tomakehurst .wiremock .matching .EqualToPattern ;
5353import com .github .tomakehurst .wiremock .matching .StringValuePattern ;
5454import com .github .tomakehurst .wiremock .matching .UrlPathPattern ;
55+ import jakarta .json .Json ;
5556
5657/**
5758 * Test class for {@link AddMapWithAILayerAction}
6364@ MapWithAISources
6465@ Projection
6566class AddMapWithAILayerActionTest {
66- @ Test
67- void testAddMapWithAILayerActionTest () {
68- MapWithAIInfo info = MapWithAILayerInfo .getInstance ().getLayers ().stream ()
67+
68+ private static class ThreadSyncMWAI extends ThreadSync .ThreadSyncExtension {
69+ public ThreadSyncMWAI () {
70+ this .registerForkJoinPool (MapWithAIDataUtils .getForkJoinPool ());
71+ }
72+ }
73+
74+ @ RegisterExtension
75+ static ThreadSyncMWAI threadSync = new ThreadSyncMWAI ();
76+
77+ @ BasicWiremock
78+ WireMockServer wireMockServer ;
79+
80+ private static MapWithAIInfo info ;
81+ private static MapWithAIInfo backupInfo ;
82+
83+ @ BeforeEach
84+ void setup () {
85+ final Map <String , StringValuePattern > parameterMap = new HashMap <>();
86+ final AnythingPattern anythingPattern = new AnythingPattern ();
87+ parameterMap .put ("geometryType" , anythingPattern );
88+ parameterMap .put ("geometry" , anythingPattern );
89+ parameterMap .put ("inSR" , new EqualToPattern ("4326" ));
90+ parameterMap .put ("f" , new EqualToPattern ("geojson" ));
91+ parameterMap .put ("outfields" , new EqualToPattern ("*" ));
92+ parameterMap .put ("result_type" , new EqualToPattern ("road_building_vector_xml" ));
93+ parameterMap .put ("resultOffset" , anythingPattern );
94+ wireMockServer .stubFor (
95+ WireMock .get (new UrlPathPattern (new EqualToPattern ("/query" ), false )).withQueryParams (parameterMap )
96+ .willReturn (WireMock .aResponse ()
97+ .withBody (Json .createObjectBuilder ().add ("type" , "FeatureCollection" )
98+ .add ("features" , Json .createArrayBuilder ().build ()).build ().toString ()))
99+ .atPriority (Integer .MIN_VALUE ));
100+ info = MapWithAILayerInfo .getInstance ().getLayers ().stream ()
69101 .filter (i -> i .getName ().equalsIgnoreCase ("MapWithAI" )).findAny ().orElse (null );
70102 assertNotNull (info );
103+ info = new MapWithAIInfo (info );
104+ }
105+
106+ @ Test
107+ void testAddMapWithAILayerActionTest () {
71108 AddMapWithAILayerAction action = new AddMapWithAILayerAction (info );
72109 assertDoesNotThrow (() -> action .actionPerformed (null ));
73110 OsmDataLayer osmLayer = new OsmDataLayer (new DataSet (), "TEST DATA" , null );
@@ -78,7 +115,7 @@ void testAddMapWithAILayerActionTest() {
78115 assertNull (MapWithAIDataUtils .getLayer (false ));
79116 action .updateEnabledState ();
80117 action .actionPerformed (null );
81- Awaitility . await (). atMost ( Durations . FIVE_SECONDS ). until (() -> MapWithAIDataUtils . getLayer ( false ) != null );
118+ threadSync . threadSync ( );
82119 assertNotNull (MapWithAIDataUtils .getLayer (false ));
83120
84121 MainApplication .getLayerManager ().removeLayer (MapWithAIDataUtils .getLayer (false ));
@@ -90,7 +127,7 @@ void testAddMapWithAILayerActionTest() {
90127
91128 action .updateEnabledState ();
92129 action .actionPerformed (null );
93- Awaitility . await (). atMost ( Durations . FIVE_SECONDS ). until (() -> ! layer . getDataSet (). isEmpty () );
130+ threadSync . threadSync ( );
94131 assertFalse (layer .getDataSet ().isEmpty ());
95132
96133 MainApplication .getLayerManager ().removeLayer (MapWithAIDataUtils .getLayer (false ));
@@ -100,69 +137,40 @@ void testAddMapWithAILayerActionTest() {
100137 mapwithaiLayer .getDataSet ()
101138 .addDataSource (new DataSource (new Bounds (39.095376 , -108.4495519 , 39.0987811 , -108.4422314 ), "" ));
102139 action .actionPerformed (null );
103- Awaitility . await (). atMost ( Durations . FIVE_SECONDS ). until (() -> ! mapwithaiLayer . getDataSet (). isEmpty () );
140+ threadSync . threadSync ( );
104141 assertFalse (mapwithaiLayer .getDataSet ().isEmpty ());
105142 }
106143
107144 @ Test
108- void testRemoteIcon () throws IOException , ExecutionException , InterruptedException {
145+ void testRemoteIcon () throws IOException {
109146 final ImageIcon blankImage = ImageProvider .createBlankIcon (ImageProvider .ImageSizes .LARGEICON );
110147 final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream ();
111148 // BufferedImage is what the current implementation uses. Otherwise, we will
112149 // have to copy it into a BufferedImage.
113- assertTrue (blankImage .getImage () instanceof BufferedImage );
114- final BufferedImage bi = (BufferedImage ) blankImage .getImage ();
150+ final BufferedImage bi = assertInstanceOf (BufferedImage .class , blankImage .getImage ());
115151 ImageIO .write (bi , "png" , byteArrayOutputStream );
116152 byte [] originalImage = byteArrayOutputStream .toByteArray ();
117- final WireMockServer wireMockServer = new WireMockServer (WireMockConfiguration .options ().dynamicPort ());
118- try {
119- wireMockServer .start ();
120- wireMockServer .addStubMapping (wireMockServer
121- .stubFor (WireMock .get ("/icon" ).willReturn (WireMock .aResponse ().withBody (originalImage ))));
122- final MapWithAIInfo info = MapWithAILayerInfo .getInstance ().getLayers ().stream ()
123- .filter (i -> i .getName ().equalsIgnoreCase ("MapWithAI" )).findAny ().orElse (null );
124- assertNotNull (info );
125- final MapWithAIInfo remoteInfo = new MapWithAIInfo (info );
126- remoteInfo .setIcon (wireMockServer .baseUrl () + "/icon" );
127- final AddMapWithAILayerAction action = new AddMapWithAILayerAction (remoteInfo );
128- GuiHelper .runInEDTAndWait (() -> {
129- /* Sync EDT */ });
130- MainApplication .worker .submit (() -> {
131- /* Sync worker thread */ }).get ();
132- final Object image = action .getValue (Action .LARGE_ICON_KEY );
133- assertTrue (image instanceof ImageIcon );
134- final ImageIcon attachedIcon = (ImageIcon ) image ;
135- assertTrue (attachedIcon .getImage () instanceof BufferedImage );
136- byteArrayOutputStream .reset ();
137- ImageIO .write ((BufferedImage ) attachedIcon .getImage (), "png" , byteArrayOutputStream );
138- final byte [] downloadedImage = byteArrayOutputStream .toByteArray ();
139- assertArrayEquals (originalImage , downloadedImage );
140- } finally {
141- wireMockServer .stop ();
142- }
153+ wireMockServer .addStubMapping (
154+ wireMockServer .stubFor (WireMock .get ("/icon" ).willReturn (WireMock .aResponse ().withBody (originalImage ))));
155+ final MapWithAIInfo remoteInfo = new MapWithAIInfo (info );
156+ remoteInfo .setIcon (wireMockServer .baseUrl () + "/icon" );
157+ final AddMapWithAILayerAction action = new AddMapWithAILayerAction (remoteInfo );
158+ threadSync .threadSync ();
159+ final Object image = action .getValue (Action .LARGE_ICON_KEY );
160+ final ImageIcon attachedIcon = assertInstanceOf (ImageIcon .class , image );
161+ final BufferedImage bufferedImage = assertInstanceOf (BufferedImage .class , attachedIcon .getImage ());
162+ byteArrayOutputStream .reset ();
163+ ImageIO .write (bufferedImage , "png" , byteArrayOutputStream );
164+ final byte [] downloadedImage = byteArrayOutputStream .toByteArray ();
165+ assertArrayEquals (originalImage , downloadedImage );
143166 }
144167
145168 @ Test
146- void testNonRegression22683 () throws ExecutionException , InterruptedException {
147- final MapWithAIInfo info = MapWithAILayerInfo .getInstance ().getLayers ().stream ()
148- .filter (i -> i .getName ().equalsIgnoreCase ("MapWithAI" )).findAny ().orElse (null );
149- assertNotNull (info );
169+ void testNonRegression22683 () {
150170 final OsmDataLayer layer = new OsmDataLayer (new DataSet (), "testNonRegression22683" , null );
151171 layer .getDataSet ().addDataSource (new DataSource (new Bounds (0 , 0 , 0.001 , 0.001 ), "Area 1" ));
152172 layer .getDataSet ().addDataSource (new DataSource (new Bounds (-0.001 , -0.001 , 0 , 0 ), "Area 2" ));
153173 MainApplication .getLayerManager ().addLayer (layer );
154- final WireMockServer server = new WireMockServer (WireMockConfiguration .options ().dynamicPort ());
155- final Map <String , StringValuePattern > parameterMap = new HashMap <>();
156- final AnythingPattern anythingPattern = new AnythingPattern ();
157- parameterMap .put ("geometryType" , anythingPattern );
158- parameterMap .put ("geometry" , anythingPattern );
159- parameterMap .put ("inSR" , new EqualToPattern ("4326" ));
160- parameterMap .put ("f" , new EqualToPattern ("geojson" ));
161- parameterMap .put ("outfields" , new EqualToPattern ("*" ));
162- parameterMap .put ("result_type" , new EqualToPattern ("road_building_vector_xml" ));
163- parameterMap .put ("resultOffset" , anythingPattern );
164- server .stubFor (WireMock .get (new UrlPathPattern (new EqualToPattern ("/query" ), false ))
165- .withQueryParams (parameterMap ).willReturn (WireMock .aResponse ().withBody ("{\" test\" :0}" )));
166174 final List <LogRecord > logs = new ArrayList <>();
167175 Handler testHandler = new Handler () {
168176 @ Override
@@ -182,22 +190,16 @@ public void close() {
182190 };
183191 Logging .getLogger ().addHandler (testHandler );
184192 try {
185- server .start ();
186- info .setUrl (server .baseUrl ());
193+ info .setUrl (wireMockServer .baseUrl ());
187194 info .setSourceType (MapWithAIType .ESRI_FEATURE_SERVER );
188195 final AddMapWithAILayerAction action = new AddMapWithAILayerAction (info );
189196 Logging .clearLastErrorAndWarnings ();
190197 assertDoesNotThrow (() -> action .actionPerformed (null ));
191- GuiHelper .runInEDTAndWait (() -> {
192- /* Sync thread */ });
193- MainApplication .worker .submit (() -> {
194- /* Sync thread */ }).get ();
198+ threadSync .threadSync ();
195199 final List <LogRecord > ides = logs .stream ()
196- .filter (record -> record .getThrown () instanceof IllegalArgumentException )
197- .collect (Collectors .toList ());
200+ .filter (record -> record .getThrown () instanceof IllegalArgumentException ).toList ();
198201 assertTrue (ides .isEmpty (), ides .stream ().map (LogRecord ::getMessage ).collect (Collectors .joining ("\n " )));
199202 } finally {
200- server .stop ();
201203 Logging .getLogger ().removeHandler (testHandler );
202204 }
203205 }
0 commit comments