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.assertNotEquals;
7   
8   import de.dlr.shepard.ErrorResponse;
9   import de.dlr.shepard.common.configuration.feature.toggles.VersioningFeatureToggle;
10  import de.dlr.shepard.common.util.Constants;
11  import de.dlr.shepard.context.collection.endpoints.DataObjectAttributes;
12  import de.dlr.shepard.context.collection.io.CollectionIO;
13  import de.dlr.shepard.context.collection.io.DataObjectIO;
14  import de.dlr.shepard.context.collection.services.DataObjectIOBuilder;
15  import de.dlr.shepard.context.version.io.VersionIO;
16  import io.quarkus.test.junit.QuarkusIntegrationTest;
17  import java.util.HashSet;
18  import java.util.Map;
19  import java.util.UUID;
20  import org.junit.jupiter.api.BeforeAll;
21  import org.junit.jupiter.api.MethodOrderer;
22  import org.junit.jupiter.api.Order;
23  import org.junit.jupiter.api.Test;
24  import org.junit.jupiter.api.TestMethodOrder;
25  
26  @QuarkusIntegrationTest
27  @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
28  public class DataObjectIT extends BaseTestCaseIT {
29  
30    private static CollectionIO collection;
31    private static CollectionIO collectionForOrderByTest;
32    private static CollectionIO versionizedCollection;
33  
34    private static String dataObjectsURL;
35    private static String orderByDataObjectsURL;
36    private static String versioningURL;
37    private static String versionizedCollectionURL;
38    private static DataObjectIO dataObject;
39    private static DataObjectIO child;
40    private static DataObjectIO successor;
41    private static DataObjectIO successorAndChild;
42    private static DataObjectIO aDataObject;
43    private static DataObjectIO bDataObject;
44    private static DataObjectIO cDataObject;
45    private static DataObjectIO dDataObject;
46    private static DataObjectIO eDataObject;
47    private static DataObjectIO fDataObject;
48    private static DataObjectIO firstVersionizedDataobject;
49    private static DataObjectIO secondVersionizedDataObject;
50    private static DataObjectIO thirdVersionizedDataObject;
51    private static UUID HEADVersionUID;
52    private static UUID firstVersionUID;
53  
54    @BeforeAll
55    public static void setUp() {
56      collection = createCollection("DataObjectTestCollection");
57      collectionForOrderByTest = createCollection("OrderByTestCollection");
58      versionizedCollection = createCollection("collection for versioning");
59  
60      dataObjectsURL = String.format("/%s/%d/%s", Constants.COLLECTIONS, collection.getId(), Constants.DATA_OBJECTS);
61      orderByDataObjectsURL = String.format(
62        "/%s/%d/%s",
63        Constants.COLLECTIONS,
64        collectionForOrderByTest.getId(),
65        Constants.DATA_OBJECTS
66      );
67      versioningURL = String.format(
68        "/%s/%d/%s",
69        Constants.COLLECTIONS,
70        versionizedCollection.getId(),
71        Constants.DATA_OBJECTS
72      );
73      versionizedCollectionURL = String.format("/%s/%d", Constants.COLLECTIONS, versionizedCollection.getId());
74  
75      var aInput = new DataObjectIO();
76      aInput.setName("a");
77      aDataObject = given()
78        .spec(requestSpecOfDefaultUser)
79        .body(aInput)
80        .when()
81        .post(orderByDataObjectsURL)
82        .then()
83        .statusCode(201)
84        .extract()
85        .as(DataObjectIO.class);
86      var bInput = new DataObjectIO();
87      bInput.setName("b");
88      bDataObject = given()
89        .spec(requestSpecOfDefaultUser)
90        .body(bInput)
91        .when()
92        .post(orderByDataObjectsURL)
93        .then()
94        .statusCode(201)
95        .extract()
96        .as(DataObjectIO.class);
97      var cInput = new DataObjectIO();
98      cInput.setName("c");
99      cDataObject = given()
100       .spec(requestSpecOfDefaultUser)
101       .body(cInput)
102       .when()
103       .post(orderByDataObjectsURL)
104       .then()
105       .statusCode(201)
106       .extract()
107       .as(DataObjectIO.class);
108     var dInput = new DataObjectIO();
109     dInput.setName("d");
110     dDataObject = given()
111       .spec(requestSpecOfDefaultUser)
112       .body(dInput)
113       .when()
114       .post(orderByDataObjectsURL)
115       .then()
116       .statusCode(201)
117       .extract()
118       .as(DataObjectIO.class);
119     var eInput = new DataObjectIO();
120     eInput.setName("e");
121     eDataObject = given()
122       .spec(requestSpecOfDefaultUser)
123       .body(eInput)
124       .when()
125       .post(orderByDataObjectsURL)
126       .then()
127       .statusCode(201)
128       .extract()
129       .as(DataObjectIO.class);
130     var fInput = new DataObjectIO();
131     fInput.setName("f");
132     fDataObject = given()
133       .spec(requestSpecOfDefaultUser)
134       .body(fInput)
135       .when()
136       .post(orderByDataObjectsURL)
137       .then()
138       .statusCode(201)
139       .extract()
140       .as(DataObjectIO.class);
141     DataObjectIO firstVersionizedDataObjectInput = new DataObjectIO();
142     firstVersionizedDataObjectInput.setName("first versionized DataObject");
143     firstVersionizedDataobject = given()
144       .spec(requestSpecOfDefaultUser)
145       .body(firstVersionizedDataObjectInput)
146       .when()
147       .post(versioningURL)
148       .then()
149       .statusCode(201)
150       .extract()
151       .as(DataObjectIO.class);
152     DataObjectIO secondVersionizedDataObjectInput = new DataObjectIO();
153     secondVersionizedDataObjectInput.setName("second versionized DataObject");
154     secondVersionizedDataObjectInput.setParentId(firstVersionizedDataobject.getId());
155     secondVersionizedDataObject = given()
156       .spec(requestSpecOfDefaultUser)
157       .body(secondVersionizedDataObjectInput)
158       .when()
159       .post(versioningURL)
160       .then()
161       .statusCode(201)
162       .extract()
163       .as(DataObjectIO.class);
164     DataObjectIO thirdVersionizedDataObjectInput = new DataObjectIO();
165     thirdVersionizedDataObjectInput.setName("third versionized DataoObject");
166     long[] thirdVersionizedDataObjectPredecessorIds = { secondVersionizedDataObject.getId() };
167     thirdVersionizedDataObjectInput.setPredecessorIds(thirdVersionizedDataObjectPredecessorIds);
168     thirdVersionizedDataObject = given()
169       .spec(requestSpecOfDefaultUser)
170       .body(thirdVersionizedDataObjectInput)
171       .when()
172       .post(versioningURL)
173       .then()
174       .statusCode(201)
175       .extract()
176       .as(DataObjectIO.class);
177   }
178 
179   @Test
180   @Order(1)
181   public void postDataObjectTest_Successful() {
182     var attributes = Map.of(
183       "a",
184       "1",
185       "b",
186       "2",
187       "key.abc",
188       "value",
189       "key|abc",
190       "value",
191       "key..abc",
192       "value",
193       "key/\\abc",
194       "value",
195       "key\"abc",
196       "value"
197     );
198     var payload = new DataObjectIO();
199     payload.setName("DataObjectDummy");
200     payload.setDescription("My Description");
201     payload.setAttributes(attributes);
202 
203     DataObjectIO actual = given()
204       .spec(requestSpecOfDefaultUser)
205       .body(payload)
206       .when()
207       .post(dataObjectsURL)
208       .then()
209       .statusCode(201)
210       .extract()
211       .as(DataObjectIO.class);
212     dataObject = actual;
213 
214     assertThat(actual.getId()).isNotNull();
215     assertThat(actual.getAttributes()).isEqualTo(attributes);
216     assertThat(actual.getDescription()).isEqualTo("My Description");
217     assertThat(actual.getCreatedAt()).isNotNull();
218     assertThat(actual.getCreatedBy()).isEqualTo(nameOfDefaultUser);
219     assertThat(actual.getIncomingIds()).isEmpty();
220     assertThat(actual.getReferenceIds()).isEmpty();
221     assertThat(actual.getChildrenIds()).isEmpty();
222     assertThat(actual.getPredecessorIds()).isEmpty();
223     assertThat(actual.getSuccessorIds()).isEmpty();
224     assertThat(actual.getParentId()).isNull();
225     assertThat(actual.getName()).isEqualTo("DataObjectDummy");
226     assertThat(actual.getCollectionId()).isEqualTo(collection.getId());
227     assertThat(actual.getUpdatedAt()).isNull();
228     assertThat(actual.getUpdatedBy()).isNull();
229   }
230 
231   @Test
232   @Order(2)
233   public void postDataObjectTest_ValidationError() {
234     // use attribute key that contains parsing delimiter ('||') and therefore is invalid
235     var attributes = Map.of("key||abc", "value");
236     var payload = new DataObjectIO();
237     payload.setName("DataObjectDummy");
238     payload.setDescription("My Description");
239     payload.setAttributes(attributes);
240 
241     given().spec(requestSpecOfDefaultUser).body(payload).when().post(dataObjectsURL).then().statusCode(400);
242   }
243 
244   @Test
245   @Order(3)
246   public void postDataObjectTest_ParentId() {
247     var payload = new DataObjectIO();
248     payload.setName("ChildDummy");
249     payload.setParentId(dataObject.getId());
250 
251     DataObjectIO actual = given()
252       .spec(requestSpecOfDefaultUser)
253       .body(payload)
254       .when()
255       .post(dataObjectsURL)
256       .then()
257       .statusCode(201)
258       .extract()
259       .as(DataObjectIO.class);
260     child = actual;
261 
262     assertThat(actual.getId()).isNotNull();
263     assertThat(actual.getChildrenIds()).isEmpty();
264     assertThat(actual.getPredecessorIds()).isEmpty();
265     assertThat(actual.getSuccessorIds()).isEmpty();
266     assertThat(actual.getParentId()).isEqualTo(dataObject.getId());
267     assertThat(actual.getCollectionId()).isEqualTo(collection.getId());
268 
269     DataObjectIO parent = given()
270       .spec(requestSpecOfDefaultUser)
271       .when()
272       .get(dataObjectsURL + "/" + dataObject.getId())
273       .then()
274       .statusCode(200)
275       .extract()
276       .as(DataObjectIO.class);
277     assertThat(parent).usingRecursiveComparison().ignoringFields("childrenIds").isEqualTo(dataObject);
278     assertThat(parent.getChildrenIds()).containsExactlyInAnyOrder(child.getId());
279     dataObject = parent;
280   }
281 
282   @Test
283   @Order(4)
284   public void postDataObjectTest_PredecessorId() {
285     var payload = new DataObjectIO();
286     payload.setName("SuccessorDummy");
287     payload.setPredecessorIds(new long[] { dataObject.getId() });
288 
289     DataObjectIO actual = given()
290       .spec(requestSpecOfDefaultUser)
291       .body(payload)
292       .when()
293       .post(dataObjectsURL)
294       .then()
295       .statusCode(201)
296       .extract()
297       .as(DataObjectIO.class);
298     successor = actual;
299 
300     assertThat(actual.getId()).isNotNull();
301     assertThat(actual.getChildrenIds()).isEmpty();
302     assertThat(actual.getPredecessorIds()).containsExactlyInAnyOrder(dataObject.getId());
303     assertThat(actual.getSuccessorIds()).isEmpty();
304     assertThat(actual.getParentId()).isNull();
305     assertThat(actual.getCollectionId()).isEqualTo(collection.getId());
306 
307     DataObjectIO predecessor = given()
308       .spec(requestSpecOfDefaultUser)
309       .when()
310       .get(dataObjectsURL + "/" + dataObject.getId())
311       .then()
312       .statusCode(200)
313       .extract()
314       .as(DataObjectIO.class);
315     assertThat(predecessor).usingRecursiveComparison().ignoringFields("successorIds").isEqualTo(dataObject);
316     assertThat(predecessor.getSuccessorIds()).containsExactlyInAnyOrder(successor.getId());
317     dataObject = predecessor;
318   }
319 
320   @Test
321   @Order(5)
322   public void postDataObjectTest_PredecessorIdAndParentId() {
323     var payload = new DataObjectIO();
324     payload.setName("ChildAndSuccessorDummy");
325     payload.setParentId(dataObject.getId());
326     payload.setPredecessorIds(new long[] { child.getId() });
327 
328     DataObjectIO actual = given()
329       .spec(requestSpecOfDefaultUser)
330       .body(payload)
331       .when()
332       .post(dataObjectsURL)
333       .then()
334       .statusCode(201)
335       .extract()
336       .as(DataObjectIO.class);
337     successorAndChild = actual;
338 
339     assertThat(actual.getId()).isNotNull();
340     assertThat(actual.getChildrenIds()).isEmpty();
341     assertThat(actual.getPredecessorIds()).containsExactlyInAnyOrder(child.getId());
342     assertThat(actual.getSuccessorIds()).isEmpty();
343     assertThat(actual.getParentId()).isEqualTo(dataObject.getId());
344     assertThat(actual.getCollectionId()).isEqualTo(collection.getId());
345 
346     DataObjectIO parent = given()
347       .spec(requestSpecOfDefaultUser)
348       .when()
349       .get(dataObjectsURL + "/" + dataObject.getId())
350       .then()
351       .statusCode(200)
352       .extract()
353       .as(DataObjectIO.class);
354     assertThat(parent).usingRecursiveComparison().ignoringFields("childrenIds").isEqualTo(dataObject);
355     assertThat(parent.getChildrenIds()).containsExactlyInAnyOrder(child.getId(), successorAndChild.getId());
356     dataObject = parent;
357 
358     DataObjectIO predecessor = given()
359       .spec(requestSpecOfDefaultUser)
360       .when()
361       .get(dataObjectsURL + "/" + child.getId())
362       .then()
363       .statusCode(200)
364       .extract()
365       .as(DataObjectIO.class);
366     assertThat(predecessor).usingRecursiveComparison().ignoringFields("successorIds").isEqualTo(child);
367     assertThat(predecessor.getSuccessorIds()).containsExactlyInAnyOrder(successorAndChild.getId());
368     child = predecessor;
369   }
370 
371   @Test
372   @Order(6)
373   public void getDataObjectTest_Successful() {
374     DataObjectIO actual = given()
375       .spec(requestSpecOfDefaultUser)
376       .when()
377       .get(dataObjectsURL + "/" + dataObject.getId())
378       .then()
379       .statusCode(200)
380       .extract()
381       .as(DataObjectIO.class);
382 
383     assertThat(actual).isEqualTo(dataObject);
384   }
385 
386   @Test
387   @Order(7)
388   public void getDataObjectTest_ByName() {
389     DataObjectIO[] response = given()
390       .spec(requestSpecOfDefaultUser)
391       .queryParam("name", dataObject.getName())
392       .when()
393       .get(dataObjectsURL)
394       .then()
395       .statusCode(200)
396       .extract()
397       .as(DataObjectIO[].class);
398 
399     assertThat(response)
400       .usingRecursiveFieldByFieldElementComparatorIgnoringFields("childrenIds", "successorIds", "predecessorIds")
401       .containsExactlyInAnyOrder(dataObject);
402   }
403 
404   @Test
405   @Order(8)
406   public void getDataObjectsTest_Successful() {
407     DataObjectIO[] response = given()
408       .spec(requestSpecOfDefaultUser)
409       .when()
410       .get(dataObjectsURL)
411       .then()
412       .statusCode(200)
413       .extract()
414       .as(DataObjectIO[].class);
415 
416     assertThat(response)
417       .usingRecursiveFieldByFieldElementComparatorIgnoringFields("childrenIds", "successorIds", "predecessorIds")
418       .containsExactlyInAnyOrder(dataObject, child, successor, successorAndChild);
419   }
420 
421   @Test
422   @Order(9)
423   public void getDataObjectsTest_ByParent() {
424     DataObjectIO[] response = given()
425       .spec(requestSpecOfDefaultUser)
426       .queryParam("parentId", dataObject.getId())
427       .when()
428       .get(dataObjectsURL)
429       .then()
430       .statusCode(200)
431       .extract()
432       .as(DataObjectIO[].class);
433 
434     assertThat(response)
435       .usingRecursiveFieldByFieldElementComparatorIgnoringFields("childrenIds", "successorIds", "predecessorIds")
436       .containsExactlyInAnyOrder(child, successorAndChild);
437   }
438 
439   @Test
440   @Order(10)
441   public void getDataObjectsTest_WithoutParent() {
442     DataObjectIO[] response = given()
443       .spec(requestSpecOfDefaultUser)
444       .queryParam("parentId", -1)
445       .when()
446       .get(dataObjectsURL)
447       .then()
448       .statusCode(200)
449       .extract()
450       .as(DataObjectIO[].class);
451 
452     assertThat(response)
453       .usingRecursiveFieldByFieldElementComparatorIgnoringFields("childrenIds", "successorIds", "predecessorIds")
454       .containsExactlyInAnyOrder(dataObject, successor);
455   }
456 
457   @Test
458   @Order(11)
459   public void getDataObjectsTest_ByPredecessor() {
460     DataObjectIO[] response = given()
461       .spec(requestSpecOfDefaultUser)
462       .queryParam("predecessorId", dataObject.getId())
463       .when()
464       .get(dataObjectsURL)
465       .then()
466       .statusCode(200)
467       .extract()
468       .as(DataObjectIO[].class);
469 
470     assertThat(response)
471       .usingRecursiveFieldByFieldElementComparatorIgnoringFields("childrenIds", "successorIds", "predecessorIds")
472       .containsExactlyInAnyOrder(successor);
473   }
474 
475   @Test
476   @Order(12)
477   public void getDataObjectsTest_WithoutPredecessor() {
478     DataObjectIO[] response = given()
479       .spec(requestSpecOfDefaultUser)
480       .queryParam("predecessorId", -1)
481       .when()
482       .get(dataObjectsURL)
483       .then()
484       .statusCode(200)
485       .extract()
486       .as(DataObjectIO[].class);
487 
488     assertThat(response)
489       .usingRecursiveFieldByFieldElementComparatorIgnoringFields("childrenIds", "successorIds", "predecessorIds")
490       .containsExactlyInAnyOrder(dataObject, child);
491   }
492 
493   @Test
494   @Order(13)
495   public void getDataObjectsTest_BySuccessor() {
496     DataObjectIO[] response = given()
497       .spec(requestSpecOfDefaultUser)
498       .queryParam("successorId", successor.getId())
499       .when()
500       .get(dataObjectsURL)
501       .then()
502       .statusCode(200)
503       .extract()
504       .as(DataObjectIO[].class);
505 
506     assertThat(response)
507       .usingRecursiveFieldByFieldElementComparatorIgnoringFields("childrenIds", "successorIds", "predecessorIds")
508       .containsExactlyInAnyOrder(dataObject);
509   }
510 
511   @Test
512   @Order(14)
513   public void getDataObjectsTest_WithoutSuccessor() {
514     DataObjectIO[] response = given()
515       .spec(requestSpecOfDefaultUser)
516       .queryParam("successorId", -1)
517       .when()
518       .get(dataObjectsURL)
519       .then()
520       .statusCode(200)
521       .extract()
522       .as(DataObjectIO[].class);
523 
524     assertThat(response)
525       .usingRecursiveFieldByFieldElementComparatorIgnoringFields("childrenIds", "successorIds", "predecessorIds")
526       .containsExactlyInAnyOrder(successor, successorAndChild);
527   }
528 
529   @Test
530   @Order(14)
531   public void getDataObjectsTest_negativeId_BadRequest() {
532     given().spec(requestSpecOfDefaultUser).when().get(dataObjectsURL + "/-1").then().statusCode(400);
533   }
534 
535   @Test
536   @Order(14)
537   public void getDataObjectsTest_wrongVersionUUIDFormat_BadRequest() {
538     // correct UUID: 00000000-0000-0000-0000-000000000000
539     // false UUID:   000000-0000-0000-0000-000000000000
540     given()
541       .spec(requestSpecOfDefaultUser)
542       .queryParam("versionUId", "000000-0000-0000-0000-000000000000")
543       .when()
544       .get(dataObjectsURL)
545       .then()
546       .statusCode(400);
547   }
548 
549   @Test
550   @Order(15)
551   public void putDataObjectTest_Successful() {
552     dataObject.setName("DataObjectSuccessorChanged");
553 
554     DataObjectIO actual = given()
555       .spec(requestSpecOfDefaultUser)
556       .body(dataObject)
557       .when()
558       .put(dataObjectsURL + "/" + dataObject.getId())
559       .then()
560       .statusCode(200)
561       .extract()
562       .as(DataObjectIO.class);
563 
564     assertThat(actual.getUpdatedAt()).isNotNull();
565     assertThat(actual.getUpdatedBy()).isEqualTo(nameOfDefaultUser);
566     assertThat(actual)
567       .usingRecursiveComparison()
568       .ignoringFields("updatedBy", "updatedAt", "childrenIds")
569       .isEqualTo(dataObject);
570     HashSet<Long> childrenActual = new HashSet<Long>();
571     for (int i = 0; i < actual.getChildrenIds().length; i++) childrenActual.add(actual.getChildrenIds()[i]);
572     HashSet<Long> childrenDataObject = new HashSet<Long>();
573     for (int i = 0; i < dataObject.getChildrenIds().length; i++) childrenDataObject.add(dataObject.getChildrenIds()[i]);
574     assertEquals(childrenActual, childrenDataObject);
575     dataObject = actual;
576   }
577 
578   @Test
579   @Order(16)
580   public void putDataObjectTest_newParent() {
581     successorAndChild.setName("DataObjectChildChanged");
582     successorAndChild.setParentId(successor.getId());
583 
584     DataObjectIO actual = given()
585       .spec(requestSpecOfDefaultUser)
586       .body(successorAndChild)
587       .when()
588       .put(dataObjectsURL + "/" + successorAndChild.getId())
589       .then()
590       .statusCode(200)
591       .extract()
592       .as(DataObjectIO.class);
593 
594     assertThat(actual).usingRecursiveComparison().ignoringFields("updatedBy", "updatedAt").isEqualTo(successorAndChild);
595     successorAndChild = actual;
596 
597     DataObjectIO oldParent = given()
598       .spec(requestSpecOfDefaultUser)
599       .when()
600       .get(dataObjectsURL + "/" + dataObject.getId())
601       .then()
602       .statusCode(200)
603       .extract()
604       .as(DataObjectIO.class);
605     assertThat(oldParent).usingRecursiveComparison().ignoringFields("childrenIds").isEqualTo(dataObject);
606     assertThat(oldParent.getChildrenIds()).doesNotContain(successorAndChild.getId());
607     dataObject = oldParent;
608 
609     successor.setChildrenIds(new long[] { actual.getId() });
610     DataObjectIO newParent = given()
611       .spec(requestSpecOfDefaultUser)
612       .when()
613       .get(dataObjectsURL + "/" + successor.getId())
614       .then()
615       .statusCode(200)
616       .extract()
617       .as(DataObjectIO.class);
618     assertThat(newParent).isEqualTo(successor);
619   }
620 
621   @Test
622   @Order(17)
623   public void putDataObjectTest_newPredecessor() {
624     child.setName("DataObjectSuccessorChanged");
625     child.setPredecessorIds(new long[] { dataObject.getId() });
626     DataObjectIO actual = given()
627       .spec(requestSpecOfDefaultUser)
628       .body(child)
629       .when()
630       .put(dataObjectsURL + "/" + child.getId())
631       .then()
632       .statusCode(200)
633       .extract()
634       .as(DataObjectIO.class);
635 
636     assertThat(actual).usingRecursiveComparison().ignoringFields("updatedBy", "updatedAt").isEqualTo(child);
637     child = actual;
638 
639     DataObjectIO newPredecessor = given()
640       .spec(requestSpecOfDefaultUser)
641       .when()
642       .get(dataObjectsURL + "/" + dataObject.getId())
643       .then()
644       .statusCode(200)
645       .extract()
646       .as(DataObjectIO.class);
647     assertThat(newPredecessor)
648       .usingRecursiveComparison()
649       .ignoringFields("successorIds", "childrenIds")
650       .isEqualTo(dataObject);
651     assertThat(newPredecessor.getChildrenIds()).containsExactlyInAnyOrder(dataObject.getChildrenIds());
652     assertThat(newPredecessor.getSuccessorIds()).containsExactlyInAnyOrder(successor.getId(), child.getId());
653     dataObject = newPredecessor;
654   }
655 
656   @Test
657   @Order(18)
658   public void deleteDataObjectTest_Successful() {
659     given()
660       .spec(requestSpecOfDefaultUser)
661       .when()
662       .delete(dataObjectsURL + "/" + dataObject.getId())
663       .then()
664       .statusCode(204);
665     given()
666       .spec(requestSpecOfDefaultUser)
667       .when()
668       .delete(dataObjectsURL + "/" + dataObject.getId())
669       .then()
670       .statusCode(404);
671     given().spec(requestSpecOfDefaultUser).when().get(dataObjectsURL + "/" + dataObject.getId()).then().statusCode(404);
672   }
673 
674   @Test
675   @Order(19)
676   public void getOrderByName() {
677     DataObjectIO[] response = given()
678       .spec(requestSpecOfDefaultUser)
679       .queryParam("orderBy", DataObjectAttributes.name)
680       .when()
681       .get(orderByDataObjectsURL)
682       .then()
683       .statusCode(200)
684       .extract()
685       .as(DataObjectIO[].class);
686     assertThat(response).containsExactly(aDataObject, bDataObject, cDataObject, dDataObject, eDataObject, fDataObject);
687   }
688 
689   @Test
690   @Order(20)
691   public void getOrderByNameDesc() {
692     DataObjectIO[] response = given()
693       .spec(requestSpecOfDefaultUser)
694       .queryParam("orderBy", DataObjectAttributes.name)
695       .queryParam("orderDesc", true)
696       .when()
697       .get(orderByDataObjectsURL)
698       .then()
699       .statusCode(200)
700       .extract()
701       .as(DataObjectIO[].class);
702     assertThat(response).containsExactly(fDataObject, eDataObject, dDataObject, cDataObject, bDataObject, aDataObject);
703   }
704 
705   @Test
706   @Order(21)
707   public void getOrderByCreatedAt() {
708     DataObjectIO[] response = given()
709       .spec(requestSpecOfDefaultUser)
710       .queryParam("orderBy", DataObjectAttributes.createdAt)
711       .queryParam("orderDesc", false)
712       .when()
713       .get(orderByDataObjectsURL)
714       .then()
715       .statusCode(200)
716       .extract()
717       .as(DataObjectIO[].class);
718     assertThat(response).containsExactly(aDataObject, bDataObject, cDataObject, dDataObject, eDataObject, fDataObject);
719   }
720 
721   @Test
722   @Order(22)
723   public void getOrderByCreatedFirstPage() {
724     DataObjectIO[] response = given()
725       .spec(requestSpecOfDefaultUser)
726       .queryParam("orderBy", DataObjectAttributes.createdAt)
727       .queryParam("orderDesc", false)
728       .queryParam("page", 0)
729       .queryParam("size", 3)
730       .when()
731       .get(orderByDataObjectsURL)
732       .then()
733       .statusCode(200)
734       .extract()
735       .as(DataObjectIO[].class);
736     assertThat(response).containsExactly(aDataObject, bDataObject, cDataObject);
737   }
738 
739   @Test
740   @Order(23)
741   public void getOrderByCreatedSecondPage() {
742     DataObjectIO[] response = given()
743       .spec(requestSpecOfDefaultUser)
744       .queryParam("orderBy", DataObjectAttributes.createdAt)
745       .queryParam("orderDesc", false)
746       .queryParam("page", 1)
747       .queryParam("size", 3)
748       .when()
749       .get(orderByDataObjectsURL)
750       .then()
751       .statusCode(200)
752       .extract()
753       .as(DataObjectIO[].class);
754     assertThat(response).containsExactly(dDataObject, eDataObject, fDataObject);
755   }
756 
757   @Test
758   @Order(24)
759   public void getOrderByCreatedDescSecondPage() {
760     DataObjectIO[] response = given()
761       .spec(requestSpecOfDefaultUser)
762       .queryParam("orderBy", DataObjectAttributes.createdAt)
763       .queryParam("orderDesc", true)
764       .queryParam("page", 1)
765       .queryParam("size", 3)
766       .when()
767       .get(orderByDataObjectsURL)
768       .then()
769       .statusCode(200)
770       .extract()
771       .as(DataObjectIO[].class);
772     assertThat(response).containsExactly(cDataObject, bDataObject, aDataObject);
773   }
774 
775   @Test
776   @Order(25)
777   public void getOrderByCreatedDescFirstPage() {
778     DataObjectIO[] response = given()
779       .spec(requestSpecOfDefaultUser)
780       .queryParam("orderBy", DataObjectAttributes.createdAt)
781       .queryParam("orderDesc", true)
782       .queryParam("page", 0)
783       .queryParam("size", 3)
784       .when()
785       .get(orderByDataObjectsURL)
786       .then()
787       .statusCode(200)
788       .extract()
789       .as(DataObjectIO[].class);
790     assertThat(response).containsExactly(fDataObject, eDataObject, dDataObject);
791   }
792 
793   @Test
794   @Order(25)
795   public void getHEADVersion() {
796     if (VersioningFeatureToggle.isEnabled()) {
797       VersionIO[] HEADVersion = given()
798         .spec(requestSpecOfDefaultUser)
799         .when()
800         .get(versionizedCollectionURL + "/versions")
801         .then()
802         .statusCode(200)
803         .extract()
804         .as(VersionIO[].class);
805       assertEquals(HEADVersion.length, 1);
806       HEADVersionUID = HEADVersion[0].getUid();
807     }
808   }
809 
810   @Test
811   @Order(26)
812   public void createFirstVersion() {
813     if (VersioningFeatureToggle.isEnabled()) {
814       VersionIO firstVersionInput = new VersionIO();
815       firstVersionInput.setName("first version");
816       firstVersionInput.setDescription("first version");
817       VersionIO firstVersion = given()
818         .spec(requestSpecOfDefaultUser)
819         .body(firstVersionInput)
820         .when()
821         .post(versionizedCollectionURL + "/versions")
822         .then()
823         .statusCode(201)
824         .extract()
825         .as(VersionIO.class);
826       assertEquals(firstVersionInput.getName(), firstVersion.getName());
827       assertEquals(firstVersionInput.getDescription(), firstVersion.getDescription());
828       firstVersionUID = firstVersion.getUid();
829     }
830   }
831 
832   @Test
833   @Order(27)
834   public void putFirstVersionizedDataObject() {
835     if (VersioningFeatureToggle.isEnabled()) {
836       String newName = "first versionized DataObject with new name";
837       firstVersionizedDataobject.setName(newName);
838       DataObjectIO actual = given()
839         .spec(requestSpecOfDefaultUser)
840         .body(firstVersionizedDataobject)
841         .when()
842         .put(versioningURL + "/" + firstVersionizedDataobject.getId())
843         .then()
844         .statusCode(200)
845         .extract()
846         .as(DataObjectIO.class);
847       assertEquals(newName, actual.getName());
848     }
849   }
850 
851   @Test
852   @Order(28)
853   public void differentFirstVersionizedDataObjects() {
854     if (VersioningFeatureToggle.isEnabled()) {
855       DataObjectIO firstDataObjectFirstVersion = given()
856         .spec(requestSpecOfDefaultUser)
857         .queryParam("versionUid", firstVersionUID.toString())
858         .when()
859         .get(versioningURL + "/" + firstVersionizedDataobject.getId())
860         .then()
861         .statusCode(200)
862         .extract()
863         .as(DataObjectIO.class);
864       DataObjectIO firstDataObjectExpliciteHEADVersion = given()
865         .spec(requestSpecOfDefaultUser)
866         .queryParam("versionUid", HEADVersionUID.toString())
867         .when()
868         .get(versioningURL + "/" + firstVersionizedDataobject.getId())
869         .then()
870         .statusCode(200)
871         .extract()
872         .as(DataObjectIO.class);
873       DataObjectIO firstDataObjectImpliciteHEADVersion = given()
874         .spec(requestSpecOfDefaultUser)
875         .when()
876         .get(versioningURL + "/" + firstVersionizedDataobject.getId())
877         .then()
878         .statusCode(200)
879         .extract()
880         .as(DataObjectIO.class);
881       assertEquals(firstDataObjectExpliciteHEADVersion.getName(), firstDataObjectImpliciteHEADVersion.getName());
882       assertNotEquals(firstDataObjectExpliciteHEADVersion.getName(), firstDataObjectFirstVersion.getName());
883     }
884   }
885 
886   @Test
887   @Order(29)
888   public void predecessorsInFirstVersion() {
889     if (VersioningFeatureToggle.isEnabled()) {
890       DataObjectIO thirdDataObjectFirstVersion = given()
891         .spec(requestSpecOfDefaultUser)
892         .queryParam("versionUid", firstVersionUID.toString())
893         .when()
894         .get(versioningURL + "/" + thirdVersionizedDataObject.getId())
895         .then()
896         .statusCode(200)
897         .extract()
898         .as(DataObjectIO.class);
899       assertEquals(1, thirdDataObjectFirstVersion.getPredecessorIds().length);
900       long actualPredecessorId = thirdDataObjectFirstVersion.getPredecessorIds()[0];
901       long expectedPredecessorId = secondVersionizedDataObject.getId();
902       assertEquals(actualPredecessorId, expectedPredecessorId);
903     }
904   }
905 
906   @Test
907   @Order(30)
908   public void parentInFirstVersion() {
909     if (VersioningFeatureToggle.isEnabled()) {
910       DataObjectIO secondDataObjectFirstVersion = given()
911         .spec(requestSpecOfDefaultUser)
912         .queryParam("versionUid", firstVersionUID.toString())
913         .when()
914         .get(versioningURL + "/" + secondVersionizedDataObject.getId())
915         .then()
916         .statusCode(200)
917         .extract()
918         .as(DataObjectIO.class);
919       long actualParentId = secondDataObjectFirstVersion.getParentId();
920       long expectedParentId = firstVersionizedDataobject.getId();
921       assertEquals(actualParentId, expectedParentId);
922     }
923   }
924 
925   @Test
926   @Order(31)
927   public void deleteFirstVersionizedDataObject() {
928     if (VersioningFeatureToggle.isEnabled()) {
929       given()
930         .spec(requestSpecOfDefaultUser)
931         .when()
932         .delete(versioningURL + "/" + firstVersionizedDataobject.getId())
933         .then()
934         .statusCode(204);
935       DataObjectIO[] response = given()
936         .spec(requestSpecOfDefaultUser)
937         .when()
938         .get(versioningURL)
939         .then()
940         .statusCode(200)
941         .extract()
942         .as(DataObjectIO[].class);
943       if (VersioningFeatureToggle.isEnabled()) assertEquals(2, response.length);
944       else assertEquals(5, response.length);
945     }
946   }
947 
948   @Test
949   @Order(32)
950   public void getDataObjectsOfFirstVersion() {
951     if (VersioningFeatureToggle.isEnabled()) {
952       DataObjectIO[] response = given()
953         .spec(requestSpecOfDefaultUser)
954         .queryParam("versionUid", firstVersionUID)
955         .when()
956         .get(versioningURL)
957         .then()
958         .statusCode(200)
959         .extract()
960         .as(DataObjectIO[].class);
961       assertEquals(3, response.length);
962     }
963   }
964 
965   @Test
966   public void getDataObject_wrongId_notFound() {
967     ErrorResponse response = given()
968       .spec(requestSpecOfDefaultUser)
969       .when()
970       .get(dataObjectsURL + "/99999")
971       .then()
972       .statusCode(404)
973       .extract()
974       .as(ErrorResponse.class);
975     assertThat(response.getMessage()).startsWith("ID ERROR - DataObject");
976   }
977 
978   @Test
979   public void getDataObject_doesNotExistNegativeId_badRequest() {
980     var actual = given()
981       .spec(requestSpecOfDefaultUser)
982       .when()
983       .get(dataObjectsURL + "/-1")
984       .then()
985       .statusCode(400)
986       .extract();
987     assertThat(actual.body().asString()).isEqualTo(
988       "{\"title\":\"Constraint Violation\",\"status\":400,\"violations\":[{\"field\":\"getDataObject.dataObjectId\",\"message\":\"must be greater than or equal to 0\"}]}"
989     );
990   }
991 
992   @Test
993   public void getDataObject_privateCollection_forbidden() {
994     // This is a test implementation for the Bug described in #475
995     CollectionIO privateCollection = createCollection("private collection", otherUser);
996     DataObjectIO privateDataObject = createDataObject("private data object", privateCollection.getId(), otherUser);
997 
998     ErrorResponse response = given()
999       .spec(requestSpecOfDefaultUser)
1000       .when()
1001       .get(
1002         String.format(
1003           "/%s/%d/%s/%d",
1004           Constants.COLLECTIONS,
1005           privateCollection.getId(),
1006           Constants.DATA_OBJECTS,
1007           privateDataObject.getId()
1008         )
1009       )
1010       .then()
1011       .statusCode(403)
1012       .extract()
1013       .as(ErrorResponse.class);
1014     assertThat(response.getMessage()).isEqualTo("The requested action is forbidden by the permission policies");
1015   }
1016 
1017   @Test
1018   public void getDataObject_wrongCollection_notFound() {
1019     CollectionIO thisCollection = createCollection("private collection");
1020     DataObjectIO thisDataObject = createDataObject("private data object", thisCollection.getId());
1021     CollectionIO otherCollection = createCollection("private collection");
1022 
1023     ErrorResponse response = given()
1024       .spec(requestSpecOfDefaultUser)
1025       .when()
1026       .get(
1027         String.format(
1028           "/%s/%d/%s/%d",
1029           Constants.COLLECTIONS,
1030           otherCollection.getId(),
1031           Constants.DATA_OBJECTS,
1032           thisDataObject.getId()
1033         )
1034       )
1035       .then()
1036       .statusCode(404)
1037       .extract()
1038       .as(ErrorResponse.class);
1039     assertThat(response.getMessage()).isEqualTo("ID ERROR - There is no association between collection and dataObject");
1040   }
1041 
1042   @Test
1043   public void putDataObjectTest_RemoveParentAndPredecessor() {
1044     DataObjectIO parent = new DataObjectIO();
1045     parent.setName("10001 Parent");
1046     parent = given()
1047       .spec(requestSpecOfDefaultUser)
1048       .body(parent)
1049       .when()
1050       .post(dataObjectsURL)
1051       .then()
1052       .statusCode(201)
1053       .extract()
1054       .as(DataObjectIO.class);
1055 
1056     DataObjectIO predecessor = new DataObjectIO();
1057     predecessor.setName("10001 predecessor");
1058     predecessor = given()
1059       .spec(requestSpecOfDefaultUser)
1060       .body(predecessor)
1061       .when()
1062       .post(dataObjectsURL)
1063       .then()
1064       .statusCode(201)
1065       .extract()
1066       .as(DataObjectIO.class);
1067 
1068     DataObjectIO dataObject = new DataObjectIO();
1069     dataObject.setName("ChildAndSuccessorDummy");
1070     dataObject.setParentId(parent.getId());
1071     dataObject.setPredecessorIds(new long[] { predecessor.getId() });
1072 
1073     dataObject = given()
1074       .spec(requestSpecOfDefaultUser)
1075       .body(dataObject)
1076       .when()
1077       .post(dataObjectsURL)
1078       .then()
1079       .statusCode(201)
1080       .extract()
1081       .as(DataObjectIO.class);
1082 
1083     dataObject.setPredecessorIds(new long[] {});
1084 
1085     dataObject = given()
1086       .spec(requestSpecOfDefaultUser)
1087       .body(dataObject)
1088       .when()
1089       .put(dataObjectsURL + "/" + dataObject.getId())
1090       .then()
1091       .statusCode(200)
1092       .extract()
1093       .as(DataObjectIO.class);
1094 
1095     dataObject = given()
1096       .spec(requestSpecOfDefaultUser)
1097       .when()
1098       .get(dataObjectsURL + "/" + dataObject.getId())
1099       .then()
1100       .statusCode(200)
1101       .extract()
1102       .as(DataObjectIO.class);
1103 
1104     assertThat(dataObject.getPredecessorIds()).isEmpty();
1105 
1106     dataObject.setParentId(null);
1107     dataObject = given()
1108       .spec(requestSpecOfDefaultUser)
1109       .body(dataObject)
1110       .when()
1111       .put(dataObjectsURL + "/" + dataObject.getId())
1112       .then()
1113       .statusCode(200)
1114       .extract()
1115       .as(DataObjectIO.class);
1116 
1117     dataObject = given()
1118       .spec(requestSpecOfDefaultUser)
1119       .when()
1120       .get(dataObjectsURL + "/" + dataObject.getId())
1121       .then()
1122       .statusCode(200)
1123       .extract()
1124       .as(DataObjectIO.class);
1125 
1126     assertThat(dataObject.getParentId()).isEqualTo(null);
1127   }
1128 
1129   @Test
1130   public void updateDataObject_deleteParentWhenPredecessorIsPresent_successfullyDeleteParent() {
1131     // Arrange
1132     var dataObjectAsParentAndPredecessorCreationPayload = new DataObjectIO();
1133     dataObjectAsParentAndPredecessorCreationPayload.setName("dataObjectWithParentAndPredecessor");
1134 
1135     DataObjectIO dataObjectAsParentAndPredecessor = given()
1136       .spec(requestSpecOfDefaultUser)
1137       .body(dataObjectAsParentAndPredecessorCreationPayload)
1138       .when()
1139       .post(dataObjectsURL)
1140       .then()
1141       .statusCode(201)
1142       .extract()
1143       .as(DataObjectIO.class);
1144 
1145     var dataObjectWithParentAndPredecessorCreationPayload = new DataObjectIO();
1146     dataObjectWithParentAndPredecessorCreationPayload.setName("dataObjectWithParentAndPredecessor");
1147     dataObjectWithParentAndPredecessorCreationPayload.setParentId(dataObjectAsParentAndPredecessor.getId());
1148     dataObjectWithParentAndPredecessorCreationPayload.setPredecessorIds(
1149       new long[] { dataObjectAsParentAndPredecessor.getId() }
1150     );
1151 
1152     DataObjectIO dataObjectWithParentAndPredecessor = given()
1153       .spec(requestSpecOfDefaultUser)
1154       .body(dataObjectWithParentAndPredecessorCreationPayload)
1155       .when()
1156       .post(dataObjectsURL)
1157       .then()
1158       .statusCode(201)
1159       .extract()
1160       .as(DataObjectIO.class);
1161 
1162     // Act
1163     dataObjectWithParentAndPredecessor.setParentId(null);
1164 
1165     given()
1166       .spec(requestSpecOfDefaultUser)
1167       .body(dataObjectWithParentAndPredecessor)
1168       .when()
1169       .put(dataObjectsURL + "/" + dataObjectWithParentAndPredecessor.getId())
1170       .then()
1171       .statusCode(200)
1172       .extract()
1173       .as(DataObjectIO.class);
1174 
1175     // Assert
1176     DataObjectIO updatedParent = given()
1177       .spec(requestSpecOfDefaultUser)
1178       .when()
1179       .get(dataObjectsURL + "/" + dataObjectWithParentAndPredecessor.getId())
1180       .then()
1181       .statusCode(200)
1182       .extract()
1183       .as(DataObjectIO.class);
1184 
1185     assertEquals(null, updatedParent.getParentId());
1186   }
1187 
1188   @Test
1189   public void updateDataObject_deleteAttribute_successfullyDeleteAttribute() {
1190     // Arrange
1191     DataObjectIO dataObjectIO = new DataObjectIOBuilder().setAttributes(Map.of("name", "my data object")).build();
1192     DataObjectIO dataObject = given()
1193       .spec(requestSpecOfDefaultUser)
1194       .body(dataObjectIO)
1195       .when()
1196       .post(dataObjectsURL)
1197       .then()
1198       .statusCode(201)
1199       .extract()
1200       .as(DataObjectIO.class);
1201 
1202     // Act
1203     dataObjectIO.setAttributes(Map.of());
1204     given()
1205       .spec(requestSpecOfDefaultUser)
1206       .body(dataObjectIO)
1207       .when()
1208       .put(dataObjectsURL + "/" + dataObject.getId())
1209       .then()
1210       .statusCode(200)
1211       .extract()
1212       .as(DataObjectIO.class);
1213 
1214     // Assert
1215     DataObjectIO updatedDataObject = given()
1216       .spec(requestSpecOfDefaultUser)
1217       .when()
1218       .get(dataObjectsURL + "/" + dataObject.getId())
1219       .then()
1220       .statusCode(200)
1221       .extract()
1222       .as(DataObjectIO.class);
1223     assertEquals(Map.of(), updatedDataObject.getAttributes());
1224   }
1225 }