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