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   
6   import de.dlr.shepard.auth.permission.io.PermissionsIO;
7   import de.dlr.shepard.auth.users.io.UserGroupIO;
8   import de.dlr.shepard.common.search.io.QueryType;
9   import de.dlr.shepard.common.search.io.ResponseBody;
10  import de.dlr.shepard.common.search.io.ResultTriple;
11  import de.dlr.shepard.common.search.io.SearchBody;
12  import de.dlr.shepard.common.search.io.SearchParams;
13  import de.dlr.shepard.common.search.io.SearchScope;
14  import de.dlr.shepard.common.util.Constants;
15  import de.dlr.shepard.common.util.TraversalRules;
16  import de.dlr.shepard.context.collection.io.CollectionIO;
17  import de.dlr.shepard.context.semantic.SemanticRepositoryType;
18  import de.dlr.shepard.context.semantic.io.SemanticAnnotationIO;
19  import de.dlr.shepard.context.semantic.io.SemanticRepositoryIO;
20  import io.quarkus.test.common.WithTestResource;
21  import io.quarkus.test.junit.QuarkusIntegrationTest;
22  import java.util.Map;
23  import org.junit.jupiter.api.BeforeAll;
24  import org.junit.jupiter.api.MethodOrderer;
25  import org.junit.jupiter.api.Order;
26  import org.junit.jupiter.api.Test;
27  import org.junit.jupiter.api.TestMethodOrder;
28  
29  @QuarkusIntegrationTest
30  @WithTestResource(WireMockResource.class)
31  @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
32  public class CollectionSearcherIT extends BaseTestCaseIT {
33  
34    private static String collectionsURL;
35    private static CollectionIO collection1;
36    private static CollectionIO collection2;
37    private static String searchURL;
38  
39    private static String repositoryURL;
40    private static SemanticRepositoryIO repository;
41    private static SemanticAnnotationIO annotation;
42    private static CollectionIO annotatedCollection;
43    private static String annotatedCollectionURL;
44  
45    @BeforeAll
46    public static void setUp() {
47      collectionsURL = "/" + Constants.COLLECTIONS;
48  
49      var payload1 = new CollectionIO();
50      payload1.setName("CollectionDummy");
51      payload1.setDescription("First Collection");
52      payload1.setAttributes(Map.of("a", "1", "b", "2"));
53      collection1 = given()
54        .spec(requestSpecOfDefaultUser)
55        .body(payload1)
56        .when()
57        .post(collectionsURL)
58        .then()
59        .statusCode(201)
60        .extract()
61        .as(CollectionIO.class);
62      var payload2 = new CollectionIO();
63      payload2.setName("secondCollectionDummy");
64      payload2.setDescription("Second Collection");
65      collection2 = given()
66        .spec(requestSpecOfDefaultUser)
67        .body(payload2)
68        .when()
69        .post(collectionsURL)
70        .then()
71        .statusCode(201)
72        .extract()
73        .as(CollectionIO.class);
74      searchURL = "/" + Constants.SEARCH;
75  
76      // for search involving SemanticAnnotations
77      repositoryURL = "/" + Constants.SEMANTIC_REPOSITORIES;
78      annotatedCollection = createCollection("SemanticsCollection");
79      annotatedCollectionURL = String.format(
80        "/%s/%d/semanticAnnotations",
81        Constants.COLLECTIONS,
82        annotatedCollection.getId()
83      );
84      var repositoryToCreate = new SemanticRepositoryIO();
85      repositoryToCreate.setName("SemanticRepository");
86      repositoryToCreate.setType(SemanticRepositoryType.SPARQL);
87      repositoryToCreate.setEndpoint(WireMockResource.getWireMockServerURlWithPath("/sparql"));
88      repository = given()
89        .spec(requestSpecOfDefaultUser)
90        .body(repositoryToCreate)
91        .when()
92        .post(repositoryURL)
93        .then()
94        .statusCode(201)
95        .extract()
96        .as(SemanticRepositoryIO.class);
97  
98      var annotationToCreate = new SemanticAnnotationIO();
99      annotationToCreate.setPropertyIRI("http://dbpedia.org/ontology/ingredient");
100     annotationToCreate.setPropertyRepositoryId(repository.getId());
101     annotationToCreate.setValueIRI("http://dbpedia.org/resource/Almond_milk");
102     annotationToCreate.setValueRepositoryId(repository.getId());
103     annotation = given()
104       .spec(requestSpecOfDefaultUser)
105       .body(annotationToCreate)
106       .when()
107       .post(annotatedCollectionURL)
108       .then()
109       .statusCode(201)
110       .extract()
111       .as(SemanticAnnotationIO.class);
112   }
113 
114   @Test
115   @Order(1)
116   public void findOneOutOfTwoCollectionsTest() {
117     SearchBody searchBody = new SearchBody();
118     SearchScope searchScope = new SearchScope();
119     searchScope.setTraversalRules(new TraversalRules[] {});
120     searchBody.setScopes(new SearchScope[] { searchScope });
121     SearchParams searchParams = new SearchParams();
122     searchParams.setQueryType(QueryType.Collection);
123     String query = String.format(
124       """
125       {
126         "OR": [
127           {
128             "property": "id",
129             "value": %d,
130             "operator": "eq"
131           },
132           {
133             "property": "number",
134             "value": 123,
135             "operator": "le"
136           }
137       ]}""",
138       collection1.getId()
139     );
140     searchParams.setQuery(query);
141     searchBody.setSearchParams(searchParams);
142     var result = given()
143       .spec(requestSpecOfDefaultUser)
144       .body(searchBody)
145       .when()
146       .post(searchURL)
147       .then()
148       .statusCode(200)
149       .extract()
150       .as(ResponseBody.class);
151     ResultTriple triple1 = new ResultTriple(collection1.getId(), null, null);
152     assertThat(result.getResultSet()).containsExactly(triple1);
153     assertThat(result.getResults()[0].getId()).isEqualTo(collection1.getId());
154     assertThat(result.getSearchParams()).isEqualTo(searchParams);
155   }
156 
157   @Test
158   @Order(2)
159   public void findCollectionByAttribute() {
160     SearchBody searchBody = new SearchBody();
161     SearchScope searchScope = new SearchScope();
162     searchScope.setTraversalRules(new TraversalRules[] {});
163     searchBody.setScopes(new SearchScope[] { searchScope });
164     SearchParams searchParams = new SearchParams();
165     searchParams.setQueryType(QueryType.Collection);
166     String query = String.format(
167       """
168       {
169         "AND": [
170           {
171             "property": "id",
172             "value": %d,
173             "operator": "eq"
174           },
175           {
176             "property": "attributes.a",
177             "value": "1",
178             "operator": "eq"
179           }
180         ]
181       }""",
182       collection1.getId()
183     );
184     searchParams.setQuery(query);
185     searchBody.setSearchParams(searchParams);
186     var result = given()
187       .spec(requestSpecOfDefaultUser)
188       .body(searchBody)
189       .when()
190       .post(searchURL)
191       .then()
192       .statusCode(200)
193       .extract()
194       .as(ResponseBody.class);
195     ResultTriple triple1 = new ResultTriple(collection1.getId(), null, null);
196     assertThat(result.getResultSet()).containsExactly(triple1);
197     assertThat(result.getResults()[0].getId()).isEqualTo(collection1.getId());
198     assertThat(result.getSearchParams()).isEqualTo(searchParams);
199   }
200 
201   @Test
202   @Order(3)
203   public void neTest() {
204     SearchBody searchBody = new SearchBody();
205     SearchScope searchScope = new SearchScope();
206     searchScope.setTraversalRules(new TraversalRules[] {});
207     searchBody.setScopes(new SearchScope[] { searchScope });
208     SearchParams searchParams = new SearchParams();
209     searchParams.setQueryType(QueryType.Collection);
210     String query = String.format(
211       """
212       {
213         "property": "id",
214         "value": %d,
215         "operator": "ne"
216       }""",
217       collection1.getId()
218     );
219     searchParams.setQuery(query);
220     searchBody.setSearchParams(searchParams);
221     var result = given()
222       .spec(requestSpecOfDefaultUser)
223       .body(searchBody)
224       .when()
225       .post(searchURL)
226       .then()
227       .statusCode(200)
228       .extract()
229       .as(ResponseBody.class);
230     ResultTriple triple1 = new ResultTriple(collection1.getId(), null, null);
231     assertThat(result.getResultSet()).doesNotContain(triple1);
232   }
233 
234   @Test
235   @Order(4)
236   public void findTwoOutOfTwoCollectionsTest() {
237     SearchBody searchBody = new SearchBody();
238     SearchScope searchScope = new SearchScope();
239     searchScope.setTraversalRules(new TraversalRules[] {});
240     searchBody.setScopes(new SearchScope[] { searchScope });
241     SearchParams searchParams = new SearchParams();
242     searchParams.setQueryType(QueryType.Collection);
243     String query = String.format(
244       """
245       {
246         "OR": [
247           {
248             "property": "id",
249             "value": %d,
250             "operator": "ge"
251           },
252           {
253             "property": "id",
254             "value": %d,
255             "operator": "le"
256           }
257       ]}""",
258       collection1.getId(),
259       collection2.getId()
260     );
261     searchParams.setQuery(query);
262     searchBody.setSearchParams(searchParams);
263     var result = given()
264       .spec(requestSpecOfDefaultUser)
265       .body(searchBody)
266       .when()
267       .post(searchURL)
268       .then()
269       .statusCode(200)
270       .extract()
271       .as(ResponseBody.class);
272     ResultTriple triple1 = new ResultTriple(collection1.getId(), null, null);
273     ResultTriple triple2 = new ResultTriple(collection2.getId(), null, null);
274     assertThat(result.getResultSet()).contains(triple1, triple2);
275   }
276 
277   @Test
278   @Order(5)
279   public void findNoCollectionTest() {
280     SearchBody searchBody = new SearchBody();
281     SearchScope searchScope = new SearchScope();
282     searchScope.setTraversalRules(new TraversalRules[] {});
283     searchBody.setScopes(new SearchScope[] { searchScope });
284     SearchParams searchParams = new SearchParams();
285     searchParams.setQueryType(QueryType.Collection);
286     String query = String.format(
287       """
288       {
289         "AND": [
290           {
291             "property": "id",
292             "value": %d,
293             "operator": "gt"
294           },
295           {
296             "property": "id",
297             "value": %d,
298             "operator": "gt"
299           }
300       ]}""",
301       collection1.getId(),
302       collection2.getId()
303     );
304     searchParams.setQuery(query);
305     searchBody.setSearchParams(searchParams);
306     var result = given()
307       .spec(requestSpecOfDefaultUser)
308       .body(searchBody)
309       .when()
310       .post(searchURL)
311       .then()
312       .statusCode(200)
313       .extract()
314       .as(ResponseBody.class);
315     ResultTriple triple1 = new ResultTriple(collection1.getId(), null, null);
316     ResultTriple triple2 = new ResultTriple(collection2.getId(), null, null);
317     assertThat(result.getResultSet()).doesNotContain(triple1, triple2);
318   }
319 
320   @Test
321   @Order(6)
322   public void findByAndTest() {
323     SearchBody searchBody = new SearchBody();
324     SearchScope searchScope = new SearchScope();
325     searchScope.setTraversalRules(new TraversalRules[] {});
326     searchBody.setScopes(new SearchScope[] { searchScope });
327     SearchParams searchParams = new SearchParams();
328     searchParams.setQueryType(QueryType.Collection);
329     String query = String.format(
330       """
331       {
332         "AND": [
333           {
334             "property": "id",
335             "value": %d,
336             "operator": "eq"
337           },
338           {
339             "property": "name",
340             "value": "%s",
341             "operator": "eq"
342           }
343       ]}""",
344       collection1.getId(),
345       collection1.getName()
346     );
347     searchParams.setQuery(query);
348     searchBody.setSearchParams(searchParams);
349     var result = given()
350       .spec(requestSpecOfDefaultUser)
351       .body(searchBody)
352       .when()
353       .post(searchURL)
354       .then()
355       .statusCode(200)
356       .extract()
357       .as(ResponseBody.class);
358     ResultTriple triple1 = new ResultTriple(collection1.getId(), null, null);
359     ResultTriple triple2 = new ResultTriple(collection2.getId(), null, null);
360     assertThat(result.getResultSet()).contains(triple1);
361     assertThat(result.getResultSet()).doesNotContain(triple2);
362   }
363 
364   @Test
365   @Order(7)
366   public void unauthorizedCollectionsSearchTest() {
367     SearchBody searchBody = new SearchBody();
368     SearchScope searchScope = new SearchScope();
369     searchScope.setTraversalRules(new TraversalRules[] {});
370     searchBody.setScopes(new SearchScope[] { searchScope });
371     SearchParams searchParams = new SearchParams();
372     searchParams.setQueryType(QueryType.Collection);
373     String query = String.format(
374       """
375       {
376         "OR": [
377           {
378             "property": "id",
379             "value": %d,
380             "operator": "ge"
381           },
382           {
383             "property": "id",
384             "value": %d,
385             "operator": "le"
386           }
387       ]}""",
388       collection1.getId(),
389       collection2.getId()
390     );
391     searchParams.setQuery(query);
392     searchBody.setSearchParams(searchParams);
393     var result = given()
394       .spec(requestSpecOfOtherUser)
395       .body(searchBody)
396       .when()
397       .post(searchURL)
398       .then()
399       .statusCode(200)
400       .extract()
401       .as(ResponseBody.class);
402     ResultTriple triple1 = new ResultTriple(collection1.getId(), null, null);
403     ResultTriple triple2 = new ResultTriple(collection2.getId(), null, null);
404     assertThat(result.getResultSet()).doesNotContain(triple1, triple2);
405   }
406 
407   @Test
408   @Order(8)
409   public void authorizedCollectionsSearchTest() {
410     String permissionsURL = "/collections/" + collection1.getId() + "/permissions";
411     PermissionsIO permissions = given()
412       .spec(requestSpecOfDefaultUser)
413       .when()
414       .get(permissionsURL)
415       .then()
416       .statusCode(200)
417       .extract()
418       .as(PermissionsIO.class);
419     String[] reader = { otherUser.getUser().getUsername() };
420     permissions.setReader(reader);
421     given()
422       .spec(requestSpecOfDefaultUser)
423       .body(permissions)
424       .when()
425       .put(permissionsURL)
426       .then()
427       .statusCode(200)
428       .extract()
429       .as(PermissionsIO.class);
430     SearchBody searchBody = new SearchBody();
431     SearchScope searchScope = new SearchScope();
432     searchScope.setTraversalRules(new TraversalRules[] {});
433     searchBody.setScopes(new SearchScope[] { searchScope });
434     SearchParams searchParams = new SearchParams();
435     searchParams.setQueryType(QueryType.Collection);
436     String query = String.format(
437       """
438       	{
439         "OR": [
440           {
441             "property": "id",
442             "value": %d,
443             "operator": "ge"
444           },
445           {
446             "property": "id",
447             "value": %d,
448             "operator": "le"
449           }
450       ]}""",
451       collection1.getId(),
452       collection2.getId()
453     );
454     searchParams.setQuery(query);
455     searchBody.setSearchParams(searchParams);
456     var result = given()
457       .spec(requestSpecOfOtherUser)
458       .body(searchBody)
459       .when()
460       .post(searchURL)
461       .then()
462       .statusCode(200)
463       .extract()
464       .as(ResponseBody.class);
465     ResultTriple triple1 = new ResultTriple(collection1.getId(), null, null);
466     ResultTriple triple2 = new ResultTriple(collection2.getId(), null, null);
467     assertThat(result.getResultSet()).contains(triple1);
468     assertThat(result.getResultSet()).doesNotContain(triple2);
469   }
470 
471   @Test
472   @Order(9)
473   public void collectionsSearchTestReaderGroup() {
474     String userGroupURL = "/" + Constants.USERGROUPS;
475     UserGroupIO userGroup = new UserGroupIO();
476     userGroup.setName("userGroup");
477     userGroup.setUsernames(new String[] { otherUser.getUser().getUsername() });
478     UserGroupIO userGroupCreated = given()
479       .spec(requestSpecOfDefaultUser)
480       .body(userGroup)
481       .when()
482       .post(userGroupURL)
483       .then()
484       .statusCode(201)
485       .extract()
486       .as(UserGroupIO.class);
487 
488     String permissionsURL = "/" + Constants.COLLECTIONS + "/" + collection2.getId() + "/" + Constants.PERMISSIONS;
489     PermissionsIO permissions = given()
490       .spec(requestSpecOfDefaultUser)
491       .when()
492       .get(permissionsURL)
493       .then()
494       .statusCode(200)
495       .extract()
496       .as(PermissionsIO.class);
497     long[] readerGroupIds = { userGroupCreated.getId() };
498     permissions.setReaderGroupIds(readerGroupIds);
499     given()
500       .spec(requestSpecOfDefaultUser)
501       .body(permissions)
502       .when()
503       .put(permissionsURL)
504       .then()
505       .statusCode(200)
506       .extract()
507       .as(PermissionsIO.class);
508     SearchBody searchBody = new SearchBody();
509     SearchScope searchScope = new SearchScope();
510     searchScope.setTraversalRules(new TraversalRules[] {});
511     searchBody.setScopes(new SearchScope[] { searchScope });
512     SearchParams searchParams = new SearchParams();
513     searchParams.setQueryType(QueryType.Collection);
514     String query = String.format(
515       """
516       	{
517         "OR": [
518           {
519             "property": "id",
520             "value": %d,
521             "operator": "ge"
522           },
523           {
524             "property": "id",
525             "value": %d,
526             "operator": "le"
527           }
528       ]}""",
529       collection1.getId(),
530       collection2.getId()
531     );
532     searchParams.setQuery(query);
533     searchBody.setSearchParams(searchParams);
534     var result = given()
535       .spec(requestSpecOfOtherUser)
536       .body(searchBody)
537       .when()
538       .post(searchURL)
539       .then()
540       .statusCode(200)
541       .extract()
542       .as(ResponseBody.class);
543     ResultTriple triple1 = new ResultTriple(collection1.getId(), null, null);
544     ResultTriple triple2 = new ResultTriple(collection2.getId(), null, null);
545     assertThat(result.getResultSet()).contains(triple1);
546     assertThat(result.getResultSet()).contains(triple2);
547   }
548 
549   @Test
550   @Order(10)
551   public void inTest() {
552     String userGroupURL = "/" + Constants.USERGROUPS;
553     UserGroupIO userGroup = new UserGroupIO();
554     userGroup.setName("userGroup");
555     userGroup.setUsernames(new String[] { otherUser.getUser().getUsername() });
556     UserGroupIO userGroupCreated = given()
557       .spec(requestSpecOfDefaultUser)
558       .body(userGroup)
559       .when()
560       .post(userGroupURL)
561       .then()
562       .statusCode(201)
563       .extract()
564       .as(UserGroupIO.class);
565 
566     String permissionsURL = "/" + Constants.COLLECTIONS + "/" + collection2.getId() + "/" + Constants.PERMISSIONS;
567     PermissionsIO permissions = given()
568       .spec(requestSpecOfDefaultUser)
569       .when()
570       .get(permissionsURL)
571       .then()
572       .statusCode(200)
573       .extract()
574       .as(PermissionsIO.class);
575     long[] readerGroupIds = { userGroupCreated.getId() };
576     permissions.setReaderGroupIds(readerGroupIds);
577     given()
578       .spec(requestSpecOfDefaultUser)
579       .body(permissions)
580       .when()
581       .put(permissionsURL)
582       .then()
583       .statusCode(200)
584       .extract()
585       .as(PermissionsIO.class);
586     SearchBody searchBody = new SearchBody();
587     SearchScope searchScope = new SearchScope();
588     searchScope.setTraversalRules(new TraversalRules[] {});
589     searchBody.setScopes(new SearchScope[] { searchScope });
590     SearchParams searchParams = new SearchParams();
591     searchParams.setQueryType(QueryType.Collection);
592     String query = String.format(
593       """
594       {
595         "property": "id",
596         "value": [%d,%d],
597         "operator": "in"
598       }""",
599       collection1.getId(),
600       collection2.getId()
601     );
602     searchParams.setQuery(query);
603     searchBody.setSearchParams(searchParams);
604     var result = given()
605       .spec(requestSpecOfOtherUser)
606       .body(searchBody)
607       .when()
608       .post(searchURL)
609       .then()
610       .statusCode(200)
611       .extract()
612       .as(ResponseBody.class);
613     ResultTriple triple1 = new ResultTriple(collection1.getId(), null, null);
614     ResultTriple triple2 = new ResultTriple(collection2.getId(), null, null);
615     assertThat(result.getResultSet()).contains(triple1);
616     assertThat(result.getResultSet()).contains(triple2);
617   }
618 
619   @Test
620   @Order(11)
621   public void searchCollectionsViaPropertyIRI() {
622     SearchBody searchBody = new SearchBody();
623     SearchScope searchScope = new SearchScope();
624     searchScope.setTraversalRules(new TraversalRules[] {});
625     searchBody.setScopes(new SearchScope[] { searchScope });
626     SearchParams searchParams = new SearchParams();
627     searchParams.setQueryType(QueryType.Collection);
628     String query =
629       "{\"property\": \"propertyIRI\",\"value\": \"" + annotation.getPropertyIRI() + "\",\"operator\": \"eq\"}";
630     searchParams.setQuery(query);
631     searchBody.setSearchParams(searchParams);
632     var result = given()
633       .spec(requestSpecOfDefaultUser)
634       .body(searchBody)
635       .when()
636       .post(searchURL)
637       .then()
638       .statusCode(200)
639       .extract()
640       .as(ResponseBody.class);
641     ResultTriple triple = new ResultTriple(annotatedCollection.getId(), null, null);
642     assertThat(result.getResultSet()).contains(triple);
643   }
644 
645   @Test
646   @Order(12)
647   public void searchCollectionsViaValueIRI() {
648     SearchBody searchBody = new SearchBody();
649     SearchScope searchScope = new SearchScope();
650     searchScope.setTraversalRules(new TraversalRules[] {});
651     searchBody.setScopes(new SearchScope[] { searchScope });
652     SearchParams searchParams = new SearchParams();
653     searchParams.setQueryType(QueryType.Collection);
654     String query =
655       "{\"property\": \"valueIRI\",\"value\": \"" +
656       annotation.getValueIRI().substring(2, 10) +
657       "\",\"operator\": \"contains\"}";
658     searchParams.setQuery(query);
659     searchBody.setSearchParams(searchParams);
660     var result = given()
661       .spec(requestSpecOfDefaultUser)
662       .body(searchBody)
663       .when()
664       .post(searchURL)
665       .then()
666       .statusCode(200)
667       .extract()
668       .as(ResponseBody.class);
669     ResultTriple triple = new ResultTriple(annotatedCollection.getId(), null, null);
670     assertThat(result.getResultSet()).contains(triple);
671   }
672 }