org.alfresco.repo.activities.AbstractSiteActivityTest.java Source code

Java tutorial

Introduction

Here is the source code for org.alfresco.repo.activities.AbstractSiteActivityTest.java

Source

/*
 * #%L
 * Alfresco Repository
 * %%
 * Copyright (C) 2005 - 2016 Alfresco Software Limited
 * %%
 * This file is part of the Alfresco software. 
 * If the software was purchased under a paid Alfresco license, the terms of 
 * the paid license agreement will prevail.  Otherwise, the software is 
 * provided under the following open source license terms:
 * 
 * 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/>.
 * #L%
 */
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.node.archive.NodeArchiveService;
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.SiteInfo;
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;
    private NodeArchiveService nodeArchiveService;

    //
    // 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");
        this.nodeArchiveService = (NodeArchiveService) applicationContext.getBean("nodeArchiveService");

        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 {
        SiteInfo siteInfo = siteService.getSite(siteId);
        if (siteInfo != null) {
            // delete site (and site's associated groups)
            siteService.deleteSite(siteId);
            nodeArchiveService.purgeArchivedNode(nodeArchiveService.getArchivedNode(siteInfo.getNodeRef()));
        }
    }

    @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");
    }
}