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