1 package de.dlr.shepard.integrationtests;
2
3 import static io.restassured.RestAssured.given;
4 import static org.assertj.core.api.Assertions.assertThat;
5
6 import de.dlr.shepard.ErrorResponse;
7 import de.dlr.shepard.common.util.Constants;
8 import de.dlr.shepard.data.timeseries.TimeseriesTestDataGenerator;
9 import de.dlr.shepard.data.timeseries.io.TimeseriesContainerIO;
10 import de.dlr.shepard.data.timeseries.io.TimeseriesWithDataPoints;
11 import de.dlr.shepard.data.timeseries.model.Timeseries;
12 import de.dlr.shepard.data.timeseries.model.TimeseriesDataPoint;
13 import de.dlr.shepard.data.timeseries.services.InstantHelper;
14 import io.quarkus.test.junit.QuarkusIntegrationTest;
15 import java.util.ArrayList;
16 import java.util.List;
17 import java.util.Map;
18 import org.junit.jupiter.api.BeforeAll;
19 import org.junit.jupiter.api.MethodOrderer;
20 import org.junit.jupiter.api.Order;
21 import org.junit.jupiter.api.Test;
22 import org.junit.jupiter.api.TestMethodOrder;
23
24 @QuarkusIntegrationTest
25 @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
26 public class TimeseriesIT extends BaseTestCaseIT {
27
28 private static String containerURL;
29
30 private static TimeseriesContainerIO container;
31 private static TimeseriesWithDataPoints payload;
32 private static long start;
33 private static long end;
34
35 @BeforeAll
36 public static void setUp() {
37 containerURL = Constants.TIMESERIES_CONTAINERS;
38 }
39
40 @Test
41 @Order(1)
42 public void createTimeseriesContainer() {
43 var containerName = "TimeseriesContainer";
44 var toCreate = new TimeseriesContainerIO();
45 toCreate.setName(containerName);
46
47 var actual = given()
48 .spec(requestSpecOfDefaultUser)
49 .body(toCreate)
50 .when()
51 .post(containerURL)
52 .then()
53 .statusCode(201)
54 .extract()
55 .as(TimeseriesContainerIO.class);
56 container = actual;
57
58 assertThat(actual.getId()).isNotNull();
59 assertThat(actual.getCreatedAt()).isNotNull();
60 assertThat(actual.getCreatedBy()).isEqualTo(nameOfDefaultUser);
61 assertThat(actual.getName()).isEqualTo(containerName);
62 assertThat(actual.getUpdatedAt()).isNull();
63 assertThat(actual.getUpdatedBy()).isNull();
64 }
65
66 @Test
67 @Order(2)
68 public void getAllTimeseriesContainers() {
69 var actual = given()
70 .spec(requestSpecOfDefaultUser)
71 .when()
72 .get(containerURL)
73 .then()
74 .statusCode(200)
75 .extract()
76 .as(TimeseriesContainerIO[].class);
77
78 assertThat(actual).contains(container);
79 }
80
81 @Test
82 @Order(3)
83 public void getTimeseriesContainer() {
84 var actual = given()
85 .spec(requestSpecOfDefaultUser)
86 .when()
87 .get(containerURL + "/" + container.getId())
88 .then()
89 .statusCode(200)
90 .extract()
91 .as(TimeseriesContainerIO.class);
92
93 assertThat(actual).isEqualTo(container);
94 }
95
96 @Test
97 public void getTimeseriesContainer_doesNotExist_notFound() {
98 ErrorResponse actual = given()
99 .spec(requestSpecOfDefaultUser)
100 .when()
101 .get(containerURL + "/99999")
102 .then()
103 .statusCode(404)
104 .extract()
105 .as(ErrorResponse.class);
106 assertThat(actual.getMessage()).isEqualTo("ID ERROR - Timeseries Container with id 99999 is null or deleted");
107 }
108
109 @Test
110 public void getTimeseriesContainer_doesNotExistNegativeId_badRequest() {
111 var actual = given()
112 .spec(requestSpecOfDefaultUser)
113 .when()
114 .get(containerURL + "/-1")
115 .then()
116 .statusCode(400)
117 .extract();
118 assertThat(actual.body().asString()).isEqualTo(
119 "{\"title\":\"Constraint Violation\",\"status\":400,\"violations\":[{\"field\":\"getTimeseriesContainer.timeseriesContainerId\",\"message\":\"must be greater than or equal to 0\"}]}"
120 );
121 }
122
123 @Test
124 @Order(4)
125 public void createTimeseries() {
126 var timeseries = TimeseriesTestDataGenerator.generateTimeseries("temperature");
127 InstantHelper instantHelper = InstantHelper.fromGermanDate("01.01.2024");
128 start = instantHelper.toNano();
129 List<TimeseriesDataPoint> dataPointsIO = new ArrayList<>(
130 List.of(
131 TimeseriesTestDataGenerator.generateDataPointDouble(instantHelper.toNano(), 22.1),
132 TimeseriesTestDataGenerator.generateDataPointDouble(instantHelper.addSeconds(1).toNano(), 22.3),
133 TimeseriesTestDataGenerator.generateDataPointDouble(instantHelper.addSeconds(1).toNano(), 22.2)
134 )
135 );
136 end = instantHelper.addSeconds(2).toNano();
137
138 payload = new TimeseriesWithDataPoints(timeseries, dataPointsIO);
139
140 var actual = given()
141 .spec(requestSpecOfDefaultUser)
142 .body(payload)
143 .when()
144 .post(String.format("%s/%d/%s", containerURL, container.getId(), Constants.PAYLOAD))
145 .then()
146 .statusCode(201)
147 .extract()
148 .as(Timeseries.class);
149
150 assertThat(actual).isEqualTo(payload.getTimeseries());
151 }
152
153 @Test
154 @Order(5)
155 public void getTimeseriesAvailable() {
156 var actual = given()
157 .spec(requestSpecOfDefaultUser)
158 .when()
159 .get(containerURL + "/" + container.getId() + "/" + Constants.AVAILABLE)
160 .then()
161 .statusCode(200)
162 .extract()
163 .as(Timeseries[].class);
164
165 Timeseries expectedTimeseriesIO = new Timeseries("temperature", "device", "location", "symbolicName", "field");
166
167 assertThat(actual).contains(expectedTimeseriesIO);
168 }
169
170 @Test
171 @Order(6)
172 public void getTimeseries() {
173 var actual = given()
174 .spec(requestSpecOfDefaultUser)
175 .when()
176 .queryParams(
177 Map.of(
178 Constants.MEASUREMENT,
179 "temperature",
180 Constants.LOCATION,
181 "location",
182 Constants.DEVICE,
183 "device",
184 Constants.SYMBOLICNAME,
185 "symbolicName",
186 Constants.FIELD,
187 "field",
188 Constants.START,
189 start,
190 Constants.END,
191 end
192 )
193 )
194 .get(containerURL + "/" + container.getId() + "/" + Constants.PAYLOAD)
195 .then()
196 .statusCode(200)
197 .extract()
198 .as(TimeseriesWithDataPoints.class);
199
200 assertThat(actual).isEqualTo(payload);
201 }
202
203 @Test
204 @Order(6)
205 public void getTimeseries_startNotSet_badRequest() {
206 var actual = given()
207 .spec(requestSpecOfDefaultUser)
208 .when()
209 .queryParams(
210 Map.of(
211 Constants.MEASUREMENT,
212 "temperature",
213 Constants.LOCATION,
214 "location",
215 Constants.DEVICE,
216 "device",
217 Constants.SYMBOLICNAME,
218 "symbolicName",
219 Constants.FIELD,
220 "field",
221 Constants.END,
222 end
223 )
224 )
225 .get(containerURL + "/" + container.getId() + "/" + Constants.PAYLOAD)
226 .then()
227 .statusCode(400)
228 .extract();
229
230 assertThat(actual.body().asString()).isEqualTo(
231 "{\"title\":\"Constraint Violation\",\"status\":400,\"violations\":[{\"field\":\"getTimeseries.start\",\"message\":\"must not be null\"}]}"
232 );
233 }
234
235 @Test
236 @Order(6)
237 public void getTimeseries_measurementIsBlank_badRequest() {
238 var actual = given()
239 .spec(requestSpecOfDefaultUser)
240 .when()
241 .queryParams(
242 Map.of(
243 Constants.MEASUREMENT,
244 " ",
245 Constants.LOCATION,
246 "location",
247 Constants.DEVICE,
248 "device",
249 Constants.SYMBOLICNAME,
250 "symbolicName",
251 Constants.FIELD,
252 "field",
253 Constants.START,
254 start,
255 Constants.END,
256 end
257 )
258 )
259 .get(containerURL + "/" + container.getId() + "/" + Constants.PAYLOAD)
260 .then()
261 .statusCode(400)
262 .extract();
263
264 assertThat(actual.body().asString()).isEqualTo(
265 "{\"title\":\"Constraint Violation\",\"status\":400,\"violations\":[{\"field\":\"getTimeseries.measurement\",\"message\":\"must not be blank\"}]}"
266 );
267 }
268
269 @Test
270 @Order(7)
271 public void deleteContainer() {
272 given().spec(requestSpecOfDefaultUser).when().delete(containerURL + "/" + container.getId()).then().statusCode(204);
273 given().spec(requestSpecOfDefaultUser).when().get(containerURL + "/" + container.getId()).then().statusCode(404);
274 }
275 }