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   
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     // This test is a testing the bug described in #475
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     // create reference to other container with specific data oid
259     toCreate.setStructuredDataOids(new String[] { payload.getStructuredData().getOid() });
260     toCreate.setStructuredDataContainerId(container.getId());
261 
262     // Act + Assert
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 }