Merge pull request #2173 from ppmdo/DS-3904

DS-3904 - Add support for startsWith parameters in the browse endpoint
This commit is contained in:
Andrea Bollini
2018-12-12 22:52:44 +01:00
committed by GitHub
4 changed files with 402 additions and 4 deletions

View File

@@ -725,8 +725,16 @@ public class RestResourceController implements InitializingBean {
if (Page.class.isAssignableFrom(linkMethod.getReturnType())) {
Page<? extends RestModel> pageResult = (Page<? extends RestAddressableModel>) linkMethod
.invoke(linkRepository, request, uuid, page, projection);
Link link = linkTo(this.getClass(), apiCategory, model).slash(uuid).slash(subpath)
.withSelfRel();
Link link = null;
String querystring = request.getQueryString();
if (querystring != null && querystring.length() > 0) {
link = linkTo(this.getClass(), apiCategory, model).slash(uuid)
.slash(subpath + '?' + querystring).withSelfRel();
} else {
link = linkTo(this.getClass(), apiCategory, model).slash(uuid).withSelfRel();
}
Page<HALResource> halResources = pageResult.map(linkRepository::wrapResource);
halResources.forEach(linkService::addLinks);

View File

@@ -61,8 +61,11 @@ public class BrowseEntryLinkRepository extends AbstractDSpaceRestRepository
// FIXME this should be bind automatically and available as method
// argument
String scope = null;
String startsWith = null;
if (request != null) {
scope = request.getParameter("scope");
startsWith = request.getParameter("startsWith");
}
@@ -103,7 +106,7 @@ public class BrowseEntryLinkRepository extends AbstractDSpaceRestRepository
// bs.setJumpToItem(focus);
// bs.setJumpToValue(valueFocus);
// bs.setJumpToValueLang(valueFocusLang);
// bs.setStartsWith(startsWith);
bs.setStartsWith(startsWith);
if (pageable != null) {
bs.setOffset(pageable.getOffset());
bs.setResultsPerPage(pageable.getPageSize());

View File

@@ -61,11 +61,13 @@ public class BrowseItemLinkRepository extends AbstractDSpaceRestRepository
String scope = null;
String filterValue = null;
String filterAuthority = null;
String startsWith = null;
if (request != null) {
scope = request.getParameter("scope");
filterValue = request.getParameter("filterValue");
filterAuthority = request.getParameter("filterAuthority");
startsWith = request.getParameter("startsWith");
}
Context context = obtainContext();
BrowseEngine be = new BrowseEngine(context);
@@ -128,7 +130,7 @@ public class BrowseItemLinkRepository extends AbstractDSpaceRestRepository
// bs.setJumpToItem(focus);
// bs.setJumpToValue(valueFocus);
// bs.setJumpToValueLang(valueFocusLang);
// bs.setStartsWith(startsWith);
bs.setStartsWith(startsWith);
if (pageable != null) {
bs.setOffset(pageable.getOffset());
bs.setResultsPerPage(pageable.getPageSize());

View File

@@ -9,6 +9,7 @@ package org.dspace.app.rest;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
@@ -498,4 +499,388 @@ public class BrowsesResourceControllerIT extends AbstractControllerIntegrationTe
"Item 7", "2016-01-12")
)));
}
@Test
public void testBrowseByEntriesStartsWith() throws Exception {
context.turnOffAuthorisationSystem();
//** GIVEN **
//1. A community-collection structure with one parent community with sub-community and two collections.
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity)
.withName("Sub Community")
.build();
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
Collection col2 = CollectionBuilder.createCollection(context, child1).withName("Collection 2").build();
//2. 7 public items that are readable by Anonymous
Item item1 = ItemBuilder.createItem(context, col1)
.withTitle("Alan Turing")
.withAuthor("Turing, Alan Mathison")
.withIssueDate("1912-06-23")
.withSubject("Computing")
.build();
Item item2 = ItemBuilder.createItem(context, col1)
.withTitle("Blade Runner")
.withAuthor("Scott, Ridley")
.withIssueDate("1982-06-25")
.withSubject("Science Fiction")
.build();
Item item3 = ItemBuilder.createItem(context, col1)
.withTitle("Python")
.withAuthor("Van Rossum, Guido")
.withIssueDate("1990")
.withSubject("Computing")
.build();
Item item4 = ItemBuilder.createItem(context, col2)
.withTitle("Java")
.withAuthor("Gosling, James")
.withIssueDate("1995-05-23")
.withSubject("Computing")
.build();
Item item5 = ItemBuilder.createItem(context, col2)
.withTitle("Zeta Reticuli")
.withAuthor("Universe")
.withIssueDate("2018-01-01")
.withSubject("Astronomy")
.build();
Item item6 = ItemBuilder.createItem(context, col2)
.withTitle("Moon")
.withAuthor("Universe")
.withIssueDate("2018-01-02")
.withSubject("Astronomy")
.build();
Item item7 = ItemBuilder.createItem(context, col2)
.withTitle("T-800")
.withAuthor("Cameron, James")
.withIssueDate("2029")
.withSubject("Science Fiction")
.build();
// ---- BROWSES BY ENTRIES ----
//** WHEN **
//An anonymous user browses the entries in the Browse by Author endpoint
//with startsWith set to U
getClient().perform(get("/api/discover/browses/author/entries?startsWith=U")
.param("size", "2"))
//** THEN **
//The status has to be 200 OK
.andExpect(status().isOk())
//We expect the content type to be "application/hal+json;charset=UTF-8"
.andExpect(content().contentType(contentType))
//We expect only the "Universe" entry to be present
.andExpect(jsonPath("$.page.totalElements", is(1)))
//As entry browsing works as a filter, we expect to be on page 0
.andExpect(jsonPath("$.page.number", is(0)))
//Verify that the index filters to the "Universe" entries and Counts 2 Items.
.andExpect(jsonPath("$._embedded.browseEntries",
contains(BrowseEntryResourceMatcher.matchBrowseEntry("Universe", 2)
)))
//Verify startsWith parameter is included in the links
.andExpect(jsonPath("$._links.self.href", containsString("?startsWith=U")));
//** WHEN **
//An anonymous user browses the entries in the Browse by Author endpoint
//with startsWith set to T and scope set to Col 1
getClient().perform(get("/api/discover/browses/author/entries?startsWith=T")
.param("scope", col1.getID().toString()))
//** THEN **
//The status has to be 200 OK
.andExpect(status().isOk())
//We expect the content type to be "application/hal+json;charset=UTF-8"
.andExpect(content().contentType(contentType))
//We expect only the entry "Turing, Alan Mathison" to be present
.andExpect(jsonPath("$.page.totalElements", is(1)))
//As entry browsing works as a filter, we expect to be on page 0
.andExpect(jsonPath("$.page.number", is(0)))
//Verify that the index filters to the "Turing, Alan'" items.
.andExpect(jsonPath("$._embedded.browseEntries",
contains(BrowseEntryResourceMatcher.matchBrowseEntry("Turing, Alan Mathison", 1)
)))
//Verify that the startsWith paramater is included in the links
.andExpect(jsonPath("$._links.self.href", containsString("?startsWith=T")));
//** WHEN **
//An anonymous user browses the entries in the Browse by Subject endpoint
//with startsWith set to C
getClient().perform(get("/api/discover/browses/subject/entries?startsWith=C"))
//** THEN **
//The status has to be 200 OK
.andExpect(status().isOk())
//We expect the content type to be "application/hal+json;charset=UTF-8"
.andExpect(content().contentType(contentType))
//We expect only the entry "Computing" to be present
.andExpect(jsonPath("$.page.totalElements", is(1)))
//As entry browsing works as a filter, we expect to be on page 0
.andExpect(jsonPath("$.page.number", is(0)))
//Verify that the index filters to the "Computing'" items.
.andExpect(jsonPath("$._embedded.browseEntries",
contains(BrowseEntryResourceMatcher.matchBrowseEntry("Computing", 3)
)))
//Verify that the startsWith paramater is included in the links
.andExpect(jsonPath("$._links.self.href", containsString("?startsWith=C")));
};
@Test
public void testBrowseByItemsStartsWith() throws Exception {
context.turnOffAuthorisationSystem();
//** GIVEN **
//1. A community-collection structure with one parent community with sub-community and two collections.
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity)
.withName("Sub Community")
.build();
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
Collection col2 = CollectionBuilder.createCollection(context, child1).withName("Collection 2").build();
//2. 7 public items that are readable by Anonymous
Item item1 = ItemBuilder.createItem(context, col1)
.withTitle("Alan Turing")
.withAuthor("Turing, Alan Mathison")
.withIssueDate("1912-06-23")
.withSubject("Computing")
.build();
Item item2 = ItemBuilder.createItem(context, col1)
.withTitle("Blade Runner")
.withAuthor("Scott, Ridley")
.withIssueDate("1982-06-25")
.withSubject("Science Fiction")
.build();
Item item3 = ItemBuilder.createItem(context, col1)
.withTitle("Python")
.withAuthor("Van Rossum, Guido")
.withIssueDate("1990")
.withSubject("Computing")
.build();
Item item4 = ItemBuilder.createItem(context, col2)
.withTitle("Java")
.withAuthor("Gosling, James")
.withIssueDate("1995-05-23")
.withSubject("Computing")
.build();
Item item5 = ItemBuilder.createItem(context, col2)
.withTitle("Zeta Reticuli")
.withAuthor("Universe")
.withIssueDate("2018-01-01")
.withSubject("Astronomy")
.build();
Item item6 = ItemBuilder.createItem(context, col2)
.withTitle("Moon")
.withAuthor("Universe")
.withIssueDate("2018-01-02")
.withSubject("Astronomy")
.build();
Item item7 = ItemBuilder.createItem(context, col2)
.withTitle("T-800")
.withAuthor("Cameron, James")
.withIssueDate("2029")
.withSubject("Science Fiction")
.build();
// ---- BROWSES BY ITEM ----
//** WHEN **
//An anonymous user browses the items in the Browse by date issued endpoint
//with startsWith set to 1990
getClient().perform(get("/api/discover/browses/dateissued/items?startsWith=1990")
.param("size", "2"))
//** THEN **
//The status has to be 200 OK
.andExpect(status().isOk())
//We expect the content type to be "application/hal+json;charset=UTF-8"
.andExpect(content().contentType(contentType))
//We expect the totalElements to be the 7 items present in the repository
.andExpect(jsonPath("$.page.totalElements", is(7)))
//We expect to jump to page 1 of the index
.andExpect(jsonPath("$.page.number", is(1)))
.andExpect(jsonPath("$.page.size", is(2)))
.andExpect(jsonPath("$._links.first.href", containsString("startsWith=1990")))
//Verify that the index jumps to the "Python" item.
.andExpect(jsonPath("$._embedded.items",
contains(ItemMatcher.matchItemWithTitleAndDateIssued(item3,
"Python", "1990"),
ItemMatcher.matchItemWithTitleAndDateIssued(item4,
"Java", "1995-05-23")
)));
//** WHEN **
//An anonymous user browses the items in the Browse by Title endpoint
//with startsWith set to T
getClient().perform(get("/api/discover/browses/title/items?startsWith=T")
.param("size", "2"))
//** THEN **
//The status has to be 200 OK
.andExpect(status().isOk())
//We expect the content type to be "application/hal+json;charset=UTF-8"
.andExpect(content().contentType(contentType))
//We expect the totalElements to be the 7 items present in the repository
.andExpect(jsonPath("$.page.totalElements", is(7)))
//We expect to jump to page 2 in the index
.andExpect(jsonPath("$.page.number", is(2)))
.andExpect(jsonPath("$._links.first.href", containsString("startsWith=T")))
//Verify that the index jumps to the "T-800" item.
.andExpect(jsonPath("$._embedded.items",
contains(ItemMatcher.matchItemWithTitleAndDateIssued(item7,
"T-800", "2029"),
ItemMatcher.matchItemWithTitleAndDateIssued(item5,
"Zeta Reticuli",
"2018-01-01")
)));
//** WHEN **
//An anonymous user browses the items in the Browse by Title endpoint
//with startsWith set to Blade and scope set to Col 1
getClient().perform(get("/api/discover/browses/title/items?startsWith=Blade")
.param("scope", col1.getID().toString())
.param("size", "2"))
//** THEN **
//The status has to be 200 OK
.andExpect(status().isOk())
//We expect the content type to be "application/hal+json;charset=UTF-8"
.andExpect(content().contentType(contentType))
//We expect the totalElements to be the 3 items present in the collection
.andExpect(jsonPath("$.page.totalElements", is(3)))
//As this is is a small collection, we expect to go-to page 0
.andExpect(jsonPath("$.page.number", is(0)))
.andExpect(jsonPath("$._links.first.href", containsString("startsWith=Blade")))
//Verify that the index jumps to the "Blade Runner" item.
.andExpect(jsonPath("$._embedded.items",
contains(ItemMatcher.matchItemWithTitleAndDateIssued(item2,
"Blade Runner",
"1982-06-25"),
ItemMatcher.matchItemWithTitleAndDateIssued(item3,
"Python", "1990")
)));
}
@Test
public void testBrowseByStartsWithAndPage() throws Exception {
context.turnOffAuthorisationSystem();
//** GIVEN **
//1. A community-collection structure with one parent community with sub-community and two collections.
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity)
.withName("Sub Community")
.build();
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
Collection col2 = CollectionBuilder.createCollection(context, child1).withName("Collection 2").build();
//2. 7 public items that are readable by Anonymous
Item item1 = ItemBuilder.createItem(context, col1)
.withTitle("Alan Turing")
.withAuthor("Turing, Alan Mathison")
.withIssueDate("1912-06-23")
.withSubject("Computing")
.build();
Item item2 = ItemBuilder.createItem(context, col1)
.withTitle("Blade Runner")
.withAuthor("Scott, Ridley")
.withIssueDate("1982-06-25")
.withSubject("Science Fiction")
.build();
Item item3 = ItemBuilder.createItem(context, col2)
.withTitle("Java")
.withAuthor("Gosling, James")
.withIssueDate("1995-05-23")
.withSubject("Computing")
.build();
Item item4 = ItemBuilder.createItem(context, col2)
.withTitle("Moon")
.withAuthor("Universe")
.withIssueDate("2018-01-02")
.withSubject("Astronomy")
.build();
Item item5 = ItemBuilder.createItem(context, col1)
.withTitle("Python")
.withAuthor("Van Rossum, Guido")
.withIssueDate("1990")
.withSubject("Computing")
.build();
Item item6 = ItemBuilder.createItem(context, col2)
.withTitle("T-800")
.withAuthor("Cameron, James")
.withIssueDate("2029")
.withSubject("Science Fiction")
.build();
Item item7 = ItemBuilder.createItem(context, col2)
.withTitle("Zeta Reticuli")
.withAuthor("Universe")
.withIssueDate("2018-01-01")
.withSubject("Astronomy")
.build();
// ---- BROWSES BY ITEM ----
//** WHEN **
//An anonymous user browses the items in the Browse by date issued endpoint
//with startsWith set to 1990 and Page to 3
getClient().perform(get("/api/discover/browses/dateissued/items?startsWith=1990")
.param("size", "2").param("page", "2"))
//** THEN **
//The status has to be 200 OK
.andExpect(status().isOk())
//We expect the content type to be "application/hal+json;charset=UTF-8"
.andExpect(content().contentType(contentType))
//We expect the totalElements to be the 7 items present in the repository
.andExpect(jsonPath("$.page.totalElements", is(7)))
//We expect to jump to page 1 of the index
.andExpect(jsonPath("$.page.number", is(2)))
.andExpect(jsonPath("$.page.size", is(2)))
.andExpect(jsonPath("$._links.first.href", containsString("startsWith=1990")))
//Verify that the index jumps to the "Zeta Reticuli" item.
.andExpect(jsonPath("$._embedded.items",
contains(ItemMatcher.matchItemWithTitleAndDateIssued(item7,
"Zeta Reticuli", "2018-01-01"),
ItemMatcher.matchItemWithTitleAndDateIssued(item4,
"Moon", "2018-01-02")
)));
}
}