1 package de.dlr.shepard.integrationtests;
2
3 import static io.restassured.RestAssured.given;
4 import static org.assertj.core.api.Assertions.assertThat;
5 import static org.junit.jupiter.api.Assertions.assertEquals;
6
7 import de.dlr.shepard.common.search.io.QueryType;
8 import de.dlr.shepard.common.search.io.ResponseBody;
9 import de.dlr.shepard.common.search.io.ResultTriple;
10 import de.dlr.shepard.common.search.io.SearchBody;
11 import de.dlr.shepard.common.search.io.SearchParams;
12 import de.dlr.shepard.common.search.io.SearchScope;
13 import de.dlr.shepard.common.util.Constants;
14 import de.dlr.shepard.common.util.TraversalRules;
15 import de.dlr.shepard.context.collection.io.CollectionIO;
16 import de.dlr.shepard.context.collection.io.DataObjectIO;
17 import io.quarkus.test.junit.QuarkusIntegrationTest;
18 import java.util.Map;
19 import org.junit.jupiter.api.BeforeAll;
20 import org.junit.jupiter.api.MethodOrderer;
21 import org.junit.jupiter.api.Order;
22 import org.junit.jupiter.api.Test;
23 import org.junit.jupiter.api.TestMethodOrder;
24
25 @QuarkusIntegrationTest
26 @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
27 public class DataObjectSearcherIT extends BaseTestCaseIT {
28
29 private static DataObjectIO dataObjectIO1;
30 private static DataObjectIO dataObjectIO2;
31 private static DataObjectIO dataObjectIO3;
32 private static DataObjectIO dataObjectIO4;
33 private static String dataObjectsURL;
34 private static CollectionIO collection;
35 private static String searchURL;
36
37 @BeforeAll
38 public static void setUp() {
39 collection = createCollection("DataObjectSearcherTestCollection");
40 dataObjectsURL = "/%s/%d/%s".formatted(Constants.COLLECTIONS, collection.getId(), Constants.DATA_OBJECTS);
41
42 searchURL = "/" + Constants.SEARCH;
43 var payload1 = new DataObjectIO();
44 payload1.setName("DataObjectSearchDummy1");
45 payload1.setDescription("description1");
46 payload1.setAttributes(Map.of("a", "1", "b", "2"));
47 dataObjectIO1 = given()
48 .spec(requestSpecOfDefaultUser)
49 .body(payload1)
50 .when()
51 .post(dataObjectsURL)
52 .then()
53 .statusCode(201)
54 .extract()
55 .as(DataObjectIO.class);
56 var payload2 = new DataObjectIO();
57 payload2.setName("DataObjectSearchDummy2");
58 payload2.setDescription("description2");
59 payload2.setAttributes(Map.of("abc", "1", "bcd", "233"));
60 dataObjectIO2 = given()
61 .spec(requestSpecOfDefaultUser)
62 .body(payload2)
63 .when()
64 .post(dataObjectsURL)
65 .then()
66 .statusCode(201)
67 .extract()
68 .as(DataObjectIO.class);
69 dataObjectIO3 = createDataObjectWithParent("DataObjectSearchDummy3", collection.getId(), dataObjectIO1.getId());
70 dataObjectIO4 = createDataObjectWithParent("DataObjectSearchDummy4", collection.getId(), dataObjectIO3.getId());
71 }
72
73 @Test
74 @Order(1)
75 public void findOneDataObjectWithOrTest() {
76 SearchBody searchBody = new SearchBody();
77 SearchScope searchScope = new SearchScope();
78 searchScope.setCollectionId(collection.getId());
79 searchScope.setTraversalRules(new TraversalRules[] {});
80 searchBody.setScopes(new SearchScope[] { searchScope });
81 SearchParams searchParams = new SearchParams();
82 searchParams.setQueryType(QueryType.DataObject);
83 String query =
84 """
85 {
86 "OR": [
87 {
88 "property": "id",
89 "value": %d,
90 "operator": "eq"
91 },
92 {
93 "property": "number",
94 "value": 123,
95 "operator": "le"
96 }
97 ]
98 }""".formatted(dataObjectIO1.getId());
99 searchParams.setQuery(query);
100 searchBody.setSearchParams(searchParams);
101 var result = given()
102 .spec(requestSpecOfDefaultUser)
103 .body(searchBody)
104 .when()
105 .post(searchURL)
106 .then()
107 .statusCode(200)
108 .extract()
109 .as(ResponseBody.class);
110 ResultTriple triple1 = new ResultTriple(collection.getId(), dataObjectIO1.getId(), null);
111 assertThat(result.getResultSet()).contains(triple1);
112 assertThat(result.getResults()[0].getId()).isEqualTo(dataObjectIO1.getId());
113 assertThat(result.getSearchParams()).isEqualTo(searchParams);
114 }
115
116 @Test
117 @Order(2)
118 public void findOneDataObjectWithAndAttributesTest() {
119 SearchBody searchBody = new SearchBody();
120 SearchScope searchScope = new SearchScope();
121 searchScope.setCollectionId(collection.getId());
122 searchScope.setTraversalRules(new TraversalRules[] {});
123 searchBody.setScopes(new SearchScope[] { searchScope });
124 SearchParams searchParams = new SearchParams();
125 searchParams.setQueryType(QueryType.DataObject);
126 String query =
127 """
128 {
129 "AND": [
130 {
131 "property": "id",
132 "value": %d,
133 "operator": "eq"
134 },
135 {
136 "property": "attributes.a",
137 "value": "1",
138 "operator": "eq"
139 }
140 ]
141 }""".formatted(dataObjectIO1.getId());
142 searchParams.setQuery(query);
143 searchBody.setSearchParams(searchParams);
144 var result = given()
145 .spec(requestSpecOfDefaultUser)
146 .body(searchBody)
147 .when()
148 .post(searchURL)
149 .then()
150 .statusCode(200)
151 .extract()
152 .as(ResponseBody.class);
153 ResultTriple triple1 = new ResultTriple(collection.getId(), dataObjectIO1.getId(), null);
154 assertThat(result.getResultSet()).contains(triple1);
155 }
156
157 @Test
158 @Order(3)
159 public void findOneDataObjectWithAndNameTest() {
160 SearchBody searchBody = new SearchBody();
161 SearchScope searchScope = new SearchScope();
162 searchScope.setCollectionId(collection.getId());
163 searchScope.setTraversalRules(new TraversalRules[] {});
164 searchBody.setScopes(new SearchScope[] { searchScope });
165 SearchParams searchParams = new SearchParams();
166 searchParams.setQueryType(QueryType.DataObject);
167 String query =
168 """
169 {
170 "AND": [
171 {
172 "property": "id",
173 "value": %d,
174 "operator": "eq"
175 },
176 {
177 "property": "name",
178 "value": "DataObjectSearchDummy1",
179 "operator": "eq"
180 }
181 ]
182 }""".formatted(dataObjectIO1.getId());
183 searchParams.setQuery(query);
184 searchBody.setSearchParams(searchParams);
185 var result = given()
186 .spec(requestSpecOfDefaultUser)
187 .body(searchBody)
188 .when()
189 .post(searchURL)
190 .then()
191 .statusCode(200)
192 .extract()
193 .as(ResponseBody.class);
194 ResultTriple triple1 = new ResultTriple(collection.getId(), dataObjectIO1.getId(), null);
195 assertThat(result.getResultSet()).contains(triple1);
196 }
197
198 @Test
199 @Order(4)
200 public void findNoDataObjectWithAndTest() {
201 SearchBody searchBody = new SearchBody();
202 SearchScope searchScope = new SearchScope();
203 searchScope.setCollectionId(collection.getId());
204 searchScope.setTraversalRules(new TraversalRules[] {});
205 searchBody.setScopes(new SearchScope[] { searchScope });
206 SearchParams searchParams = new SearchParams();
207 searchParams.setQueryType(QueryType.DataObject);
208 String query =
209 """
210 {
211 "AND": [
212 {
213 "property": "id",
214 "value": %d,
215 "operator": "eq"
216 },
217 {
218 "property": "name",
219 "value": "DataObjectSearchDummy2",
220 "operator": "eq"
221 }
222 ]
223 }""".formatted(dataObjectIO1.getId());
224 searchParams.setQuery(query);
225 searchBody.setSearchParams(searchParams);
226 var result = given()
227 .spec(requestSpecOfDefaultUser)
228 .body(searchBody)
229 .when()
230 .post(searchURL)
231 .then()
232 .statusCode(200)
233 .extract()
234 .as(ResponseBody.class);
235 assertEquals(0, result.getResultSet().length);
236 }
237
238 @Test
239 @Order(5)
240 public void findNoneOfTwoDataObjectsTest() {
241 SearchBody searchBody = new SearchBody();
242 SearchScope searchScope = new SearchScope();
243 searchScope.setCollectionId(collection.getId());
244 searchScope.setTraversalRules(new TraversalRules[] {});
245 searchBody.setScopes(new SearchScope[] { searchScope });
246 SearchParams searchParams = new SearchParams();
247 searchParams.setQueryType(QueryType.DataObject);
248 String query =
249 """
250 {
251 "AND": [
252 {
253 "property": "id",
254 "value": %d,
255 "operator": "eq"
256 },
257 {
258 "property": "name",
259 "value": "DataObjectSearchDummy2",
260 "operator": "eq"
261 }
262 ]
263 }""".formatted(dataObjectIO1.getId());
264 searchParams.setQuery(query);
265 searchBody.setSearchParams(searchParams);
266 var result = given()
267 .spec(requestSpecOfDefaultUser)
268 .body(searchBody)
269 .when()
270 .post(searchURL)
271 .then()
272 .statusCode(200)
273 .extract()
274 .as(ResponseBody.class);
275 ResultTriple triple1 = new ResultTriple(collection.getId(), dataObjectIO1.getId(), null);
276 ResultTriple triple2 = new ResultTriple(collection.getId(), dataObjectIO2.getId(), null);
277 assertThat(result.getResultSet()).doesNotContain(triple1, triple2);
278 }
279
280 @Test
281 @Order(6)
282 public void findOneOutOfTwoDataObjectsTest() {
283 SearchBody searchBody = new SearchBody();
284 SearchScope searchScope = new SearchScope();
285 searchScope.setCollectionId(collection.getId());
286 searchScope.setTraversalRules(new TraversalRules[] {});
287 searchBody.setScopes(new SearchScope[] { searchScope });
288 SearchParams searchParams = new SearchParams();
289 searchParams.setQueryType(QueryType.DataObject);
290 String query =
291 """
292 {
293 "AND": [
294 {
295 "property": "id",
296 "value": %d,
297 "operator": "eq"
298 },
299 {
300 "property": "name",
301 "value": "DataObjectSearchDummy",
302 "operator": "contains"
303 }
304 ]
305 }""".formatted(dataObjectIO2.getId());
306 searchParams.setQuery(query);
307 searchBody.setSearchParams(searchParams);
308 var result = given()
309 .spec(requestSpecOfDefaultUser)
310 .body(searchBody)
311 .when()
312 .post(searchURL)
313 .then()
314 .statusCode(200)
315 .extract()
316 .as(ResponseBody.class);
317 ResultTriple triple1 = new ResultTriple(collection.getId(), dataObjectIO1.getId(), null);
318 ResultTriple triple2 = new ResultTriple(collection.getId(), dataObjectIO2.getId(), null);
319 assertThat(result.getResultSet()).doesNotContain(triple1);
320 assertThat(result.getResultSet()).contains(triple2);
321 }
322
323 @Test
324 @Order(7)
325 public void findTwoDataObjectsWithOrTest() {
326 SearchBody searchBody = new SearchBody();
327 SearchScope searchScope = new SearchScope();
328 searchScope.setCollectionId(collection.getId());
329 searchScope.setTraversalRules(new TraversalRules[] {});
330 searchBody.setScopes(new SearchScope[] { searchScope });
331 SearchParams searchParams = new SearchParams();
332 searchParams.setQueryType(QueryType.DataObject);
333 String query =
334 """
335 {
336 "OR": [
337 {
338 "property": "id",
339 "value": %d,
340 "operator": "eq"
341 },
342 {
343 "property": "name",
344 "value": "DataObjectSearchDummy1",
345 "operator": "eq"
346 }
347 ]
348 }""".formatted(dataObjectIO2.getId());
349 searchParams.setQuery(query);
350 searchBody.setSearchParams(searchParams);
351 var result = given()
352 .spec(requestSpecOfDefaultUser)
353 .body(searchBody)
354 .when()
355 .post(searchURL)
356 .then()
357 .statusCode(200)
358 .extract()
359 .as(ResponseBody.class);
360 ResultTriple triple1 = new ResultTriple(collection.getId(), dataObjectIO1.getId(), null);
361 ResultTriple triple2 = new ResultTriple(collection.getId(), dataObjectIO2.getId(), null);
362 assertThat(result.getResultSet()).contains(triple1, triple2);
363 }
364
365 @Test
366 @Order(8)
367 public void findOneOutOfFourDataObjectsTest() {
368 SearchBody searchBody = new SearchBody();
369 SearchScope searchScope = new SearchScope();
370 searchScope.setCollectionId(collection.getId());
371 searchScope.setDataObjectId(dataObjectIO1.getId());
372 searchScope.setTraversalRules(new TraversalRules[] { TraversalRules.children });
373 searchBody.setScopes(new SearchScope[] { searchScope });
374 SearchParams searchParams = new SearchParams();
375 searchParams.setQueryType(QueryType.DataObject);
376 String query =
377 """
378 {
379 "AND": [
380 {
381 "property": "id",
382 "value": %d,
383 "operator": "eq"
384 },
385 {
386 "property": "name",
387 "value": "DataObjectSearchDummy4",
388 "operator": "eq"
389 }
390 ]}""".formatted(dataObjectIO4.getId());
391 searchParams.setQuery(query);
392 searchBody.setSearchParams(searchParams);
393 var result = given()
394 .spec(requestSpecOfDefaultUser)
395 .body(searchBody)
396 .when()
397 .post(searchURL)
398 .then()
399 .statusCode(200)
400 .extract()
401 .as(ResponseBody.class);
402 ResultTriple triple1 = new ResultTriple(collection.getId(), dataObjectIO1.getId(), null);
403 ResultTriple triple2 = new ResultTriple(collection.getId(), dataObjectIO2.getId(), null);
404 ResultTriple triple3 = new ResultTriple(collection.getId(), dataObjectIO3.getId(), null);
405 ResultTriple triple4 = new ResultTriple(collection.getId(), dataObjectIO4.getId(), null);
406 assertThat(result.getResultSet()).doesNotContain(triple1, triple2, triple3);
407 assertThat(result.getResultSet()).contains(triple4);
408 }
409
410 @Test
411 @Order(8)
412 public void findAnotherOneOutOfFourDataObjectsByParentsTest() {
413 SearchBody searchBody = new SearchBody();
414 SearchScope searchScope = new SearchScope();
415 searchScope.setCollectionId(collection.getId());
416 searchScope.setDataObjectId(dataObjectIO4.getId());
417 searchScope.setTraversalRules(new TraversalRules[] { TraversalRules.parents });
418 searchBody.setScopes(new SearchScope[] { searchScope });
419 SearchParams searchParams = new SearchParams();
420 searchParams.setQueryType(QueryType.DataObject);
421 String query =
422 """
423 {
424 "AND": [
425 {
426 "property": "id",
427 "value": %d,
428 "operator": "eq"
429 },
430 {
431 "property": "name",
432 "value": "DataObjectSearchDummy1",
433 "operator": "eq"
434 }
435 ]}""".formatted(dataObjectIO1.getId());
436 searchParams.setQuery(query);
437 searchBody.setSearchParams(searchParams);
438 var result = given()
439 .spec(requestSpecOfDefaultUser)
440 .body(searchBody)
441 .when()
442 .post(searchURL)
443 .then()
444 .statusCode(200)
445 .extract()
446 .as(ResponseBody.class);
447 ResultTriple triple1 = new ResultTriple(collection.getId(), dataObjectIO1.getId(), null);
448 ResultTriple triple2 = new ResultTriple(collection.getId(), dataObjectIO2.getId(), null);
449 ResultTriple triple3 = new ResultTriple(collection.getId(), dataObjectIO3.getId(), null);
450 ResultTriple triple4 = new ResultTriple(collection.getId(), dataObjectIO4.getId(), null);
451 assertThat(result.getResultSet()).contains(triple1);
452 assertThat(result.getResultSet()).doesNotContain(triple2, triple3, triple4);
453 }
454
455 @Test
456 @Order(10)
457 public void stringContainsTest() {
458 SearchBody searchBody = new SearchBody();
459 SearchScope searchScope = new SearchScope();
460 searchScope.setTraversalRules(new TraversalRules[] {});
461 searchBody.setScopes(new SearchScope[] { searchScope });
462 SearchParams searchParams = new SearchParams();
463 searchParams.setQueryType(QueryType.DataObject);
464 String query =
465 """
466 {
467 "property": "name",
468 "value": "ummy",
469 "operator": "contains"
470 }""";
471 searchParams.setQuery(query);
472 searchBody.setSearchParams(searchParams);
473 var result = given()
474 .spec(requestSpecOfDefaultUser)
475 .body(searchBody)
476 .when()
477 .post(searchURL)
478 .then()
479 .statusCode(200)
480 .extract()
481 .as(ResponseBody.class);
482 ResultTriple triple1 = new ResultTriple(collection.getId(), dataObjectIO1.getId(), null);
483 ResultTriple triple2 = new ResultTriple(collection.getId(), dataObjectIO2.getId(), null);
484 ResultTriple triple3 = new ResultTriple(collection.getId(), dataObjectIO3.getId(), null);
485 ResultTriple triple4 = new ResultTriple(collection.getId(), dataObjectIO4.getId(), null);
486 assertThat(result.getResultSet()).contains(triple1, triple2, triple3, triple4);
487 }
488
489 @Test
490 @Order(11)
491 public void unauthorizedUserTest() {
492 SearchBody searchBody = new SearchBody();
493 SearchScope searchScope = new SearchScope();
494 searchScope.setTraversalRules(new TraversalRules[] {});
495 searchBody.setScopes(new SearchScope[] { searchScope });
496 SearchParams searchParams = new SearchParams();
497 searchParams.setQueryType(QueryType.DataObject);
498 String query =
499 """
500 {
501 "property": "referencedDataObjectId",
502 "value": "ummy",
503 "operator": "eq"
504 }""";
505 searchParams.setQuery(query);
506 searchBody.setSearchParams(searchParams);
507 var result = given()
508 .spec(requestSpecOfOtherUser)
509 .body(searchBody)
510 .when()
511 .post(searchURL)
512 .then()
513 .statusCode(200)
514 .extract()
515 .as(ResponseBody.class);
516 assertEquals(0, result.getResultSet().length);
517 }
518
519 private static DataObjectIO createDataObjectWithParent(String name, long collectionId, long parentID) {
520 var dataObjectsURL = "/%s/%d/%s/".formatted(Constants.COLLECTIONS, collectionId, Constants.DATA_OBJECTS);
521
522 DataObjectIO dataObjectIO = new DataObjectIO();
523 dataObjectIO.setName(name);
524 dataObjectIO.setParentId(parentID);
525 var dataObject = given()
526 .spec(requestSpecOfDefaultUser)
527 .body(dataObjectIO)
528 .when()
529 .post(dataObjectsURL)
530 .then()
531 .statusCode(201)
532 .extract()
533 .as(DataObjectIO.class);
534 return dataObject;
535 }
536 }