From 5a109a9f02050f875ffce568d1f9059c1afceacc Mon Sep 17 00:00:00 2001
From: srosse <none@none>
Date: Wed, 13 Mar 2013 17:55:02 +0100
Subject: [PATCH] OO-563: fix RS if the group used by reservations was deleted

---
 .../olat/group/manager/BusinessGroupDAO.java  |  14 +-
 .../manager/BusinessGroupServiceImpl.java     |  37 ++---
 .../olat/group/test/BusinessGroupDAOTest.java |  21 +++
 .../group/test/BusinessGroupServiceTest.java  | 147 ++++++++++++++++++
 4 files changed, 194 insertions(+), 25 deletions(-)

diff --git a/src/main/java/org/olat/group/manager/BusinessGroupDAO.java b/src/main/java/org/olat/group/manager/BusinessGroupDAO.java
index 7233b9e7dd7..878d0ebd456 100644
--- a/src/main/java/org/olat/group/manager/BusinessGroupDAO.java
+++ b/src/main/java/org/olat/group/manager/BusinessGroupDAO.java
@@ -188,10 +188,6 @@ public class BusinessGroupDAO {
 	}
 	
 	public BusinessGroup loadForUpdate(Long id) {
-		EntityManager em = dbInstance.getCurrentEntityManager();
-		//BusinessGroup group = em.find(BusinessGroupImpl.class, id, LockModeType.PESSIMISTIC_WRITE);
-		
-		
 		StringBuilder sb = new StringBuilder();
 		sb.append("select bgi from ").append(BusinessGroupImpl.class.getName()).append(" bgi ")
 			.append(" inner join fetch bgi.ownerGroup ownerGroup")
@@ -200,9 +196,13 @@ public class BusinessGroupDAO {
 			.append(" inner join fetch bgi.resource resource")
 			.append(" where bgi.key=:key");
 		
-		return em.createQuery(sb.toString(), BusinessGroup.class)
-				.setParameter("key", id).setLockMode(LockModeType.PESSIMISTIC_WRITE)
-				.getSingleResult();
+		List<BusinessGroup> groups = dbInstance.getCurrentEntityManager()
+				.createQuery(sb.toString(), BusinessGroup.class)
+				.setParameter("key", id)
+				.setLockMode(LockModeType.PESSIMISTIC_WRITE)
+				.getResultList();
+		if(groups.isEmpty()) return null;
+		return groups.get(0);
 	}
 	
 	public BusinessGroup merge(BusinessGroup group) {
diff --git a/src/main/java/org/olat/group/manager/BusinessGroupServiceImpl.java b/src/main/java/org/olat/group/manager/BusinessGroupServiceImpl.java
index df0891cfd89..a7e54479ff7 100644
--- a/src/main/java/org/olat/group/manager/BusinessGroupServiceImpl.java
+++ b/src/main/java/org/olat/group/manager/BusinessGroupServiceImpl.java
@@ -998,10 +998,11 @@ public class BusinessGroupServiceImpl implements BusinessGroupService, UserDataD
 	public void cancelPendingParticipation(Identity ureqIdentity, ResourceReservation reservation) {
 		if(reservation != null && "BusinessGroup".equals(reservation.getResource().getResourceableTypeName())) {
 			BusinessGroup group = businessGroupDAO.loadForUpdate(reservation.getResource().getResourceableId());
-
-			SyncUserListTask syncIM = new SyncUserListTask(group);
-			transferFirstIdentityFromWaitingToParticipant(ureqIdentity, group, null, null);
-			syncIM(syncIM, group);
+			if(group != null) {
+				SyncUserListTask syncIM = new SyncUserListTask(group);
+				transferFirstIdentityFromWaitingToParticipant(ureqIdentity, group, null, null);
+				syncIM(syncIM, group);
+			}
 		}
 	}
 
@@ -1011,22 +1012,22 @@ public class BusinessGroupServiceImpl implements BusinessGroupService, UserDataD
 		ResourceReservation reservation = acService.getReservation(reservationOwner, resource);
 		if(reservation != null && "BusinessGroup".equals(resource.getResourceableTypeName())) {
 			BusinessGroup group = businessGroupDAO.loadForUpdate(resource.getResourceableId());
-
-			String type = reservation.getType();
-			if("group_coach".equals(type)) {
-				if(!securityManager.isIdentityInSecurityGroup(reservationOwner, group.getOwnerGroup())) {
-					SyncUserListTask syncIM = new SyncUserListTask(group);
-					internalAddCoach(reservationOwner, group, syncIM);
-					syncIM(syncIM, group);
-				}
-			} else if("group_participant".equals(type)) {
-				if(!securityManager.isIdentityInSecurityGroup(reservationOwner, group.getPartipiciantGroup())) {
-					SyncUserListTask syncIM = new SyncUserListTask(group);
-					internalAddParticipant(reservationOwner, group, syncIM);
-					syncIM(syncIM, group);
+			if(group != null) {
+				String type = reservation.getType();
+				if("group_coach".equals(type)) {
+					if(!securityManager.isIdentityInSecurityGroup(reservationOwner, group.getOwnerGroup())) {
+						SyncUserListTask syncIM = new SyncUserListTask(group);
+						internalAddCoach(reservationOwner, group, syncIM);
+						syncIM(syncIM, group);
+					}
+				} else if("group_participant".equals(type)) {
+					if(!securityManager.isIdentityInSecurityGroup(reservationOwner, group.getPartipiciantGroup())) {
+						SyncUserListTask syncIM = new SyncUserListTask(group);
+						internalAddParticipant(reservationOwner, group, syncIM);
+						syncIM(syncIM, group);
+					}
 				}
 			}
-			
 			reservationDao.deleteReservation(reservation);
 		}
 	}
diff --git a/src/test/java/org/olat/group/test/BusinessGroupDAOTest.java b/src/test/java/org/olat/group/test/BusinessGroupDAOTest.java
index 0dd7143c88d..caf6993849e 100644
--- a/src/test/java/org/olat/group/test/BusinessGroupDAOTest.java
+++ b/src/test/java/org/olat/group/test/BusinessGroupDAOTest.java
@@ -165,6 +165,27 @@ public class BusinessGroupDAOTest extends OlatTestCase {
 		Assert.assertTrue(reloadedGroup.getAutoCloseRanksEnabled());
 	}
 	
+	@Test
+	public void loadBusinessGroup_forUpdate() {
+		//create a group
+		BusinessGroup group = businessGroupDao.createAndPersist(null, "gdco", "gdco-desc", 0, 10, true, true, false, false, false);
+		dbInstance.commitAndCloseSession();
+		
+		//load an lock
+		BusinessGroup groupForUpdate = businessGroupDao.loadForUpdate(group.getKey());
+		Assert.assertNotNull(groupForUpdate);
+		Assert.assertEquals(group, groupForUpdate);
+		dbInstance.commit();//release lock
+	}
+	
+	@Test
+	public void loadBusinessGroup_forUpdate_notFound() {
+		//load and lock an inexistent group
+		BusinessGroup groupForUpdate = businessGroupDao.loadForUpdate(new Long(0l));
+		Assert.assertNull(groupForUpdate);
+		dbInstance.commit();//release lock
+	}
+	
 	@Test
 	public void loadBusinessGroupWithOwner() {
 		Identity owner = JunitTestHelper.createAndPersistIdentityAsUser("bdao-1-" + UUID.randomUUID().toString());
diff --git a/src/test/java/org/olat/group/test/BusinessGroupServiceTest.java b/src/test/java/org/olat/group/test/BusinessGroupServiceTest.java
index 4cc5a71c9af..9e4ed15c626 100644
--- a/src/test/java/org/olat/group/test/BusinessGroupServiceTest.java
+++ b/src/test/java/org/olat/group/test/BusinessGroupServiceTest.java
@@ -24,6 +24,7 @@ import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
 import java.util.ArrayList;
+import java.util.Calendar;
 import java.util.Collections;
 import java.util.List;
 import java.util.UUID;
@@ -51,6 +52,9 @@ import org.olat.group.BusinessGroup;
 import org.olat.group.BusinessGroupService;
 import org.olat.group.model.SearchBusinessGroupParams;
 import org.olat.repository.RepositoryEntry;
+import org.olat.resource.accesscontrol.ACService;
+import org.olat.resource.accesscontrol.manager.ACReservationDAO;
+import org.olat.resource.accesscontrol.model.ResourceReservation;
 import org.olat.test.JunitTestHelper;
 import org.olat.test.OlatTestCase;
 import org.olat.user.UserManager;
@@ -70,6 +74,10 @@ public class BusinessGroupServiceTest extends OlatTestCase {
 	@Autowired
 	private UserManager userManager;
 	@Autowired
+	private ACService acService;
+	@Autowired
+	private ACReservationDAO reservationDao;
+	@Autowired
 	private BaseSecurity securityManager;
 	@Autowired
 	private BusinessGroupService businessGroupService;
@@ -752,4 +760,143 @@ public class BusinessGroupServiceTest extends OlatTestCase {
 	}
 	
 
+	@Test
+	public void testAcceptPendingParticipation_participant() {
+		//create a group
+		Identity id = JunitTestHelper.createAndPersistIdentityAsUser("Reserv-bg-" + UUID.randomUUID().toString());
+		BusinessGroup group = businessGroupService.createBusinessGroup(null, "Free group", "But you must wait", new Integer(0), new Integer(2), false, false, null);
+		
+		//create a reservation
+		Calendar cal = Calendar.getInstance();
+		cal.add(Calendar.HOUR, 6);
+		ResourceReservation reservation = reservationDao.createReservation(id, "group_participant", cal.getTime(), group.getResource());
+		dbInstance.commitAndCloseSession();
+		Assert.assertNotNull(reservation);
+		Assert.assertEquals("group_participant", reservation.getType());
+		Assert.assertEquals(group.getResource(), reservation.getResource());
+		
+		//check that the user is not participant
+		Assert.assertFalse(securityManager.isIdentityInSecurityGroup(id, group.getPartipiciantGroup()));
+		
+		//accept reservation
+		businessGroupService.acceptPendingParticipation(id, id, group.getResource());
+		dbInstance.commitAndCloseSession();
+		
+	//check that the user is participant
+		boolean participant = securityManager.isIdentityInSecurityGroup(id, group.getPartipiciantGroup());
+		Assert.assertTrue(participant);
+	}
+
+	@Test
+	public void testAcceptPendingParticipation_coach() {
+		//create a group
+		Identity id = JunitTestHelper.createAndPersistIdentityAsUser("Reserv-bg-" + UUID.randomUUID().toString());
+		BusinessGroup group = businessGroupService.createBusinessGroup(null, "Free group", "But you must wait", new Integer(0), new Integer(2), false, false, null);
+		
+		//create a reservation
+		Calendar cal = Calendar.getInstance();
+		cal.add(Calendar.HOUR, 6);
+		ResourceReservation reservation = reservationDao.createReservation(id, "group_coach", cal.getTime(), group.getResource());
+		dbInstance.commitAndCloseSession();
+		Assert.assertNotNull(reservation);
+		
+		//check that the user is not participant
+		Assert.assertFalse(securityManager.isIdentityInSecurityGroup(id, group.getOwnerGroup()));
+		
+		//accept reservation
+		acService.acceptReservationToResource(id, reservation);
+		dbInstance.commitAndCloseSession();
+		
+		//check that the user is participant
+		Assert.assertTrue(securityManager.isIdentityInSecurityGroup(id, group.getOwnerGroup()));
+		//check that the reservations are deleted
+		List<ResourceReservation> reservations = reservationDao.loadReservations(id);
+		Assert.assertNotNull(reservations);
+		Assert.assertTrue(reservations.isEmpty());
+	}
+
+	@Test
+	public void testCancelPendingParticipation_participant() {
+		//create a group
+		Identity id = JunitTestHelper.createAndPersistIdentityAsUser("Reserv-bg-" + UUID.randomUUID().toString());
+		BusinessGroup group = businessGroupService.createBusinessGroup(null, "Free group", "But you must wait", new Integer(0), new Integer(2), false, false, null);
+		
+		//create a reservation
+		Calendar cal = Calendar.getInstance();
+		cal.add(Calendar.HOUR, 6);
+		ResourceReservation reservation = reservationDao.createReservation(id, "group_participant", cal.getTime(), group.getResource());
+		dbInstance.commitAndCloseSession();
+		Assert.assertNotNull(reservation);
+		
+		//check that the user is not participant
+		Assert.assertFalse(securityManager.isIdentityInSecurityGroup(id, group.getPartipiciantGroup()));
+		
+		//accept reservation
+		acService.removeReservation(id, id, reservation);
+		dbInstance.commitAndCloseSession();
+		
+		//check that the user is not participant
+		Assert.assertFalse(securityManager.isIdentityInSecurityGroup(id, group.getPartipiciantGroup()));
+		//check that the reservations are deleted
+		List<ResourceReservation> reservations = reservationDao.loadReservations(id);
+		Assert.assertNotNull(reservations);
+		Assert.assertTrue(reservations.isEmpty());
+	}
+	
+	@Test
+	public void testCancelPendingParticipation_deletedGroup() {
+		//create a group
+		Identity id = JunitTestHelper.createAndPersistIdentityAsUser("Reserv-bg-" + UUID.randomUUID().toString());
+		BusinessGroup group = businessGroupService.createBusinessGroup(null, "Free group", "But you must wait", new Integer(0), new Integer(2), false, false, null);
+		
+		//create a reservation
+		Calendar cal = Calendar.getInstance();
+		cal.add(Calendar.HOUR, 6);
+		ResourceReservation reservation = reservationDao.createReservation(id, "group_participant", cal.getTime(), group.getResource());
+		dbInstance.commitAndCloseSession();
+		Assert.assertNotNull(reservation);
+		
+		//delete the group
+		businessGroupService.deleteBusinessGroup(group);
+		dbInstance.commitAndCloseSession();
+		
+		//accept reservation
+		acService.removeReservation(id, id, reservation);
+		dbInstance.commitAndCloseSession();
+		
+		//check that the user is not participant
+		boolean participant2 = securityManager.isIdentityInSecurityGroup(id, group.getPartipiciantGroup());
+		Assert.assertFalse(participant2);
+		//check that the reservations are deleted
+		List<ResourceReservation> reservations = reservationDao.loadReservations(id);
+		Assert.assertNotNull(reservations);
+		Assert.assertTrue(reservations.isEmpty());
+	}
+	
+	@Test
+	public void testAcceptPendingParticipation_deletedGroup() {
+		//create a group
+		Identity id = JunitTestHelper.createAndPersistIdentityAsUser("Reserv-bg-" + UUID.randomUUID().toString());
+		BusinessGroup group = businessGroupService.createBusinessGroup(null, "Free group", "But you must wait", new Integer(0), new Integer(2), false, false, null);
+		
+		//create a reservation
+		Calendar cal = Calendar.getInstance();
+		cal.add(Calendar.HOUR, 6);
+		ResourceReservation reservation = reservationDao.createReservation(id, "group_coach", cal.getTime(), group.getResource());
+		dbInstance.commitAndCloseSession();
+		Assert.assertNotNull(reservation);
+		
+		//delete the group
+		businessGroupService.deleteBusinessGroup(group);
+		dbInstance.commitAndCloseSession();
+		
+		//accept reservation
+		acService.acceptReservationToResource(id, reservation);
+		dbInstance.commitAndCloseSession();
+		
+		//check that the reservations are deleted
+		List<ResourceReservation> reservations = reservationDao.loadReservations(id);
+		Assert.assertNotNull(reservations);
+		Assert.assertTrue(reservations.isEmpty());
+	}
 }
\ No newline at end of file
-- 
GitLab