View Javadoc
1   /*
2    * Copyright 2022 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.bremersee.geojson.spring.boot.autoconfigure;
18  
19  import static org.assertj.core.api.Assertions.assertThat;
20  
21  import java.util.Arrays;
22  import java.util.List;
23  import java.util.stream.Collectors;
24  import org.bremersee.geojson.GeoJsonFeature;
25  import org.bremersee.geojson.GeoJsonFeatureCollection;
26  import org.bremersee.geojson.GeoJsonGeometryFactory;
27  import org.bremersee.geojson.spring.boot.autoconfigure.app.GeometryEntity;
28  import org.bremersee.geojson.spring.boot.autoconfigure.app.GeometryEntityRepository;
29  import org.bremersee.geojson.spring.boot.autoconfigure.app.TestConfiguration;
30  import org.junit.jupiter.api.MethodOrderer;
31  import org.junit.jupiter.api.Order;
32  import org.junit.jupiter.api.Test;
33  import org.junit.jupiter.api.TestMethodOrder;
34  import org.locationtech.jts.geom.Coordinate;
35  import org.locationtech.jts.geom.Geometry;
36  import org.locationtech.jts.geom.LineString;
37  import org.locationtech.jts.geom.LinearRing;
38  import org.locationtech.jts.geom.MultiPoint;
39  import org.locationtech.jts.geom.Point;
40  import org.locationtech.jts.geom.Polygon;
41  import org.springframework.beans.factory.annotation.Autowired;
42  import org.springframework.boot.test.context.SpringBootTest;
43  import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
44  import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
45  import org.springframework.context.annotation.ComponentScan;
46  import org.springframework.core.ParameterizedTypeReference;
47  import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
48  import org.springframework.test.annotation.DirtiesContext;
49  import org.springframework.test.annotation.DirtiesContext.ClassMode;
50  import org.springframework.test.web.reactive.server.WebTestClient;
51  import org.testcontainers.containers.MongoDBContainer;
52  import org.testcontainers.junit.jupiter.Container;
53  import org.testcontainers.junit.jupiter.Testcontainers;
54  import org.testcontainers.utility.DockerImageName;
55  import reactor.core.publisher.Mono;
56  
57  /**
58   * The geo json autoconfigure integration test.
59   *
60   * @author Christian Bremer
61   */
62  @Testcontainers
63  @SpringBootTest(
64      classes = {TestConfiguration.class},
65      webEnvironment = WebEnvironment.RANDOM_PORT,
66      properties = {
67          "spring.main.web-application-type=reactive",
68          "spring.data.mongodb.auto-index-creation=true"
69      })
70  @ComponentScan(basePackageClasses = {GeometryEntityRepository.class})
71  @EnableMongoRepositories(basePackageClasses = {GeometryEntityRepository.class})
72  @DirtiesContext(classMode = ClassMode.AFTER_CLASS)
73  @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
74  public class GeoJsonAutoConfigureIntegrationTest {
75  
76    @Container
77    @ServiceConnection
78    static MongoDBContainer mongoDBContainer = new MongoDBContainer(DockerImageName
79        .parse("mongo:4.0.10"));
80  
81    /**
82     * The Geometry factory.
83     */
84    @Autowired
85    GeoJsonGeometryFactory geometryFactory;
86  
87    /**
88     * The Repository.
89     */
90    @Autowired
91    GeometryEntityRepository repository;
92  
93    /**
94     * The test web client.
95     */
96    @Autowired
97    WebTestClient webClient;
98  
99    /**
100    * Transform.
101    */
102   @Order(10)
103   @Test
104   void transform() {
105     MultiPoint geometry = geometryFactory.createMultiPoint(List.of(
106         geometryFactory.createPoint(1., 2.),
107         geometryFactory.createPoint(6., 7.)
108     ));
109     GeoJsonFeature<Geometry, Object> expected = new GeoJsonFeature<>("987", geometry, true, null);
110     webClient
111         .get()
112         .uri("/geo/transform?id={id}&geometry={geometry}&withBoundingBox={withBoundingBox}",
113             expected.getId(), expected.getGeometry().toText(), true)
114         .exchange()
115         .expectStatus()
116         .isOk()
117         .expectBody(new ParameterizedTypeReference<GeoJsonFeature<Geometry, Object>>() {
118         })
119         .value(response -> assertThat(response).isEqualTo(expected));
120   }
121 
122   /**
123    * Find features.
124    */
125   @Order(20)
126   @Test
127   void findFeatures() {
128     LinearRing ring = geometryFactory.createLinearRing(List.of(
129         new Coordinate(2., 3.),
130         new Coordinate(6., 4.),
131         new Coordinate(6., 8.),
132         new Coordinate(2., 3.)));
133     Polygon polygon = geometryFactory.createPolygon(ring);
134     LineString lineString = geometryFactory.createLineString(Arrays.asList(
135         new Coordinate(2., 3.),
136         new Coordinate(6., 7.)));
137     Point point = geometryFactory.createPoint(7., 8.);
138     List<Geometry> geometries = List.of(point, lineString, polygon);
139 
140     GeoJsonFeatureCollection<Geometry, Object> expected = save(geometries).block();
141 
142     webClient
143         .get()
144         .uri("/geo")
145         .exchange()
146         .expectStatus()
147         .isOk()
148         .expectBody(new ParameterizedTypeReference<GeoJsonFeatureCollection<Geometry, Object>>() {
149         })
150         .value(response -> assertThat(response).isEqualTo(expected));
151   }
152 
153   /**
154    * Save feature.
155    */
156   @Order(30)
157   @Test
158   void saveFeature() {
159     LineString lineString = geometryFactory.createLineString(Arrays.asList(
160         new Coordinate(2., 3.),
161         new Coordinate(6., 7.)));
162     //noinspection unchecked
163     webClient.post()
164         .uri("/geo")
165         .body(Mono.just(lineString), LineString.class)
166         .exchange()
167         .expectStatus()
168         .isOk()
169         .expectBody(new ParameterizedTypeReference<GeoJsonFeature<Geometry, Object>>() {
170         })
171         .value(response -> assertThat(response.getGeometry()).isEqualTo(lineString));
172 
173   }
174 
175   private Mono<GeoJsonFeatureCollection<Geometry, Object>> save(List<Geometry> geometries) {
176     return repository.saveAll(geometries.stream()
177             .map(GeometryEntity::new)
178             .collect(Collectors.toList()))
179         .map(entity -> new GeoJsonFeature<>(entity.getId(), entity.getGeometry(), false, null))
180         .collect(
181             () -> new GeoJsonFeatureCollection<>(
182                 true,
183                 (o1, o2) -> o1.getId().compareToIgnoreCase(o2.getId())),
184             GeoJsonFeatureCollection::add);
185 
186   }
187 
188 }