View Javadoc
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 }