Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CIRC-2116] Allowed SP endpoint should support patronGroupId parameter #1483

Closed
wants to merge 25 commits into from
Closed
Changes from 2 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
19bf73c
[CIRC-2051] Add ecsRequestRouting parameter to allowed-service-points…
roman-barannyk Apr 15, 2024
e131373
Merge remote-tracking branch 'origin/ecs-tlr-feature' into ecs-tlr-fe…
roman-barannyk Apr 23, 2024
6e3315d
conflicts resolving
roman-barannyk Apr 23, 2024
ae6991d
conflicts resolving
roman-barannyk Apr 24, 2024
32b7e00
CIRC-2081: Fetch TLR settings from mod-settings (#1467)
OleksandrVidinieiev Apr 26, 2024
3167b20
CIRC-2072 Create a facade for instance search
MagzhanArtykov Apr 30, 2024
6676cde
CIRC-2072 Create a facade for instance search
MagzhanArtykov May 2, 2024
1c1cd46
CIRC-2072 Added API test
MagzhanArtykov May 13, 2024
6797c1b
CIRC-2072 Added API test
MagzhanArtykov May 15, 2024
eac3e54
CIRC-2072 Create a facade for instance search
MagzhanArtykov May 20, 2024
1b29087
CIRC-2072 Create a facade for instance search
MagzhanArtykov May 21, 2024
a6e440e
CIRC-2072 Create a facade for instance search
MagzhanArtykov May 23, 2024
1c88c01
CIRC-2072 Create a facade for instance search
MagzhanArtykov May 24, 2024
be46a67
CIRC-2072 Create a facade for instance search
MagzhanArtykov May 24, 2024
9d68320
CIRC-2072 Create a facade for instance search
MagzhanArtykov May 27, 2024
af5a9f7
CIRC-2072 Create a facade for instance search
MagzhanArtykov May 27, 2024
f86281c
CIRC-2072 Create a facade for instance search
MagzhanArtykov May 27, 2024
0702200
CIRC-2072 Create a facade for instance search
MagzhanArtykov May 27, 2024
0b2acfd
CIRC-2072 Create a facade for instance search
MagzhanArtykov May 28, 2024
123dca6
Merge pull request #1471 from folio-org/CIRC-2072b
MagzhanArtykov May 29, 2024
ba47983
Merge branch 'master' into ecs-tlr-feature
OleksandrVidinieiev May 30, 2024
3f6bd4f
CIRC-2101: Fetch item details across tenants (#1474)
OleksandrVidinieiev Jun 6, 2024
5cff758
Merge branch 'master' into ecs-tlr-feature
alexanderkurash Jun 21, 2024
ea17564
CIRC-2109 Pass additional includeRoutingServicePoints parameter when …
alexanderkurash Jul 3, 2024
c6742f8
CIRC-2116 Allowed SP endpoint should support patronGroupId parameter
MagzhanArtykov Jul 5, 2024
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
2 changes: 1 addition & 1 deletion descriptors/ModuleDescriptor-template.json
Original file line number Diff line number Diff line change
@@ -649,7 +649,7 @@
},
{
"id": "allowed-service-points",
"version": "1.0",
"version": "1.2",
"handlers": [
{
"methods": [
10 changes: 9 additions & 1 deletion ramls/circulation.raml
Original file line number Diff line number Diff line change
@@ -343,6 +343,14 @@ resourceTypes:
description: "Instance ID"
pattern: "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[1-5][a-fA-F0-9]{3}-[89abAB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}$"
required: false
useStubItem:
description: "When true, allows to apply circulation rules based on patron group only"
type: boolean
required: false
ecsRequestRouting:
description: "When true, returns only service points with ecsRequestRouting"
type: boolean
required: false
responses:
200:
description: "List of allowed service points was retrieved successfully"
@@ -364,4 +372,4 @@ resourceTypes:
description: "Internal server error"
body:
text/plain:
example: "Internal server error"
example: "Internal server error"
Original file line number Diff line number Diff line change
@@ -19,6 +19,9 @@ public class AllowedServicePointsRequest {
private String requesterId;
private String instanceId;
private String itemId;
private String requestId;
private boolean useStubItem;
private boolean ecsRequestRouting;

public boolean isForTitleLevelRequest() {
return instanceId != null;
@@ -27,7 +30,6 @@ public boolean isForTitleLevelRequest() {
public boolean isForItemLevelRequest() {
return itemId != null;
}
private String requestId;

public AllowedServicePointsRequest updateWithRequestInformation(Request request) {
log.debug("updateWithRequestInformation:: parameters request: {}", request);
Original file line number Diff line number Diff line change
@@ -206,22 +206,24 @@ public CompletableFuture<Result<Collection<ServicePoint>>> findServicePointsById
.thenApply(r -> r.map(MultipleRecords::getRecords));
}

public CompletableFuture<Result<Collection<ServicePoint>>> fetchPickupLocationServicePoints() {
public CompletableFuture<Result<Collection<ServicePoint>>> fetchServicePointsByIndexName(
String indexName) {

return createServicePointsFetcher().find(MultipleCqlIndexValuesCriteria.builder()
.indexName("pickupLocation")
.indexName(indexName)
.indexOperator(CqlQuery::matchAny)
.value("true")
.build())
.thenApply(r -> r.map(MultipleRecords::getRecords));
}

public CompletableFuture<Result<Collection<ServicePoint>>> fetchPickupLocationServicePointsByIds(
Set<String> ids) {
public CompletableFuture<Result<Collection<ServicePoint>>>
fetchPickupLocationServicePointsByIdsAndIndexName(Set<String> ids, String indexName) {

log.debug("filterIdsByServicePointsAndPickupLocationExistence:: parameters ids: {}",
() -> collectionAsString(ids));
log.debug("filterIdsByServicePointsAndPickupLocationExistence:: parameters ids: {}, " +
"indexName: {}", () -> collectionAsString(ids), () -> indexName);

Result<CqlQuery> pickupLocationQuery = exactMatch("pickupLocation", "true");
Result<CqlQuery> pickupLocationQuery = exactMatch(indexName, "true");

return createServicePointsFetcher().findByIdIndexAndQuery(ids, "id", pickupLocationQuery)
.thenApply(r -> r.map(MultipleRecords::getRecords));
Original file line number Diff line number Diff line change
@@ -53,7 +53,8 @@ private void get(RoutingContext routingContext) {

ofAsync(routingContext)
.thenApply(r -> r.next(AllowedServicePointsResource::buildRequest))
.thenCompose(r -> r.after(new AllowedServicePointsService(clients)::getAllowedServicePoints))
.thenCompose(r -> r.after(request -> new AllowedServicePointsService(
clients, request.isEcsRequestRouting()).getAllowedServicePoints(request)))
.thenApply(r -> r.map(AllowedServicePointsResource::toJson))
.thenApply(r -> r.map(JsonHttpResponse::ok))
.exceptionally(CommonFailures::failedDueToServerError)
@@ -67,25 +68,12 @@ private static Result<AllowedServicePointsRequest> buildRequest(RoutingContext r
.map(String::toUpperCase)
.map(Request.Operation::valueOf)
.orElse(null);

AllowedServicePointsRequest request = new AllowedServicePointsRequest(operation,
queryParams.get("requesterId"), queryParams.get("instanceId"), queryParams.get("itemId"),
queryParams.get("requestId"));

return validateAllowedServicePointsRequest(request);
}

private static Result<AllowedServicePointsRequest> validateAllowedServicePointsRequest(
AllowedServicePointsRequest allowedServicePointsRequest) {

log.debug("validateAllowedServicePointsRequest:: parameters allowedServicePointsRequest: {}",
allowedServicePointsRequest);

Request.Operation operation = allowedServicePointsRequest.getOperation();
String requesterId = allowedServicePointsRequest.getRequesterId();
String instanceId = allowedServicePointsRequest.getInstanceId();
String itemId = allowedServicePointsRequest.getItemId();
String requestId = allowedServicePointsRequest.getRequestId();
String requesterId = queryParams.get("requesterId");
String instanceId = queryParams.get("instanceId");
String itemId = queryParams.get("itemId");
String requestId = queryParams.get("requestId");
String useStubItem = queryParams.get("useStubItem");
String ecsRequestRouting = queryParams.get("ecsRequestRouting");

List<String> errors = new ArrayList<>();

@@ -110,7 +98,8 @@ private static Result<AllowedServicePointsRequest> validateAllowedServicePointsR
log.warn("Request ID is not a valid UUID: {}", requestId);
errors.add(String.format("Request ID is not a valid UUID: %s.", requestId));
}

validateBoolean(useStubItem, "useStubItem", errors);
validateBoolean(ecsRequestRouting, "ecsRequestRouting", errors);
// Checking parameter combinations

boolean allowedCombinationOfParametersDetected = false;
@@ -154,7 +143,16 @@ private static Result<AllowedServicePointsRequest> validateAllowedServicePointsR
return failed(new BadRequestFailure(errorMessage));
}

return succeeded(allowedServicePointsRequest);
return succeeded(new AllowedServicePointsRequest(operation, requesterId, instanceId, itemId,
requestId, Boolean.parseBoolean(useStubItem), Boolean.parseBoolean(ecsRequestRouting)));
}

private static void validateBoolean(String parameter, String parameterName, List<String> errors) {
if (parameter != null && !"true".equals(parameter) && !"false".equals(parameter)) {
log.warn("validateBoolean:: {} is not a valid boolean: {}",
parameterName, parameter);
errors.add(String.format("%s is not a valid boolean: %s.", parameterName, parameter));
}
}

private static JsonObject toJson(Map<RequestType, Set<AllowedServicePoint>> allowedServicePoints) {
Original file line number Diff line number Diff line change
@@ -57,6 +57,8 @@

public class AllowedServicePointsService {
private static final Logger log = LogManager.getLogger(MethodHandles.lookup().lookupClass());
private static final String ECS_REQUEST_ROUTING_INDEX_NAME = "ecsRequestRouting";
private static final String PICKUP_LOCATION_INDEX_NAME = "pickupLocation";
private final ItemRepository itemRepository;
private final UserRepository userRepository;
private final RequestRepository requestRepository;
@@ -65,8 +67,9 @@ public class AllowedServicePointsService {
private final ItemByInstanceIdFinder itemFinder;
private final ConfigurationRepository configurationRepository;
private final InstanceRepository instanceRepository;
private final String indexName;

public AllowedServicePointsService(Clients clients) {
public AllowedServicePointsService(Clients clients, boolean isEcsRequestRouting) {
itemRepository = new ItemRepository(clients);
userRepository = new UserRepository(clients);
requestRepository = new RequestRepository(clients);
@@ -75,6 +78,7 @@ public AllowedServicePointsService(Clients clients) {
configurationRepository = new ConfigurationRepository(clients);
instanceRepository = new InstanceRepository(clients);
itemFinder = new ItemByInstanceIdFinder(clients.holdingsStorage(), itemRepository);
indexName = isEcsRequestRouting ? ECS_REQUEST_ROUTING_INDEX_NAME : PICKUP_LOCATION_INDEX_NAME;
}

public CompletableFuture<Result<Map<RequestType, Set<AllowedServicePoint>>>>
@@ -353,7 +357,7 @@ private Map<RequestType, Set<AllowedServicePoint>> combineAllowedServicePoints(
}

private CompletableFuture<Result<Set<AllowedServicePoint>>> fetchAllowedServicePoints() {
return servicePointRepository.fetchPickupLocationServicePoints()
return servicePointRepository.fetchServicePointsByIndexName(indexName)
.thenApply(r -> r.map(servicePoints -> servicePoints.stream()
.map(AllowedServicePoint::new)
.collect(Collectors.toSet())));
@@ -365,7 +369,7 @@ private CompletableFuture<Result<Set<AllowedServicePoint>>> fetchPickupLocationS
log.debug("filterIdsByServicePointsAndPickupLocationExistence:: parameters ids: {}",
() -> collectionAsString(ids));

return servicePointRepository.fetchPickupLocationServicePointsByIds(ids)
return servicePointRepository.fetchPickupLocationServicePointsByIdsAndIndexName(ids, indexName)
.thenApply(servicePointsResult -> servicePointsResult
.map(servicePoints -> servicePoints.stream()
.map(AllowedServicePoint::new)
147 changes: 125 additions & 22 deletions src/test/java/api/requests/AllowedServicePointsAPITests.java
Original file line number Diff line number Diff line change
@@ -154,8 +154,8 @@ void shouldReturnListOfAllowedServicePointsForRequest(RequestType requestType,
.collect(Collectors.toSet()));

var response = requestLevel == TITLE
? get("create", requesterId, instanceId, null, null, HttpStatus.SC_OK).getJson()
: get("create", requesterId, null, itemId, null, HttpStatus.SC_OK).getJson();
? get("create", requesterId, instanceId, null, null, null, null, HttpStatus.SC_OK).getJson()
: get("create", requesterId, null, itemId, null, null, null, HttpStatus.SC_OK).getJson();

assertThat(response, allowedServicePointMatcher(Map.of(requestType, allowedSpInResponse)));
}
@@ -223,7 +223,7 @@ void shouldReturnListOfAllowedServicePointsForRequestReplacement(
var requestId = request == null ? null : request.getId().toString();

var response =
get("replace", null, null, null, requestId, HttpStatus.SC_OK).getJson();
get("replace", null, null, null, requestId, null, null, HttpStatus.SC_OK).getJson();

assertThat(response, allowedServicePointMatcher(Map.of(requestType, allowedSpInResponse)));
}
@@ -624,8 +624,8 @@ void shouldReturnAllowedServicePointsForAllEnabledRequestTypes() {
@Test
void getReplaceFailsWhenRequestDoesNotExist() {
String requestId = randomId();
Response response = get("replace", null, null, null, requestId,
HttpStatus.SC_UNPROCESSABLE_ENTITY);
Response response = get("replace", null, null, null, requestId, null,
null, HttpStatus.SC_UNPROCESSABLE_ENTITY);
assertThat(response.getJson(), hasErrorWith(hasMessage(
String.format("Request with ID %s was not found", requestId))));
}
@@ -634,8 +634,8 @@ void getReplaceFailsWhenRequestDoesNotExist() {
void getMoveFailsWhenRequestDoesNotExist() {
String requestId = randomId();
String itemId = itemsFixture.basedUponNod().getId().toString();
Response response = get("move", null, null, itemId, requestId,
HttpStatus.SC_UNPROCESSABLE_ENTITY);
Response response = get("move", null, null, itemId, requestId, null,
null, HttpStatus.SC_UNPROCESSABLE_ENTITY);
assertThat(response.getJson(), hasErrorWith(hasMessage(
String.format("Request with ID %s was not found", requestId))));
}
@@ -696,62 +696,152 @@ void shouldReturnListOfAllowedServicePointsForRequestMove(RequestLevel requestLe

// Valid "move" request
var moveResponse =
get("move", null, null, itemToMoveToId, requestId, HttpStatus.SC_OK).getJson();
get("move", null, null, itemToMoveToId, requestId, null, null, HttpStatus.SC_OK).getJson();
assertThat(moveResponse, allowedServicePointMatcher(Map.of(HOLD, List.of(sp2))));

// Invalid "move" requests
var invalidMoveResponse1 = get("move", null, null, null, requestId,
HttpStatus.SC_BAD_REQUEST);
null, null, HttpStatus.SC_BAD_REQUEST);
assertThat(invalidMoveResponse1.getBody(), equalTo("Invalid combination of query parameters"));

var invalidMoveResponse2 = get("move", null, null, itemToMoveToId, null,
HttpStatus.SC_BAD_REQUEST);
null, null, HttpStatus.SC_BAD_REQUEST);
assertThat(invalidMoveResponse2.getBody(), equalTo("Invalid combination of query parameters"));

var invalidMoveResponse3 = get("move", null, null, null, null,
HttpStatus.SC_BAD_REQUEST);
null, null, HttpStatus.SC_BAD_REQUEST);
assertThat(invalidMoveResponse3.getBody(), equalTo("Invalid combination of query parameters"));

var invalidMoveResponse4 = get("move", requesterId, null, itemToMoveToId, requestId,
HttpStatus.SC_BAD_REQUEST);
null, null, HttpStatus.SC_BAD_REQUEST);
assertThat(invalidMoveResponse4.getBody(), equalTo("Invalid combination of query parameters"));

var invalidMoveResponse5 = get("move", null, instanceId, itemToMoveToId, requestId,
HttpStatus.SC_BAD_REQUEST);
null, null, HttpStatus.SC_BAD_REQUEST);
assertThat(invalidMoveResponse5.getBody(), equalTo("Invalid combination of query parameters"));

// Valid "replace" request
var replaceResponse =
get("replace", null, null, null, requestId, HttpStatus.SC_OK).getJson();
get("replace", null, null, null, requestId, null, null, HttpStatus.SC_OK).getJson();
assertThat(replaceResponse, allowedServicePointMatcher(Map.of(HOLD, List.of(sp2))));

// Invalid "replace" requests
var invalidReplaceResponse1 = get("replace", null, null, null, null,
HttpStatus.SC_BAD_REQUEST);
null, null, HttpStatus.SC_BAD_REQUEST);
assertThat(invalidReplaceResponse1.getBody(),
equalTo("Invalid combination of query parameters"));

var invalidReplaceResponse2 = get("replace", requesterId, null, null, requestId,
HttpStatus.SC_BAD_REQUEST);
null, null, HttpStatus.SC_BAD_REQUEST);
assertThat(invalidReplaceResponse2.getBody(),
equalTo("Invalid combination of query parameters"));

var invalidReplaceResponse3 = get("replace", null, instanceId, null, requestId,
HttpStatus.SC_BAD_REQUEST);
null, null, HttpStatus.SC_BAD_REQUEST);
assertThat(invalidReplaceResponse3.getBody(),
equalTo("Invalid combination of query parameters"));

var invalidReplaceResponse4 = get("replace", null, null, requestedItemId, requestId,
HttpStatus.SC_BAD_REQUEST);
null, null, HttpStatus.SC_BAD_REQUEST);
assertThat(invalidReplaceResponse4.getBody(),
equalTo("Invalid combination of query parameters"));

var invalidReplaceResponse5 = get("replace", requesterId, instanceId,
requestedItemId, requestId, HttpStatus.SC_BAD_REQUEST);
requestedItemId, requestId, null, null, HttpStatus.SC_BAD_REQUEST);
assertThat(invalidReplaceResponse5.getBody(),
equalTo("Invalid combination of query parameters"));
}

@Test
void shouldUseStubItemParameterInCirculationRuleMatchingWhenPresent() {
var requesterId = usersFixture.steve().getId().toString();
var instanceId = itemsFixture.createMultipleItemsForTheSameInstance(2).get(0)
.getInstanceId().toString();
var cd1 = servicePointsFixture.cd1();
var cd2 = servicePointsFixture.cd2();
var cd4 = servicePointsFixture.cd4();
var cd5 = servicePointsFixture.cd5();
final UUID book = materialTypesFixture.book().getId();
final UUID patronGroup = patronGroupsFixture.regular().getId();
circulationRulesFixture.updateCirculationRules(createRules("m " + book +
"+ g " + patronGroup, "g " + patronGroup));

var response = getCreateOp(requesterId, instanceId, null, "true", null, HttpStatus.SC_OK)
.getJson();
assertThat(response, hasNoJsonPath(PAGE.getValue()));
JsonArray allowedServicePoints = response.getJsonArray(HOLD.getValue());
assertServicePointsMatch(allowedServicePoints, List.of(cd1, cd2, cd4, cd5));
allowedServicePoints = response.getJsonArray(RECALL.getValue());
assertServicePointsMatch(allowedServicePoints, List.of(cd1, cd2, cd4, cd5));

response = getCreateOp(requesterId, instanceId, null, "false", null, HttpStatus.SC_OK)
.getJson();
assertThat(response, hasNoJsonPath(HOLD.getValue()));
assertThat(response, hasNoJsonPath(RECALL.getValue()));
allowedServicePoints = response.getJsonArray(PAGE.getValue());
assertServicePointsMatch(allowedServicePoints, List.of(cd1, cd2, cd4, cd5));

response = getCreateOp(requesterId, instanceId, null, HttpStatus.SC_OK).getJson();
assertThat(response, hasNoJsonPath(HOLD.getValue()));
assertThat(response, hasNoJsonPath(RECALL.getValue()));
allowedServicePoints = response.getJsonArray(PAGE.getValue());
assertServicePointsMatch(allowedServicePoints, List.of(cd1, cd2, cd4, cd5));
}

@Test
void shouldReturnErrorIfUseStubItemIsInvalid() {
Response errorResponse = getCreateOp(UUID.randomUUID().toString(),
UUID.randomUUID().toString(), null, "invalid", null,
HttpStatus.SC_BAD_REQUEST);
assertThat(errorResponse.getBody(), is("useStubItem is not a valid boolean: invalid."));
}

@Test
void shouldConsiderEcsRequestRoutingParameterForAllowedServicePoints() {
var requesterId = usersFixture.steve().getId().toString();
var instanceId = itemsFixture.createMultipleItemsForTheSameInstance(2).get(0)
.getInstanceId().toString();
var cd1 = servicePointsFixture.cd1();
var cd2 = servicePointsFixture.cd2();
var cd4 = servicePointsFixture.cd4();
var cd11 = servicePointsFixture.cd11();

final Map<RequestType, Set<UUID>> allowedServicePointsInPolicy = new HashMap<>();
allowedServicePointsInPolicy.put(PAGE, Set.of(cd1.getId(), cd2.getId(), cd11.getId()));
allowedServicePointsInPolicy.put(HOLD, Set.of(cd4.getId(), cd2.getId(), cd11.getId()));
var requestPolicy = requestPoliciesFixture.createRequestPolicyWithAllowedServicePoints(
allowedServicePointsInPolicy, PAGE, HOLD);
policiesActivation.use(PoliciesToActivate.builder().requestPolicy(requestPolicy));

var response = getCreateOp(requesterId, instanceId, null, "false", "true",
HttpStatus.SC_OK).getJson();
JsonArray allowedServicePoints = response.getJsonArray(PAGE.getValue());
assertServicePointsMatch(allowedServicePoints, List.of(cd11));
assertThat(response, hasNoJsonPath(HOLD.getValue()));
assertThat(response, hasNoJsonPath(RECALL.getValue()));

response = getCreateOp(requesterId, instanceId, null, "false", "false",
HttpStatus.SC_OK).getJson();
allowedServicePoints = response.getJsonArray(PAGE.getValue());
assertServicePointsMatch(allowedServicePoints, List.of(cd1, cd2));
assertThat(response, hasNoJsonPath(HOLD.getValue()));
assertThat(response, hasNoJsonPath(RECALL.getValue()));

response = getCreateOp(requesterId, instanceId, null, "false", null,
HttpStatus.SC_OK).getJson();
allowedServicePoints = response.getJsonArray(PAGE.getValue());
assertServicePointsMatch(allowedServicePoints, List.of(cd1, cd2));
assertThat(response, hasNoJsonPath(HOLD.getValue()));
assertThat(response, hasNoJsonPath(RECALL.getValue()));
}

@Test
void shouldReturnErrorIfEcsRequestRoutingIsInvalid() {
Response errorResponse = getCreateOp(UUID.randomUUID().toString(),
UUID.randomUUID().toString(), null, null, "invalid", HttpStatus.SC_BAD_REQUEST);
assertThat(errorResponse.getBody(), is("ecsRequestRouting is not a valid boolean: invalid."));
}

private void assertServicePointsMatch(JsonArray response,
List<IndividualResource> expectedServicePoints) {

@@ -775,18 +865,25 @@ private void assertServicePointsMatch(JsonArray response,
.map(sp -> sp.getJson().getString("name")).toArray(String[]::new)));
}

private Response getCreateOp(String requesterId, String instanceId, String itemId,
String useStubItem, String ecsRequestRouting, int expectedStatusCode) {

return get("create", requesterId, instanceId, itemId, null, useStubItem,
ecsRequestRouting, expectedStatusCode);
}

private Response getCreateOp(String requesterId, String instanceId, String itemId,
int expectedStatusCode) {

return get("create", requesterId, instanceId, itemId, null, expectedStatusCode);
return get("create", requesterId, instanceId, itemId, null, null, null, expectedStatusCode);
}

private Response getReplaceOp(String requestId, int expectedStatusCode) {
return get("replace", null, null, null, requestId, expectedStatusCode);
return get("replace", null, null, null, requestId, null, null, expectedStatusCode);
}

private Response get(String operation, String requesterId, String instanceId, String itemId,
String requestId, int expectedStatusCode) {
String requestId, String useStubItem, String ecsRequestRouting, int expectedStatusCode) {

List<QueryStringParameter> queryParams = new ArrayList<>();
queryParams.add(namedParameter("operation", operation));
@@ -802,6 +899,12 @@ private Response get(String operation, String requesterId, String instanceId, St
if (requestId != null) {
queryParams.add(namedParameter("requestId", requestId));
}
if (useStubItem != null) {
queryParams.add(namedParameter("useStubItem", useStubItem));
}
if (ecsRequestRouting != null) {
queryParams.add(namedParameter("ecsRequestRouting", ecsRequestRouting));
}

return restAssuredClient.get(allowedServicePointsUrl(), queryParams, expectedStatusCode,
"allowed-service-points");
Original file line number Diff line number Diff line change
@@ -285,7 +285,7 @@ void recallRequestWithMGDAndRDValuesChangesDueDateToMGDWithCLDDM() {

setFallbackPolicies(canCirculateRollingPolicy);

servicePointsFixture.create(new ServicePointBuilder(checkOutServicePointId, "CLDDM Desk", "clddm", "CLDDM Desk Test", null, null, TRUE, null, null));
servicePointsFixture.create(new ServicePointBuilder(checkOutServicePointId, "CLDDM Desk", "clddm", "CLDDM Desk Test", null, null, TRUE, null, null, null));

// We use the loan date to calculate the minimum guaranteed due date (MGD)
final ZonedDateTime loanDate =
53 changes: 41 additions & 12 deletions src/test/java/api/support/builders/ServicePointBuilder.java
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@ public class ServicePointBuilder extends JsonBuilder implements Builder {
private final JsonObject holdShelfExpiryPeriod;

private final String holdShelfClosedLibraryDateManagement;
private final Boolean ecsRequestRouting;

public ServicePointBuilder(
UUID id,
@@ -28,7 +29,8 @@ public ServicePointBuilder(
Integer shelvingLagTime,
Boolean pickupLocation,
JsonObject holdShelfExpiryPeriod,
String holdShelfClosedLibraryDateManagement) {
String holdShelfClosedLibraryDateManagement,
Boolean ecsRequestRouting) {
this.id = id;
this.name = name;
this.code = code;
@@ -38,6 +40,7 @@ public ServicePointBuilder(
this.pickupLocation = pickupLocation;
this.holdShelfExpiryPeriod = holdShelfExpiryPeriod;
this.holdShelfClosedLibraryDateManagement = holdShelfClosedLibraryDateManagement;
this.ecsRequestRouting = ecsRequestRouting;
}

public ServicePointBuilder(String name, String code, String discoveryDisplayName) {
@@ -50,6 +53,7 @@ public ServicePointBuilder(String name, String code, String discoveryDisplayName
null,
false,
null,
null,
null);
}

@@ -64,8 +68,9 @@ public static ServicePointBuilder from(IndividualResource response) {
getIntegerProperty(representation, "shelvingLagTime", null),
getBooleanProperty(representation, "pickupLocation"),
getObjectProperty(representation, "holdShelfExpiryPeriod"),
getProperty(representation, "holdShelfClosedLibraryDateManagement")
);
getProperty(representation, "holdShelfClosedLibraryDateManagement"),
getBooleanProperty(representation, "ecsRequestRouting")
);
}

@Override
@@ -80,6 +85,7 @@ public JsonObject create() {
put(servicePoint, "pickupLocation", this.pickupLocation);
put(servicePoint, "holdShelfExpiryPeriod", this.holdShelfExpiryPeriod);
put(servicePoint, "holdShelfClosedLibraryDateManagement", this.holdShelfClosedLibraryDateManagement);
put(servicePoint, "ecsRequestRouting", this.ecsRequestRouting);

return servicePoint;
}
@@ -94,7 +100,8 @@ public ServicePointBuilder withId(UUID newId) {
this.shelvingLagTime,
this.pickupLocation,
this.holdShelfExpiryPeriod,
this.holdShelfClosedLibraryDateManagement);
this.holdShelfClosedLibraryDateManagement,
this.ecsRequestRouting);
}

public ServicePointBuilder withName(String newName) {
@@ -107,7 +114,8 @@ public ServicePointBuilder withName(String newName) {
this.shelvingLagTime,
this.pickupLocation,
this.holdShelfExpiryPeriod,
this.holdShelfClosedLibraryDateManagement);
this.holdShelfClosedLibraryDateManagement,
this.ecsRequestRouting);
}

public ServicePointBuilder withCode(String newCode) {
@@ -120,7 +128,8 @@ public ServicePointBuilder withCode(String newCode) {
this.shelvingLagTime,
this.pickupLocation,
this.holdShelfExpiryPeriod,
this.holdShelfClosedLibraryDateManagement);
this.holdShelfClosedLibraryDateManagement,
this.ecsRequestRouting);
}

public ServicePointBuilder withDiscoveryDisplayName(String newDiscoveryDisplayName) {
@@ -133,7 +142,8 @@ public ServicePointBuilder withDiscoveryDisplayName(String newDiscoveryDisplayNa
this.shelvingLagTime,
this.pickupLocation,
this.holdShelfExpiryPeriod,
this.holdShelfClosedLibraryDateManagement);
this.holdShelfClosedLibraryDateManagement,
this.ecsRequestRouting);
}

public ServicePointBuilder withDescription(String newDescription) {
@@ -146,7 +156,8 @@ public ServicePointBuilder withDescription(String newDescription) {
this.shelvingLagTime,
this.pickupLocation,
this.holdShelfExpiryPeriod,
this.holdShelfClosedLibraryDateManagement);
this.holdShelfClosedLibraryDateManagement,
this.ecsRequestRouting);
}

public ServicePointBuilder withShelvingLagTime(Integer newShelvingLagTime) {
@@ -159,7 +170,8 @@ public ServicePointBuilder withShelvingLagTime(Integer newShelvingLagTime) {
newShelvingLagTime,
this.pickupLocation,
this.holdShelfExpiryPeriod,
this.holdShelfClosedLibraryDateManagement);
this.holdShelfClosedLibraryDateManagement,
this.ecsRequestRouting);
}

public ServicePointBuilder withPickupLocation(Boolean newPickupLocation) {
@@ -172,7 +184,8 @@ public ServicePointBuilder withPickupLocation(Boolean newPickupLocation) {
this.shelvingLagTime,
newPickupLocation,
this.holdShelfExpiryPeriod,
this.holdShelfClosedLibraryDateManagement);
this.holdShelfClosedLibraryDateManagement,
this.ecsRequestRouting);
}

public ServicePointBuilder withHoldShelfExpriyPeriod(int duration, String intervalId) {
@@ -190,7 +203,8 @@ public ServicePointBuilder withHoldShelfExpriyPeriod(int duration, String interv
this.shelvingLagTime,
this.pickupLocation,
holdShelfExpiryPeriod,
this.holdShelfClosedLibraryDateManagement);
this.holdShelfClosedLibraryDateManagement,
this.ecsRequestRouting);
}

public ServicePointBuilder withholdShelfClosedLibraryDateManagement(String expirationDateManagement) {
@@ -203,6 +217,21 @@ public ServicePointBuilder withholdShelfClosedLibraryDateManagement(String expir
this.shelvingLagTime,
this.pickupLocation,
this.holdShelfExpiryPeriod,
expirationDateManagement);
expirationDateManagement,
this.ecsRequestRouting);
}

public ServicePointBuilder withEcsRequestRouting(Boolean ecsRequestRouting) {
return new ServicePointBuilder(
this.id,
this.name,
this.code,
this.discoveryDisplayName,
this.description,
this.shelvingLagTime,
this.pickupLocation,
this.holdShelfExpiryPeriod,
this.holdShelfClosedLibraryDateManagement,
ecsRequestRouting);
}
}
8 changes: 8 additions & 0 deletions src/test/java/api/support/fixtures/ServicePointExamples.java
Original file line number Diff line number Diff line change
@@ -79,4 +79,12 @@ static ServicePointBuilder basedUponCircDesk10() {
.withholdShelfClosedLibraryDateManagement(ExpirationDateManagement.MOVE_TO_THE_END_OF_THE_NEXT_OPEN_DAY.name())
.withHoldShelfExpriyPeriod(6, "Months");
}

static ServicePointBuilder basedUponCircDesk11() {
return new ServicePointBuilder("Circ Desk 11", "cd11",
"Circulation Desk -- Back Entrance")
.withPickupLocation(FALSE)
.withEcsRequestRouting(TRUE)
.withHoldShelfExpriyPeriod(6, "Months");
}
}
6 changes: 6 additions & 0 deletions src/test/java/api/support/fixtures/ServicePointsFixture.java
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@

import static api.support.fixtures.ServicePointExamples.basedUponCircDesk1;
import static api.support.fixtures.ServicePointExamples.basedUponCircDesk10;
import static api.support.fixtures.ServicePointExamples.basedUponCircDesk11;
import static api.support.fixtures.ServicePointExamples.basedUponCircDesk2;
import static api.support.fixtures.ServicePointExamples.basedUponCircDesk3;
import static api.support.fixtures.ServicePointExamples.basedUponCircDesk4;
@@ -81,6 +82,11 @@ public IndividualResource cd10() {
return create(basedUponCircDesk10());
}

public IndividualResource cd11() {

return create(basedUponCircDesk11());
}

public IndividualResource create(ServicePointBuilder builder) {

return servicePointRecordCreator.createIfAbsent(builder);