diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/DiscoverQueryBuilder.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/DiscoverQueryBuilder.java index c666d9d01d..aa59788a24 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/DiscoverQueryBuilder.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/DiscoverQueryBuilder.java @@ -240,6 +240,7 @@ public class DiscoverQueryBuilder implements InitializingBean { // "show more" url int facetLimit = pageSize + 1; //This should take care of the sorting for us + prefix = StringUtils.isNotBlank(prefix) ? prefix.toLowerCase() : null; queryArgs.addFacetField(new DiscoverFacetField(facet.getIndexFieldName(), facet.getType(), facetLimit, facet.getSortOrderSidebar(), StringUtils.trimToNull(prefix))); } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java index 021006cc02..23c104faa8 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java @@ -362,6 +362,146 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest ; } + @Test + public void discoverFacetsAuthorTestWithPrefix_Capital_And_Special_Chars() throws Exception { + context.turnOffAuthorisationSystem(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Collection collection = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection").build(); + + Item publicItem1 = ItemBuilder.createItem(context, collection) + .withTitle("Public item 1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, John") + .withAuthor("Jan, Doe") + .build(); + + Item publicItem2 = ItemBuilder.createItem(context, collection) + .withTitle("Public item 2") + .withIssueDate("2016-02-13") + .withAuthor("S’Idan, Mo") + .withAuthor("Tick&Tock") + .build(); + + Item publicItem3 = ItemBuilder.createItem(context, collection) + .withTitle("Public item 3") + .withIssueDate("2016-02-13") + .withAuthor("M Akai") + .withAuthor("stIjn, SmITH") + .build(); + + Item publicItem4 = ItemBuilder.createItem(context, collection) + .withTitle("Public item 4") + .withIssueDate("2012-05-13") + .withSubject("St Augustine") + .build(); + + Item publicItem5 = ItemBuilder.createItem(context, collection) + .withTitle("Public item 5") + .withIssueDate("2015-11-23") + .withSubject("Health & Medicine") + .build(); + + Item publicItem6 = ItemBuilder.createItem(context, collection) + .withTitle("Public item 6") + .withIssueDate("2003-07-11") + .withSubject("1% economy") + .build(); + + Item publicItem7 = ItemBuilder.createItem(context, collection) + .withTitle("Public item 7") + .withIssueDate("2008-12-31") + .withSubject("I.T.") + .build(); + + Item publicItem8 = ItemBuilder.createItem(context, collection) + .withTitle("Public item 8") + .withIssueDate("2013-07-21") + .withSubject("?Unknown") + .build(); + + context.restoreAuthSystemState(); + + // The prefix query for author queries should be case-insensitive and correctly handle special characters + + getClient().perform(get("/api/discover/facets/author") + .param("prefix", "Smith")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.values", + containsInAnyOrder(FacetValueMatcher.entryFacetWithoutSelfLink("Smith, John")))); + + getClient().perform(get("/api/discover/facets/author") + .param("prefix", "S")) + .andExpect(jsonPath("$._embedded.values", + containsInAnyOrder(FacetValueMatcher + .entryFacetWithoutSelfLink("Smith, John"), + FacetValueMatcher + .entryFacetWithoutSelfLink("S’Idan, Mo"), + FacetValueMatcher + .entryFacetWithoutSelfLink("stIjn, SmITH")))); + + getClient().perform(get("/api/discover/facets/author") + .param("prefix", "M A")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.values", + containsInAnyOrder(FacetValueMatcher.entryFacetWithoutSelfLink("M Akai")))); + + getClient().perform(get("/api/discover/facets/author") + .param("prefix", "S’I")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.values", + containsInAnyOrder(FacetValueMatcher.entryFacetWithoutSelfLink("S’Idan, Mo")))); + + getClient().perform(get("/api/discover/facets/author") + .param("prefix", "Jan, D")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.values", + containsInAnyOrder(FacetValueMatcher.entryFacetWithoutSelfLink("Jan, Doe")))); + + getClient().perform(get("/api/discover/facets/author") + .param("prefix", "Tick&")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.values", + containsInAnyOrder(FacetValueMatcher.entryFacetWithoutSelfLink("Tick&Tock")))); + + // Should also be the case for subject queries + + getClient().perform(get("/api/discover/facets/subject") + .param("prefix", "St A")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.values", + containsInAnyOrder(FacetValueMatcher + .entryFacetWithoutSelfLink("St Augustine")))); + + getClient().perform(get("/api/discover/facets/subject") + .param("prefix", "Health & M")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.values", + containsInAnyOrder(FacetValueMatcher + .entryFacetWithoutSelfLink("Health & Medicine")))); + + getClient().perform(get("/api/discover/facets/subject") + .param("prefix", "1% e")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.values", + containsInAnyOrder(FacetValueMatcher.entryFacetWithoutSelfLink("1% economy")))); + + getClient().perform(get("/api/discover/facets/subject") + .param("prefix", "I.")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.values", + containsInAnyOrder(FacetValueMatcher.entryFacetWithoutSelfLink("I.T.")))); + + getClient().perform(get("/api/discover/facets/subject") + .param("prefix", "?U")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.values", + containsInAnyOrder(FacetValueMatcher.entryFacetWithoutSelfLink("?Unknown")))); + } + @Test public void discoverFacetsAuthorTestForHasMoreFalse() throws Exception { //Turn of the authorization system so that we can create the structure specified below diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/FacetValueMatcher.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/FacetValueMatcher.java index a68356da53..2c7cebdbe9 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/FacetValueMatcher.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/FacetValueMatcher.java @@ -31,6 +31,13 @@ public class FacetValueMatcher { ); } + public static Matcher entryFacetWithoutSelfLink(String label) { + return allOf( + hasJsonPath("$.label", is(label)), + hasJsonPath("$.type", is("discover")) + ); + } + public static Matcher entryAuthorWithAuthority(String label, String authority, int count) { return allOf( hasJsonPath("$.authorityKey", is(authority)),