Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@
* Fix offset handling when retrieving holdings from HoldingsIQ. ([MODKBEKBJ-825](https://folio-org.atlassian.net/browse/MODKBEKBJ-825))
* Fix error messages format received from HoldingsIQ. ([MODKBEKBJ-826](https://folio-org.atlassian.net/browse/MODKBEKBJ-826))
* Fix updater not returned on get access-types collection. ([MODKBEKBJ-842](https://folio-org.atlassian.net/browse/MODKBEKBJ-842))
* Set "permissions: contents: read" in maven.yml ([FOLIO-4553](https://folio-org.atlassian.net/browse/FOLIO-4553))
* Return 422 on post package validation errors ([MODKBEKBJ-862](https://folio-org.atlassian.net/browse/MODKBEKBJ-862))

### Tech Dept
* Set "permissions: contents: read" in maven.yml ([FOLIO-4553](https://folio-org.atlassian.net/browse/FOLIO-4553))
* Description ([ISSUE](https://folio-org.atlassian.net/browse/ISSUE))

### Dependencies
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ public void postEholdingsPackages(String contentType, PackagePostRequest entity,

template
.addErrorMapper(NotFoundException.class, error400NotFoundMapper())
.addErrorMapper(InputValidationException.class, error422InputValidationMapper())
.executeWithResult(Package.class);
}

Expand Down
71 changes: 44 additions & 27 deletions src/test/java/org/folio/rest/impl/EholdingsPackagesImplTest.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.folio.rest.impl;

import static io.netty.handler.codec.http.HttpHeaderValues.APPLICATION_JSON;
import static java.util.concurrent.CompletableFuture.completedFuture;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
Expand Down Expand Up @@ -102,13 +103,6 @@ void setUp() {
.build();
}

@SuppressWarnings("unchecked")
private Function<RmApiTemplateContext, CompletableFuture<?>> captureRequestAction() {
var captor = ArgumentCaptor.forClass(Function.class);
verify(template).requestAction(captor.capture());
return captor.getValue();
}

@Test
void shouldFetchPackagesByTagFilterWhenTagsFilterIsGiven() {
var filter = PackageRecordFilter.builder().filterTags(List.of("tag1")).sort("relevance")
Expand Down Expand Up @@ -158,28 +152,35 @@ void shouldRetrieveAllPackagesWhenFilterCustomIsNotSet() {
verify(packageService).retrievePackages(null, filter, context);
}

private void invokeGetEholdingsPackages(PackageRecordFilter filter) {
impl.getEholdingsPackages(filter.getFilterCustom(), filter.getQuery(), filter.getQueryField(),
filter.getQueryType(), filter.isHighlight(), filter.getFilterSelected(), filter.getFilterType(),
filter.getFilterVisibility(), filter.getFilterFreeAccess(), filter.getFilterTags(),
filter.getFilterAccessType(), filter.getSort(), filter.getPage(), filter.getCount(), OKAPI_HEADERS,
asyncResultHandler, null);
}

@Test
void shouldCreateCustomPackage() {
var entity = new PackagePostRequest()
.withData(new PackagePostData().withAttributes(new PackagePostDataAttributes()));
when(packageService.createCustomPackage(entity, context)).thenReturn(completedFuture(null));

impl.postEholdingsPackages("application/json", entity, OKAPI_HEADERS, asyncResultHandler, null);
impl.postEholdingsPackages(APPLICATION_JSON.toString(), entity, OKAPI_HEADERS, asyncResultHandler, null);

captureRequestAction().apply(context);
verify(packageService).createCustomPackage(entity, context);
verify(template).addErrorMapper(eq(NotFoundException.class), any());
verify(template).executeWithResult(org.folio.rest.jaxrs.model.Package.class);
}

@Test
@SuppressWarnings("unchecked")
void shouldMapInputValidationExceptionTo422OnCreateCustomPackage() {
var entity = new PackagePostRequest()
.withData(new PackagePostData().withAttributes(new PackagePostDataAttributes()));

impl.postEholdingsPackages(APPLICATION_JSON.toString(), entity, OKAPI_HEADERS, asyncResultHandler, null);

var mapperCaptor = ArgumentCaptor.forClass(Function.class);
verify(template).addErrorMapper(eq(InputValidationException.class), mapperCaptor.capture());
var response = (Response) mapperCaptor.getValue()
.apply(new InputValidationException("Invalid name", "name must not be empty"));
assertEquals(422, response.getStatus());
}

@Test
void shouldRetrievePackageWithRelatedData() {
when(packageService.retrievePackageWithRelatedData(any(), any(), any())).thenReturn(completedFuture(null));
Expand All @@ -198,7 +199,8 @@ void shouldUpdatePackage() {
.withData(new PackagePutData().withAttributes(new PackagePutDataAttributes()));
when(packageService.updatePackage(any(), any(), any())).thenReturn(completedFuture(null));

impl.putEholdingsPackagesByPackageId("19-3964", "application/json", entity, OKAPI_HEADERS, asyncResultHandler,
impl.putEholdingsPackagesByPackageId("19-3964", APPLICATION_JSON.toString(), entity, OKAPI_HEADERS,
asyncResultHandler,
null);

captureRequestAction().apply(context);
Expand Down Expand Up @@ -258,13 +260,6 @@ void shouldRetrievePackageTitlesWhenNoTagOrAccessTypeFilterIsGiven() {
verify(template).requestAction(same(stubFunction));
}

private void invokeGetResources(ResourceFilter filter) {
impl.getEholdingsPackagesResourcesByPackageId(filter.getPackageId(), filter.getFilterTags(),
filter.getFilterAccessType(), filter.getFilterSelected(), filter.getFilterType(), filter.getFilterName(),
filter.getFilterIsxn(), filter.getFilterSubject(), filter.getFilterPublisher(), filter.getSort(),
filter.getPage(), filter.getCount(), OKAPI_HEADERS, asyncResultHandler, null);
}

@Test
void shouldUpdateTagsForPackage() {
var credentialsId = UUID.randomUUID();
Expand All @@ -275,7 +270,7 @@ void shouldUpdateTagsForPackage() {
when(packageService.updateTagsForPackage(entity, credentialsId, "19-3964", "fs"))
.thenReturn(completedFuture(attributes));

impl.putEholdingsPackagesTagsByPackageId("19-3964", "application/json", entity, OKAPI_HEADERS,
impl.putEholdingsPackagesTagsByPackageId("19-3964", APPLICATION_JSON.toString(), entity, OKAPI_HEADERS,
asyncResultHandler, null);

verify(asyncResultHandler).handle(responseCaptor.capture());
Expand All @@ -294,7 +289,7 @@ void shouldReturn422WhenTagsUpdateFails() {
when(packageService.updateTagsForPackage(any(), any(), any(), any()))
.thenReturn(CompletableFuture.failedFuture(new InputValidationException("invalid", "invalid tags")));

impl.putEholdingsPackagesTagsByPackageId("19-3964", "application/json", entity, OKAPI_HEADERS,
impl.putEholdingsPackagesTagsByPackageId("19-3964", APPLICATION_JSON.toString(), entity, OKAPI_HEADERS,
asyncResultHandler, null);

verify(asyncResultHandler).handle(responseCaptor.capture());
Expand All @@ -307,10 +302,32 @@ void shouldRetrievePackagesBulk() {
var entity = new PackagePostBulkFetchRequest().withPackages(java.util.Set.of("19-3964"));
when(packagesRmApiService.retrievePackagesBulk(entity.getPackages())).thenReturn(completedFuture(null));

impl.postEholdingsPackagesBulkFetch("application/json", entity, OKAPI_HEADERS, asyncResultHandler, null);
impl.postEholdingsPackagesBulkFetch(APPLICATION_JSON.toString(), entity, OKAPI_HEADERS, asyncResultHandler, null);

captureRequestAction().apply(context);
verify(packagesRmApiService).retrievePackagesBulk(entity.getPackages());
verify(template).executeWithResult(org.folio.rest.jaxrs.model.PackageBulkFetchCollection.class);
}

@SuppressWarnings("unchecked")
private Function<RmApiTemplateContext, CompletableFuture<?>> captureRequestAction() {
var captor = ArgumentCaptor.forClass(Function.class);
verify(template).requestAction(captor.capture());
return captor.getValue();
}

private void invokeGetEholdingsPackages(PackageRecordFilter filter) {
impl.getEholdingsPackages(filter.getFilterCustom(), filter.getQuery(), filter.getQueryField(),
filter.getQueryType(), filter.isHighlight(), filter.getFilterSelected(), filter.getFilterType(),
filter.getFilterVisibility(), filter.getFilterFreeAccess(), filter.getFilterTags(),
filter.getFilterAccessType(), filter.getSort(), filter.getPage(), filter.getCount(), OKAPI_HEADERS,
asyncResultHandler, null);
}

private void invokeGetResources(ResourceFilter filter) {
impl.getEholdingsPackagesResourcesByPackageId(filter.getPackageId(), filter.getFilterTags(),
filter.getFilterAccessType(), filter.getFilterSelected(), filter.getFilterType(), filter.getFilterName(),
filter.getFilterIsxn(), filter.getFilterSubject(), filter.getFilterPublisher(), filter.getSort(),
filter.getPage(), filter.getCount(), OKAPI_HEADERS, asyncResultHandler, null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -901,6 +901,18 @@ void shouldReturn422OnPostPackageWithInvalidAccessTypeId() {
error.getErrors().getFirst().getMessage());
}

@Test
void shouldReturn422OnPostPackageWithEmptyName() {
var requestBody = readFile(POST_PACKAGE_REQUEST).replace("\"name\": \"TEST_NAME\"", "\"name\": \"\"");

var error = postWithStatus(packagesPath(), requestBody, SC_UNPROCESSABLE_CONTENT).as(JsonapiError.class);

assertEquals(1, error.getErrors().size());
assertErrorContainsTitle(error, "Invalid name");
assertEquals("name must not be empty", error.getErrors().getFirst().getDetail());
wm.verify(0, postRequestedFor(urlPathEqualTo(packageRmApiV1(STUB_VENDOR_ID))));
}

@Test
void shouldReturn400WhenPackagePostDataIsInvalid() {
mockGet(WireMock.equalTo(rootProxyCustomLabelsRmApi()), readFile(GET_PACKAGE_PROVIDER_RESPONSE));
Expand Down
Loading