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 = String.format("/%s/%d/%s", 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 = String.format(
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 }""",
99 dataObjectIO1.getId()
100 );
101 searchParams.setQuery(query);
102 searchBody.setSearchParams(searchParams);
103 var result = given()
104 .spec(requestSpecOfDefaultUser)
105 .body(searchBody)
106 .when()
107 .post(searchURL)
108 .then()
109 .statusCode(200)
110 .extract()
111 .as(ResponseBody.class);
112 ResultTriple triple1 = new ResultTriple(collection.getId(), dataObjectIO1.getId(), null);
113 assertThat(result.getResultSet()).contains(triple1);
114 assertThat(result.getResults()[0].getId()).isEqualTo(dataObjectIO1.getId());
115 assertThat(result.getSearchParams()).isEqualTo(searchParams);
116 }
117
118 @Test
119 @Order(2)
120 public void findOneDataObjectWithAndAttributesTest() {
121 SearchBody searchBody = new SearchBody();
122 SearchScope searchScope = new SearchScope();
123 searchScope.setCollectionId(collection.getId());
124 searchScope.setTraversalRules(new TraversalRules[] {});
125 searchBody.setScopes(new SearchScope[] { searchScope });
126 SearchParams searchParams = new SearchParams();
127 searchParams.setQueryType(QueryType.DataObject);
128 String query = String.format(
129 """
130 {
131 "AND": [
132 {
133 "property": "id",
134 "value": %d,
135 "operator": "eq"
136 },
137 {
138 "property": "attributes.a",
139 "value": "1",
140 "operator": "eq"
141 }
142 ]
143 }""",
144 dataObjectIO1.getId()
145 );
146 searchParams.setQuery(query);
147 searchBody.setSearchParams(searchParams);
148 var result = given()
149 .spec(requestSpecOfDefaultUser)
150 .body(searchBody)
151 .when()
152 .post(searchURL)
153 .then()
154 .statusCode(200)
155 .extract()
156 .as(ResponseBody.class);
157 ResultTriple triple1 = new ResultTriple(collection.getId(), dataObjectIO1.getId(), null);
158 assertThat(result.getResultSet()).contains(triple1);
159 }
160
161 @Test
162 @Order(3)
163 public void findOneDataObjectWithAndNameTest() {
164 SearchBody searchBody = new SearchBody();
165 SearchScope searchScope = new SearchScope();
166 searchScope.setCollectionId(collection.getId());
167 searchScope.setTraversalRules(new TraversalRules[] {});
168 searchBody.setScopes(new SearchScope[] { searchScope });
169 SearchParams searchParams = new SearchParams();
170 searchParams.setQueryType(QueryType.DataObject);
171 String query = String.format(
172 """
173 {
174 "AND": [
175 {
176 "property": "id",
177 "value": %d,
178 "operator": "eq"
179 },
180 {
181 "property": "name",
182 "value": "DataObjectSearchDummy1",
183 "operator": "eq"
184 }
185 ]
186 }""",
187 dataObjectIO1.getId()
188 );
189 searchParams.setQuery(query);
190 searchBody.setSearchParams(searchParams);
191 var result = given()
192 .spec(requestSpecOfDefaultUser)
193 .body(searchBody)
194 .when()
195 .post(searchURL)
196 .then()
197 .statusCode(200)
198 .extract()
199 .as(ResponseBody.class);
200 ResultTriple triple1 = new ResultTriple(collection.getId(), dataObjectIO1.getId(), null);
201 assertThat(result.getResultSet()).contains(triple1);
202 }
203
204 @Test
205 @Order(4)
206 public void findNoDataObjectWithAndTest() {
207 SearchBody searchBody = new SearchBody();
208 SearchScope searchScope = new SearchScope();
209 searchScope.setCollectionId(collection.getId());
210 searchScope.setTraversalRules(new TraversalRules[] {});
211 searchBody.setScopes(new SearchScope[] { searchScope });
212 SearchParams searchParams = new SearchParams();
213 searchParams.setQueryType(QueryType.DataObject);
214 String query = String.format(
215 """
216 {
217 "AND": [
218 {
219 "property": "id",
220 "value": %d,
221 "operator": "eq"
222 },
223 {
224 "property": "name",
225 "value": "DataObjectSearchDummy2",
226 "operator": "eq"
227 }
228 ]
229 }""",
230 dataObjectIO1.getId()
231 );
232 searchParams.setQuery(query);
233 searchBody.setSearchParams(searchParams);
234 var result = given()
235 .spec(requestSpecOfDefaultUser)
236 .body(searchBody)
237 .when()
238 .post(searchURL)
239 .then()
240 .statusCode(200)
241 .extract()
242 .as(ResponseBody.class);
243 assertEquals(0, result.getResultSet().length);
244 }
245
246 @Test
247 @Order(5)
248 public void findNoneOfTwoDataObjectsTest() {
249 SearchBody searchBody = new SearchBody();
250 SearchScope searchScope = new SearchScope();
251 searchScope.setCollectionId(collection.getId());
252 searchScope.setTraversalRules(new TraversalRules[] {});
253 searchBody.setScopes(new SearchScope[] { searchScope });
254 SearchParams searchParams = new SearchParams();
255 searchParams.setQueryType(QueryType.DataObject);
256 String query = String.format(
257 """
258 {
259 "AND": [
260 {
261 "property": "id",
262 "value": %d,
263 "operator": "eq"
264 },
265 {
266 "property": "name",
267 "value": "DataObjectSearchDummy2",
268 "operator": "eq"
269 }
270 ]
271 }""",
272 dataObjectIO1.getId()
273 );
274 searchParams.setQuery(query);
275 searchBody.setSearchParams(searchParams);
276 var result = given()
277 .spec(requestSpecOfDefaultUser)
278 .body(searchBody)
279 .when()
280 .post(searchURL)
281 .then()
282 .statusCode(200)
283 .extract()
284 .as(ResponseBody.class);
285 ResultTriple triple1 = new ResultTriple(collection.getId(), dataObjectIO1.getId(), null);
286 ResultTriple triple2 = new ResultTriple(collection.getId(), dataObjectIO2.getId(), null);
287 assertThat(result.getResultSet()).doesNotContain(triple1, triple2);
288 }
289
290 @Test
291 @Order(6)
292 public void findOneOutOfTwoDataObjectsTest() {
293 SearchBody searchBody = new SearchBody();
294 SearchScope searchScope = new SearchScope();
295 searchScope.setCollectionId(collection.getId());
296 searchScope.setTraversalRules(new TraversalRules[] {});
297 searchBody.setScopes(new SearchScope[] { searchScope });
298 SearchParams searchParams = new SearchParams();
299 searchParams.setQueryType(QueryType.DataObject);
300 String query = String.format(
301 """
302 {
303 "AND": [
304 {
305 "property": "id",
306 "value": %d,
307 "operator": "eq"
308 },
309 {
310 "property": "name",
311 "value": "DataObjectSearchDummy",
312 "operator": "contains"
313 }
314 ]
315 }""",
316 dataObjectIO2.getId()
317 );
318 searchParams.setQuery(query);
319 searchBody.setSearchParams(searchParams);
320 var result = given()
321 .spec(requestSpecOfDefaultUser)
322 .body(searchBody)
323 .when()
324 .post(searchURL)
325 .then()
326 .statusCode(200)
327 .extract()
328 .as(ResponseBody.class);
329 ResultTriple triple1 = new ResultTriple(collection.getId(), dataObjectIO1.getId(), null);
330 ResultTriple triple2 = new ResultTriple(collection.getId(), dataObjectIO2.getId(), null);
331 assertThat(result.getResultSet()).doesNotContain(triple1);
332 assertThat(result.getResultSet()).contains(triple2);
333 }
334
335 @Test
336 @Order(7)
337 public void findTwoDataObjectsWithOrTest() {
338 SearchBody searchBody = new SearchBody();
339 SearchScope searchScope = new SearchScope();
340 searchScope.setCollectionId(collection.getId());
341 searchScope.setTraversalRules(new TraversalRules[] {});
342 searchBody.setScopes(new SearchScope[] { searchScope });
343 SearchParams searchParams = new SearchParams();
344 searchParams.setQueryType(QueryType.DataObject);
345 String query = String.format(
346 """
347 {
348 "OR": [
349 {
350 "property": "id",
351 "value": %d,
352 "operator": "eq"
353 },
354 {
355 "property": "name",
356 "value": "DataObjectSearchDummy1",
357 "operator": "eq"
358 }
359 ]
360 }""",
361 dataObjectIO2.getId()
362 );
363 searchParams.setQuery(query);
364 searchBody.setSearchParams(searchParams);
365 var result = given()
366 .spec(requestSpecOfDefaultUser)
367 .body(searchBody)
368 .when()
369 .post(searchURL)
370 .then()
371 .statusCode(200)
372 .extract()
373 .as(ResponseBody.class);
374 ResultTriple triple1 = new ResultTriple(collection.getId(), dataObjectIO1.getId(), null);
375 ResultTriple triple2 = new ResultTriple(collection.getId(), dataObjectIO2.getId(), null);
376 assertThat(result.getResultSet()).contains(triple1, triple2);
377 }
378
379 @Test
380 @Order(8)
381 public void findOneOutOfFourDataObjectsTest() {
382 SearchBody searchBody = new SearchBody();
383 SearchScope searchScope = new SearchScope();
384 searchScope.setCollectionId(collection.getId());
385 searchScope.setDataObjectId(dataObjectIO1.getId());
386 searchScope.setTraversalRules(new TraversalRules[] { TraversalRules.children });
387 searchBody.setScopes(new SearchScope[] { searchScope });
388 SearchParams searchParams = new SearchParams();
389 searchParams.setQueryType(QueryType.DataObject);
390 String query = String.format(
391 """
392 {
393 "AND": [
394 {
395 "property": "id",
396 "value": %d,
397 "operator": "eq"
398 },
399 {
400 "property": "name",
401 "value": "DataObjectSearchDummy4",
402 "operator": "eq"
403 }
404 ]}""",
405 dataObjectIO4.getId()
406 );
407 searchParams.setQuery(query);
408 searchBody.setSearchParams(searchParams);
409 var result = given()
410 .spec(requestSpecOfDefaultUser)
411 .body(searchBody)
412 .when()
413 .post(searchURL)
414 .then()
415 .statusCode(200)
416 .extract()
417 .as(ResponseBody.class);
418 ResultTriple triple1 = new ResultTriple(collection.getId(), dataObjectIO1.getId(), null);
419 ResultTriple triple2 = new ResultTriple(collection.getId(), dataObjectIO2.getId(), null);
420 ResultTriple triple3 = new ResultTriple(collection.getId(), dataObjectIO3.getId(), null);
421 ResultTriple triple4 = new ResultTriple(collection.getId(), dataObjectIO4.getId(), null);
422 assertThat(result.getResultSet()).doesNotContain(triple1, triple2, triple3);
423 assertThat(result.getResultSet()).contains(triple4);
424 }
425
426 @Test
427 @Order(8)
428 public void findAnotherOneOutOfFourDataObjectsByParentsTest() {
429 SearchBody searchBody = new SearchBody();
430 SearchScope searchScope = new SearchScope();
431 searchScope.setCollectionId(collection.getId());
432 searchScope.setDataObjectId(dataObjectIO4.getId());
433 searchScope.setTraversalRules(new TraversalRules[] { TraversalRules.parents });
434 searchBody.setScopes(new SearchScope[] { searchScope });
435 SearchParams searchParams = new SearchParams();
436 searchParams.setQueryType(QueryType.DataObject);
437 String query = String.format(
438 """
439 {
440 "AND": [
441 {
442 "property": "id",
443 "value": %d,
444 "operator": "eq"
445 },
446 {
447 "property": "name",
448 "value": "DataObjectSearchDummy1",
449 "operator": "eq"
450 }
451 ]}""",
452 dataObjectIO1.getId()
453 );
454 searchParams.setQuery(query);
455 searchBody.setSearchParams(searchParams);
456 var result = given()
457 .spec(requestSpecOfDefaultUser)
458 .body(searchBody)
459 .when()
460 .post(searchURL)
461 .then()
462 .statusCode(200)
463 .extract()
464 .as(ResponseBody.class);
465 ResultTriple triple1 = new ResultTriple(collection.getId(), dataObjectIO1.getId(), null);
466 ResultTriple triple2 = new ResultTriple(collection.getId(), dataObjectIO2.getId(), null);
467 ResultTriple triple3 = new ResultTriple(collection.getId(), dataObjectIO3.getId(), null);
468 ResultTriple triple4 = new ResultTriple(collection.getId(), dataObjectIO4.getId(), null);
469 assertThat(result.getResultSet()).contains(triple1);
470 assertThat(result.getResultSet()).doesNotContain(triple2, triple3, triple4);
471 }
472
473 @Test
474 @Order(10)
475 public void stringContainsTest() {
476 SearchBody searchBody = new SearchBody();
477 SearchScope searchScope = new SearchScope();
478 searchScope.setTraversalRules(new TraversalRules[] {});
479 searchBody.setScopes(new SearchScope[] { searchScope });
480 SearchParams searchParams = new SearchParams();
481 searchParams.setQueryType(QueryType.DataObject);
482 String query =
483 """
484 {
485 "property": "name",
486 "value": "ummy",
487 "operator": "contains"
488 }""";
489 searchParams.setQuery(query);
490 searchBody.setSearchParams(searchParams);
491 var result = given()
492 .spec(requestSpecOfDefaultUser)
493 .body(searchBody)
494 .when()
495 .post(searchURL)
496 .then()
497 .statusCode(200)
498 .extract()
499 .as(ResponseBody.class);
500 ResultTriple triple1 = new ResultTriple(collection.getId(), dataObjectIO1.getId(), null);
501 ResultTriple triple2 = new ResultTriple(collection.getId(), dataObjectIO2.getId(), null);
502 ResultTriple triple3 = new ResultTriple(collection.getId(), dataObjectIO3.getId(), null);
503 ResultTriple triple4 = new ResultTriple(collection.getId(), dataObjectIO4.getId(), null);
504 assertThat(result.getResultSet()).contains(triple1, triple2, triple3, triple4);
505 }
506
507 @Test
508 @Order(11)
509 public void unauthorizedUserTest() {
510 SearchBody searchBody = new SearchBody();
511 SearchScope searchScope = new SearchScope();
512 searchScope.setTraversalRules(new TraversalRules[] {});
513 searchBody.setScopes(new SearchScope[] { searchScope });
514 SearchParams searchParams = new SearchParams();
515 searchParams.setQueryType(QueryType.DataObject);
516 String query =
517 """
518 {
519 "property": "referencedDataObjectId",
520 "value": "ummy",
521 "operator": "eq"
522 }""";
523 searchParams.setQuery(query);
524 searchBody.setSearchParams(searchParams);
525 var result = given()
526 .spec(requestSpecOfOtherUser)
527 .body(searchBody)
528 .when()
529 .post(searchURL)
530 .then()
531 .statusCode(200)
532 .extract()
533 .as(ResponseBody.class);
534 assertEquals(0, result.getResultSet().length);
535 }
536
537 private static DataObjectIO createDataObjectWithParent(String name, long collectionId, long parentID) {
538 var dataObjectsURL = String.format("/%s/%d/%s/", Constants.COLLECTIONS, collectionId, Constants.DATA_OBJECTS);
539
540 DataObjectIO dataObjectIO = new DataObjectIO();
541 dataObjectIO.setName(name);
542 dataObjectIO.setParentId(parentID);
543 var dataObject = given()
544 .spec(requestSpecOfDefaultUser)
545 .body(dataObjectIO)
546 .when()
547 .post(dataObjectsURL)
548 .then()
549 .statusCode(201)
550 .extract()
551 .as(DataObjectIO.class);
552 return dataObject;
553 }
554 }