diff --git a/src/main/java/edu/tamu/app/controller/ServiceController.java b/src/main/java/edu/tamu/app/controller/ServiceController.java index cce2ffe..6f0f8de 100644 --- a/src/main/java/edu/tamu/app/controller/ServiceController.java +++ b/src/main/java/edu/tamu/app/controller/ServiceController.java @@ -17,6 +17,7 @@ import edu.tamu.app.model.Service; import edu.tamu.app.model.repo.IdeaRepo; import edu.tamu.app.model.repo.ServiceRepo; +import edu.tamu.app.model.request.FilteredPageRequest; import edu.tamu.app.model.request.IssueRequest; import edu.tamu.app.model.request.ServiceRequest; import edu.tamu.app.service.ProjectService; @@ -52,6 +53,12 @@ public ApiResponse getPublicServices() { return new ApiResponse(SUCCESS, serviceRepo.findByIsPublicOrderByStatusDescNameAsc(true)); } + @RequestMapping("/page") + @PreAuthorize("hasRole('ANONYMOUS')") + public ApiResponse page(@RequestBody FilteredPageRequest filteredPageRequest) { + return new ApiResponse(SUCCESS, serviceRepo.findAll(filteredPageRequest.getServiceSpecification(), filteredPageRequest.getPageRequest())); + } + @RequestMapping("/{id}") @PreAuthorize("hasRole('ANONYMOUS')") public ApiResponse getService(@PathVariable Long id) { diff --git a/src/main/java/edu/tamu/app/model/repo/ServiceRepo.java b/src/main/java/edu/tamu/app/model/repo/ServiceRepo.java index 6487a5e..8a58c4c 100644 --- a/src/main/java/edu/tamu/app/model/repo/ServiceRepo.java +++ b/src/main/java/edu/tamu/app/model/repo/ServiceRepo.java @@ -2,6 +2,9 @@ import java.util.List; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.repository.JpaRepository; import edu.tamu.app.enums.Status; @@ -10,6 +13,8 @@ public interface ServiceRepo extends JpaRepository, ServiceRepoCustom { + public Page findAll(Specification specification, Pageable pageable); + public List findByIsPublicOrderByStatusDescNameAsc(Boolean isPublic); public List findByIsAuto(Boolean isAuto); diff --git a/src/main/java/edu/tamu/app/model/repo/specification/AbstractSpecification.java b/src/main/java/edu/tamu/app/model/repo/specification/AbstractSpecification.java index 7abdab5..7dd2e25 100644 --- a/src/main/java/edu/tamu/app/model/repo/specification/AbstractSpecification.java +++ b/src/main/java/edu/tamu/app/model/repo/specification/AbstractSpecification.java @@ -49,11 +49,18 @@ public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuild } } - query.orderBy(cb.desc(root.get("lastModified"))); + toPredicateDefaultQueryOrderBy(root, query, cb); return builder.build(cb); } + /** + * Allow implementing classes to control order by in case lastModified is non-existent. + */ + protected void toPredicateDefaultQueryOrderBy(Root root, CriteriaQuery query, CriteriaBuilder cb) { + query.orderBy(cb.desc(root.get("lastModified"))); + } + private class PredicateBuilder { private final Map> predicates; diff --git a/src/main/java/edu/tamu/app/model/repo/specification/ServiceSpecification.java b/src/main/java/edu/tamu/app/model/repo/specification/ServiceSpecification.java new file mode 100644 index 0000000..17b6d3a --- /dev/null +++ b/src/main/java/edu/tamu/app/model/repo/specification/ServiceSpecification.java @@ -0,0 +1,19 @@ +package edu.tamu.app.model.repo.specification; + +import java.util.Map; + +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Root; + +public class ServiceSpecification extends AbstractSpecification { + + public ServiceSpecification(Map filters) { + super(filters); + } + + @Override + protected void toPredicateDefaultQueryOrderBy(Root root, CriteriaQuery query, CriteriaBuilder cb) { + query.orderBy(cb.desc(root.get("name"))); + } +} diff --git a/src/main/java/edu/tamu/app/model/request/FilteredPageRequest.java b/src/main/java/edu/tamu/app/model/request/FilteredPageRequest.java index 4269ca8..334473e 100644 --- a/src/main/java/edu/tamu/app/model/request/FilteredPageRequest.java +++ b/src/main/java/edu/tamu/app/model/request/FilteredPageRequest.java @@ -13,9 +13,11 @@ import edu.tamu.app.model.FeatureProposal; import edu.tamu.app.model.Idea; import edu.tamu.app.model.Note; +import edu.tamu.app.model.Service; import edu.tamu.app.model.repo.specification.FeatureProposalSpecification; import edu.tamu.app.model.repo.specification.IdeaSpecification; import edu.tamu.app.model.repo.specification.NoteSpecification; +import edu.tamu.app.model.repo.specification.ServiceSpecification; public class FilteredPageRequest { @@ -42,6 +44,11 @@ public IdeaSpecification getIdeaSpecification() { return new IdeaSpecification(filters); } + @JsonIgnore + public ServiceSpecification getServiceSpecification() { + return new ServiceSpecification(filters); + } + @JsonIgnore public FeatureProposalSpecification getFeatureProposalSpecification() { return new FeatureProposalSpecification(filters); diff --git a/src/test/java/edu/tamu/app/controller/FeatureProposalControllerTest.java b/src/test/java/edu/tamu/app/controller/FeatureProposalControllerTest.java index 2fb1d5e..a36f661 100644 --- a/src/test/java/edu/tamu/app/controller/FeatureProposalControllerTest.java +++ b/src/test/java/edu/tamu/app/controller/FeatureProposalControllerTest.java @@ -17,6 +17,9 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; import org.springframework.messaging.simp.SimpMessagingTemplate; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.junit4.SpringRunner; @@ -30,6 +33,8 @@ import edu.tamu.app.model.repo.FeatureProposalRepo; import edu.tamu.app.model.repo.ServiceRepo; import edu.tamu.app.model.repo.UserRepo; +import edu.tamu.app.model.repo.specification.FeatureProposalSpecification; +import edu.tamu.app.model.request.FilteredPageRequest; import edu.tamu.weaver.auth.model.Credentials; import edu.tamu.weaver.response.ApiResponse; @@ -56,6 +61,7 @@ public class FeatureProposalControllerTest { private static FeatureProposal TEST_FEATURE_PROPOSAL3 = new FeatureProposal(TEST_FEATURE_PROPOSAL_TITLE3, TEST_FEATURE_PROPOSAL_DESCRIPTION3, TEST_USER1); private static FeatureProposal TEST_MODIFIED_FEATURE_PROPOSAL = new FeatureProposal(TEST_MODIFIED_FEATURE_PROPOSAL_TITLE, TEST_MODIFIED_FEATURE_PROPOSAL_DESCRIPTION, TEST_USER2, TEST_SERVICE); private static List mockFeatureProposalList = new ArrayList(Arrays.asList(new FeatureProposal[] { TEST_FEATURE_PROPOSAL1, TEST_FEATURE_PROPOSAL2, TEST_FEATURE_PROPOSAL3 })); + private static Page mockPageableFeatureProposalList = new PageImpl(Arrays.asList(new FeatureProposal[] { TEST_FEATURE_PROPOSAL1, TEST_FEATURE_PROPOSAL2, TEST_FEATURE_PROPOSAL3 })); private static User user = new User("123456789"); @@ -80,11 +86,13 @@ public class FeatureProposalControllerTest { private FeatureProposalController featureProposalController; @Before + @SuppressWarnings("unchecked") public void setup() throws UserNotFoundException { MockitoAnnotations.initMocks(this); when(credentials.getUin()).thenReturn("123456789"); when(userRepo.findByUsername(any(String.class))).thenReturn(Optional.of(user)); when(featureProposalRepo.findAll()).thenReturn(mockFeatureProposalList); + when(featureProposalRepo.findAll(any(FeatureProposalSpecification.class), any(Pageable.class))).thenReturn(mockPageableFeatureProposalList); when(featureProposalRepo.findOne(any(Long.class))).thenReturn(TEST_FEATURE_PROPOSAL1); when(featureProposalRepo.create(any(FeatureProposal.class), any(Credentials.class))).thenReturn(TEST_FEATURE_PROPOSAL1); when(featureProposalRepo.create(any(Idea.class))).thenReturn(TEST_FEATURE_PROPOSAL1); @@ -94,6 +102,17 @@ public void setup() throws UserNotFoundException { doNothing().when(featureProposalRepo).delete(any(FeatureProposal.class)); } + @Test + @SuppressWarnings("unchecked") + public void testPage() { + FilteredPageRequest mockFilter = new FilteredPageRequest(); + response = featureProposalController.getAllFeatureProposalsByService(mockFilter); + assertEquals("Not successful at getting paged FeatureProposals", SUCCESS, response.getMeta().getStatus()); + + Page page = (Page) response.getPayload().get("PageImpl"); + assertEquals("The paged list of FeatureProposals is the wrong length", mockPageableFeatureProposalList.getSize(), page.getSize()); + } + @Test public void testFeatureProposal() { response = featureProposalController.getFeatureProposal(TEST_FEATURE_PROPOSAL1.getId()); diff --git a/src/test/java/edu/tamu/app/controller/IdeaControllerTest.java b/src/test/java/edu/tamu/app/controller/IdeaControllerTest.java index 428597a..61c261e 100644 --- a/src/test/java/edu/tamu/app/controller/IdeaControllerTest.java +++ b/src/test/java/edu/tamu/app/controller/IdeaControllerTest.java @@ -17,6 +17,9 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; import org.springframework.messaging.simp.SimpMessagingTemplate; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.junit4.SpringRunner; @@ -29,6 +32,8 @@ import edu.tamu.app.model.repo.IdeaRepo; import edu.tamu.app.model.repo.ServiceRepo; import edu.tamu.app.model.repo.UserRepo; +import edu.tamu.app.model.repo.specification.IdeaSpecification; +import edu.tamu.app.model.request.FilteredPageRequest; import edu.tamu.weaver.auth.model.Credentials; import edu.tamu.weaver.response.ApiResponse; @@ -55,6 +60,7 @@ public class IdeaControllerTest { private static Idea TEST_IDEA3 = new Idea(TEST_IDEA_TITLE3, TEST_IDEA_DESCRIPTION3, TEST_USER1); private static Idea TEST_MODIFIED_IDEA = new Idea(TEST_MODIFIED_IDEA_TITLE, TEST_MODIFIED_IDEA_DESCRIPTION, TEST_USER2, TEST_SERVICE); private static List mockIdeaList = new ArrayList(Arrays.asList(new Idea[] { TEST_IDEA1, TEST_IDEA2, TEST_IDEA3 })); + private static Page mockPageableIdeaList = new PageImpl(Arrays.asList(new Idea[] { TEST_IDEA1, TEST_IDEA2, TEST_IDEA3 })); private static User user = new User("123456789"); @@ -79,11 +85,13 @@ public class IdeaControllerTest { private IdeaController ideaController; @Before + @SuppressWarnings("unchecked") public void setup() throws UserNotFoundException { MockitoAnnotations.initMocks(this); when(credentials.getUin()).thenReturn("123456789"); when(userRepo.findByUsername(any(String.class))).thenReturn(Optional.of(user)); when(ideaRepo.findAll()).thenReturn(mockIdeaList); + when(ideaRepo.findAll(any(IdeaSpecification.class), any(Pageable.class))).thenReturn(mockPageableIdeaList); when(ideaRepo.findOne(any(Long.class))).thenReturn(TEST_IDEA1); when(ideaRepo.create(any(Idea.class), any(Credentials.class))).thenReturn(TEST_IDEA1); when(ideaRepo.update(any(Idea.class))).thenReturn(TEST_MODIFIED_IDEA); @@ -92,6 +100,17 @@ public void setup() throws UserNotFoundException { doNothing().when(ideaRepo).delete(any(Idea.class)); } + @Test + @SuppressWarnings("unchecked") + public void testPage() { + FilteredPageRequest mockFilter = new FilteredPageRequest(); + response = ideaController.page(mockFilter); + assertEquals("Not successful at getting paged Ideas", SUCCESS, response.getMeta().getStatus()); + + Page page = (Page) response.getPayload().get("PageImpl"); + assertEquals("The paged list of Ideas is the wrong length", mockPageableIdeaList.getSize(), page.getSize()); + } + @Test public void testIdea() { response = ideaController.getById(TEST_IDEA1.getId()); diff --git a/src/test/java/edu/tamu/app/controller/NoteControllerTest.java b/src/test/java/edu/tamu/app/controller/NoteControllerTest.java index 2243e79..ea28252 100644 --- a/src/test/java/edu/tamu/app/controller/NoteControllerTest.java +++ b/src/test/java/edu/tamu/app/controller/NoteControllerTest.java @@ -17,6 +17,9 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; import org.springframework.messaging.simp.SimpMessagingTemplate; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.junit4.SpringRunner; @@ -30,6 +33,8 @@ import edu.tamu.app.model.repo.NoteRepo; import edu.tamu.app.model.repo.ServiceRepo; import edu.tamu.app.model.repo.UserRepo; +import edu.tamu.app.model.repo.specification.NoteSpecification; +import edu.tamu.app.model.request.FilteredPageRequest; import edu.tamu.weaver.auth.model.Credentials; import edu.tamu.weaver.response.ApiResponse; @@ -52,6 +57,7 @@ public class NoteControllerTest { private static Note TEST_NOTE3 = new Note(TEST_NOTE_TITLE3, TEST_USER1); private static Note TEST_MODIFIED_NOTE = new Note(TEST_MODIFIED_NOTE_TITLE, TEST_USER2, NoteType.ISSUE, "", TEST_SERVICE); private static List mockNoteList = new ArrayList(Arrays.asList(new Note[] { TEST_NOTE1, TEST_NOTE2, TEST_NOTE3 })); + private static Page mockPageableNoteList = new PageImpl(Arrays.asList(new Note[] { TEST_NOTE1, TEST_NOTE2, TEST_NOTE3 })); private static User user = new User("123456789"); @@ -76,11 +82,13 @@ public class NoteControllerTest { private NoteController noteController; @Before + @SuppressWarnings("unchecked") public void setup() throws UserNotFoundException { MockitoAnnotations.initMocks(this); when(credentials.getUin()).thenReturn("123456789"); when(userRepo.findByUsername(any(String.class))).thenReturn(Optional.of(user)); when(noteRepo.findAll()).thenReturn(mockNoteList); + when(noteRepo.findAll(any(NoteSpecification.class), any(Pageable.class))).thenReturn(mockPageableNoteList); when(noteRepo.findOne(any(Long.class))).thenReturn(TEST_NOTE1); when(noteRepo.create(any(Note.class), any(Credentials.class))).thenReturn(TEST_NOTE1); when(noteRepo.update(any(Note.class))).thenReturn(TEST_MODIFIED_NOTE); @@ -89,6 +97,17 @@ public void setup() throws UserNotFoundException { doNothing().when(noteRepo).delete(any(Note.class)); } + @Test + @SuppressWarnings("unchecked") + public void testPage() { + FilteredPageRequest mockFilter = new FilteredPageRequest(); + response = noteController.page(mockFilter); + assertEquals("Not successful at getting paged Notes", SUCCESS, response.getMeta().getStatus()); + + Page page = (Page) response.getPayload().get("PageImpl"); + assertEquals("The paged list of Notes is the wrong length", mockPageableNoteList.getSize(), page.getSize()); + } + @Test public void testNote() { response = noteController.getById(TEST_NOTE1.getId()); diff --git a/src/test/java/edu/tamu/app/controller/ServiceControllerTest.java b/src/test/java/edu/tamu/app/controller/ServiceControllerTest.java index ae9a9ac..2d12c1d 100644 --- a/src/test/java/edu/tamu/app/controller/ServiceControllerTest.java +++ b/src/test/java/edu/tamu/app/controller/ServiceControllerTest.java @@ -18,6 +18,9 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; import org.springframework.messaging.simp.SimpMessagingTemplate; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.junit4.SpringRunner; @@ -31,7 +34,9 @@ import edu.tamu.app.model.repo.IdeaRepo; import edu.tamu.app.model.repo.ServiceRepo; import edu.tamu.app.model.repo.UserRepo; +import edu.tamu.app.model.repo.specification.ServiceSpecification; import edu.tamu.app.model.request.AbstractRequest; +import edu.tamu.app.model.request.FilteredPageRequest; import edu.tamu.app.model.request.IssueRequest; import edu.tamu.app.model.request.ServiceRequest; import edu.tamu.app.service.ProjectService; @@ -59,6 +64,7 @@ public class ServiceControllerTest { private static final Service TEST_SERVICE3 = new Service(TEST_SERVICE3_NAME, TEST_SERVICE_STATUS, TEST_IS_AUTO, TEST_IS_PUBLIC, TEST_NOT_ON_SHORT_LIST, "", ""); private static final Service TEST_MODIFIED_SERVICE1 = new Service(TEST_SERVICE1_NAME, TEST_SERVICE_STATUS, TEST_IS_AUTO, TEST_IS_NOT_PUBLIC, TEST_NOT_ON_SHORT_LIST, "", ""); private static final List mockServiceList = new ArrayList(Arrays.asList(new Service[] { TEST_SERVICE1, TEST_SERVICE2, TEST_SERVICE3 })); + private static final Page mockPageableServiceList = new PageImpl(Arrays.asList(new Service[] { TEST_SERVICE1, TEST_SERVICE2, TEST_SERVICE3 })); private static final List mockPublicServiceList = new ArrayList(Arrays.asList(new Service[] { TEST_SERVICE1, TEST_SERVICE3 })); private static final User TEST_SERVICE = new User("123456789"); @@ -92,11 +98,14 @@ public class ServiceControllerTest { private ServiceController serviceController; @Before + @SuppressWarnings("unchecked") public void setup() throws UserNotFoundException { MockitoAnnotations.initMocks(this); when(credentials.getUin()).thenReturn("123456789"); when(userRepo.findByUsername(any(String.class))).thenReturn(Optional.of(TEST_SERVICE)); when(systemMonitorService.getOverallStatus()).thenReturn(new OverallStatus(edu.tamu.app.enums.OverallMessageType.SUCCESS, "Success")); + when(serviceRepo.findAll()).thenReturn(mockServiceList); + when(serviceRepo.findAll(any(ServiceSpecification.class), any(Pageable.class))).thenReturn(mockPageableServiceList); when(serviceRepo.findAllByOrderByStatusDescNameAsc()).thenReturn(mockServiceList); when(serviceRepo.findByIsPublicOrderByStatusDescNameAsc(true)).thenReturn(mockPublicServiceList); when(serviceRepo.findOne(any(Long.class))).thenReturn(TEST_SERVICE1); @@ -135,6 +144,17 @@ private int countPublicServices(List list) { return count; } + @Test + @SuppressWarnings("unchecked") + public void testPage() { + FilteredPageRequest mockFilter = new FilteredPageRequest(); + response = serviceController.page(mockFilter); + assertEquals("Not successful at getting paged Services", SUCCESS, response.getMeta().getStatus()); + + Page page = (Page) response.getPayload().get("PageImpl"); + assertEquals("The paged list of Services is the wrong length", mockPageableServiceList.getSize(), page.getSize()); + } + @Test public void testService() { response = serviceController.getService(TEST_SERVICE1.getId());