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   import static org.junit.jupiter.api.Assertions.assertNotNull;
7   import static org.junit.jupiter.api.Assertions.assertNull;
8   
9   import de.dlr.shepard.ErrorResponse;
10  import de.dlr.shepard.common.configuration.feature.toggles.VersioningFeatureToggle;
11  import de.dlr.shepard.common.util.Constants;
12  import de.dlr.shepard.context.collection.io.CollectionIO;
13  import de.dlr.shepard.context.collection.io.DataObjectIO;
14  import de.dlr.shepard.context.version.io.VersionIO;
15  import de.dlr.shepard.data.file.io.FileContainerIO;
16  import io.quarkus.test.junit.QuarkusIntegrationTest;
17  import io.restassured.builder.RequestSpecBuilder;
18  import io.restassured.http.ContentType;
19  import io.restassured.specification.RequestSpecification;
20  import java.util.Map;
21  import org.junit.jupiter.api.BeforeAll;
22  import org.junit.jupiter.api.MethodOrderer;
23  import org.junit.jupiter.api.Order;
24  import org.junit.jupiter.api.Test;
25  import org.junit.jupiter.api.TestMethodOrder;
26  
27  @QuarkusIntegrationTest
28  @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
29  public class CollectionIT extends BaseTestCaseIT {
30  
31    private static String collectionsURL;
32    private static CollectionIO collection;
33    private static CollectionIO collectionWithDefaultFileContainer;
34    private static VersionIO firstVersion;
35    private static VersionIO secondVersion;
36    private static String name;
37    private static long VersionizedCollectionShepardId;
38    private static String VersionizedCollectionName;
39    private static String newVersionizedCollectionName;
40    private static FileContainerIO defaultFileContainerIO;
41  
42    @BeforeAll
43    public static void setUp() {
44      collectionsURL = "/" + Constants.COLLECTIONS;
45      defaultFileContainerIO = createFileContainer("DefaultFileContainer");
46    }
47  
48    @Test
49    @Order(1)
50    public void postCollectionTest_Successful() {
51      var payload = new CollectionIO();
52      name = "CollectionDummy" + System.currentTimeMillis();
53      payload.setName(name);
54      payload.setDescription("My Description");
55      payload.setAttributes(Map.of("a", "1", "b", "2"));
56      CollectionIO actual = given()
57        .spec(requestSpecOfDefaultUser)
58        .body(payload)
59        .when()
60        .post(collectionsURL)
61        .then()
62        .statusCode(201)
63        .extract()
64        .as(CollectionIO.class);
65      collection = actual;
66  
67      assertThat(actual.getId()).isNotNull();
68      assertThat(actual.getAttributes()).isEqualTo(Map.of("a", "1", "b", "2"));
69      assertThat(actual.getDescription()).isEqualTo("My Description");
70      assertThat(actual.getCreatedAt()).isNotNull();
71      assertThat(actual.getCreatedBy()).isEqualTo(nameOfDefaultUser);
72      assertThat(actual.getName()).isEqualTo(name);
73      assertThat(actual.getDataObjectIds()).isEmpty();
74      assertThat(actual.getUpdatedAt()).isNull();
75      assertThat(actual.getUpdatedBy()).isNull();
76      assertThat(actual.getDefaultFileContainerId()).isNull();
77    }
78  
79    @Test
80    @Order(1)
81    public void postCollectionTest_withDefaultContainer_SuccessDefaultFileContainerExists() {
82      var payload = new CollectionIO();
83      name = "CollectionDummy2" + System.currentTimeMillis();
84      payload.setName(name);
85      payload.setDescription("My Description");
86      payload.setAttributes(Map.of("a", "1", "b", "2"));
87      payload.setDefaultFileContainerId(defaultFileContainerIO.getId());
88  
89      CollectionIO actual = given()
90        .spec(requestSpecOfDefaultUser)
91        .body(payload)
92        .when()
93        .post(collectionsURL)
94        .then()
95        .statusCode(201)
96        .extract()
97        .as(CollectionIO.class);
98      collectionWithDefaultFileContainer = actual;
99  
100     assertThat(actual.getId()).isNotNull();
101     assertThat(actual.getAttributes()).isEqualTo(Map.of("a", "1", "b", "2"));
102     assertThat(actual.getDescription()).isEqualTo("My Description");
103     assertThat(actual.getCreatedAt()).isNotNull();
104     assertThat(actual.getCreatedBy()).isEqualTo(nameOfDefaultUser);
105     assertThat(actual.getName()).isEqualTo(name);
106     assertThat(actual.getDataObjectIds()).isEmpty();
107     assertThat(actual.getUpdatedAt()).isNull();
108     assertThat(actual.getUpdatedBy()).isNull();
109     assertThat(actual.getDefaultFileContainerId()).isEqualTo(defaultFileContainerIO.getId());
110   }
111 
112   @Test
113   @Order(1)
114   public void postCollectionTest_withDefaultContainer_FailureDefaultFileContainerDoesNotExist() {
115     var payload = new CollectionIO();
116     name = "CollectionDummy" + System.currentTimeMillis();
117     payload.setName(name);
118     payload.setDescription("My Description");
119     payload.setAttributes(Map.of("a", "1", "b", "2"));
120     payload.setDefaultFileContainerId(9999999L);
121 
122     given().spec(requestSpecOfDefaultUser).body(payload).when().post(collectionsURL).then().statusCode(404);
123   }
124 
125   @Test
126   @Order(1)
127   public void postCollectionTest_withDefaultContainer_FailureUserHasNoReadPermissionsOnDefaultFileContainer() {
128     var payload = new CollectionIO();
129     name = "CollectionDummy" + System.currentTimeMillis();
130     payload.setName(name);
131     payload.setDescription("My Description");
132     payload.setAttributes(Map.of("a", "1", "b", "2"));
133     payload.setDefaultFileContainerId(defaultFileContainerIO.getId());
134 
135     given().spec(requestSpecOfOtherUser).body(payload).when().post(collectionsURL).then().statusCode(403);
136   }
137 
138   @Test
139   @Order(2)
140   public void postCollectionTest_WithoutAuth() {
141     var payload = new CollectionIO();
142     payload.setName(name);
143 
144     var wrongSpecification = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
145     given().spec(wrongSpecification).body(payload).when().post(collectionsURL).then().statusCode(401);
146   }
147 
148   @Test
149   @Order(3)
150   public void postCollectionTest_BadJson() {
151     String payload = "{,}";
152     given().spec(requestSpecOfDefaultUser).body(payload).when().post(collectionsURL).then().statusCode(400);
153   }
154 
155   @Test
156   @Order(4)
157   public void postCollectionTest_BadBody() {
158     String payload = "{\"attribute\":\"value\"}";
159     given().spec(requestSpecOfDefaultUser).body(payload).when().post(collectionsURL).then().statusCode(400);
160   }
161 
162   @Test
163   @Order(5)
164   public void getCollectionTest_Successful() {
165     CollectionIO actual = given()
166       .spec(requestSpecOfDefaultUser)
167       .when()
168       .get(collectionsURL + "/" + collection.getId())
169       .then()
170       .statusCode(200)
171       .extract()
172       .as(CollectionIO.class);
173 
174     assertThat(actual).isEqualTo(collection);
175     assertThat(actual.getDefaultFileContainerId()).isEqualTo(null);
176   }
177 
178   @Test
179   @Order(6)
180   public void getCollectionTest_withDataObject() {
181     var payload = new DataObjectIO();
182     payload.setName(name);
183 
184     DataObjectIO dataObject = given()
185       .spec(requestSpecOfDefaultUser)
186       .body(payload)
187       .when()
188       .post(collectionsURL + "/" + collection.getId() + "/" + Constants.DATA_OBJECTS)
189       .then()
190       .statusCode(201)
191       .extract()
192       .as(DataObjectIO.class);
193 
194     CollectionIO actual = given()
195       .spec(requestSpecOfDefaultUser)
196       .when()
197       .get(collectionsURL + "/" + collection.getId())
198       .then()
199       .statusCode(200)
200       .extract()
201       .as(CollectionIO.class);
202     collection = actual;
203 
204     assertThat(actual.getDataObjectIds()).contains(dataObject.getId());
205   }
206 
207   @Test
208   @Order(7)
209   public void getCollectionTest_QueryParamNameSuccessful() {
210     CollectionIO[] response = given()
211       .spec(requestSpecOfDefaultUser)
212       .queryParam("name", collection.getName())
213       .when()
214       .get(collectionsURL)
215       .then()
216       .statusCode(200)
217       .extract()
218       .as(CollectionIO[].class);
219 
220     assertThat(response).containsExactly(collection);
221   }
222 
223   @Test
224   @Order(8)
225   public void getCollectionTest_wrongId_notFound() {
226     ErrorResponse response = given()
227       .spec(requestSpecOfDefaultUser)
228       .when()
229       .get(collectionsURL + "/99999")
230       .then()
231       .statusCode(404)
232       .extract()
233       .as(ErrorResponse.class);
234     assertThat(response.getMessage()).isEqualTo("ID ERROR - Collection with id 99999 is null or deleted");
235   }
236 
237   @Test
238   @Order(8)
239   public void getCollectionTest_doesNotExistNegativeId_badRequest() {
240     var actual = given()
241       .spec(requestSpecOfDefaultUser)
242       .when()
243       .get(collectionsURL + "/-1")
244       .then()
245       .statusCode(400)
246       .extract();
247     assertThat(actual.body().asString()).isEqualTo(
248       "{\"title\":\"Constraint Violation\",\"status\":400,\"violations\":[{\"field\":\"getCollection.collectionId\",\"message\":\"must be greater than or equal to 0\"}]}"
249     );
250   }
251 
252   @Test
253   @Order(9)
254   public void getCollectionTest_privateCollection_forbidden() {
255     RequestSpecification otherUserRequestSpecification = new RequestSpecBuilder()
256       .setContentType(ContentType.JSON)
257       .addHeader("X-API-KEY", otherUser.getApiKey().getJws())
258       .build();
259 
260     ErrorResponse response = given()
261       .spec(otherUserRequestSpecification)
262       .when()
263       .get(collectionsURL + "/" + collection.getId())
264       .then()
265       .statusCode(403)
266       .extract()
267       .as(ErrorResponse.class);
268     assertThat(response.getMessage()).isEqualTo("The requested action is forbidden by the permission policies");
269   }
270 
271   @Test
272   @Order(10)
273   public void getCollectionsTest_Successful() {
274     CollectionIO[] response = given()
275       .spec(requestSpecOfDefaultUser)
276       .when()
277       .get(collectionsURL)
278       .then()
279       .statusCode(200)
280       .extract()
281       .as(CollectionIO[].class);
282 
283     assertThat(response).contains(collection);
284   }
285 
286   @Test
287   @Order(11)
288   public void putCollectionTest_Successful() {
289     collection.setName("CollectionDummyChanged");
290 
291     CollectionIO actualResponse = given()
292       .spec(requestSpecOfDefaultUser)
293       .body(collection)
294       .when()
295       .put(collectionsURL + "/" + collection.getId())
296       .then()
297       .statusCode(200)
298       .extract()
299       .as(CollectionIO.class);
300 
301     assertThat(actualResponse.getUpdatedAt()).isNotNull();
302     assertThat(actualResponse.getUpdatedBy()).isEqualTo(nameOfDefaultUser);
303     assertThat(actualResponse)
304       .usingRecursiveComparison()
305       .ignoringFields("updatedBy", "updatedAt")
306       .isEqualTo(collection);
307   }
308 
309   @Test
310   @Order(12)
311   public void putCollectionTest_withDefaultContainer_SuccessDefaultFileContainerExists() {
312     // add default FileContainer to collection without filecontainer
313     name = "CollectionDummyChanged" + System.currentTimeMillis();
314     collection.setName(name);
315     collection.setDefaultFileContainerId(defaultFileContainerIO.getId());
316 
317     CollectionIO actualResponse = given()
318       .spec(requestSpecOfDefaultUser)
319       .body(collection)
320       .when()
321       .put(collectionsURL + "/" + collection.getId())
322       .then()
323       .statusCode(200)
324       .extract()
325       .as(CollectionIO.class);
326 
327     assertThat(actualResponse.getUpdatedAt()).isNotNull();
328     assertThat(actualResponse.getUpdatedBy()).isEqualTo(nameOfDefaultUser);
329     assertThat(actualResponse)
330       .usingRecursiveComparison()
331       .ignoringFields("updatedBy", "updatedAt")
332       .isEqualTo(collection);
333     assertThat(actualResponse.getDefaultFileContainerId()).isEqualTo(defaultFileContainerIO.getId());
334     collection = actualResponse;
335   }
336 
337   @Test
338   @Order(12)
339   public void putCollectionTest_unsetDefaultContainer_Success() {
340     name = "CollectionDummyChanged" + System.currentTimeMillis();
341     collection.setName(name);
342     collection.setDefaultFileContainerId(null);
343 
344     CollectionIO actualResponse = given()
345       .spec(requestSpecOfDefaultUser)
346       .body(collection)
347       .when()
348       .put(collectionsURL + "/" + collection.getId())
349       .then()
350       .statusCode(200)
351       .extract()
352       .as(CollectionIO.class);
353 
354     assertThat(actualResponse.getUpdatedAt()).isNotNull();
355     assertThat(actualResponse.getUpdatedBy()).isEqualTo(nameOfDefaultUser);
356     assertThat(actualResponse)
357       .usingRecursiveComparison()
358       .ignoringFields("updatedBy", "updatedAt")
359       .isEqualTo(collection);
360     assertThat(actualResponse.getDefaultFileContainerId()).isNull();
361     collection = actualResponse;
362   }
363 
364   @Test
365   @Order(12)
366   public void putCollectionTest_withDefaultContainer_FailureDefaultFileContainerDoesNotExist() {
367     name = "CollectionDummyChanged" + System.currentTimeMillis();
368     collection.setName(name);
369     collection.setDefaultFileContainerId(9999L);
370 
371     given()
372       .spec(requestSpecOfDefaultUser)
373       .body(collection)
374       .when()
375       .put(collectionsURL + "/" + collection.getId())
376       .then()
377       .statusCode(404);
378   }
379 
380   @Test
381   @Order(12)
382   public void putCollectionTest_withDefaultContainer_FailureUserHasNoReadPermissionsOnDefaultFileContainer() {
383     // add default FileContainer to collection without filecontainer
384     name = "CollectionDummyChanged" + System.currentTimeMillis();
385     collection.setName(name);
386     collection.setDefaultFileContainerId(defaultFileContainerIO.getId());
387 
388     given()
389       .spec(requestSpecOfOtherUser)
390       .body(collection)
391       .when()
392       .put(collectionsURL + "/" + collection.getId())
393       .then()
394       .statusCode(403);
395   }
396 
397   @Test
398   @Order(13)
399   public void deleteCollectionTest_Successful() {
400     given()
401       .spec(requestSpecOfDefaultUser)
402       .when()
403       .delete(collectionsURL + "/" + collection.getId())
404       .then()
405       .statusCode(204);
406     given().spec(requestSpecOfDefaultUser).when().get(collectionsURL + "/" + collection.getId()).then().statusCode(404);
407 
408     given()
409       .spec(requestSpecOfDefaultUser)
410       .when()
411       .delete(collectionsURL + "/" + collectionWithDefaultFileContainer.getId())
412       .then()
413       .statusCode(204);
414     given().spec(requestSpecOfDefaultUser).when().get(collectionsURL + "/" + collection.getId()).then().statusCode(404);
415   }
416 
417   @Test
418   @Order(14)
419   public void getinitialHEADVersion() {
420     if (VersioningFeatureToggle.isEnabled()) {
421       var payload = new CollectionIO();
422       VersionizedCollectionName = "VersionizedCollection";
423       payload.setName(VersionizedCollectionName);
424       payload.setDescription(VersionizedCollectionName);
425       CollectionIO actual = given()
426         .spec(requestSpecOfDefaultUser)
427         .body(payload)
428         .when()
429         .post(collectionsURL)
430         .then()
431         .statusCode(201)
432         .extract()
433         .as(CollectionIO.class);
434       VersionizedCollectionShepardId = actual.getId();
435       VersionIO[] versions = given()
436         .spec(requestSpecOfDefaultUser)
437         .when()
438         .get(collectionsURL + "/" + VersionizedCollectionShepardId + "/versions")
439         .then()
440         .statusCode(200)
441         .extract()
442         .as(VersionIO[].class);
443       assertEquals(versions.length, 1);
444       VersionIO HEADVersion = versions[0];
445       assertEquals(HEADVersion.getName(), "HEAD");
446       assertEquals(HEADVersion.getDescription(), "HEAD version");
447     }
448   }
449 
450   @Test
451   @Order(15)
452   public void createNewVersion() {
453     if (VersioningFeatureToggle.isEnabled()) {
454       VersionIO newVersion = new VersionIO();
455       newVersion.setName("first version");
456       newVersion.setDescription("first version of versionized collection");
457       firstVersion = given()
458         .spec(requestSpecOfDefaultUser)
459         .body(newVersion)
460         .when()
461         .post(collectionsURL + "/" + VersionizedCollectionShepardId + "/versions")
462         .then()
463         .statusCode(201)
464         .extract()
465         .as(VersionIO.class);
466       assertEquals(firstVersion.getName(), newVersion.getName());
467       assertEquals(firstVersion.getDescription(), newVersion.getDescription());
468     }
469   }
470 
471   @Test
472   @Order(16)
473   public void createSecondVersion() {
474     if (VersioningFeatureToggle.isEnabled()) {
475       VersionIO newVersion = new VersionIO();
476       newVersion.setName("second version");
477       newVersion.setDescription("second version of versionized collection");
478       secondVersion = given()
479         .spec(requestSpecOfDefaultUser)
480         .body(newVersion)
481         .when()
482         .post(collectionsURL + "/" + VersionizedCollectionShepardId + "/versions")
483         .then()
484         .statusCode(201)
485         .extract()
486         .as(VersionIO.class);
487       assertEquals(secondVersion.getName(), newVersion.getName());
488       assertEquals(secondVersion.getDescription(), newVersion.getDescription());
489     }
490   }
491 
492   @Test
493   @Order(17)
494   public void getAllVersions() {
495     if (VersioningFeatureToggle.isEnabled()) {
496       VersionIO[] versions = given()
497         .spec(requestSpecOfDefaultUser)
498         .when()
499         .get(collectionsURL + "/" + VersionizedCollectionShepardId + "/versions")
500         .then()
501         .statusCode(200)
502         .extract()
503         .as(VersionIO[].class);
504       assertEquals(versions.length, 3);
505       VersionIO HEADVersionCandidate = null;
506       VersionIO firstVersionCandidate = null;
507       VersionIO secondVersionCandidate = null;
508       for (int i = 0; i < 3; i++) {
509         if (versions[i].getName().equals("HEAD")) HEADVersionCandidate = versions[i];
510         if (versions[i].getUid().equals(firstVersion.getUid())) firstVersionCandidate = versions[i];
511         if (versions[i].getUid().equals(secondVersion.getUid())) secondVersionCandidate = versions[i];
512       }
513       assertNotNull(HEADVersionCandidate);
514       assertNotNull(firstVersionCandidate);
515       assertNotNull(secondVersionCandidate);
516       assertEquals(HEADVersionCandidate.getPredecessorUUID(), secondVersionCandidate.getUid());
517       assertEquals(secondVersionCandidate.getPredecessorUUID(), firstVersionCandidate.getUid());
518       assertNull(firstVersionCandidate.getPredecessorUUID());
519     }
520   }
521 
522   @Test
523   @Order(18)
524   public void modifyHEADCollection() {
525     if (VersioningFeatureToggle.isEnabled()) {
526       CollectionIO newVersionizedCollection = new CollectionIO();
527       newVersionizedCollectionName = "updated versionized collection";
528       newVersionizedCollection.setName(newVersionizedCollectionName);
529       CollectionIO actual = given()
530         .spec(requestSpecOfDefaultUser)
531         .body(newVersionizedCollection)
532         .when()
533         .put(collectionsURL + "/" + VersionizedCollectionShepardId)
534         .then()
535         .statusCode(200)
536         .extract()
537         .as(CollectionIO.class);
538       assertEquals(actual.getName(), newVersionizedCollectionName);
539       assertEquals(actual.getId(), VersionizedCollectionShepardId);
540     }
541   }
542 
543   @Test
544   @Order(19)
545   public void retrieveModifiedHEADCollection() {
546     if (VersioningFeatureToggle.isEnabled()) {
547       CollectionIO actual = given()
548         .spec(requestSpecOfDefaultUser)
549         .when()
550         .get(collectionsURL + "/" + VersionizedCollectionShepardId)
551         .then()
552         .statusCode(200)
553         .extract()
554         .as(CollectionIO.class);
555       assertEquals(actual.getName(), newVersionizedCollectionName);
556     }
557   }
558 
559   @Test
560   @Order(20)
561   public void retrieveSecondVersion() {
562     if (VersioningFeatureToggle.isEnabled()) {
563       VersionIO actual = given()
564         .spec(requestSpecOfDefaultUser)
565         .when()
566         .get(collectionsURL + "/" + VersionizedCollectionShepardId + "/versions/" + secondVersion.getUid().toString())
567         .then()
568         .statusCode(200)
569         .extract()
570         .as(VersionIO.class);
571       assertEquals(actual, secondVersion);
572     }
573   }
574 
575   @Test
576   @Order(21)
577   public void retrieveSecondVersionOfCollection() {
578     if (VersioningFeatureToggle.isEnabled()) {
579       CollectionIO actual = given()
580         .spec(requestSpecOfDefaultUser)
581         .queryParam("versionUid", secondVersion.getUid().toString())
582         .when()
583         .get(collectionsURL + "/" + VersionizedCollectionShepardId)
584         .then()
585         .statusCode(200)
586         .extract()
587         .as(CollectionIO.class);
588       assertEquals(actual.getName(), VersionizedCollectionName);
589     }
590   }
591 
592   @Test
593   @Order(22)
594   public void updateCollection_deleteAttribute_successfullyDeleteAttribute() {
595     // Arrange
596     CollectionIO collectionIO = new CollectionIO();
597     collectionIO.setName("Some name");
598     collectionIO.setAttributes(Map.of("name", "my data object"));
599     CollectionIO collection = given()
600       .spec(requestSpecOfDefaultUser)
601       .body(collectionIO)
602       .when()
603       .post(collectionsURL)
604       .then()
605       .statusCode(201)
606       .extract()
607       .as(CollectionIO.class);
608 
609     // Act
610     collectionIO.setAttributes(Map.of());
611     given()
612       .spec(requestSpecOfDefaultUser)
613       .body(collectionIO)
614       .when()
615       .put(collectionsURL + "/" + collection.getId())
616       .then()
617       .statusCode(200)
618       .extract()
619       .as(CollectionIO.class);
620 
621     // Assert
622     CollectionIO updatedCollection = given()
623       .spec(requestSpecOfDefaultUser)
624       .when()
625       .get(collectionsURL + "/" + collection.getId())
626       .then()
627       .statusCode(200)
628       .extract()
629       .as(CollectionIO.class);
630     assertEquals(Map.of(), updatedCollection.getAttributes());
631   }
632 }