/** * $Id$ * $URL$ ************************************************************************** * Copyright (c) 2012 The Sakai Foundation * * Licensed under the Educational Community License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.osedu.org/licenses/ECL-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.sakaiproject.entitybroker.providers; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.sakaiproject.entity.api.ResourceProperties; import org.sakaiproject.entitybroker.DeveloperHelperService; import org.sakaiproject.entitybroker.EntityReference; import org.sakaiproject.entitybroker.EntityView; import org.sakaiproject.entitybroker.entityprovider.capabilities.CollectionResolvable; import org.sakaiproject.entitybroker.entityprovider.extension.ActionReturn; import org.sakaiproject.entitybroker.entityprovider.extension.EntityData; import org.sakaiproject.entitybroker.entityprovider.search.Restriction; import org.sakaiproject.entitybroker.entityprovider.search.Search; import org.sakaiproject.entitybroker.providers.model.EntityMember; import org.sakaiproject.entitybroker.providers.model.EntityUser; import org.sakaiproject.exception.IdUnusedException; import org.sakaiproject.exception.PermissionException; import org.sakaiproject.mock.domain.*; import org.sakaiproject.site.api.SiteService; import org.sakaiproject.util.BaseResourceProperties; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import static org.junit.Assert.*; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; public class MembershipEntityProviderTest { @Mock private SiteService siteService; @Mock private DeveloperHelperService developerHelperService; @Mock private UserEntityProvider userEntityProvider; private MembershipEntityProvider provider; @Before public void setUp() { MockitoAnnotations.initMocks(this); provider = new MembershipEntityProvider(); provider.setSiteService(siteService); provider.setDeveloperHelperService(developerHelperService); provider.setUserEntityProvider(userEntityProvider); } @Test public void handleSiteMembershipPreservesDotsInSiteIdPathParams_GET() throws IdUnusedException { EntityView entityView = new EntityView("/membership/site/site.with.dots.json"); entityView.setMethod(EntityView.Method.GET); Site site = new Site(); site.setId("site.with.dots"); EntityUser user = new EntityUser(); user.setId("user-foo"); user.setEid("user-foo"); Member member = new Member(); member.setUserId("user-foo"); member.setUserEid("user-foo"); Map<String,org.sakaiproject.authz.api.Member> members = new HashMap<String,org.sakaiproject.authz.api.Member>(); members.put("user-foo", member); site.setMembers(members); when(siteService.getSite("site.with.dots")).thenReturn(site); when(developerHelperService.getCurrentUserReference()).thenReturn("/user/me"); when(siteService.allowViewRoster("site.with.dots")).thenReturn(true); when(userEntityProvider.getUserById("user-foo")).thenReturn(user); ActionReturn result = provider.handleSiteMemberships(entityView, new HashMap<String, Object>()); assertEquals(1, result.getEntitiesList().size()); assertEquals("user-foo::site:site.with.dots", result.getEntitiesList().get(0).getEntityId()); } @Test public void handleSiteMembershipPreservesDotsInSiteIdQueryParams_GET() throws IdUnusedException { EntityView entityView = new EntityView("/membership/site"); entityView.setMethod(EntityView.Method.GET); Map<String,Object> params = new HashMap<String,Object>(); params.put("siteId", "site.with.dots"); Site site = new Site(); site.setId("site.with.dots"); EntityUser user = new EntityUser(); user.setId("user-foo"); user.setEid("user-foo"); Member member = new Member(); member.setUserId("user-foo"); member.setUserEid("user-foo"); Map<String,org.sakaiproject.authz.api.Member> members = new HashMap<String,org.sakaiproject.authz.api.Member>(); members.put("user-foo", member); site.setMembers(members); when(siteService.getSite("site.with.dots")).thenReturn(site); when(developerHelperService.getCurrentUserReference()).thenReturn("/user/me"); when(siteService.allowViewRoster("site.with.dots")).thenReturn(true); when(userEntityProvider.getUserById("user-foo")).thenReturn(user); ActionReturn result = provider.handleSiteMemberships(entityView, params); assertEquals(1, result.getEntitiesList().size()); assertEquals("user-foo::site:site.with.dots", result.getEntitiesList().get(0).getEntityId()); } @Test public void handleSiteMembershipPreservesDotsInSiteIdPathParams_POST() throws IdUnusedException, PermissionException { EntityView entityView = new EntityView("/membership/site/site.with.dots.json"); entityView.setMethod(EntityView.Method.POST); Map<String,Object> params = new HashMap<String,Object>(); params.put("memberRole", "role-foo"); params.put("userSearchValues", "user-foo"); Site site = new Site(); site.setId("site.with.dots"); EntityUser user = new EntityUser(); user.setEid("user-foo"); user.setId("user-foo"); user.setEmail("user-foo@school.edu"); Member member = new Member(); member.setUserId("user-foo"); member.setUserEid("user-foo"); Map<String,org.sakaiproject.authz.api.Member> members = new HashMap<String,org.sakaiproject.authz.api.Member>(); members.put("user-foo", member); site.setMembers(members); when(siteService.getSite("site.with.dots")).thenReturn(site); when(developerHelperService.getCurrentUserReference()).thenReturn("/user/me"); when(siteService.allowViewRoster("site.with.dots")).thenReturn(true); when(userEntityProvider.findUserFromSearchValue("user-foo")).thenReturn(user); when(userEntityProvider.getCurrentUser(null)).thenReturn(user); when(userEntityProvider.getUserById("user-foo")).thenReturn(user); ActionReturn result = provider.handleSiteMemberships(entityView, params); assertEquals(1, result.getEntitiesList().size()); assertEquals("user-foo::site:site.with.dots", result.getEntitiesList().get(0).getEntityId()); verify(siteService).saveSiteMembership(site); } @Test public void handleSiteMembershipPreservesDotsInSiteIdQueryParams_POST() throws IdUnusedException, PermissionException { EntityView entityView = new EntityView("/membership/site"); entityView.setMethod(EntityView.Method.POST); Map<String,Object> params = new HashMap<String,Object>(); params.put("siteId", "site.with.dots"); params.put("memberRole", "role-foo"); params.put("userSearchValues", "user-foo"); Site site = new Site(); site.setId("site.with.dots"); EntityUser user = new EntityUser(); user.setEid("user-foo"); user.setId("user-foo"); user.setEmail("user-foo@school.edu"); Member member = new Member(); member.setUserId("user-foo"); member.setUserEid("user-foo"); Map<String,org.sakaiproject.authz.api.Member> members = new HashMap<String,org.sakaiproject.authz.api.Member>(); members.put("user-foo", member); site.setMembers(members); when(siteService.getSite("site.with.dots")).thenReturn(site); when(developerHelperService.getCurrentUserReference()).thenReturn("/user/me"); when(siteService.allowViewRoster("site.with.dots")).thenReturn(true); when(userEntityProvider.findUserFromSearchValue("user-foo")).thenReturn(user); when(userEntityProvider.getCurrentUser(null)).thenReturn(user); when(userEntityProvider.getUserById("user-foo")).thenReturn(user); ActionReturn result = provider.handleSiteMemberships(entityView, params); assertEquals(1, result.getEntitiesList().size()); assertEquals("user-foo::site:site.with.dots", result.getEntitiesList().get(0).getEntityId()); verify(siteService).saveSiteMembership(site); } @Test public void getGroupMembershipsPreservesDotsInGroupIdPathParams_GET() { EntityView entityView = new EntityView("/membership/group/group.with.dots.json"); entityView.setMethod(EntityView.Method.GET); Site site = new Site(); site.setId("site-foo"); Group group = new Group(site); group.setId("group.with.dots"); EntityUser user = new EntityUser(); user.setId("user-foo"); user.setEid("user-foo"); Map<String, org.sakaiproject.authz.api.Member> members = new HashMap<String, org.sakaiproject.authz.api.Member>(); Member member = new Member(); member.setUserId("user-foo"); member.setUserEid("user-foo"); members.put("user-foo", member); group.setMembers(members); when(siteService.findGroup("group.with.dots")).thenReturn(group); when(developerHelperService.getCurrentUserReference()).thenReturn("/user/me"); when(siteService.allowViewRoster("site-foo")).thenReturn(true); when(userEntityProvider.getUserById("user-foo")).thenReturn(user); List<EntityData> result = provider.getGroupMemberships(entityView, new HashMap<String, Object>()); assertEquals(1, result.size()); assertEquals("user-foo::group:group.with.dots", result.get(0).getEntityId()); } @Test public void getGroupMembershipsPreservesDotsInGroupIdQueryParams_GET() { EntityView entityView = new EntityView("/membership/group"); entityView.setMethod(EntityView.Method.GET); Map<String,Object> params = new HashMap<String,Object>(); params.put("groupId", "group.with.dots"); Site site = new Site(); site.setId("site-foo"); Group group = new Group(site); group.setId("group.with.dots"); EntityUser user = new EntityUser(); user.setId("user-foo"); user.setEid("user-foo"); Map<String, org.sakaiproject.authz.api.Member> members = new HashMap<String, org.sakaiproject.authz.api.Member>(); Member member = new Member(); member.setUserId("user-foo"); member.setUserEid("user-foo"); members.put("user-foo", member); group.setMembers(members); when(siteService.findGroup("group.with.dots")).thenReturn(group); when(developerHelperService.getCurrentUserReference()).thenReturn("/user/me"); when(siteService.allowViewRoster("site-foo")).thenReturn(true); when(userEntityProvider.getUserById("user-foo")).thenReturn(user); List<EntityData> result = provider.getGroupMemberships(entityView, params); assertEquals(1, result.size()); assertEquals("user-foo::group:group.with.dots", result.get(0).getEntityId()); } @Test public void getGroupMembershipsPreservesDotsInGroupIdPathParams_POST() throws PermissionException, IdUnusedException { EntityView entityView = new EntityView("/membership/group/group.with.dots.json"); entityView.setMethod(EntityView.Method.POST); Map<String,Object> params = new HashMap<String,Object>(); params.put("action", "remove"); params.put("userIds", "user-foo"); Site site = new Site(); site.setId("site-foo"); Group group = new Group(site); group.setId("group.with.dots"); ResourceProperties groupProperties = new BaseResourceProperties(); groupProperties.addProperty("group_prop_wsetup_created", "true"); group.setProperties(groupProperties); Map<String, org.sakaiproject.authz.api.Member> members = new HashMap<String, org.sakaiproject.authz.api.Member>(); Member member = new Member(); member.setUserId("user-foo"); member.setUserEid("user-foo"); members.put("user-foo", member); group.setMembers(members); when(siteService.findGroup("group.with.dots")).thenReturn(group); when(siteService.allowUpdateSite("site-foo")).thenReturn(true); when(userEntityProvider.findAndCheckUserId(null, "user-foo")).thenReturn("user-foo"); List<EntityData> result = provider.getGroupMemberships(entityView, params); verify(siteService).save(site); assertEquals(0, group.getMembers().size()); assertNull(result); } // groupId in query params not supported for getGroupMemberships() POSTs. So no test for that.... // entityExists() doesn't actually do anything so no test for that... @Test public void getEntityPreservesDotsInEntityIds() throws IdUnusedException { Site site = new Site(); site.setId("site.with.dots"); EntityUser user = new EntityUser(); user.setId("user-foo"); user.setEid("user-foo"); Member member = new Member(); member.setUserId("user-foo"); member.setUserEid("user-foo"); Map<String,org.sakaiproject.authz.api.Member> members = new HashMap<String,org.sakaiproject.authz.api.Member>(); members.put("user-foo", member); site.setMembers(members); when(siteService.getSite("site.with.dots")).thenReturn(site); when(developerHelperService.getCurrentUserReference()).thenReturn("/user/me"); when(developerHelperService.getCurrentUserId()).thenReturn("me"); when(siteService.allowViewRoster("site.with.dots")).thenReturn(true); when(userEntityProvider.getUserById("user-foo")).thenReturn(user); // This is the constructor EB actually uses when building an EntityReference to pass to getEntity() for a GET // request. For a dotted ID to work at all, an extension would have been specified on the originally requested // ID, e.g. /membership/user-foo:site:site.with.dots.json. If a content type isn't specified for a dotted ID, // e.g. /membership/user-foo:site:site.with.dots, the AccessProvider will blow up with a 406 b/c it thinks // "dots" is the requested content type. As long as the content type is expected, though, it will be stripped // off before the ID is handed to the EntityReference constructor EntityMember membership = (EntityMember) provider.getEntity(new EntityReference("membership", "user-foo::site:site.with.dots")); assertEquals("user-foo::site:site.with.dots", membership.getId()); assertEquals("user-foo", membership.getUserId()); } @Test public void getEntitiesPreservesDotsInSiteIds() throws IdUnusedException { Search search = new Search(); // Technically, just adding a content type extension, e.g. .json, would cause the location reference to // resolve, but nobody would actually do that b/c it doesn't affect the returned content type. search.addRestriction(new Restriction(CollectionResolvable.SEARCH_LOCATION_REFERENCE, "/site/site.with.dots")); Site site = new Site(); site.setId("site.with.dots"); EntityUser user = new EntityUser(); user.setId("user-foo"); user.setEid("user-foo"); Member member = new Member(); member.setUserId("user-foo"); member.setUserEid("user-foo"); Map<String,org.sakaiproject.authz.api.Member> members = new HashMap<String,org.sakaiproject.authz.api.Member>(); members.put("user-foo", member); site.setMembers(members); when(siteService.getSite("site.with.dots")).thenReturn(site); when(developerHelperService.getCurrentUserReference()).thenReturn("/user/me"); when(developerHelperService.getCurrentUserId()).thenReturn("me"); when(siteService.allowViewRoster("site.with.dots")).thenReturn(true); when(userEntityProvider.getUserById("user-foo")).thenReturn(user); List<EntityData> results = (List<EntityData>)provider.getEntities(null, search); assertEquals(1, results.size()); assertEquals("user-foo::site:site.with.dots", results.get(0).getEntityId()); } @Test public void getEntitiesPreservesDotsInGroupIds() throws IdUnusedException { Search search = new Search(); // Technically, just adding a content type extension, e.g. .json, would cause the location reference to // resolve, but nobody would actually do that b/c it doesn't affect the returned content type. search.addRestriction(new Restriction(CollectionResolvable.SEARCH_LOCATION_REFERENCE, "/group/group.with.dots")); Site site = new Site(); site.setId("site-foo"); Group group = new Group(site); group.setId("group.with.dots"); EntityUser user = new EntityUser(); user.setId("user-foo"); user.setEid("user-foo"); Map<String, org.sakaiproject.authz.api.Member> members = new HashMap<String, org.sakaiproject.authz.api.Member>(); Member member = new Member(); member.setUserId("user-foo"); member.setUserEid("user-foo"); members.put("user-foo", member); group.setMembers(members); when(siteService.findGroup("group.with.dots")).thenReturn(group); when(developerHelperService.getCurrentUserReference()).thenReturn("/user/me"); when(developerHelperService.getCurrentUserId()).thenReturn("me"); when(siteService.allowViewRoster("site-foo")).thenReturn(true); when(userEntityProvider.getUserById("user-foo")).thenReturn(user); List<EntityData> results = (List<EntityData>)provider.getEntities(null, search); assertEquals(1, results.size()); assertEquals("user-foo::group:group.with.dots", results.get(0).getEntityId()); } // we don't have a createEntityPreservesDotsInSiteIdQueryParams() test b/c passing a // org.sakaiproject.mock.domain.Member to createEntity() doesn't actually work. @Test public void createEntityPreservesDotsInSiteIdsInEntityMembers() throws IdUnusedException, PermissionException { EntityMember member = new EntityMember(); member.setUserId("user-foo"); member.setMemberRole("role-foo"); member.setActive(true); member.setLocationReference("/site/site.with.dots"); Site site = new Site(); site.setId("site.with.dots"); site.setJoinable(true); when(siteService.getSite("site.with.dots")).thenReturn(site); when(userEntityProvider.findAndCheckUserId("user-foo", "user-foo")).thenReturn("user-foo"); when(developerHelperService.getCurrentUserReference()).thenReturn("/user/me"); String entityId = provider.createEntity(null, member, new HashMap<String, Object>()); verify(siteService).saveSiteMembership(site); assertEquals("user-foo::site:site.with.dots", entityId); } @Test public void createEntityPreservesDotsInGroupIdsInEntityMembers() throws IdUnusedException, PermissionException { EntityMember member = new EntityMember(); member.setUserId("user-foo"); member.setMemberRole("role-foo"); member.setActive(true); member.setLocationReference("/group/group.with.dots"); Site site = new Site(); site.setId("site-foo"); site.setJoinable(true); Group group = new Group(site); group.setId("group.with.dots"); when(siteService.findGroup("group.with.dots")).thenReturn(group); when(userEntityProvider.findAndCheckUserId("user-foo", "user-foo")).thenReturn("user-foo"); when(developerHelperService.getCurrentUserReference()).thenReturn("/user/me"); String entityId = provider.createEntity(null, member, new HashMap<String, Object>()); verify(siteService).saveGroupMembership(site); assertEquals("user-foo::group:group.with.dots", entityId); } @Test public void deleteEntityPreservesDotsInSiteIds() throws IdUnusedException, PermissionException { EntityReference ref = new EntityReference("membership", "user-foo::site:site.with.dots"); Site site = new Site(); site.setId("site.with.dots"); EntityUser user = new EntityUser(); user.setId("user-foo"); user.setEid("user-foo"); Member member = new Member(); member.setUserId("user-foo"); member.setUserEid("user-foo"); Map<String,org.sakaiproject.authz.api.Member> members = new HashMap<String,org.sakaiproject.authz.api.Member>(); members.put("user-foo", member); site.setMembers(members); when(siteService.getSite("site.with.dots")).thenReturn(site); provider.deleteEntity(ref, new HashMap<String, Object>()); verify(siteService).saveSiteMembership(site); assertEquals(0, site.getMembers().size()); } @Test public void deleteEntityPreservesDotsInGroupIds() throws PermissionException, IdUnusedException { EntityReference ref = new EntityReference("membership", "user-foo::group:group.with.dots"); Site site = new Site(); site.setId("site-foo"); Group group = new Group(site); group.setId("group.with.dots"); EntityUser user = new EntityUser(); user.setId("user-foo"); user.setEid("user-foo"); Map<String, org.sakaiproject.authz.api.Member> members = new HashMap<String, org.sakaiproject.authz.api.Member>(); Member member = new Member(); member.setUserId("user-foo"); member.setUserEid("user-foo"); members.put("user-foo", member); group.setMembers(members); when(siteService.findGroup("group.with.dots")).thenReturn(group); provider.deleteEntity(ref, new HashMap<String, Object>()); verify(siteService).saveGroupMembership(site); assertEquals(0, group.getMembers().size()); } @Test public void joinCurrentUserToSitePreservesDotsInSiteIdPathParams_Format1() throws PermissionException, IdUnusedException { EntityView entityView = new EntityView("/membership/join/site/site.with.dots.json"); entityView.setMethod(EntityView.Method.POST); entityView.setViewKey(EntityView.VIEW_NEW); assertTrue(provider.joinCurrentUserToSite(entityView, new HashMap<String, Object>())); verify(siteService).join("site.with.dots"); } @Test public void joinCurrentUserToSitePreservesDotsInSiteIdPathParams_Format2() throws PermissionException, IdUnusedException { EntityView entityView = new EntityView("/membership/join/site.with.dots.json"); entityView.setMethod(EntityView.Method.POST); entityView.setViewKey(EntityView.VIEW_NEW); assertTrue(provider.joinCurrentUserToSite(entityView, new HashMap<String, Object>())); verify(siteService).join("site.with.dots"); } @Test public void joinCurrentUserToSitePreservesDotsInSiteIdQueryParams() throws PermissionException, IdUnusedException { EntityView entityView = new EntityView("/membership/join"); entityView.setMethod(EntityView.Method.POST); entityView.setViewKey(EntityView.VIEW_NEW); Map<String,Object> params = new HashMap<String,Object>(); params.put("siteId", "site.with.dots"); assertTrue(provider.joinCurrentUserToSite(entityView, params)); verify(siteService).join("site.with.dots"); } @Test public void unjoinCurrentUserToSitePreservesDotsInSiteIdPathParams_Format1() throws PermissionException, IdUnusedException { EntityView entityView = new EntityView("/membership/unjoin/site/site.with.dots.json"); entityView.setMethod(EntityView.Method.POST); entityView.setViewKey(EntityView.VIEW_NEW); assertTrue(provider.unjoinCurrentUserFromSite(entityView, new HashMap<String, Object>())); verify(siteService).unjoin("site.with.dots"); } @Test public void unjoinCurrentUserToSitePreservesDotsInSiteIdPathParams_Format2() throws PermissionException, IdUnusedException { EntityView entityView = new EntityView("/membership/unjoin/site.with.dots.json"); entityView.setMethod(EntityView.Method.POST); entityView.setViewKey(EntityView.VIEW_NEW); assertTrue(provider.unjoinCurrentUserFromSite(entityView, new HashMap<String, Object>())); verify(siteService).unjoin("site.with.dots"); } @Test public void unjoinCurrentUserToSitePreservesDotsInSiteIdQueryParams() throws PermissionException, IdUnusedException { EntityView entityView = new EntityView("/membership/unjoin"); entityView.setMethod(EntityView.Method.POST); entityView.setViewKey(EntityView.VIEW_NEW); Map<String,Object> params = new HashMap<String,Object>(); params.put("siteId", "site.with.dots"); assertTrue(provider.unjoinCurrentUserFromSite(entityView, params)); verify(siteService).unjoin("site.with.dots"); } }