Alan Davis 92a49b48e6 Merged HEAD-BUG-FIX (4.3/Cloud) to HEAD (4.3/Cloud)
57072: Merged V4.2-BUG-FIX (4.2.1) to HEAD-BUG-FIX (Cloud/4.3)
      56559: Merged V4.1-BUG-FIX (4.1.7) to V4.2-BUG-FIX (4.2.1)
         56110: MNT-9104 : If username contains uppercase letters the action of joining a site will not be displayed in "My activities"
          Rename test SiteActivityTest to AbstractSiteActivityTest and FeedCleanerTest to AbstractFeedCleanerTest.
          Add case sensitivity tests SiteActivityTestCaseInsensitivity, SiteActivityTestCaseSensitivity, FeedCleanerTestCaseInsensitivity, FeedCleanerTestCaseSensitivity.
          Was implemented code, the activities dependent of 'user.name.caseSensitive' property.


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@61703 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
2014-02-11 19:14:16 +00:00

596 lines
20 KiB
Java

/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.activities;
import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.List;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.activities.feed.FeedGenerator;
import org.alfresco.repo.activities.feed.local.LocalFeedTaskProcessor;
import org.alfresco.repo.activities.post.lookup.PostLookup;
import org.alfresco.repo.management.subsystems.ChildApplicationContextFactory;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.permissions.AccessDeniedException;
import org.alfresco.repo.site.SiteModel;
import org.alfresco.service.cmr.activities.ActivityService;
import org.alfresco.service.cmr.activities.FeedControl;
import org.alfresco.service.cmr.security.MutableAuthenticationService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.cmr.site.SiteService;
import org.alfresco.service.cmr.site.SiteVisibility;
import org.alfresco.util.ApplicationContextHelper;
import org.alfresco.util.PropertyMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test;
import org.quartz.Scheduler;
import org.springframework.context.ApplicationContext;
/**
* Simple Activity Service unit test using site (membership) activities
*
* @author janv
*/
public abstract class AbstractSiteActivityTest
{
private static Log logger = LogFactory.getLog(AbstractSiteActivityTest.class);
private ApplicationContext applicationContext;
private SiteService siteService;
private ActivityService activityService;
private MutableAuthenticationService authenticationService;
private PersonService personService;
private PostLookup postLookup;
private FeedGenerator feedGenerator;
//
// Test config & data
//
// Location of activity type templates (for site activities)
private static final String TEST_TEMPLATES_LOCATION = "activities"; // assumes test-resources is on classpath
// Test users
private static final String ADMIN_USER = "admin";
private static final String ADMIN_PW = "admin";
private static String user1 = null;
private static String user2 = null;
private static String user3 = null;
private static String user4 = null;
private static final String USER_PW = "password";
// Test sites
private static String site1 = null;
private static String site2 = null;
private static String site3 = null;
// AppToolId for site membership activities
private static String appToolId = "siteService"; // refer to SiteService
private static boolean membersAddedUpdated = false;
private static boolean membersRemoved = false;
private static boolean controlsCreated = false;
public AbstractSiteActivityTest()
{
}
@Before
public void setUp() throws Exception
{
applicationContext = ApplicationContextHelper.getApplicationContext();
String testid = ""+System.currentTimeMillis();
// Let's shut down the scheduler so that we aren't competing with the scheduled versions of the post lookup and
// feed generator jobs
Scheduler scheduler = (Scheduler) applicationContext.getBean("schedulerFactory");
scheduler.shutdown();
// Get the required services
this.activityService = (ActivityService)applicationContext.getBean("activityService");
this.siteService = (SiteService)applicationContext.getBean("SiteService");
this.authenticationService = (MutableAuthenticationService)applicationContext.getBean("AuthenticationService");
this.personService = (PersonService)applicationContext.getBean("PersonService");
LocalFeedTaskProcessor feedProcessor = null;
// alternative: would need to add subsystem context to config location (see above)
//this.postLookup = (PostLookup)applicationContext.getBean("postLookup");
//this.feedGenerator = (FeedGenerator)applicationContext.getBean("feedGenerator");
//feedProcessor = (LocalFeedTaskProcessor)applicationContext.getBean("feedTaskProcessor");
ChildApplicationContextFactory activitiesFeed = (ChildApplicationContextFactory)applicationContext.getBean("ActivitiesFeed");
ApplicationContext activitiesFeedCtx = activitiesFeed.getApplicationContext();
this.postLookup = (PostLookup)activitiesFeedCtx.getBean("postLookup");
this.feedGenerator = (FeedGenerator)activitiesFeedCtx.getBean("feedGenerator");
feedProcessor = (LocalFeedTaskProcessor)activitiesFeedCtx.getBean("feedTaskProcessor");
List<String> templateSearchPaths = new ArrayList<String>(1);
templateSearchPaths.add(TEST_TEMPLATES_LOCATION);
feedProcessor.setTemplateSearchPaths(templateSearchPaths);
feedProcessor.setUseRemoteCallbacks(false);
site1 = "test_site1_" + testid;
site2 = "test_site2_" + testid;
site3 = "test_site3_" + testid;
user1 = "Test_User1_" + testid;
user2 = "Test_User2_" + testid;
user3 = "Test_User3_" + testid;
user4 = "Test_User4_" + testid;
// create users
login(ADMIN_USER, ADMIN_PW);
createUser(user1, USER_PW);
createUser(user2, USER_PW);
createUser(user3, USER_PW);
createUser(user4, USER_PW);
// create sites
// create public site
createSite(site1, true);
// create private sites
createSite(site2, false);
createSite(site3, false);
}
@After
public void tearDown() throws Exception
{
login(ADMIN_USER, ADMIN_PW);
deleteUser(user1);
deleteUser(user2);
deleteUser(user3);
deleteUser(user4);
deleteSite(site1);
deleteSite(site2);
deleteSite(site3);
membersAddedUpdated = false;
membersRemoved = false;
controlsCreated = false;
}
protected void createSite(String siteId, boolean isPublic) throws Exception
{
siteService.createSite("myPreset", siteId, "myTitle", "myDescription", (isPublic ? SiteVisibility.PUBLIC : SiteVisibility.PRIVATE));
if (logger.isDebugEnabled())
{
logger.debug("createdSite: " + siteId);
}
}
protected void deleteSite(String siteId) throws Exception
{
// delete site (and site's associated groups)
siteService.deleteSite(siteId);
}
@Test
//MNT-9104 If username contains uppercase letters the action of joining a site will not be displayed in "My activities"
public void testUserActivitiesOnSite() throws Exception
{
login(ADMIN_USER, ADMIN_PW);
addMembership(site1, user4, SiteModel.SITE_CONSUMER);
generateFeed();
login(user4, USER_PW);
getUserFeed(user4, site1, false, false, true, 1);
}
@Test
public void testGetSiteFeedsBefore() throws Exception
{
login(ADMIN_USER, ADMIN_PW);
getSiteFeed(site1, 0);
getSiteFeed(site2, 0); // site 2 is private, but accessible to admins
getSiteFeed(site3, 0); // site 3 is private, but accessible to admins
login(user4, USER_PW);
getSiteFeed(site1, 0); // site 1 is public, hence site feed is accessible to any user of the system
try
{
getSiteFeed(site2, 0); // site 2 is private, hence only accessible to members or admins
fail("Site feed for private site should not be accessible to non-admin / non-member");
}
catch (AccessDeniedException ade)
{
// ignore
}
try
{
getSiteFeed(site3, 0); // site 3 is private, hence only accessible to members or admins
fail("Site feed for private site should not be accessible to non-admin / non-member");
}
catch (AccessDeniedException ade)
{
// ignore
}
}
protected void getSiteFeed(String siteId, int expectedCount) throws Exception
{
assertEquals(expectedCount, activityService.getSiteFeedEntries(siteId).size());
}
@Test
public void testGetUserFeedsBefore() throws Exception
{
// as admin
login(ADMIN_USER, ADMIN_PW);
getUserFeed(user1, true, 0);
getUserFeed(user2, true, 0);
getUserFeed(user3, true, 0);
getUserFeed(user4, true, 0);
// as user1
login(user1, USER_PW);
getUserFeed(user1, false, 0);
// as user2
login(user2, USER_PW);
try
{
getUserFeed(user1, true, 0);
fail("User feed should only be accessible to user or an admin");
}
catch (AccessDeniedException ade)
{
// ignore
}
// as user1 - with filter args ...
login(user1, USER_PW);
getUserFeed(null, site1, false, false, false, 0);
getUserFeed(null, site2, false, false, false, 0);
getUserFeed(null, site3, false, false, false, 0);
getUserFeed(null, null, false, true, false, 0);
getUserFeed(null, null, false, false, true, 0);
getUserFeed(null, null, false, true, true, 0);
}
protected void getUserFeed(String userId, boolean isAdmin, int expectedCount) throws Exception
{
getUserFeed(userId, null, isAdmin, false, false, expectedCount);
}
protected void getUserFeed(String userId, String siteId, boolean isAdmin, boolean excludeThisUser, boolean excludeOtherUsers, int expectedCount) throws Exception
{
if (userId == null)
{
userId = AuthenticationUtil.getFullyAuthenticatedUser();
}
assertEquals(expectedCount, activityService.getUserFeedEntries(userId, siteId, excludeThisUser, excludeOtherUsers, null, null).size());
}
@Test
public void testUserFeedControls() throws Exception
{
if (! controlsCreated)
{
// user 1 opts out of all activities for site 1
login(user1, USER_PW);
addFeedControl(site1, null);
// user 2 opts out of site membership activities (across all sites)
login(user2, USER_PW);
addFeedControl(null, appToolId);
// user 3 opts out of site membership activities for site 1 only
login(user3, USER_PW);
addFeedControl(site1, appToolId);
// TODO add more here, once we have more appToolIds
controlsCreated = true;
}
}
@Test
public void testAddAndUpdateMemberships() throws Exception
{
if (! membersAddedUpdated)
{
login(ADMIN_USER, ADMIN_PW);
addAndUpdateMemberships(site1, true); // public site, include all users
addAndUpdateMemberships(site2, true); // private site, include all users
addAndUpdateMemberships(site3, false); // private site, do not include user 4
generateFeed();
membersAddedUpdated = true;
}
}
@Test
public void testGetSiteFeedsAfterAddAndUpdateMemberships() throws Exception
{
testAddAndUpdateMemberships();
login(ADMIN_USER, ADMIN_PW);
getSiteFeed(site1, 8); // 8 = 4 users, each with 1 join, 1 role change
getSiteFeed(site2, 8); // 8 = 4 users, each with 1 join, 1 role change
getSiteFeed(site3, 6); // 6 = 3 users, each with 1 join, 1 role change (not user 4)
login(user4, USER_PW);
getSiteFeed(site1, 8);
getSiteFeed(site2, 8); // site 2 is private, user 4 is a member
try
{
getSiteFeed(site3, 0); // site 3 is private, user 4 is not a member
fail("Site feed for private site should not be accessible to non-admin / non-member");
}
catch (AccessDeniedException ade)
{
// ignore
}
}
@Test
public void testRemoveMemberships() throws Exception
{
if (! membersRemoved)
{
testAddAndUpdateMemberships();
login(ADMIN_USER, ADMIN_PW);
removeMemberships(site1, true);
removeMemberships(site2, true);
removeMemberships(site3, false);
generateFeed();
membersRemoved = true;
}
}
protected void addAndUpdateMemberships(String siteId, boolean includeUser4) throws Exception
{
// add member -> join site
addMembership(siteId, user1, SiteModel.SITE_CONSUMER);
addMembership(siteId, user2, SiteModel.SITE_MANAGER);
addMembership(siteId, user3, SiteModel.SITE_COLLABORATOR);
if (includeUser4) { addMembership(siteId, user4, SiteModel.SITE_CONSUMER); }
// update member -> change role
updateMembership(siteId, user1, SiteModel.SITE_MANAGER);
updateMembership(siteId, user2, SiteModel.SITE_COLLABORATOR);
updateMembership(siteId, user3, SiteModel.SITE_CONSUMER);
if (includeUser4) { updateMembership(siteId, user4, SiteModel.SITE_COLLABORATOR); }
}
protected void removeMemberships(String siteId, boolean includeUser4) throws Exception
{
// remove member -> leave site
removeMembership(siteId, user1);
removeMembership(siteId, user2);
removeMembership(siteId, user3);
if (includeUser4) { removeMembership(siteId, user4); }
}
private void addFeedControl(String siteId, String appToolId) throws Exception
{
// set feed control for current user
activityService.setFeedControl(new FeedControl(siteId, appToolId));
}
@Test
public void testGetSiteFeedsAfterRemoveMemberships() throws Exception
{
testAddAndUpdateMemberships();
testRemoveMemberships();
login(ADMIN_USER, ADMIN_PW);
getSiteFeed(site1, 12); // 12 = 4 users, each with 1 join, 1 role change, 1 leave
getSiteFeed(site2, 12); // 12 = 4 users, each with 1 join, 1 role change, 1 leave
getSiteFeed(site3, 9); // 9 = 3 users, each with 1 join, 1 role change, 1 leave (not user 4)
login(user4, USER_PW);
getSiteFeed(site1, 12);
try
{
getSiteFeed(site2, 0); // site 2 is private, user 4 is no longer a member
fail("Site feed for private site should not be accessible to non-admin / non-member");
}
catch (AccessDeniedException ade)
{
// ignore
}
try
{
getSiteFeed(site3, 0); // site 3 is private, user 4 was never a member
fail("Site feed for private site should not be accessible to non-admin / non-member");
}
catch (AccessDeniedException ade)
{
// ignore
}
}
@Test
public void testGetUserFeedsAfter() throws Exception
{
testUserFeedControls();
testAddAndUpdateMemberships();
testRemoveMemberships();
// as admin
login(ADMIN_USER, ADMIN_PW);
// site 1, with 4 users, each with 1 join, 1 role change = 4x2 = 8
// site 2, with 4 users, each with 1 join, 1 role change = 4x2 = 8
// site 3, with 3 users, each with 1 join, 1 role change = 3x2 = 6
// user 1 belongs to 3 sites = (2x8)+(1x6) = 22
// user 2 belongs to 3 sites = (2x8)+(1x6) = 22
// user 3 belongs to 3 sites = (2x8)+(1x6) = 22
// user 4 belongs to 2 sites = (2x8) = 16
getUserFeed(user1, true, 14); // 14 = (22 - 8) due to feed control - exclude site 1
getUserFeed(user2, true, 0); // 0 = due to feed control - exclude site membership activities (across all sites)
getUserFeed(user3, true, 14); // 14 = (22 - 8) due to feed control - exclude site membership activities for site 1
getUserFeed(user4, true, 16); // 16 = no feed control
// as user1
login(user1, USER_PW);
getUserFeed(user1, false, 14);
// as user2
login(user2, USER_PW);
try
{
getUserFeed(user1, true, 14);
fail("User feed should only be accessible to user or an admin");
}
catch (AccessDeniedException ade)
{
// ignore
}
// as user1 - with filter args ...
login(user1, USER_PW);
getUserFeed(null, site1, false, false, false, 0);
getUserFeed(null, site2, false, false, false, 8);
getUserFeed(null, site3, false, false, false, 6);
getUserFeed(null, null, false, false, false, 14); // no filter
getUserFeed(null, null, false, true, false, 12); // exclude any from user1
getUserFeed(null, null, false, false, true, 2); // exclude all except user1
getUserFeed(null, null, false, true, true, 0); // exclude all (NOOP)
// TODO - add more (eg. other non-admin user activities)
}
private void addMembership(String siteId, String userName, String role) throws Exception
{
updateMembership(siteId, userName, role);
}
private void updateMembership(String siteId, String userName, String role) throws Exception
{
siteService.setMembership(siteId, userName, role);
}
private void removeMembership(String siteId, String userName) throws Exception
{
siteService.removeMembership(siteId, userName);
}
protected void createUser(String userName, String password)
{
if (authenticationService.authenticationExists(userName) == false)
{
authenticationService.createAuthentication(userName, password.toCharArray());
PropertyMap ppOne = new PropertyMap(4);
ppOne.put(ContentModel.PROP_USERNAME, userName);
ppOne.put(ContentModel.PROP_FIRSTNAME, "firstName");
ppOne.put(ContentModel.PROP_LASTNAME, "lastName");
ppOne.put(ContentModel.PROP_EMAIL, "email@email.com");
ppOne.put(ContentModel.PROP_JOBTITLE, "jobTitle");
personService.createPerson(ppOne);
}
}
protected void deleteUser(String userName)
{
personService.deletePerson(userName);
}
private void login(String username, String password)
{
AuthenticationUtil.setFullyAuthenticatedUser(username);
}
private void generateFeed() throws Exception
{
postLookup.execute();
feedGenerator.execute();
}
@AfterClass
// remove system "user.name.caseSensitive" property
public static void afterClass()
{
System.clearProperty("user.name.caseSensitive");
}
}