View Javadoc
1   package de.dlr.shepard.integrationtests;
2   
3   import static io.restassured.RestAssured.given;
4   
5   import de.dlr.shepard.context.collection.io.CollectionIO;
6   import de.dlr.shepard.context.collection.io.DataObjectIO;
7   import io.quarkus.test.junit.QuarkusIntegrationTest;
8   import java.util.List;
9   import java.util.Map;
10  import java.util.stream.Stream;
11  import lombok.AllArgsConstructor;
12  import lombok.Getter;
13  import lombok.NoArgsConstructor;
14  import lombok.Setter;
15  import org.junit.jupiter.api.BeforeAll;
16  import org.junit.jupiter.params.ParameterizedTest;
17  import org.junit.jupiter.params.provider.MethodSource;
18  
19  @Getter
20  @Setter
21  @AllArgsConstructor
22  @NoArgsConstructor
23  class EndpointTestCase {
24  
25    private String url;
26    private List<String> methods;
27    private Map<String, String> validPathParams;
28    private Map<String, String> invalidPathParams;
29    private Map<String, String> notFoundPathParams;
30    private Map<String, Map<String, Integer>> expectedStatusCodes;
31    private Map<String, Object> requestBody;
32    private Map<String, Object> invalidRequestBody;
33  }
34  
35  @QuarkusIntegrationTest
36  public class GenericEndpointsIT extends BaseTestCaseIT {
37  
38    private static CollectionIO collection;
39    private static DataObjectIO dataObject;
40  
41    @BeforeAll
42    public static void setup() {
43      collection = createCollection("A Collection");
44      dataObject = createDataObject("A dataobject", collection.getId());
45    }
46  
47    /**
48     * This parametrized test will perform all the needed tests on each test case.
49     * The covered test cases:
50     * - Requests with valid path
51     * - Requests with invalid path
52     * - Requests with valid body (POST, PUT)
53     * - Requests with invalid body (POST, PUT)
54     * - Requests for not found resource
55     * - Unauthorized access
56     * - Unauthorized public access (no user)
57     *
58     * Hint: Keep delete the last test case as it will delete the tested resource.
59     */
60    @ParameterizedTest
61    @MethodSource("getEndpoints")
62    public void testEndpoints(EndpointTestCase testCase) {
63      for (String method : testCase.getMethods()) {
64        testUnauthorizedAccess(testCase, method);
65        if (method.equals("POST") || method.equals("PUT")) {
66          testValidRequestsWithBody(testCase, method);
67          testInvalidRequestsWithInvalidBody(testCase, method);
68        } else {
69          testValidRequests(testCase, method);
70          testInvalidPathParams(testCase, method);
71        }
72        testNotFound(testCase, method);
73        testUnauthenticatedAccess(testCase, method);
74      }
75    }
76  
77    private void testValidRequests(EndpointTestCase testCase, String method) {
78      given()
79        .spec(requestSpecOfDefaultUser)
80        .pathParams(testCase.getValidPathParams())
81        .when()
82        .request(method, testCase.getUrl())
83        .then()
84        .statusCode(testCase.getExpectedStatusCodes().get(method).get("valid"));
85    }
86  
87    private void testInvalidPathParams(EndpointTestCase testCase, String method) {
88      if (testCase.getInvalidPathParams() == null) return;
89      given()
90        .spec(requestSpecOfDefaultUser)
91        .pathParams(testCase.getInvalidPathParams())
92        .when()
93        .request(method, testCase.getUrl())
94        .then()
95        .statusCode(testCase.getExpectedStatusCodes().get(method).get("invalid"));
96    }
97  
98    private void testValidRequestsWithBody(EndpointTestCase testCase, String method) {
99      given()
100       .spec(requestSpecOfDefaultUser)
101       .pathParams(testCase.getValidPathParams())
102       .when()
103       .body(testCase.getRequestBody())
104       .request(method, testCase.getUrl())
105       .then()
106       .statusCode(testCase.getExpectedStatusCodes().get(method).get("valid"));
107   }
108 
109   private void testInvalidRequestsWithInvalidBody(EndpointTestCase testCase, String method) {
110     given()
111       .spec(requestSpecOfDefaultUser)
112       .pathParams(testCase.getValidPathParams())
113       .when()
114       .body(testCase.getInvalidRequestBody())
115       .request(method, testCase.getUrl())
116       .then()
117       .statusCode(testCase.getExpectedStatusCodes().get(method).get("invalid"));
118   }
119 
120   private void testUnauthorizedAccess(EndpointTestCase testCase, String method) {
121     if (testCase.getExpectedStatusCodes().get(method).get("unauthorized") == null) return;
122     given()
123       .spec(requestSpecOfOtherUser)
124       .pathParams(testCase.getValidPathParams())
125       .when()
126       .request(method, testCase.getUrl())
127       .then()
128       .statusCode(testCase.getExpectedStatusCodes().get(method).get("unauthorized"));
129   }
130 
131   private void testUnauthenticatedAccess(EndpointTestCase testCase, String method) {
132     if (testCase.getExpectedStatusCodes().get(method).get("unauthenticated") == null) return;
133     given()
134       .spec(requestSpecNoUser)
135       .pathParams(testCase.getValidPathParams())
136       .when()
137       .request(method, testCase.getUrl())
138       .then()
139       .statusCode(testCase.getExpectedStatusCodes().get(method).get("unauthenticated"));
140   }
141 
142   private void testNotFound(EndpointTestCase testCase, String method) {
143     if (testCase.getExpectedStatusCodes().get(method).get("notFound") == null) return;
144     given()
145       .spec(requestSpecOfDefaultUser)
146       .pathParams(testCase.getNotFoundPathParams())
147       .when()
148       .request(method, testCase.getUrl())
149       .then()
150       .statusCode(testCase.getExpectedStatusCodes().get(method).get("notFound"));
151   }
152 
153   public static List<EndpointTestCase> loadTestCases() {
154     return List.of(
155       new EndpointTestCase(
156         "/collections",
157         List.of("GET", "POST"),
158         Map.of(),
159         null,
160         null,
161         Map.of(
162           "GET",
163           Map.of("valid", 200, "unauthenticated", 401),
164           "POST",
165           Map.of("valid", 201, "invalid", 400, "unauthenticated", 401)
166         ),
167         Map.of("name", "coll name"),
168         Map.of()
169       ),
170       new EndpointTestCase(
171         "/collections/{collectionId}",
172         List.of("GET", "PUT"),
173         Map.of("collectionId", Long.toString(collection.getId())),
174         Map.of("collectionId", "-1"),
175         Map.of("collectionId", "999999999"),
176         Map.of(
177           "GET",
178           Map.of("valid", 200, "invalid", 400, "unauthorized", 403, "unauthenticated", 401, "notFound", 404),
179           "PUT",
180           Map.of("valid", 200, "invalid", 400, "unauthorized", 403, "unauthenticated", 401, "notFound", 404)
181         ),
182         Map.of("name", "coll name"),
183         Map.of()
184       ),
185       new EndpointTestCase(
186         "/collections/{collectionId}/permissions",
187         List.of("GET", "PUT"),
188         Map.of("collectionId", Long.toString(collection.getId())),
189         Map.of("collectionId", "-1"),
190         Map.of("collectionId", "999999999"),
191         Map.of(
192           "GET",
193           Map.of("valid", 200, "invalid", 400, "unauthorized", 403, "unauthenticated", 401, "notFound", 404),
194           "PUT",
195           Map.of("valid", 200, "invalid", 400, "unauthorized", 403, "unauthenticated", 401, "notFound", 404)
196         ),
197         Map.of(
198           "owner",
199           nameOfDefaultUser,
200           "permissionType",
201           "Private",
202           "reader",
203           List.of(),
204           "writer",
205           List.of(),
206           "readerGroupIds",
207           List.of(),
208           "writerGroupIds",
209           List.of(),
210           "manager",
211           List.of()
212         ),
213         Map.of()
214       ),
215       new EndpointTestCase(
216         "/collections/{collectionId}/roles",
217         List.of("GET"),
218         Map.of("collectionId", Long.toString(collection.getId())),
219         Map.of("collectionId", "-1"),
220         Map.of("collectionId", "999999999"),
221         Map.of(
222           "GET",
223           Map.of("valid", 200, "invalid", 400, "unauthorized", 403, "unauthenticated", 401, "notFound", 404)
224         ),
225         Map.of(),
226         Map.of()
227       ),
228       new EndpointTestCase(
229         "/collections/{collectionId}/export",
230         List.of("GET"),
231         Map.of("collectionId", Long.toString(collection.getId())),
232         Map.of("collectionId", "-1"),
233         Map.of("collectionId", "999999999"),
234         Map.of(
235           "GET",
236           Map.of("valid", 200, "invalid", 400, "unauthorized", 403, "unauthenticated", 401, "notFound", 404)
237         ),
238         Map.of(),
239         Map.of()
240       ),
241       new EndpointTestCase(
242         "/collections/{collectionId}/dataObjects/{dataObjectId}",
243         List.of("GET"),
244         Map.of("collectionId", Long.toString(collection.getId()), "dataObjectId", Long.toString(dataObject.getId())),
245         Map.of("collectionId", Long.toString(collection.getId()), "dataObjectId", "-1"),
246         Map.of("collectionId", Long.toString(collection.getId()), "dataObjectId", "9999999"),
247         Map.of(
248           "GET",
249           Map.of("valid", 200, "invalid", 400, "unauthorized", 403, "unauthenticated", 401, "notFound", 404)
250         ),
251         Map.of("name", "coll name"),
252         Map.of()
253       ),
254       new EndpointTestCase(
255         "/collections/{collectionId}",
256         List.of("DELETE"),
257         Map.of("collectionId", Long.toString(collection.getId())),
258         Map.of("collectionId", "-1"),
259         Map.of("collectionId", "999999999"),
260         Map.of(
261           "DELETE",
262           Map.of("valid", 204, "invalid", 400, "unauthorized", 403, "unauthenticated", 401, "notFound", 404)
263         ),
264         Map.of(),
265         Map.of()
266       )
267     );
268   }
269 
270   private static Stream<EndpointTestCase> getEndpoints() {
271     return loadTestCases().stream();
272   }
273 }