1 package de.dlr.shepard.integrationtests;
2
3 import static io.restassured.RestAssured.given;
4 import static org.assertj.core.api.Assertions.assertThat;
5
6 import com.fasterxml.jackson.core.JsonProcessingException;
7 import com.fasterxml.jackson.databind.JsonMappingException;
8 import com.fasterxml.jackson.databind.ObjectMapper;
9 import de.dlr.shepard.ErrorResponse;
10 import de.dlr.shepard.common.util.Constants;
11 import de.dlr.shepard.context.collection.io.CollectionIO;
12 import de.dlr.shepard.context.collection.io.DataObjectIO;
13 import de.dlr.shepard.context.references.structureddata.io.StructuredDataReferenceIO;
14 import de.dlr.shepard.data.structureddata.entities.StructuredData;
15 import de.dlr.shepard.data.structureddata.entities.StructuredDataPayload;
16 import de.dlr.shepard.data.structureddata.io.StructuredDataContainerIO;
17 import io.quarkus.test.junit.QuarkusIntegrationTest;
18 import java.util.Map;
19 import org.junit.jupiter.api.BeforeAll;
20 import org.junit.jupiter.api.MethodOrderer;
21 import org.junit.jupiter.api.Order;
22 import org.junit.jupiter.api.Test;
23 import org.junit.jupiter.api.TestMethodOrder;
24
25 @QuarkusIntegrationTest
26 @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
27 public class StructuredDataReferenceIT extends BaseTestCaseIT {
28
29 private static CollectionIO collection;
30 private static DataObjectIO dataObject;
31
32 private static String referencesURL;
33 private static String containerURL;
34
35 private static StructuredDataContainerIO container;
36 private static StructuredDataReferenceIO reference;
37 private static StructuredDataPayload payload;
38
39 private ObjectMapper objectMapper = new ObjectMapper();
40
41 @BeforeAll
42 public static void setUp() {
43 collection = createCollection("StructuredDataReferenceTestCollection");
44 dataObject = createDataObject("StructuredDataReferenceTestDataObject", collection.getId());
45
46 referencesURL = "/%s/%d/%s/%d/%s".formatted(
47 Constants.COLLECTIONS,
48 collection.getId(),
49 Constants.DATA_OBJECTS,
50 dataObject.getId(),
51 Constants.STRUCTURED_DATA_REFERENCES
52 );
53
54 containerURL = "/" + Constants.STRUCTURED_DATA_CONTAINERS;
55
56 var toCreate = new StructuredDataContainerIO();
57 toCreate.setName("StructuredDataContainer");
58 container = given()
59 .spec(requestSpecOfDefaultUser)
60 .body(toCreate)
61 .when()
62 .post(containerURL)
63 .then()
64 .statusCode(201)
65 .extract()
66 .as(StructuredDataContainerIO.class);
67 var structuredData = new StructuredData();
68 structuredData.setName("My Structured Data");
69 payload = new StructuredDataPayload(
70 structuredData,
71 "{\"Hallo\":\"Welt\",\"number\":123,\"list\":[\"a\",\"b\"],\"object\":{\"a\":\"b\"}}"
72 );
73 var actual = given()
74 .spec(requestSpecOfDefaultUser)
75 .body(payload)
76 .when()
77 .post("%s/%d/%s".formatted(containerURL, container.getId(), Constants.PAYLOAD))
78 .then()
79 .statusCode(201)
80 .extract()
81 .as(StructuredData.class);
82 payload.setStructuredData(actual);
83 }
84
85 @Test
86 @Order(1)
87 public void createStructuredDataReference() {
88 var toCreate = new StructuredDataReferenceIO();
89 toCreate.setName("StructuredDataReferenceDummy");
90 toCreate.setStructuredDataOids(new String[] { payload.getStructuredData().getOid() });
91 toCreate.setStructuredDataContainerId(container.getId());
92
93 var actual = given()
94 .spec(requestSpecOfDefaultUser)
95 .body(toCreate)
96 .when()
97 .post(referencesURL)
98 .then()
99 .statusCode(201)
100 .extract()
101 .as(StructuredDataReferenceIO.class);
102 reference = actual;
103
104 assertThat(actual.getId()).isNotNull();
105 assertThat(actual.getCreatedAt()).isNotNull();
106 assertThat(actual.getCreatedBy()).isEqualTo(nameOfDefaultUser);
107 assertThat(actual.getDataObjectId()).isEqualTo(dataObject.getId());
108 assertThat(actual.getName()).isEqualTo("StructuredDataReferenceDummy");
109 assertThat(actual.getStructuredDataContainerId()).isEqualTo(container.getId());
110 assertThat(actual.getStructuredDataOids()).containsExactly(payload.getStructuredData().getOid());
111 assertThat(actual.getType()).isEqualTo("StructuredDataReference");
112 assertThat(actual.getUpdatedAt()).isNull();
113 assertThat(actual.getUpdatedBy()).isNull();
114 }
115
116 @Test
117 @Order(2)
118 public void getStructuredDataReferences() {
119 var actual = given()
120 .spec(requestSpecOfDefaultUser)
121 .when()
122 .get(referencesURL)
123 .then()
124 .statusCode(200)
125 .extract()
126 .as(StructuredDataReferenceIO[].class);
127
128 assertThat(actual).containsExactly(reference);
129 }
130
131 @Test
132 @Order(3)
133 public void getStructuredDataReference() {
134 var actual = given()
135 .spec(requestSpecOfDefaultUser)
136 .when()
137 .get(referencesURL + "/" + reference.getId())
138 .then()
139 .statusCode(200)
140 .extract()
141 .as(StructuredDataReferenceIO.class);
142
143 assertThat(actual).isEqualTo(reference);
144 }
145
146 @Test
147 @Order(4)
148 public void getStructuredDataReference_doesNotExist_notFound() {
149 var actual = given()
150 .spec(requestSpecOfDefaultUser)
151 .when()
152 .get(referencesURL + "/99999")
153 .then()
154 .statusCode(404)
155 .extract()
156 .as(ErrorResponse.class);
157
158 assertThat(actual.getMessage()).isEqualTo("ID ERROR - Structured Data Reference with id 99999 is null or deleted");
159 }
160
161 @Test
162 @Order(5)
163 public void getStructuredDataReference_isIsCollectionId_notFound() {
164 var actual = given()
165 .spec(requestSpecOfDefaultUser)
166 .when()
167 .get(referencesURL + "/" + collection.getId())
168 .then()
169 .statusCode(404)
170 .extract()
171 .as(ErrorResponse.class);
172
173 assertThat(actual.getMessage()).isEqualTo(
174 "ID ERROR - Structured Data Reference with id %s is null or deleted".formatted(collection.getId())
175 );
176 }
177
178 @Test
179 @Order(6)
180 public void getStructuredDataReference_idBelongsToWrongDataObject_notFound() {
181 DataObjectIO otherDataObject = createDataObject("OtherStructuredDataReferenceTestDataObject", collection.getId());
182
183 StructuredDataReferenceIO toCreate = new StructuredDataReferenceIO();
184 toCreate.setName("StructuredDataReferenceDummy");
185 toCreate.setStructuredDataOids(new String[] { payload.getStructuredData().getOid() });
186 toCreate.setStructuredDataContainerId(container.getId());
187
188 StructuredDataReferenceIO otherRef = given()
189 .spec(requestSpecOfDefaultUser)
190 .body(toCreate)
191 .when()
192 .post(
193 "/%s/%d/%s/%d/%s".formatted(
194 Constants.COLLECTIONS,
195 collection.getId(),
196 Constants.DATA_OBJECTS,
197 otherDataObject.getId(),
198 Constants.STRUCTURED_DATA_REFERENCES
199 )
200 )
201 .then()
202 .statusCode(201)
203 .extract()
204 .as(StructuredDataReferenceIO.class);
205
206 var actual = given()
207 .spec(requestSpecOfDefaultUser)
208 .when()
209 .get(referencesURL + "/" + otherRef.getId())
210 .then()
211 .statusCode(404)
212 .extract()
213 .as(ErrorResponse.class);
214
215 assertThat(actual.getMessage()).isEqualTo("ID ERROR - There is no association between dataObject and reference");
216 }
217
218 @Test
219 @Order(7)
220 @SuppressWarnings("unchecked")
221 public void getStructuredDataReferencePayload() throws JsonMappingException, JsonProcessingException {
222 var actual = given()
223 .spec(requestSpecOfDefaultUser)
224 .when()
225 .get(
226 "%s/%d/%s/%s".formatted(
227 referencesURL,
228 reference.getId(),
229 Constants.PAYLOAD,
230 payload.getStructuredData().getOid()
231 )
232 )
233 .then()
234 .statusCode(200)
235 .extract()
236 .as(StructuredDataPayload.class);
237 var payloadMap = objectMapper.readValue(actual.getPayload(), Map.class);
238 var expectedMap = objectMapper.readValue(payload.getPayload(), Map.class);
239
240 assertThat(actual.getStructuredData()).isEqualTo(payload.getStructuredData());
241 assertThat(payloadMap).containsAllEntriesOf(expectedMap);
242 assertThat(actual.getStructuredData()).isEqualTo(payload.getStructuredData());
243 }
244
245 @Test
246 @Order(8)
247 public void getStructuredDataReference_referenceToPrivateContainerOfOtherUser_notAllowed() {
248
249 CollectionIO otherCollection = createCollection("CollectionContainingReferencingDataObject", otherUser);
250 DataObjectIO otherDataObject = createDataObject(
251 "ReferencingDataObjectOfOtherUser",
252 otherCollection.getId(),
253 otherUser
254 );
255
256 StructuredDataReferenceIO toCreate = new StructuredDataReferenceIO();
257 toCreate.setName("StructuredDataReferenceDummy");
258
259 toCreate.setStructuredDataOids(new String[] { payload.getStructuredData().getOid() });
260 toCreate.setStructuredDataContainerId(container.getId());
261
262
263 ErrorResponse errorResponse = given()
264 .spec(requestSpecOfOtherUser)
265 .body(toCreate)
266 .when()
267 .post(
268 "/%s/%d/%s/%d/%s".formatted(
269 Constants.COLLECTIONS,
270 otherCollection.getId(),
271 Constants.DATA_OBJECTS,
272 otherDataObject.getId(),
273 Constants.STRUCTURED_DATA_REFERENCES
274 )
275 )
276 .then()
277 .statusCode(403)
278 .extract()
279 .as(ErrorResponse.class);
280
281 assertThat(errorResponse.getMessage()).isEqualTo(
282 "The requested action is forbidden by the permission policies. User has no READ permissions."
283 );
284 }
285
286 @Test
287 @Order(9)
288 public void deleteReferences() {
289 given()
290 .spec(requestSpecOfDefaultUser)
291 .when()
292 .delete(referencesURL + "/" + reference.getId())
293 .then()
294 .statusCode(204);
295 given()
296 .spec(requestSpecOfDefaultUser)
297 .when()
298 .delete(referencesURL + "/" + reference.getId())
299 .then()
300 .statusCode(404);
301 given().spec(requestSpecOfDefaultUser).when().get(referencesURL + "/" + reference.getId()).then().statusCode(404);
302 }
303 }