Skip to content

Commit

Permalink
oasp#193: a simple offset based paging support on the server side ava…
Browse files Browse the repository at this point in the history
…ilable through REST (GET)
  • Loading branch information
llaszkie committed Apr 25, 2015
1 parent b1ba022 commit ae52292
Show file tree
Hide file tree
Showing 5 changed files with 313 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package io.oasp.module.rest.service.api;

import net.sf.mmm.util.search.api.SearchCriteria;
import net.sf.mmm.util.search.base.AbstractSearchCriteria;

/**
* This type is a wrapper for paging parameters used in REST API. Provides also convenient conversion to
* {@link SearchCriteria} query.
*
* @author llaszkie
*/
public class PagingParameters {

/**
* An empty parameters indicating no paging in request.
*/
public static final PagingParameters NO_PAGING = new PagingParameters();

private static final int DEFAULT_MAX_RESULT_PER_PAGE = 100;

private boolean off;

private int pageNumber;

private int count;

/**
* The constructor.
*
* @param pageNumber number of the requested page (1-based index)
* @param count limit of entries for one page. if <code>null</code> default value will be used
*/
public PagingParameters(int pageNumber, Integer count) {

super();
this.pageNumber = pageNumber;
this.count = count != null ? count : DEFAULT_MAX_RESULT_PER_PAGE;
}

/**
* The constructor. Indicates NO paging.
*/
public PagingParameters() {

super();
this.off = true;
}

/**
* @return <code>true</code> if NO paging was requested
*/
public boolean isOff() {

return this.off;
}

/**
* Arms provided criteria with held paging parameters unless paging parameters were NOT provided.
*
* @param criteria criteria to be extended.
*/
public void extendIfRequested(AbstractSearchCriteria criteria) {

if (!this.off) {
criteria.setHitOffset((this.pageNumber - 1) * this.count);
criteria.setMaximumHitCount(this.count);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,25 @@ public List<String> getList(String key) {
return list;
}

/**
* Gets the paging parameters from the request (if provided). There are two of them. The "page" points to a requested
* chunk of data (1-based index: obligatory if paging functionality is desired). The "count" allows client to specify
* the chunk size (optional: a default value 100 for page size will be used if omitted)
*
* @return the {@link PagingParameters} as provided or complemented with default or an empty one if NO paging was
* requested
*/
public PagingParameters getPaging() {

Integer page = get("page", Integer.class, false);
if (null != page) {
Integer count = get("count", Integer.class, false);
return new PagingParameters(page, count);
}

return PagingParameters.NO_PAGING;
}

/**
* @param uriInfo is the {@link UriInfo}.
* @return a new instance of {@link RequestParameters} for {@link UriInfo#getQueryParameters()}.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package io.oasp.module.rest.service.api;

import net.sf.mmm.util.search.base.AbstractSearchCriteria;

import org.junit.Assert;
import org.junit.Test;

/**
* This type is the test-case of {@link PagingParameters}
*
* @author llaszkie
*/
public class PagingParametersTest extends Assert {

private PagingParameters parameters;

/**
* Test method for {@link io.oasp.module.rest.service.api.PagingParameters#isOff()}.
*/
@Test
public void testIsOff() {

// given // when
this.parameters = new PagingParameters();

// then
assertTrue("Paging support is off.", this.parameters.isOff());
}

/**
* Test method for {@link io.oasp.module.rest.service.api.PagingParameters#isOff()}.
*/
@Test
public void testIsOn() {

// given // when
this.parameters = new PagingParameters(1, null);

// then
assertFalse("Paging support is on.", this.parameters.isOff());
}

/**
* Test method for
* {@link io.oasp.module.rest.service.api.PagingParameters#extendIfRequested(net.sf.mmm.util.search.base.AbstractSearchCriteria)}
* .
*/
@Test
@SuppressWarnings("serial")
public void testExtend() {

// given
this.parameters = new PagingParameters(2, 5);
AbstractSearchCriteria criteria = new AbstractSearchCriteria() {
};

// when
this.parameters.extendIfRequested(criteria);

// then
assertEquals("Search criteria offset was set.", 1 * 5, criteria.getHitOffset());
assertEquals("Search criteria maximum hit count was set.", 5, criteria.getMaximumHitCount().intValue());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ public List<OrderCto> findOrders(@Context UriInfo info) {
OrderSearchCriteriaTo criteria = new OrderSearchCriteriaTo();
criteria.setTableId(parameters.get("tableId", Long.class, false));
criteria.setState(parameters.get("state", OrderState.class, false));
parameters.getPaging().extendIfRequested(criteria);
return this.salesManagement.findOrderCtos(criteria);
}

Expand All @@ -111,6 +112,7 @@ public List<OrderPositionEto> findOrderPositions(@Context UriInfo info) {
criteria.setCookId(parameters.get("cookId", Long.class, false));
criteria.setState(parameters.get("state", OrderPositionState.class, false));
criteria.setMealOrSideDish(parameters.get("mealOrSideDish", boolean.class, false));
parameters.getPaging().extendIfRequested(criteria);
return this.salesManagement.findOrderPositions(criteria);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
package io.oasp.gastronomy.restaurant.salesmanagement.service.impl.rest;

import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import io.oasp.gastronomy.restaurant.salesmanagement.common.api.datatype.OrderPositionState;
import io.oasp.gastronomy.restaurant.salesmanagement.common.api.datatype.OrderState;
import io.oasp.gastronomy.restaurant.salesmanagement.logic.api.Salesmanagement;
import io.oasp.gastronomy.restaurant.salesmanagement.logic.api.to.OrderCto;
import io.oasp.gastronomy.restaurant.salesmanagement.logic.api.to.OrderPositionEto;
import io.oasp.gastronomy.restaurant.salesmanagement.logic.api.to.OrderPositionSearchCriteriaTo;
import io.oasp.gastronomy.restaurant.salesmanagement.logic.api.to.OrderSearchCriteriaTo;

import java.util.ArrayList;
import java.util.List;

import javax.ws.rs.core.MultivaluedHashMap;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.UriInfo;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

/**
* This is the test-case of {@link SalesmanagementRestServiceImpl}.
*
* @author llaszkie
*/
@RunWith(MockitoJUnitRunner.class)
public class SalesmanagementRestServiceTest extends Assert {

@Mock
private Salesmanagement salesManagement;

@Mock
private UriInfo info;

@InjectMocks
private SalesmanagementRestServiceImpl salesManagementRestService = new SalesmanagementRestServiceImpl();

/**
* Test method for
* {@link io.oasp.gastronomy.restaurant.salesmanagement.service.impl.rest.SalesmanagementRestServiceImpl#findOrders(javax.ws.rs.core.UriInfo)}
* .
*/
@Test
public void testShouldFindOrders() {

// given
MultivaluedMap<String, String> parameters = new MultivaluedHashMap<>();
parameters.putSingle("tableId", "1");
parameters.putSingle("state", "OPEN");
when(this.info.getQueryParameters()).thenReturn(parameters);

List<OrderCto> expectedOrders = new ArrayList<>();
when(this.salesManagement.findOrderCtos(any(OrderSearchCriteriaTo.class))).thenReturn(expectedOrders);

// and when
List<OrderCto> foundOrders = this.salesManagementRestService.findOrders(this.info);

// then expected orders were found
assertSame("Expected orders were found.", expectedOrders, foundOrders);
// then expected criteria were provided
OrderSearchCriteriaTo expectedCriteria = new OrderSearchCriteriaTo();
expectedCriteria.setTableId(1L);
expectedCriteria.setState(OrderState.OPEN);
verify(this.salesManagement, times(1)).findOrderCtos(eq(expectedCriteria));
}

/**
* Test method for
* {@link io.oasp.gastronomy.restaurant.salesmanagement.service.impl.rest.SalesmanagementRestServiceImpl#findOrders(javax.ws.rs.core.UriInfo)}
* .
*/
@Test
public void testShouldFindOrdersWithPaging() {

// given
MultivaluedMap<String, String> parameters = new MultivaluedHashMap<>();
parameters.putSingle("page", "3");
parameters.putSingle("count", "100");
when(this.info.getQueryParameters()).thenReturn(parameters);

// and when
this.salesManagementRestService.findOrders(this.info);

// then expected criteria were provided
OrderSearchCriteriaTo expectedCriteria = new OrderSearchCriteriaTo();
expectedCriteria.setHitOffset(200);
expectedCriteria.setMaximumHitCount(100);
verify(this.salesManagement, times(1)).findOrderCtos(eq(expectedCriteria));
}

/**
* Test method for
* {@link io.oasp.gastronomy.restaurant.salesmanagement.service.impl.rest.SalesmanagementRestServiceImpl#findOrderPositions(javax.ws.rs.core.UriInfo)}
* .
*/
@Test
public void testShouldFindOrderPositions() {

// given
MultivaluedMap<String, String> parameters = new MultivaluedHashMap<>();
parameters.putSingle("orderId", "1");
parameters.putSingle("cookId", "2");
parameters.putSingle("state", "PAYED");
parameters.putSingle("mealOrSideDish", "true");
when(this.info.getQueryParameters()).thenReturn(parameters);

List<OrderPositionEto> expectedOrderPositions = new ArrayList<>();
when(this.salesManagement.findOrderPositions(any(OrderPositionSearchCriteriaTo.class))).thenReturn(
expectedOrderPositions);

// and when
List<OrderPositionEto> foundOrderPositions = this.salesManagementRestService.findOrderPositions(this.info);

// then expected order positions were found
assertSame("Expected order positions were found.", expectedOrderPositions, foundOrderPositions);
// then expected criteria were provided
OrderPositionSearchCriteriaTo expectedCriteria = new OrderPositionSearchCriteriaTo();
expectedCriteria.setOrderId(1L);
expectedCriteria.setCookId(2L);
expectedCriteria.setState(OrderPositionState.PAYED);
expectedCriteria.setMealOrSideDish(true);
verify(this.salesManagement, times(1)).findOrderPositions(eq(expectedCriteria));
}

/**
* Test method for
* {@link io.oasp.gastronomy.restaurant.salesmanagement.service.impl.rest.SalesmanagementRestServiceImpl#findOrderPositions(javax.ws.rs.core.UriInfo)}
* .
*/
@Test
public void testShouldFindOrderPositionsWithPaging() {

// given
MultivaluedMap<String, String> parameters = new MultivaluedHashMap<>();
parameters.putSingle("page", "4");
parameters.putSingle("count", "50");
when(this.info.getQueryParameters()).thenReturn(parameters);

// and when
this.salesManagementRestService.findOrderPositions(this.info);

// then expected criteria were provided
OrderPositionSearchCriteriaTo expectedCriteria = new OrderPositionSearchCriteriaTo();
expectedCriteria.setHitOffset(150);
expectedCriteria.setMaximumHitCount(50);
verify(this.salesManagement, times(1)).findOrderPositions(eq(expectedCriteria));
}

}

0 comments on commit ae52292

Please sign in to comment.