diff --git a/src/main/java/org/wise/portal/dao/work/StudentWorkDao.java b/src/main/java/org/wise/portal/dao/work/StudentWorkDao.java index d012975f0..3934c75a9 100644 --- a/src/main/java/org/wise/portal/dao/work/StudentWorkDao.java +++ b/src/main/java/org/wise/portal/dao/work/StudentWorkDao.java @@ -31,6 +31,7 @@ import org.wise.vle.domain.work.StudentWork; import java.util.List; +import java.util.Set; /** * Domain Access Object for StudentWork @@ -45,6 +46,9 @@ List getStudentWorkListByParams(Integer id, Run run, Group period, List getWorkForComponentByWorkgroup(Workgroup workgroup, String nodeId, String componentId); + List getWorkForComponentByWorkgroups(Set workgroups, String nodeId, + String componentId); + List getWorkForComponentByPeriod(Run run, Group period, String nodeId, String componentId); diff --git a/src/main/java/org/wise/portal/dao/work/impl/HibernateStudentWorkDao.java b/src/main/java/org/wise/portal/dao/work/impl/HibernateStudentWorkDao.java index dd75e3d1d..60a140915 100644 --- a/src/main/java/org/wise/portal/dao/work/impl/HibernateStudentWorkDao.java +++ b/src/main/java/org/wise/portal/dao/work/impl/HibernateStudentWorkDao.java @@ -25,6 +25,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Set; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; @@ -119,6 +120,22 @@ public List getWorkForComponentByWorkgroup(Workgroup workgroup, Str return (List) query.getResultList(); } + @Override + public List getWorkForComponentByWorkgroups(Set workgroups, String nodeId, + String componentId) { + CriteriaBuilder cb = getCriteriaBuilder(); + CriteriaQuery cq = cb.createQuery(StudentWork.class); + Root studentWorkRoot = cq.from(StudentWork.class); + List predicates = new ArrayList(); + predicates.add(cb.in(studentWorkRoot.get("workgroup")).value(workgroups)); + predicates.add(cb.equal(studentWorkRoot.get("nodeId"), nodeId)); + predicates.add(cb.equal(studentWorkRoot.get("componentId"), componentId)); + cq.select(studentWorkRoot).where(predicates.toArray(new Predicate[predicates.size()])) + .orderBy(cb.asc(studentWorkRoot.get("serverSaveTime"))); + TypedQuery query = entityManager.createQuery(cq); + return (List) query.getResultList(); + } + private List getStudentWorkListByParamsPredicates(CriteriaBuilder cb, Root studentWorkRoot, Integer id, Run run, Group period, Workgroup workgroup, Boolean isAutoSave, Boolean isSubmit, String nodeId, String componentId, String componentType, diff --git a/src/main/java/org/wise/portal/domain/peergroup/PeerGroup.java b/src/main/java/org/wise/portal/domain/peergroup/PeerGroup.java index fd311c7fa..d8feb13ae 100644 --- a/src/main/java/org/wise/portal/domain/peergroup/PeerGroup.java +++ b/src/main/java/org/wise/portal/domain/peergroup/PeerGroup.java @@ -26,6 +26,7 @@ import java.util.Set; import org.wise.portal.domain.peergroupactivity.PeerGroupActivity; +import org.wise.portal.domain.user.User; import org.wise.portal.domain.workgroup.Workgroup; /** @@ -41,4 +42,6 @@ public interface PeerGroup { void setMembers(Set members); public void addMember(Workgroup workgroup); + + boolean isMember(User user); } diff --git a/src/main/java/org/wise/portal/domain/peergroup/impl/PeerGroupImpl.java b/src/main/java/org/wise/portal/domain/peergroup/impl/PeerGroupImpl.java index 82e38da73..3ba2ab02e 100644 --- a/src/main/java/org/wise/portal/domain/peergroup/impl/PeerGroupImpl.java +++ b/src/main/java/org/wise/portal/domain/peergroup/impl/PeerGroupImpl.java @@ -41,6 +41,7 @@ import org.wise.portal.domain.peergroup.PeerGroup; import org.wise.portal.domain.peergroupactivity.PeerGroupActivity; import org.wise.portal.domain.peergroupactivity.impl.PeerGroupActivityImpl; +import org.wise.portal.domain.user.User; import org.wise.portal.domain.workgroup.Workgroup; import org.wise.portal.domain.workgroup.impl.WorkgroupImpl; @@ -82,4 +83,14 @@ public PeerGroupImpl(PeerGroupActivity activity, Set members) { public void addMember(Workgroup workgroup) { this.members.add(workgroup); } + + @Override + public boolean isMember(User user) { + for (Workgroup workgroup : members) { + if (workgroup.getMembers().contains(user)) { + return true; + } + } + return false; + } } diff --git a/src/main/java/org/wise/portal/presentation/web/controllers/peergroup/PeerGroupAPIController.java b/src/main/java/org/wise/portal/presentation/web/controllers/peergroup/PeerGroupAPIController.java index 2f5b19fc4..9b1103273 100644 --- a/src/main/java/org/wise/portal/presentation/web/controllers/peergroup/PeerGroupAPIController.java +++ b/src/main/java/org/wise/portal/presentation/web/controllers/peergroup/PeerGroupAPIController.java @@ -23,6 +23,8 @@ */ package org.wise.portal.presentation.web.controllers.peergroup; +import java.util.List; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.access.annotation.Secured; @@ -45,6 +47,7 @@ import org.wise.portal.service.run.RunService; import org.wise.portal.service.user.UserService; import org.wise.portal.service.workgroup.WorkgroupService; +import org.wise.vle.domain.work.StudentWork; @RestController @Secured("ROLE_USER") @@ -66,7 +69,7 @@ public class PeerGroupAPIController { @Autowired private PeerGroupActivityService peerGroupActivityService; - @GetMapping("/run/{runId}/workgroup/{workgroupId}/node-id/{nodeId}/component-id/{componentId}") + @GetMapping("/{runId}/{workgroupId}/{nodeId}/{componentId}") PeerGroup getPeerGroup(@PathVariable Long runId, @PathVariable Long workgroupId, @PathVariable String nodeId, @PathVariable String componentId, Authentication auth) throws ObjectNotFoundException, PeerGroupActivityNotFoundException, @@ -87,4 +90,20 @@ private PeerGroup getPeerGroup(Run run, String nodeId, String componentId, Workg PeerGroupActivity activity = peerGroupActivityService.getByComponent(run, nodeId, componentId); return peerGroupService.getPeerGroup(workgroup, activity); } + + @GetMapping("/{peerGroupId}/student-work") + List getPeerGroupWork(@PathVariable Long peerGroupId, Authentication auth) + throws ObjectNotFoundException { + PeerGroup peerGroup = peerGroupService.getById(peerGroupId); + if (isUserInPeerGroup(peerGroup, auth)) { + return peerGroupService.getStudentWork(peerGroup); + } else { + throw new AccessDeniedException("Not permitted"); + } + } + + private boolean isUserInPeerGroup(PeerGroup peerGroup, Authentication auth) { + User user = userService.retrieveUserByUsername(auth.getName()); + return peerGroup.isMember(user); + } } diff --git a/src/main/java/org/wise/portal/service/peergroup/PeerGroupService.java b/src/main/java/org/wise/portal/service/peergroup/PeerGroupService.java index b0c20ce9a..7a8b59a9f 100644 --- a/src/main/java/org/wise/portal/service/peergroup/PeerGroupService.java +++ b/src/main/java/org/wise/portal/service/peergroup/PeerGroupService.java @@ -23,15 +23,27 @@ */ package org.wise.portal.service.peergroup; +import java.util.List; + +import org.wise.portal.dao.ObjectNotFoundException; import org.wise.portal.domain.peergroup.PeerGroup; import org.wise.portal.domain.peergroupactivity.PeerGroupActivity; import org.wise.portal.domain.workgroup.Workgroup; +import org.wise.vle.domain.work.StudentWork; /** * @author Hiroki Terashima */ public interface PeerGroupService { + /** + * Gets the PeerGroup with the specified id + * @param id Long PeerGroup's id + * @return matched PeerGroup + * @throws ObjectNotFoundException when PeerGroup with the given id is not found + */ + public PeerGroup getById(Long id) throws ObjectNotFoundException; + /** * Gets a PeerGroup for the specified workgroup and PeerGroupActivity if a PeerGroup * does not exist, create one. @@ -46,4 +58,11 @@ public interface PeerGroupService { */ PeerGroup getPeerGroup(Workgroup workgroup, PeerGroupActivity activity) throws PeerGroupActivityThresholdNotSatisfiedException, PeerGroupCreationException; + + /** + * Gets StudentWork for the PeerGroup's activity from all the members in the PeerGroup + * @param peerGroup group of workgroups in the PeerGroup + * @return List of StudentWork by members in the PeerGroup for the activity + */ + public List getStudentWork(PeerGroup peerGroup); } diff --git a/src/main/java/org/wise/portal/service/peergroup/impl/PeerGroupServiceImpl.java b/src/main/java/org/wise/portal/service/peergroup/impl/PeerGroupServiceImpl.java index 4abe08606..9647fe040 100644 --- a/src/main/java/org/wise/portal/service/peergroup/impl/PeerGroupServiceImpl.java +++ b/src/main/java/org/wise/portal/service/peergroup/impl/PeerGroupServiceImpl.java @@ -32,6 +32,7 @@ import org.json.JSONException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.wise.portal.dao.ObjectNotFoundException; import org.wise.portal.dao.peergroup.PeerGroupDao; import org.wise.portal.dao.work.StudentWorkDao; import org.wise.portal.domain.group.Group; @@ -60,6 +61,10 @@ public class PeerGroupServiceImpl implements PeerGroupService { @Autowired private StudentWorkDao studentWorkDao; + public PeerGroup getById(Long id) throws ObjectNotFoundException { + return peerGroupDao.getById(id); + } + @Override public PeerGroup getPeerGroup(Workgroup workgroup, PeerGroupActivity activity) throws PeerGroupActivityThresholdNotSatisfiedException, PeerGroupCreationException { @@ -139,4 +144,11 @@ private List getLogicComponentStudentWorkForPeriod(PeerGroupActivit } return studentWorkUniqueWorkgroups; } + + @Override + public List getStudentWork(PeerGroup peerGroup) { + return studentWorkDao.getWorkForComponentByWorkgroups(peerGroup.getMembers(), + peerGroup.getPeerGroupActivity().getNodeId(), + peerGroup.getPeerGroupActivity().getComponentId()); + } } diff --git a/src/test/java/org/wise/portal/dao/work/impl/HibernateStudentWorkDaoTest.java b/src/test/java/org/wise/portal/dao/work/impl/HibernateStudentWorkDaoTest.java index db82e97a2..1e2ff8c58 100644 --- a/src/test/java/org/wise/portal/dao/work/impl/HibernateStudentWorkDaoTest.java +++ b/src/test/java/org/wise/portal/dao/work/impl/HibernateStudentWorkDaoTest.java @@ -27,7 +27,9 @@ import java.sql.Timestamp; import java.util.Calendar; +import java.util.HashSet; import java.util.List; +import java.util.Set; import org.junit.Before; import org.junit.Test; @@ -105,6 +107,18 @@ public void getWorkForComponentByWorkgroup_ShouldReturnStudentWork() { assertEquals("studentWork1", studentWorkList.get(0).getStudentData()); } + @Test + public void getWorkForComponentByWorkgroups_ShouldReturnStudentWork() { + Set workgroups = new HashSet(); + workgroups.add(workgroup1); + workgroups.add(workgroup2); + List studentWorkList = studentWorkDao.getWorkForComponentByWorkgroups(workgroups, + "node1", "component1"); + assertEquals(2, studentWorkList.size()); + assertEquals("studentWork1", studentWorkList.get(0).getStudentData()); + assertEquals("studentWork3", studentWorkList.get(1).getStudentData()); + } + private StudentWork createStudentWork(Workgroup workgroup, String nodeId, String componentId, String studentData) { StudentWork studentWork = new StudentWork(); diff --git a/src/test/java/org/wise/portal/presentation/web/controllers/peergroup/PeerGroupAPIControllerTest.java b/src/test/java/org/wise/portal/presentation/web/controllers/peergroup/PeerGroupAPIControllerTest.java index 90f47dbfb..69b185150 100644 --- a/src/test/java/org/wise/portal/presentation/web/controllers/peergroup/PeerGroupAPIControllerTest.java +++ b/src/test/java/org/wise/portal/presentation/web/controllers/peergroup/PeerGroupAPIControllerTest.java @@ -3,6 +3,9 @@ import static org.easymock.EasyMock.*; import static org.junit.Assert.*; +import java.util.ArrayList; +import java.util.List; + import org.easymock.EasyMockRunner; import org.easymock.Mock; import org.easymock.TestSubject; @@ -10,6 +13,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.security.access.AccessDeniedException; +import org.wise.portal.dao.ObjectNotFoundException; import org.wise.portal.domain.peergroup.PeerGroup; import org.wise.portal.domain.peergroup.impl.PeerGroupImpl; import org.wise.portal.domain.peergroupactivity.PeerGroupActivity; @@ -20,6 +24,7 @@ import org.wise.portal.service.peergroup.PeerGroupService; import org.wise.portal.service.peergroupactivity.PeerGroupActivityNotFoundException; import org.wise.portal.service.peergroupactivity.PeerGroupActivityService; +import org.wise.vle.domain.work.StudentWork; @RunWith(EasyMockRunner.class) public class PeerGroupAPIControllerTest extends APIControllerTest { @@ -39,13 +44,18 @@ public class PeerGroupAPIControllerTest extends APIControllerTest { private PeerGroupActivity peerGroupActivity; - private PeerGroup peerGroup; + private PeerGroup peerGroup1; + + private Long peerGroup1Id = 1L; + + private List peerGroup1StudentWork = new ArrayList(); @Before public void setUp() { super.setUp(); peerGroupActivity = new PeerGroupActivityImpl(); - peerGroup = new PeerGroupImpl(); + peerGroup1 = new PeerGroupImpl(); + peerGroup1.addMember(workgroup1); } @Test @@ -109,6 +119,66 @@ public void getPeerGroup_FoundExistingGroupOrGroupCreated_ReturnGroup() throws E verifyAll(); } + @Test + public void getPeerGroupWork_NonExistingPeerGroupId_ThrowObjectNotFound() { + expectPeerGroupIdNotExist(); + replayAll(); + try { + controller.getPeerGroupWork(peerGroup1Id, studentAuth); + fail("Expected ObjectNotFoundException, but was not thrown"); + } catch (ObjectNotFoundException e) { + } + verifyAll(); + } + + @Test + public void getPeerGroupWork_UserNotInPeerGroup_ThrowAccessDenied() + throws ObjectNotFoundException { + expectPeerGroup(); + expectUserNotInPeerGroup(); + replayAll(); + try { + controller.getPeerGroupWork(peerGroup1Id, studentAuth); + fail("Expected AccessDeniedException, but was not thrown"); + } catch (AccessDeniedException e) { + } + verifyAll(); + } + + @Test + public void getPeerGroupWork_UserInPeerGroup_ReturnStudentWork() throws ObjectNotFoundException { + expectPeerGroup(); + expectUserInPeerGroup(); + expectGetStudentWork(); + replayAll(); + assertNotNull(controller.getPeerGroupWork(peerGroup1Id, studentAuth)); + verifyAll(); + } + + private void expectGetStudentWork() { + expect(peerGroupService.getStudentWork(peerGroup1)).andReturn(peerGroup1StudentWork); + } + + private void expectUserNotInPeerGroup() { + expect(userService.retrieveUserByUsername(studentAuth.getName())).andReturn(student2); + } + + private void expectUserInPeerGroup() { + expect(userService.retrieveUserByUsername(studentAuth.getName())).andReturn(student1); + } + + private void expectPeerGroup() throws ObjectNotFoundException { + expect(peerGroupService.getById(peerGroup1Id)).andReturn(peerGroup1); + } + + private void expectPeerGroupIdNotExist() { + try { + expect(peerGroupService.getById(peerGroup1Id)).andThrow(new ObjectNotFoundException( + peerGroup1Id, PeerGroup.class)); + } catch (ObjectNotFoundException e) { + } + } + private void expectWorkgroupAssociatedWithRunAndActivityFound() throws Exception, PeerGroupActivityNotFoundException { expectWorkgroupAssociatedWithRun(true); @@ -145,7 +215,7 @@ private void expectPeerGroupCreationException() throws Exception { } private void expectPeerGroupCreated() throws Exception { - expect(peerGroupService.getPeerGroup(workgroup1, peerGroupActivity)).andReturn(peerGroup); + expect(peerGroupService.getPeerGroup(workgroup1, peerGroupActivity)).andReturn(peerGroup1); } private void verifyAll() { diff --git a/src/test/java/org/wise/portal/service/peergroup/impl/PeerGroupServiceImplTest.java b/src/test/java/org/wise/portal/service/peergroup/impl/PeerGroupServiceImplTest.java index 05696b59b..f4488a646 100644 --- a/src/test/java/org/wise/portal/service/peergroup/impl/PeerGroupServiceImplTest.java +++ b/src/test/java/org/wise/portal/service/peergroup/impl/PeerGroupServiceImplTest.java @@ -82,7 +82,7 @@ public void setUp() throws Exception { super.setUp(); PeerGroupServiceTestHelper testHelper = new PeerGroupServiceTestHelper(run1, run1Component2); activity = testHelper.activity; - peerGroup = new PeerGroupImpl(); + peerGroup = testHelper.peerGroup1; } @Test @@ -155,6 +155,22 @@ public void getPeerGroup_PeerGroupNotInDBAndAllThresholdsSatisfied_CreateAndRetu verifyAll(); } + @Test + public void getStudentWork_PeerGroupExist_ReturnStudentWorkList() { + expectGetWorkForComponentByWorkgroups(); + replayAll(); + assertEquals(service.getStudentWork(peerGroup).size(), 3); + verifyAll(); + } + + private void expectGetWorkForComponentByWorkgroups() { + expect(studentWorkDao.getWorkForComponentByWorkgroups(peerGroup.getMembers(), + peerGroup.getPeerGroupActivity().getNodeId(), + peerGroup.getPeerGroupActivity().getComponentId())).andReturn( + createStudentWorkList(componentWorkSubmit1, componentWorkSubmit2, + componentWorkNonSubmit1)); + } + private void expectWorkgroupsInPeerGroup(List asList) { expect(peerGroupDao.getWorkgroupsInPeerGroup(activity)).andReturn(Arrays.asList()); } diff --git a/src/test/java/org/wise/portal/service/peergroup/impl/PeerGroupServiceTestHelper.java b/src/test/java/org/wise/portal/service/peergroup/impl/PeerGroupServiceTestHelper.java index 8ecf22f9e..0b64e1fd1 100644 --- a/src/test/java/org/wise/portal/service/peergroup/impl/PeerGroupServiceTestHelper.java +++ b/src/test/java/org/wise/portal/service/peergroup/impl/PeerGroupServiceTestHelper.java @@ -23,6 +23,9 @@ */ package org.wise.portal.service.peergroup.impl; +import java.util.HashSet; +import java.util.Set; + import org.json.JSONObject; import org.wise.portal.dao.Component; import org.wise.portal.domain.peergroup.PeerGroup; @@ -31,6 +34,7 @@ import org.wise.portal.domain.peergroupactivity.impl.PeerGroupActivityImpl; import org.wise.portal.domain.project.impl.ProjectComponent; import org.wise.portal.domain.run.Run; +import org.wise.portal.domain.workgroup.Workgroup; import org.wise.portal.service.WISEServiceTest; /** @@ -62,8 +66,9 @@ public PeerGroupServiceTestHelper(Run run, Component component) throws Exception super.setUp(); activity = new PeerGroupActivityImpl(run, component.nodeId, new ProjectComponent(new JSONObject(peerGroupActivityComponentString))); - peerGroup1 = new PeerGroupImpl(); - peerGroup1.addMember(run1Workgroup1); - peerGroup1.addMember(run1Workgroup2); + Set members = new HashSet(); + members.add(run1Workgroup1); + members.add(run1Workgroup2); + peerGroup1 = new PeerGroupImpl(activity, members); } }