|
18 | 18 | import org.springframework.boot.context.properties.EnableConfigurationProperties; |
19 | 19 | import org.springframework.boot.test.context.SpringBootTest; |
20 | 20 | import org.springframework.http.HttpEntity; |
| 21 | +import org.springframework.http.HttpMethod; |
| 22 | +import org.springframework.http.HttpStatus; |
| 23 | +import org.springframework.http.ResponseEntity; |
21 | 24 | import org.springframework.test.context.TestPropertySource; |
22 | 25 | import org.springframework.web.client.RestTemplate; |
23 | 26 |
|
| 27 | +import java.math.BigInteger; |
24 | 28 | import java.util.ArrayList; |
25 | 29 | import java.util.HashMap; |
26 | 30 | import java.util.List; |
@@ -264,7 +268,6 @@ public void verifyRequestUrlGenerateCorrect() { |
264 | 268 | ); |
265 | 269 | assertEquals("https://test.com/geoserver/wfs?VERSION=1.0.0&typeName=test:layer&SERVICE=WFS&REQUEST=GetFeature&outputFormat=shape-zip&cql_filter=((timestamp DURING 2024-01-01T00:00:00Z/2024-12-31T23:59:59Z))", result, "Correct url 1"); |
266 | 270 | } |
267 | | - |
268 | 271 | /** |
269 | 272 | * Make sure the url generated contains the correct polygon |
270 | 273 | * |
@@ -299,4 +302,179 @@ public void verifyRequestUrlGenerateCorrectWithPolygon() throws JsonProcessingEx |
299 | 302 | result, |
300 | 303 | "Correct url 1"); |
301 | 304 | } |
| 305 | + /** |
| 306 | + * Verify estimate size on success request |
| 307 | + */ |
| 308 | + @Test |
| 309 | + void shouldReturnEstimatedSizeWhenBothRequestsSucceed() { |
| 310 | + String uuid = "lyr-123"; |
| 311 | + String layer = "water_bodies"; |
| 312 | + String start = "2024-01-01"; |
| 313 | + String end = "2024-12-31"; |
| 314 | + Object multiPolygon = new Object(); // or real geometry |
| 315 | + List<String> fields = List.of("name", "area"); |
| 316 | + String format = "application/json"; |
| 317 | + |
| 318 | + // 1. Hits response (XML) |
| 319 | + String hitsXml = """ |
| 320 | + <?xml version="1.0" encoding="UTF-8"?> |
| 321 | + <wfs:FeatureCollection |
| 322 | + xmlns:xs="http://www.w3.org/2001/XMLSchema" |
| 323 | + xmlns:wfs="http://www.opengis.net/wfs" |
| 324 | + xmlns:gml="http://www.opengis.net/gml" |
| 325 | + xmlns:ogc="http://www.opengis.net/ogc" |
| 326 | + xmlns:ows="http://www.opengis.net/ows" |
| 327 | + xmlns:xlink="http://www.w3.org/1999/xlink" |
| 328 | + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| 329 | + numberOfFeatures="227193" |
| 330 | + timeStamp="2026-03-01T22:28:56.206Z" |
| 331 | + xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd" |
| 332 | + /> |
| 333 | + """; |
| 334 | + ResponseEntity<String> hitsResponse = new ResponseEntity<>(hitsXml, HttpStatus.OK); |
| 335 | + |
| 336 | + // 2. Sample response (small payload) |
| 337 | + byte[] sampleBytes = "fake data".getBytes(); |
| 338 | + ResponseEntity<byte[]> sampleResponse = new ResponseEntity<>(sampleBytes, HttpStatus.OK); |
| 339 | + |
| 340 | + doReturn(hitsResponse) |
| 341 | + .when(restTemplate).exchange( |
| 342 | + argThat((String url) -> url != null && url.contains("resultType=hits")), |
| 343 | + eq(HttpMethod.GET), |
| 344 | + any(HttpEntity.class), |
| 345 | + eq(String.class)); |
| 346 | + |
| 347 | + doReturn(sampleResponse) |
| 348 | + .when(restTemplate).exchange( |
| 349 | + argThat((String url) -> url != null && url.contains("maxFeatures=" + DownloadWfsDataService.SAMPLES_SIZE)), |
| 350 | + eq(HttpMethod.GET), any(), eq(byte[].class)); |
| 351 | + |
| 352 | + doReturn(Optional.of("http://dummy.com/wfs")) |
| 353 | + .when(wfsServer).getFeatureServerUrl(eq(uuid), anyString()); |
| 354 | + |
| 355 | + WfsFields fs = WfsFields.builder() |
| 356 | + .fields(List.of( |
| 357 | + WfsField.builder().type("dateTime").name("time").build() |
| 358 | + )) |
| 359 | + .build(); |
| 360 | + |
| 361 | + doReturn(fs) |
| 362 | + .when(wfsServer).getDownloadableFields(eq(uuid), any(WfsServer.WfsFeatureRequest.class)); |
| 363 | + |
| 364 | + BigInteger size = downloadWfsDataService.estimateDownloadSize( |
| 365 | + uuid, layer, start, end, multiPolygon, fields, format); |
| 366 | + |
| 367 | + // Should have call with resultType=hits to get number of record |
| 368 | + verify(restTemplate).exchange( |
| 369 | + eq("https://dummy.com/wfs?VERSION=1.1.0&typeName=water_bodies&SERVICE=WFS&REQUEST=GetFeature&resultType=hits&propertyName=name,area&cql_filter=((time DURING 2024-01-01T00:00:00Z/2024-12-31T23:59:59Z))"), // or contains(...) |
| 370 | + eq(HttpMethod.GET), |
| 371 | + any(), |
| 372 | + eq(String.class) // or byte[].class etc. |
| 373 | + ); |
| 374 | + |
| 375 | + // Should also call with maxFeatures |
| 376 | + verify(restTemplate).exchange( |
| 377 | + eq("https://dummy.com/wfs?REQUEST=GetFeature&propertyName=name,area&VERSION=1.0.0&typeName=water_bodies&SERVICE=WFS&outputFormat=application/json&maxFeatures=500&cql_filter=((time DURING 2024-01-01T00:00:00Z/2024-12-31T23:59:59Z))"), // or contains(...) |
| 378 | + eq(HttpMethod.GET), |
| 379 | + any(), |
| 380 | + eq(byte[].class) // or byte[].class etc. |
| 381 | + ); |
| 382 | + |
| 383 | + // numberOfFeatures="227193" |
| 384 | + long expected = 227193L * sampleBytes.length / DownloadWfsDataService.SAMPLES_SIZE; |
| 385 | + assertEquals(BigInteger.valueOf(expected), size, "Size match"); |
| 386 | + } |
| 387 | + /** |
| 388 | + * Expect illegal exception when param is wrong |
| 389 | + */ |
| 390 | + @Test |
| 391 | + void throwExceptionWhenHitsRequestFails() { |
| 392 | + |
| 393 | + String uuid = "lyr-123"; |
| 394 | + String layer = "imos:aatams_sattag_dm_profile_map1"; |
| 395 | + String start = "2024-01-01"; |
| 396 | + String end = "2024-12-31"; |
| 397 | + Object multiPolygon = new Object(); // or real geometry |
| 398 | + List<String> fields = List.of("name", "area"); |
| 399 | + String format = "application/json"; |
| 400 | + |
| 401 | + // 1. Hits response (XML), indicate error |
| 402 | + String hitsXml = """ |
| 403 | + <?xml version="1.0" encoding="UTF-8"?> |
| 404 | + <ows:ExceptionReport xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ows="http://www.opengis.net/ows" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0.0" xsi:schemaLocation="http://www.opengis.net/ows https://geoserver-123.aodn.org.au/geoserver/schemas/ows/1.0.0/owsExceptionReport.xsd"> |
| 405 | + <ows:Exception exceptionCode="InvalidParameterValue" locator="typeName"> |
| 406 | + <ows:ExceptionText>Feature type imos:aatams_sattag_dm_profile_map1 unknown</ows:ExceptionText> |
| 407 | + </ows:Exception> |
| 408 | + </ows:ExceptionReport> |
| 409 | + """; |
| 410 | + ResponseEntity<String> hitsResponse = new ResponseEntity<>(hitsXml, HttpStatus.OK); |
| 411 | + doReturn(hitsResponse) |
| 412 | + .when(restTemplate).exchange( |
| 413 | + argThat((String url) -> url != null && url.contains("resultType=hits")), |
| 414 | + eq(HttpMethod.GET), |
| 415 | + any(HttpEntity.class), |
| 416 | + eq(String.class)); |
| 417 | + |
| 418 | + doReturn(Optional.of("http://dummy.com/wfs")) |
| 419 | + .when(wfsServer).getFeatureServerUrl(eq(uuid), anyString()); |
| 420 | + |
| 421 | + WfsFields fs = WfsFields.builder() |
| 422 | + .fields(List.of( |
| 423 | + WfsField.builder().type("dateTime").name("time").build() |
| 424 | + )) |
| 425 | + .build(); |
| 426 | + |
| 427 | + doReturn(fs) |
| 428 | + .when(wfsServer).getDownloadableFields(eq(uuid), any(WfsServer.WfsFeatureRequest.class)); |
| 429 | + |
| 430 | + assertThrows(IllegalArgumentException.class, |
| 431 | + () -> downloadWfsDataService.estimateDownloadSize( |
| 432 | + uuid, layer, start, end, multiPolygon, fields, format) |
| 433 | + ); |
| 434 | + } |
| 435 | + |
| 436 | + @Test |
| 437 | + void returnsNullWhenParserThrowsException() { |
| 438 | + String uuid = "lyr-123"; |
| 439 | + String layer = "imos:aatams_sattag_dm_profile_map1"; |
| 440 | + String start = "2024-01-01"; |
| 441 | + String end = "2024-12-31"; |
| 442 | + Object multiPolygon = new Object(); // or real geometry |
| 443 | + List<String> fields = List.of("name", "area"); |
| 444 | + String format = "application/json"; |
| 445 | + |
| 446 | + // 1. A syntax error XML, should not see this but just incase |
| 447 | + String hitsXml = """ |
| 448 | + <?xml version="1.0" encoding="UTF-8"?> |
| 449 | + <ows:ExceptionReport23433 xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ows="http://www.opengis.net/ows" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0.0" xsi:schemaLocation="http://www.opengis.net/ows https://geoserver-123.aodn.org.au/geoserver/schemas/ows/1.0.0/owsExceptionReport.xsd"> |
| 450 | + <ows:Exception exceptionCode="InvalidParameterValue" locator="typeName"> |
| 451 | + <ows:ExceptionText>Feature type imos:aatams_sattag_dm_profile_map1 unknown</ows:ExceptionText> |
| 452 | + </ows:Exception> |
| 453 | + </ows:ExceptionReport> |
| 454 | + """; |
| 455 | + ResponseEntity<String> hitsResponse = new ResponseEntity<>(hitsXml, HttpStatus.OK); |
| 456 | + doReturn(hitsResponse) |
| 457 | + .when(restTemplate).exchange( |
| 458 | + argThat((String url) -> url != null && url.contains("resultType=hits")), |
| 459 | + eq(HttpMethod.GET), |
| 460 | + any(HttpEntity.class), |
| 461 | + eq(String.class)); |
| 462 | + |
| 463 | + doReturn(Optional.of("http://dummy.com/wfs")) |
| 464 | + .when(wfsServer).getFeatureServerUrl(eq(uuid), anyString()); |
| 465 | + |
| 466 | + WfsFields fs = WfsFields.builder() |
| 467 | + .fields(List.of( |
| 468 | + WfsField.builder().type("dateTime").name("time").build() |
| 469 | + )) |
| 470 | + .build(); |
| 471 | + |
| 472 | + doReturn(fs) |
| 473 | + .when(wfsServer).getDownloadableFields(eq(uuid), any(WfsServer.WfsFeatureRequest.class)); |
| 474 | + |
| 475 | + BigInteger size = downloadWfsDataService.estimateDownloadSize( |
| 476 | + uuid, layer, start, end, multiPolygon, fields, format); |
| 477 | + |
| 478 | + assertNull(size, "Size should be null"); |
| 479 | + } |
302 | 480 | } |
0 commit comments