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.ErrorResponse;
8   import de.dlr.shepard.common.configuration.feature.toggles.VersioningFeatureToggle;
9   import de.dlr.shepard.common.util.Constants;
10  import de.dlr.shepard.context.collection.io.CollectionIO;
11  import de.dlr.shepard.context.collection.io.DataObjectIO;
12  import de.dlr.shepard.context.references.dataobject.io.DataObjectReferenceIO;
13  import de.dlr.shepard.context.version.io.VersionIO;
14  import io.quarkus.test.junit.QuarkusIntegrationTest;
15  import java.util.UUID;
16  import org.junit.jupiter.api.BeforeAll;
17  import org.junit.jupiter.api.MethodOrderer;
18  import org.junit.jupiter.api.Order;
19  import org.junit.jupiter.api.Test;
20  import org.junit.jupiter.api.TestMethodOrder;
21  import org.junit.jupiter.api.condition.EnabledIf;
22  
23  @QuarkusIntegrationTest
24  @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
25  public class DataObjectReferenceIT extends BaseTestCaseIT {
26  
27    private static CollectionIO collection1;
28    private static CollectionIO collection2;
29    private static DataObjectIO dataObject11;
30    private static DataObjectIO dataObject12;
31    private static DataObjectIO dataObject21;
32    private static DataObjectIO dataObject22;
33  
34    private static UUID c1v1UID;
35  
36    private static String c1d1referencesURL;
37    private static String c1d2referencesURL;
38    private static String c2d1referencesURL;
39  
40    private static DataObjectReferenceIO reference11to12;
41    private static DataObjectReferenceIO reference12to21;
42    private static DataObjectReferenceIO reference21to12;
43  
44    @BeforeAll
45    public static void setUp() {
46      collection1 = createCollection("1cDataObjectReferenceTestCollection");
47      collection2 = createCollection("2cDataObjectReferenceTestCollection");
48      dataObject11 = createDataObject("1c1dDataObject", collection1.getId());
49      dataObject12 = createDataObject("1c2dDataObject", collection1.getId());
50      dataObject21 = createDataObject("2c1dDataObject", collection2.getId());
51      dataObject22 = createDataObject("2c2dDataObject", collection2.getId());
52  
53      c1d1referencesURL = "/%s/%d/%s/%d/%s".formatted(
54          Constants.COLLECTIONS,
55          collection1.getId(),
56          Constants.DATA_OBJECTS,
57          dataObject11.getId(),
58          Constants.DATAOBJECT_REFERENCES
59        );
60      c1d2referencesURL = "/%s/%d/%s/%d/%s".formatted(
61          Constants.COLLECTIONS,
62          collection1.getId(),
63          Constants.DATA_OBJECTS,
64          dataObject12.getId(),
65          Constants.DATAOBJECT_REFERENCES
66        );
67      c2d1referencesURL = "/%s/%d/%s/%d/%s".formatted(
68          Constants.COLLECTIONS,
69          collection2.getId(),
70          Constants.DATA_OBJECTS,
71          dataObject21.getId(),
72          Constants.DATAOBJECT_REFERENCES
73        );
74  
75      var referenceToCreate = new DataObjectReferenceIO();
76      referenceToCreate.setName("reference12to21");
77      referenceToCreate.setRelationship("integrationtest");
78      referenceToCreate.setReferencedDataObjectId(dataObject21.getId());
79      reference12to21 = given()
80        .spec(requestSpecOfDefaultUser)
81        .body(referenceToCreate)
82        .when()
83        .post(c1d2referencesURL)
84        .then()
85        .statusCode(201)
86        .extract()
87        .as(DataObjectReferenceIO.class);
88  
89      referenceToCreate = new DataObjectReferenceIO();
90      referenceToCreate.setName("reference21to12");
91      referenceToCreate.setRelationship("integrationtest");
92      referenceToCreate.setReferencedDataObjectId(dataObject12.getId());
93      reference21to12 = given()
94        .spec(requestSpecOfDefaultUser)
95        .body(referenceToCreate)
96        .when()
97        .post(c2d1referencesURL)
98        .then()
99        .statusCode(201)
100       .extract()
101       .as(DataObjectReferenceIO.class);
102 
103     referenceToCreate = new DataObjectReferenceIO();
104     referenceToCreate.setName("reference21to22");
105     referenceToCreate.setRelationship("integrationtest");
106     referenceToCreate.setReferencedDataObjectId(dataObject22.getId());
107   }
108 
109   @Test
110   @Order(1)
111   public void createDataObjectReferenceTest() {
112     var toCreate = new DataObjectReferenceIO();
113     toCreate.setName("DataObjectReferenceDummy");
114     toCreate.setRelationship("integrationtests");
115     toCreate.setReferencedDataObjectId(dataObject12.getId());
116 
117     var actual = given()
118       .spec(requestSpecOfDefaultUser)
119       .body(toCreate)
120       .when()
121       .post(c1d1referencesURL)
122       .then()
123       .statusCode(201)
124       .extract()
125       .as(DataObjectReferenceIO.class);
126     reference11to12 = actual;
127 
128     assertThat(actual.getId()).isNotNull();
129     assertThat(actual.getCreatedAt()).isNotNull();
130     assertThat(actual.getCreatedBy()).isEqualTo(nameOfDefaultUser);
131     assertThat(actual.getDataObjectId()).isEqualTo(dataObject11.getId());
132     assertThat(actual.getName()).isEqualTo("DataObjectReferenceDummy");
133     assertThat(actual.getRelationship()).isEqualTo("integrationtests");
134     assertThat(actual.getReferencedDataObjectId()).isEqualTo(dataObject12.getId());
135     assertThat(actual.getType()).isEqualTo("DataObjectReference");
136     assertThat(actual.getUpdatedAt()).isNull();
137     assertThat(actual.getUpdatedBy()).isNull();
138   }
139 
140   @Test
141   @Order(2)
142   public void createDataObjectReferenceTest_ReferencedDoesNotExist() {
143     var toCreate = new DataObjectReferenceIO();
144     toCreate.setName("DataObjectReferenceDummy2");
145     toCreate.setRelationship("integrationtests");
146     toCreate.setReferencedDataObjectId(-2);
147 
148     given().spec(requestSpecOfDefaultUser).body(toCreate).when().post(c1d1referencesURL).then().statusCode(400);
149   }
150 
151   @Test
152   @Order(3)
153   public void getDataObjectReferenceTest() {
154     var actual = given()
155       .spec(requestSpecOfDefaultUser)
156       .when()
157       .get(c1d1referencesURL + "/" + reference11to12.getId())
158       .then()
159       .statusCode(200)
160       .extract()
161       .as(DataObjectReferenceIO.class);
162     assertThat(actual).isEqualTo(reference11to12);
163   }
164 
165   @Test
166   @Order(4)
167   public void getDataObjectReferencesTest() {
168     var actual = given()
169       .spec(requestSpecOfDefaultUser)
170       .when()
171       .get(c1d1referencesURL)
172       .then()
173       .statusCode(200)
174       .extract()
175       .as(DataObjectReferenceIO[].class);
176     assertThat(actual).containsExactly(reference11to12);
177   }
178 
179   @Test
180   @Order(5)
181   public void getDataObjectReference_referenceDoesNotExist_notFound() {
182     var actual = given()
183       .spec(requestSpecOfDefaultUser)
184       .when()
185       .get(c1d1referencesURL + "/99999")
186       .then()
187       .statusCode(404)
188       .extract()
189       .as(ErrorResponse.class);
190 
191     assertThat(actual.getMessage()).isEqualTo("ID ERROR - Data Object Reference with id 99999 is null or deleted");
192   }
193 
194   @Test
195   @Order(6)
196   public void getDataObjectReference_idBelongsToWrongDataObject_notFound() {
197     var actual = given()
198       .spec(requestSpecOfDefaultUser)
199       .when()
200       .get(c1d1referencesURL + "/" + reference21to12.getId())
201       .then()
202       .statusCode(404)
203       .extract()
204       .as(ErrorResponse.class);
205 
206     assertThat(actual.getMessage()).isEqualTo("ID ERROR - There is no association between dataObject and reference");
207   }
208 
209   @Test
210   @Order(7)
211   public void getDataObjectReferencedTest() {
212     var referencedURL =
213       "/%s/%d/%s/%d".formatted(
214           Constants.COLLECTIONS,
215           collection1.getId(),
216           Constants.DATA_OBJECTS,
217           dataObject12.getId()
218         );
219     var actual = given()
220       .spec(requestSpecOfDefaultUser)
221       .when()
222       .get(referencedURL)
223       .then()
224       .statusCode(200)
225       .extract()
226       .as(DataObjectIO.class);
227     assertEquals(actual.getIncomingIds().length, 2);
228     assertThat(actual.getIncomingIds()).contains(reference11to12.getId());
229     assertThat(actual.getIncomingIds()).contains(reference21to12.getId());
230   }
231 
232   @Test
233   @Order(8)
234   public void getDataObjectReferencePayloadTest() {
235     var actual = given()
236       .spec(requestSpecOfDefaultUser)
237       .when()
238       .get("%s/%d/%s".formatted(c1d1referencesURL, reference11to12.getId(), Constants.PAYLOAD))
239       .then()
240       .statusCode(200)
241       .extract()
242       .as(DataObjectIO.class);
243 
244     assertThat(actual)
245       .usingRecursiveComparison()
246       .ignoringFields("incomingIds")
247       .ignoringFields("referenceIds")
248       .isEqualTo(dataObject12);
249     assertEquals(actual.getIncomingIds().length, 2);
250     assertThat(actual.getIncomingIds()).contains(reference11to12.getId());
251     assertThat(actual.getIncomingIds()).contains(reference21to12.getId());
252   }
253 
254   @Test
255   @Order(9)
256   public void getDataObjectReferencePayload_referencedDataObjectPrivateFromOtherUser_returnsForbidden() {
257     // This test is a check for the bug described in #475
258     // Arrange
259     CollectionIO collectionWithReferencingDataObject = createCollection(
260       "collectionWithReferencedDataObject",
261       otherUser
262     );
263     DataObjectIO referencingDataObject = createDataObject(
264       "referencingDataObject",
265       collectionWithReferencingDataObject.getId(),
266       otherUser
267     );
268 
269     String referencesURL =
270       "/%s/%d/%s/%d/%s".formatted(
271           Constants.COLLECTIONS,
272           collectionWithReferencingDataObject.getId(),
273           Constants.DATA_OBJECTS,
274           referencingDataObject.getId(),
275           Constants.DATAOBJECT_REFERENCES
276         );
277 
278     DataObjectReferenceIO referenceToCreate = new DataObjectReferenceIO();
279     referenceToCreate.setName("reference");
280     referenceToCreate.setRelationship("integrationtest");
281     referenceToCreate.setReferencedDataObjectId(dataObject11.getId()); // create ref to foreign dataobject 'dataobject11' from 'user'
282 
283     // Act + Assert
284     var error = given()
285       .spec(requestSpecOfOtherUser)
286       .body(referenceToCreate)
287       .when()
288       .post(referencesURL)
289       .then()
290       .statusCode(400)
291       .extract()
292       .as(ErrorResponse.class);
293 
294     assertEquals(
295       "You do not have permissions to access the referenced DataObject with id %s.".formatted(dataObject11.getId()),
296       error.getMessage()
297     );
298   }
299 
300   @Test
301   @Order(10)
302   public void deleteDataObjectReferenceTest() {
303     given()
304       .spec(requestSpecOfDefaultUser)
305       .when()
306       .delete(c1d1referencesURL + "/" + reference11to12.getId())
307       .then()
308       .statusCode(204);
309 
310     given()
311       .spec(requestSpecOfDefaultUser)
312       .when()
313       .get(c1d1referencesURL + "/" + reference11to12.getId())
314       .then()
315       .statusCode(404);
316   }
317 
318   @Test
319   @Order(10)
320   @EnabledIf(VersioningFeatureToggle.IS_ENABLED_METHOD_ID)
321   public void createNewVersionCollection1Test() {
322     String versionizeCollection1URL = "/" + Constants.COLLECTIONS + "/" + collection1.getId() + "/versions";
323     VersionIO inputVersion = new VersionIO();
324     inputVersion.setName("c1v1");
325     inputVersion.setDescription("first version of collection 1");
326     VersionIO actual = given()
327       .spec(requestSpecOfDefaultUser)
328       .body(inputVersion)
329       .when()
330       .post(versionizeCollection1URL)
331       .then()
332       .statusCode(201)
333       .extract()
334       .as(VersionIO.class);
335     assertEquals(actual.getName(), inputVersion.getName());
336     c1v1UID = actual.getUid();
337   }
338 
339   @Test
340   @Order(11)
341   @EnabledIf(VersioningFeatureToggle.IS_ENABLED_METHOD_ID)
342   public void incomingReferencesToDataObject12InHEADVersionTest() {
343     var referencedURL =
344       "/%s/%d/%s/%d".formatted(
345           Constants.COLLECTIONS,
346           collection1.getId(),
347           Constants.DATA_OBJECTS,
348           dataObject12.getId()
349         );
350     var actual = given()
351       .spec(requestSpecOfDefaultUser)
352       .when()
353       .get(referencedURL)
354       .then()
355       .statusCode(200)
356       .extract()
357       .as(DataObjectIO.class);
358     assertThat(actual.getIncomingIds()).containsExactly(reference21to12.getId());
359   }
360 
361   @Test
362   @Order(12)
363   @EnabledIf(VersioningFeatureToggle.IS_ENABLED_METHOD_ID)
364   public void incomingReferencesToDataObject12InFirstVersionTest() {
365     var referencedURL =
366       "/%s/%d/%s/%d".formatted(
367           Constants.COLLECTIONS,
368           collection1.getId(),
369           Constants.DATA_OBJECTS,
370           dataObject12.getId()
371         );
372     var actual = given()
373       .spec(requestSpecOfDefaultUser)
374       .queryParam("versionUid", c1v1UID)
375       .when()
376       .get(referencedURL)
377       .then()
378       .statusCode(200)
379       .extract()
380       .as(DataObjectIO.class);
381     assertEquals(actual.getIncomingIds().length, 0);
382   }
383 
384   @Test
385   @Order(13)
386   @EnabledIf(VersioningFeatureToggle.IS_ENABLED_METHOD_ID)
387   public void multipleIncomingReferencesToDataObject21InHEADVersion() {
388     var referencedURL =
389       "/%s/%d/%s/%d".formatted(
390           Constants.COLLECTIONS,
391           collection2.getId(),
392           Constants.DATA_OBJECTS,
393           dataObject21.getId()
394         );
395     var actual = given()
396       .spec(requestSpecOfDefaultUser)
397       .when()
398       .get(referencedURL)
399       .then()
400       .statusCode(200)
401       .extract()
402       .as(DataObjectIO.class);
403     assertEquals(actual.getIncomingIds().length, 2);
404     assertThat(actual.getIncomingIds()).contains(reference12to21.getId());
405   }
406 
407   @Test
408   public void getDataObjectReferencePayload_referencedDataObjectDeleted_returnsForbidden() {
409     // Arrange
410     CollectionIO collectionWithReferencingDataObject = createCollection("collectionWithReferencingDataObject");
411     DataObjectIO referencingDataObject = createDataObject(
412       "referencingDataObject",
413       collectionWithReferencingDataObject.getId()
414     );
415     CollectionIO collectionWithReferencedDataObject = createCollection("collectionWithReferencedDataObject");
416     DataObjectIO referencedDataObject = createDataObject(
417       "referencedDataObject",
418       collectionWithReferencedDataObject.getId()
419     );
420 
421     String referencesURL =
422       "/%s/%d/%s/%d/%s".formatted(
423           Constants.COLLECTIONS,
424           collectionWithReferencingDataObject.getId(),
425           Constants.DATA_OBJECTS,
426           referencingDataObject.getId(),
427           Constants.DATAOBJECT_REFERENCES
428         );
429 
430     DataObjectReferenceIO referenceToCreate = new DataObjectReferenceIO();
431     referenceToCreate.setName("reference");
432     referenceToCreate.setRelationship("integrationtest");
433     referenceToCreate.setReferencedDataObjectId(referencedDataObject.getId());
434     DataObjectReferenceIO reference = given()
435       .spec(requestSpecOfDefaultUser)
436       .body(referenceToCreate)
437       .when()
438       .post(referencesURL)
439       .then()
440       .statusCode(201)
441       .extract()
442       .as(DataObjectReferenceIO.class);
443 
444     // Act
445     given()
446       .spec(requestSpecOfDefaultUser)
447       .when()
448       .delete(
449         "/%s/%d/%s/%d".formatted(
450             Constants.COLLECTIONS,
451             collectionWithReferencedDataObject.getId(),
452             Constants.DATA_OBJECTS,
453             referencedDataObject.getId()
454           )
455       )
456       .then()
457       .statusCode(204);
458 
459     // Assert
460     given()
461       .spec(requestSpecOfDefaultUser)
462       .when()
463       .get("%s/%d/%s".formatted(referencesURL, reference.getId(), Constants.PAYLOAD))
464       .then()
465       .statusCode(404);
466   }
467 }