|
30 | 30 | import org.eclipse.edc.protocol.dsp.http.spi.message.GetDspRequest;
|
31 | 31 | import org.eclipse.edc.protocol.dsp.http.spi.message.PostDspRequest;
|
32 | 32 | import org.eclipse.edc.protocol.dsp.http.spi.message.ResponseDecorator;
|
| 33 | +import org.eclipse.edc.protocol.dsp.spi.type.DspNamespace; |
33 | 34 | import org.eclipse.edc.spi.result.Result;
|
34 | 35 | import org.eclipse.edc.transform.spi.TypeTransformerRegistry;
|
35 | 36 | import org.eclipse.edc.web.jersey.testfixtures.RestControllerTestBase;
|
|
47 | 48 | import static org.eclipse.edc.protocol.dsp.catalog.http.api.CatalogApiPaths.BASE_PATH;
|
48 | 49 | import static org.eclipse.edc.protocol.dsp.catalog.http.api.CatalogApiPaths.CATALOG_REQUEST;
|
49 | 50 | import static org.eclipse.edc.protocol.dsp.catalog.http.api.CatalogApiPaths.DATASET_REQUEST;
|
50 |
| -import static org.eclipse.edc.protocol.dsp.spi.type.DspCatalogPropertyAndTypeNames.DSPACE_TYPE_CATALOG_REQUEST_MESSAGE_IRI; |
| 51 | +import static org.eclipse.edc.protocol.dsp.spi.type.DspCatalogPropertyAndTypeNames.DSPACE_TYPE_CATALOG_REQUEST_MESSAGE_TERM; |
| 52 | +import static org.eclipse.edc.protocol.dsp.spi.type.DspConstants.DSP_NAMESPACE_V_08; |
| 53 | +import static org.eclipse.edc.protocol.dsp.spi.type.DspConstants.DSP_NAMESPACE_V_2024_1; |
| 54 | +import static org.eclipse.edc.protocol.dsp.spi.version.DspVersions.V_2024_1_PATH; |
51 | 55 | import static org.mockito.ArgumentMatchers.any;
|
52 | 56 | import static org.mockito.ArgumentMatchers.eq;
|
53 | 57 | import static org.mockito.ArgumentMatchers.isA;
|
|
56 | 60 | import static org.mockito.Mockito.verifyNoInteractions;
|
57 | 61 | import static org.mockito.Mockito.when;
|
58 | 62 |
|
59 |
| -@ApiTest |
60 |
| -class DspCatalogApiControllerTest extends RestControllerTestBase { |
61 |
| - |
62 |
| - private final TypeTransformerRegistry transformerRegistry = mock(); |
63 |
| - private final CatalogProtocolService service = mock(); |
64 |
| - private final DspRequestHandler dspRequestHandler = mock(); |
65 |
| - private final ContinuationTokenManager continuationTokenManager = mock(); |
66 |
| - |
67 |
| - @Test |
68 |
| - void getDataset_shouldGetResource() { |
69 |
| - when(dspRequestHandler.getResource(any())).thenReturn(Response.ok().type(APPLICATION_JSON).build()); |
70 |
| - |
71 |
| - baseRequest() |
72 |
| - .get(DATASET_REQUEST + "/datasetId") |
73 |
| - .then() |
74 |
| - .statusCode(200) |
75 |
| - .contentType(JSON); |
76 |
| - |
77 |
| - var captor = ArgumentCaptor.forClass(GetDspRequest.class); |
78 |
| - verify(dspRequestHandler).getResource(captor.capture()); |
79 |
| - var request = captor.getValue(); |
80 |
| - assertThat(request.getToken()).isEqualTo("auth"); |
81 |
| - assertThat(request.getResultClass()).isEqualTo(Dataset.class); |
82 |
| - assertThat(request.getId()).isEqualTo("datasetId"); |
83 |
| - } |
84 |
| - |
85 |
| - @Override |
86 |
| - protected Object controller() { |
87 |
| - return new DspCatalogApiController(service, dspRequestHandler, continuationTokenManager); |
88 |
| - } |
| 63 | +class DspCatalogApiControllerTest { |
89 | 64 |
|
90 |
| - private RequestSpecification baseRequest() { |
91 |
| - return given() |
92 |
| - .baseUri("http://localhost:" + port) |
93 |
| - .basePath(BASE_PATH) |
94 |
| - .header(HttpHeaders.AUTHORIZATION, "auth") |
95 |
| - .when(); |
96 |
| - } |
| 65 | + abstract static class Tests extends RestControllerTestBase { |
97 | 66 |
|
98 |
| - @Nested |
99 |
| - class RequestCatalog { |
| 67 | + protected final TypeTransformerRegistry transformerRegistry = mock(); |
| 68 | + protected final CatalogProtocolService service = mock(); |
| 69 | + protected final DspRequestHandler dspRequestHandler = mock(); |
| 70 | + protected final ContinuationTokenManager continuationTokenManager = mock(); |
100 | 71 |
|
101 | 72 | @Test
|
102 |
| - void shouldCreateResource() { |
103 |
| - var requestBody = createObjectBuilder().add(TYPE, DSPACE_TYPE_CATALOG_REQUEST_MESSAGE_IRI).build(); |
104 |
| - var catalog = createObjectBuilder().add(JsonLdKeywords.TYPE, "catalog").build(); |
105 |
| - when(transformerRegistry.transform(any(Catalog.class), eq(JsonObject.class))).thenReturn(Result.success(catalog)); |
106 |
| - when(dspRequestHandler.createResource(any(), any())).thenReturn(Response.ok().type(APPLICATION_JSON_TYPE).build()); |
107 |
| - when(continuationTokenManager.createResponseDecorator(any())).thenReturn(mock()); |
| 73 | + void getDataset_shouldGetResource() { |
| 74 | + when(dspRequestHandler.getResource(any())).thenReturn(Response.ok().type(APPLICATION_JSON).build()); |
108 | 75 |
|
109 | 76 | baseRequest()
|
110 |
| - .contentType(JSON) |
111 |
| - .body(requestBody) |
112 |
| - .post(CATALOG_REQUEST) |
| 77 | + .get(DATASET_REQUEST + "/datasetId") |
113 | 78 | .then()
|
114 | 79 | .statusCode(200)
|
115 | 80 | .contentType(JSON);
|
116 | 81 |
|
117 |
| - var captor = ArgumentCaptor.forClass(PostDspRequest.class); |
118 |
| - verify(dspRequestHandler).createResource(captor.capture(), isA(ResponseDecorator.class)); |
| 82 | + var captor = ArgumentCaptor.forClass(GetDspRequest.class); |
| 83 | + verify(dspRequestHandler).getResource(captor.capture()); |
119 | 84 | var request = captor.getValue();
|
120 |
| - assertThat(request.getInputClass()).isEqualTo(CatalogRequestMessage.class); |
121 |
| - assertThat(request.getResultClass()).isEqualTo(Catalog.class); |
122 |
| - assertThat(request.getExpectedMessageType()).isEqualTo(DSPACE_TYPE_CATALOG_REQUEST_MESSAGE_IRI); |
123 |
| - assertThat(request.getProcessId()).isNull(); |
124 | 85 | assertThat(request.getToken()).isEqualTo("auth");
|
125 |
| - assertThat(request.getMessage()).isEqualTo(requestBody); |
126 |
| - verify(continuationTokenManager).createResponseDecorator("http://localhost:%d/catalog/request".formatted(port)); |
| 86 | + assertThat(request.getResultClass()).isEqualTo(Dataset.class); |
| 87 | + assertThat(request.getId()).isEqualTo("datasetId"); |
127 | 88 | }
|
128 | 89 |
|
129 |
| - @Test |
130 |
| - void shouldApplyContinuationToken_whenPassed() { |
131 |
| - var requestBody = createObjectBuilder().add(TYPE, DSPACE_TYPE_CATALOG_REQUEST_MESSAGE_IRI).build(); |
132 |
| - var catalog = createObjectBuilder().add(JsonLdKeywords.TYPE, "catalog").build(); |
133 |
| - when(transformerRegistry.transform(any(Catalog.class), eq(JsonObject.class))).thenReturn(Result.success(catalog)); |
134 |
| - when(dspRequestHandler.createResource(any(), any())).thenReturn(Response.ok().type(APPLICATION_JSON_TYPE).build()); |
135 |
| - when(continuationTokenManager.createResponseDecorator(any())).thenReturn(mock()); |
136 |
| - var enrichedRequestBody = createObjectBuilder(requestBody).add("query", Json.createObjectBuilder()).build(); |
137 |
| - when(continuationTokenManager.applyQueryFromToken(any(), any())).thenReturn(Result.success(enrichedRequestBody)); |
138 | 90 |
|
139 |
| - baseRequest() |
140 |
| - .contentType(JSON) |
141 |
| - .body(requestBody) |
142 |
| - .post(CATALOG_REQUEST + "?continuationToken=pagination-token") |
143 |
| - .then() |
144 |
| - .statusCode(200) |
145 |
| - .contentType(JSON); |
| 91 | + protected abstract String basePath(); |
146 | 92 |
|
147 |
| - var captor = ArgumentCaptor.forClass(PostDspRequest.class); |
148 |
| - verify(dspRequestHandler).createResource(captor.capture(), isA(ResponseDecorator.class)); |
149 |
| - var request = captor.getValue(); |
150 |
| - assertThat(request.getMessage()).isSameAs(enrichedRequestBody); |
151 |
| - verify(continuationTokenManager).applyQueryFromToken(requestBody, "pagination-token"); |
| 93 | + protected abstract DspNamespace namespace(); |
| 94 | + |
| 95 | + private RequestSpecification baseRequest() { |
| 96 | + return given() |
| 97 | + .baseUri("http://localhost:" + port) |
| 98 | + .basePath(basePath()) |
| 99 | + .header(HttpHeaders.AUTHORIZATION, "auth") |
| 100 | + .when(); |
152 | 101 | }
|
153 | 102 |
|
154 |
| - @Test |
155 |
| - void shouldReturnBadRequest_whenContinuationTokenIsNotValid() { |
156 |
| - var requestBody = createObjectBuilder().add(TYPE, DSPACE_TYPE_CATALOG_REQUEST_MESSAGE_IRI).build(); |
157 |
| - when(continuationTokenManager.applyQueryFromToken(any(), any())).thenReturn(Result.failure("error")); |
| 103 | + @Nested |
| 104 | + class RequestCatalog { |
| 105 | + |
| 106 | + @Test |
| 107 | + void shouldCreateResource() { |
| 108 | + var requestBody = createObjectBuilder().add(TYPE, namespace().toIri(DSPACE_TYPE_CATALOG_REQUEST_MESSAGE_TERM)).build(); |
| 109 | + var catalog = createObjectBuilder().add(JsonLdKeywords.TYPE, "catalog").build(); |
| 110 | + when(transformerRegistry.transform(any(Catalog.class), eq(JsonObject.class))).thenReturn(Result.success(catalog)); |
| 111 | + when(dspRequestHandler.createResource(any(), any())).thenReturn(Response.ok().type(APPLICATION_JSON_TYPE).build()); |
| 112 | + when(continuationTokenManager.createResponseDecorator(any())).thenReturn(mock()); |
| 113 | + |
| 114 | + baseRequest() |
| 115 | + .contentType(JSON) |
| 116 | + .body(requestBody) |
| 117 | + .post(CATALOG_REQUEST) |
| 118 | + .then() |
| 119 | + .statusCode(200) |
| 120 | + .contentType(JSON); |
| 121 | + |
| 122 | + var captor = ArgumentCaptor.forClass(PostDspRequest.class); |
| 123 | + verify(dspRequestHandler).createResource(captor.capture(), isA(ResponseDecorator.class)); |
| 124 | + var request = captor.getValue(); |
| 125 | + assertThat(request.getInputClass()).isEqualTo(CatalogRequestMessage.class); |
| 126 | + assertThat(request.getResultClass()).isEqualTo(Catalog.class); |
| 127 | + assertThat(request.getExpectedMessageType()).isEqualTo(namespace().toIri(DSPACE_TYPE_CATALOG_REQUEST_MESSAGE_TERM)); |
| 128 | + assertThat(request.getProcessId()).isNull(); |
| 129 | + assertThat(request.getToken()).isEqualTo("auth"); |
| 130 | + assertThat(request.getMessage()).isEqualTo(requestBody); |
| 131 | + verify(continuationTokenManager).createResponseDecorator("http://localhost:%d%s".formatted(port, basePath() + CATALOG_REQUEST)); |
| 132 | + } |
| 133 | + |
| 134 | + @Test |
| 135 | + void shouldApplyContinuationToken_whenPassed() { |
| 136 | + var requestBody = createObjectBuilder().add(TYPE, namespace().toIri(DSPACE_TYPE_CATALOG_REQUEST_MESSAGE_TERM)).build(); |
| 137 | + var catalog = createObjectBuilder().add(JsonLdKeywords.TYPE, "catalog").build(); |
| 138 | + when(transformerRegistry.transform(any(Catalog.class), eq(JsonObject.class))).thenReturn(Result.success(catalog)); |
| 139 | + when(dspRequestHandler.createResource(any(), any())).thenReturn(Response.ok().type(APPLICATION_JSON_TYPE).build()); |
| 140 | + when(continuationTokenManager.createResponseDecorator(any())).thenReturn(mock()); |
| 141 | + var enrichedRequestBody = createObjectBuilder(requestBody).add("query", Json.createObjectBuilder()).build(); |
| 142 | + when(continuationTokenManager.applyQueryFromToken(any(), any())).thenReturn(Result.success(enrichedRequestBody)); |
| 143 | + |
| 144 | + baseRequest() |
| 145 | + .contentType(JSON) |
| 146 | + .body(requestBody) |
| 147 | + .post(CATALOG_REQUEST + "?continuationToken=pagination-token") |
| 148 | + .then() |
| 149 | + .statusCode(200) |
| 150 | + .contentType(JSON); |
| 151 | + |
| 152 | + var captor = ArgumentCaptor.forClass(PostDspRequest.class); |
| 153 | + verify(dspRequestHandler).createResource(captor.capture(), isA(ResponseDecorator.class)); |
| 154 | + var request = captor.getValue(); |
| 155 | + assertThat(request.getMessage()).isSameAs(enrichedRequestBody); |
| 156 | + verify(continuationTokenManager).applyQueryFromToken(requestBody, "pagination-token"); |
| 157 | + } |
| 158 | + |
| 159 | + @Test |
| 160 | + void shouldReturnBadRequest_whenContinuationTokenIsNotValid() { |
| 161 | + var requestBody = createObjectBuilder().add(TYPE, namespace().toIri(DSPACE_TYPE_CATALOG_REQUEST_MESSAGE_TERM)).build(); |
| 162 | + when(continuationTokenManager.applyQueryFromToken(any(), any())).thenReturn(Result.failure("error")); |
| 163 | + |
| 164 | + baseRequest() |
| 165 | + .contentType(JSON) |
| 166 | + .body(requestBody) |
| 167 | + .post(CATALOG_REQUEST + "?continuationToken=pagination-token") |
| 168 | + .then() |
| 169 | + .statusCode(400); |
| 170 | + |
| 171 | + verifyNoInteractions(dspRequestHandler, transformerRegistry); |
| 172 | + } |
| 173 | + } |
| 174 | + } |
158 | 175 |
|
159 |
| - baseRequest() |
160 |
| - .contentType(JSON) |
161 |
| - .body(requestBody) |
162 |
| - .post(CATALOG_REQUEST + "?continuationToken=pagination-token") |
163 |
| - .then() |
164 |
| - .statusCode(400); |
| 176 | + @ApiTest |
| 177 | + @Nested |
| 178 | + class DspCatalogApiControllerV08Test extends Tests { |
| 179 | + |
| 180 | + @Override |
| 181 | + protected String basePath() { |
| 182 | + return BASE_PATH; |
| 183 | + } |
| 184 | + |
| 185 | + @Override |
| 186 | + protected DspNamespace namespace() { |
| 187 | + return DSP_NAMESPACE_V_08; |
| 188 | + } |
165 | 189 |
|
166 |
| - verifyNoInteractions(dspRequestHandler, transformerRegistry); |
| 190 | + @Override |
| 191 | + protected Object controller() { |
| 192 | + return new DspCatalogApiController(service, dspRequestHandler, continuationTokenManager); |
167 | 193 | }
|
168 | 194 | }
|
169 | 195 |
|
| 196 | + @ApiTest |
| 197 | + @Nested |
| 198 | + class DspCatalogApiControllerV20241Test extends Tests { |
| 199 | + |
| 200 | + @Override |
| 201 | + protected String basePath() { |
| 202 | + return V_2024_1_PATH + BASE_PATH; |
| 203 | + } |
| 204 | + |
| 205 | + @Override |
| 206 | + protected DspNamespace namespace() { |
| 207 | + return DSP_NAMESPACE_V_2024_1; |
| 208 | + } |
| 209 | + |
| 210 | + @Override |
| 211 | + protected Object controller() { |
| 212 | + return new DspCatalogApiController20241(service, dspRequestHandler, continuationTokenManager); |
| 213 | + } |
| 214 | + } |
170 | 215 | }
|
0 commit comments