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
258
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());
282
283
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
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
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
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 }