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