/*
* Copyright (c) 2010 Lockheed Martin Corporation
*
* Licensed under the Apache 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.apache.org/licenses/LICENSE-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.eurekastreams.server.action.execution.profile;
import static org.eurekastreams.commons.test.IsEqualInternally.equalInternally;
import static org.junit.Assert.assertEquals;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.eurekastreams.commons.actions.context.Principal;
import org.eurekastreams.commons.actions.context.PrincipalActionContext;
import org.eurekastreams.commons.actions.context.TaskHandlerActionContext;
import org.eurekastreams.commons.actions.context.service.ServiceActionContext;
import org.eurekastreams.commons.server.UserActionRequest;
import org.eurekastreams.server.action.execution.stream.PostActivityExecutionStrategy;
import org.eurekastreams.server.action.request.profile.RequestForGroupMembershipRequest;
import org.eurekastreams.server.action.request.profile.SetFollowingStatusByGroupCreatorRequest;
import org.eurekastreams.server.action.request.profile.SetFollowingStatusRequest;
import org.eurekastreams.server.domain.EntityType;
import org.eurekastreams.server.domain.Follower;
import org.eurekastreams.server.domain.Follower.FollowerStatus;
import org.eurekastreams.server.persistence.DomainGroupMapper;
import org.eurekastreams.server.persistence.mappers.DomainMapper;
import org.eurekastreams.server.persistence.mappers.cache.AddCachedGroupFollower;
import org.eurekastreams.server.persistence.mappers.db.DeleteRequestForGroupMembership;
import org.eurekastreams.server.persistence.mappers.stream.GetDomainGroupsByShortNames;
import org.eurekastreams.server.search.modelview.DomainGroupModelView;
import org.eurekastreams.server.search.modelview.PersonModelView;
import org.eurekastreams.server.testing.TestContextCreator;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.jmock.integration.junit4.JUnit4Mockery;
import org.jmock.lib.legacy.ClassImposteriser;
import org.junit.Before;
import org.junit.Test;
import edu.emory.mathcs.backport.java.util.Collections;
/**
* Test class for the {@link SetFollowingGroupStatusExecution} class.
*
*/
public class SetFollowingGroupStatusExecutionTest
{
/** Test data. */
private static final long FOLLOWER_ID = 1L;
/** Test data. */
private static final String FOLLOWER_ACCOUNT = "jdoe";
/** Test data. */
private static final long ACTOR_ID = 1010L;
/** Test data. */
private static final String ACTOR_ACCOUNT = "smith";
/** Test data. */
private static final String GROUP_UNIQUEID = "thegroup";
/** Test data. */
private static final long GROUP_ID = 1000L;
/** Test data. */
private static final String GROUP_NAME = "The Group";
/**
* System under test.
*/
private SetFollowingGroupStatusExecution sut;
/**
* Context for building mock objects.
*/
private final Mockery context = new JUnit4Mockery()
{
{
setImposteriser(ClassImposteriser.INSTANCE);
}
};
/**
* Mock instance of GetDomainGroupsByShortNames.
*/
private final GetDomainGroupsByShortNames groupByShortNameMapperMock = context
.mock(GetDomainGroupsByShortNames.class);
/** Mapper to get person by id (for getting account id). */
private final DomainMapper<Long, PersonModelView> getPersonByIdMapper = context.mock(DomainMapper.class,
"getPersonByIdMapper");
/**
* Mapper to get the person id from an account id.
*/
private final DomainMapper<String, Long> getPersonIdFromAccountIdMapper = context.mock(DomainMapper.class,
"getPersonIdFromAccountIdMapper");
/**
* Mock instance of DomainGroupMapper.
*/
private final DomainGroupMapper groupMapperMock = context.mock(DomainGroupMapper.class);
/**
* Mock instance of AddCachedGroupFollower.
*/
private final AddCachedGroupFollower addCachedGroupFollowerMapperMock = context.mock(AddCachedGroupFollower.class);
/**
* Mock instance of GetGroupFollowerIds.
*/
private final DomainMapper<Long, List<Long>> groupFollowerIdsMapperMock = context.mock(DomainMapper.class,
"groupFollowerIdsMapperMock");
/**
* Mocked principal object.
*/
private final Principal principalMock = context.mock(Principal.class);
/** Mapper to remove group access requests. */
private final DeleteRequestForGroupMembership deleteRequestForGroupMembershipMapper = context
.mock(DeleteRequestForGroupMembership.class);
/**
* Delete cache key mapper.
*/
private final DomainMapper<Set<String>, Boolean> deleteCacheKeyMapper = context.mock(DomainMapper.class,
"deleteCacheKeyMapper");
/**
* Post an activity.
*/
private final PostActivityExecutionStrategy postActivity = context.mock(PostActivityExecutionStrategy.class);
/** Fixture: group. */
private final DomainGroupModelView group = context.mock(DomainGroupModelView.class, "group");
/** Fixture: follower ids (a mock to insure SUT doesn't alter it). */
private final List<Long> followerIds = context.mock(List.class, "followerIds");
/** Fixture: principal for user requesting the action. */
private Principal principal;
/**
* Method to setup the System Under Test.
*/
@Before
public void setUp()
{
principal = TestContextCreator.createPrincipal(ACTOR_ACCOUNT, ACTOR_ID);
sut = new SetFollowingGroupStatusExecution(groupByShortNameMapperMock, getPersonByIdMapper,
getPersonIdFromAccountIdMapper, groupMapperMock, addCachedGroupFollowerMapperMock,
groupFollowerIdsMapperMock, deleteRequestForGroupMembershipMapper, postActivity, deleteCacheKeyMapper);
context.checking(new Expectations()
{
{
allowing(group).getName();
will(returnValue(GROUP_NAME));
allowing(group).getEntityId();
will(returnValue(GROUP_ID));
allowing(followerIds).size();
will(returnValue(5));
}
});
}
/**
* Test the successful SetFollowing method when a group is followed.
*
* @throws Exception
* - on error.
*/
@Test
public void testSetFollowing() throws Exception
{
final RequestForGroupMembershipRequest delRequest = new RequestForGroupMembershipRequest(GROUP_ID, 1L);
context.checking(new Expectations()
{
{
oneOf(getPersonIdFromAccountIdMapper).execute(with(any(String.class)));
will(returnValue(FOLLOWER_ID));
oneOf(groupByShortNameMapperMock).fetchUniqueResult(with(any(String.class)));
will(returnValue(group));
oneOf(groupMapperMock).addFollower(FOLLOWER_ID, GROUP_ID);
oneOf(addCachedGroupFollowerMapperMock).execute(1L, GROUP_ID);
oneOf(deleteRequestForGroupMembershipMapper).execute(with(equalInternally(delRequest)));
oneOf(deleteCacheKeyMapper).execute(Collections.singleton("Per:1"));
oneOf(postActivity).execute(with(any(TaskHandlerActionContext.class)));
oneOf(groupFollowerIdsMapperMock).execute(GROUP_ID);
will(returnValue(followerIds));
}
});
SetFollowingStatusRequest currentRequest = new SetFollowingStatusRequest("ntaccount", "groupshortname",
EntityType.GROUP, false, Follower.FollowerStatus.FOLLOWING);
TaskHandlerActionContext<PrincipalActionContext> actionContext = TestContextCreator
.createTaskHandlerContextWithPrincipal(currentRequest, principal);
Serializable result = sut.execute(actionContext);
context.assertIsSatisfied();
assertEquals(5, result);
assertEquals(2, actionContext.getUserActionRequests().size());
}
/**
* Test the successful SetFollowing method when a group is followed.
*
* @throws Exception
* - on error.
*/
@Test
public void testSetFollowingWithDifferentRequestObject() throws Exception
{
final PersonModelView testFollower = new PersonModelView();
testFollower.setEntityId(FOLLOWER_ID);
final RequestForGroupMembershipRequest delRequest = new RequestForGroupMembershipRequest(GROUP_ID, 1L);
final PersonModelView person = context.mock(PersonModelView.class);
context.checking(new Expectations()
{
{
allowing(getPersonByIdMapper).execute(FOLLOWER_ID);
will(returnValue(person));
allowing(person).getAccountId();
oneOf(groupMapperMock).addFollower(FOLLOWER_ID, GROUP_ID);
oneOf(addCachedGroupFollowerMapperMock).execute(1L, GROUP_ID);
oneOf(deleteRequestForGroupMembershipMapper).execute(with(equalInternally(delRequest)));
oneOf(deleteCacheKeyMapper).execute(Collections.singleton("Per:1"));
oneOf(postActivity).execute(with(any(TaskHandlerActionContext.class)));
oneOf(groupFollowerIdsMapperMock).execute(GROUP_ID);
will(returnValue(followerIds));
}
});
SetFollowingStatusByGroupCreatorRequest currentRequest = new SetFollowingStatusByGroupCreatorRequest(
FOLLOWER_ID, GROUP_ID, Follower.FollowerStatus.FOLLOWING, "Group Name", false);
TaskHandlerActionContext<PrincipalActionContext> actionContext = TestContextCreator
.createTaskHandlerContextWithPrincipal(currentRequest, principal);
Serializable result = sut.execute(actionContext);
context.assertIsSatisfied();
assertEquals(5, result);
assertEquals(2, actionContext.getUserActionRequests().size());
}
/**
* Tests a user approving another to follow a private group.
*/
@Test
public void testFollowPrivateGroup()
{
SetFollowingStatusRequest request = new SetFollowingStatusRequest(FOLLOWER_ACCOUNT, GROUP_UNIQUEID,
EntityType.GROUP, false, FollowerStatus.FOLLOWING);
final RequestForGroupMembershipRequest mapperRequest1 = new RequestForGroupMembershipRequest(GROUP_ID,
FOLLOWER_ID);
context.checking(new Expectations()
{
{
allowing(getPersonIdFromAccountIdMapper).execute(FOLLOWER_ACCOUNT);
will(returnValue(FOLLOWER_ID));
allowing(groupByShortNameMapperMock).fetchUniqueResult(GROUP_UNIQUEID);
will(returnValue(group));
oneOf(groupMapperMock).addFollower(FOLLOWER_ID, GROUP_ID);
oneOf(addCachedGroupFollowerMapperMock).execute(FOLLOWER_ID, GROUP_ID);
oneOf(deleteRequestForGroupMembershipMapper).execute(with(equalInternally(mapperRequest1)));
will(returnValue(true));
oneOf(deleteCacheKeyMapper).execute(Collections.singleton("Per:1"));
oneOf(postActivity).execute(with(any(TaskHandlerActionContext.class)));
oneOf(groupFollowerIdsMapperMock).execute(GROUP_ID);
will(returnValue(followerIds));
}
});
TaskHandlerActionContext<PrincipalActionContext> actionContext = TestContextCreator
.createTaskHandlerContextWithPrincipal(request, principal);
Serializable result = sut.execute(actionContext);
context.assertIsSatisfied();
assertEquals(5, result);
assertEquals(3, actionContext.getUserActionRequests().size());
}
/**
* Test the setFollowing method when a group is unfollowed.
*
* @throws Exception
* - on error.
*/
@Test
public void testRemoveFollowing() throws Exception
{
context.checking(new Expectations()
{
{
oneOf(getPersonIdFromAccountIdMapper).execute(with(any(String.class)));
will(returnValue(FOLLOWER_ID));
oneOf(groupByShortNameMapperMock).fetchUniqueResult(with(any(String.class)));
will(returnValue(group));
oneOf(groupMapperMock).removeFollower(FOLLOWER_ID, GROUP_ID);
oneOf(groupFollowerIdsMapperMock).execute(GROUP_ID);
will(returnValue(followerIds));
}
});
SetFollowingStatusRequest currentRequest = new SetFollowingStatusRequest("ntaccount", "groupshortname",
EntityType.GROUP, false, Follower.FollowerStatus.NOTFOLLOWING);
TaskHandlerActionContext<PrincipalActionContext> actionContext = TestContextCreator
.createTaskHandlerContextWithPrincipal(currentRequest, principal);
Serializable result = sut.execute(actionContext);
context.assertIsSatisfied();
assertEquals(5, result);
assertEquals(3, actionContext.getUserActionRequests().size());
}
/**
* Test a failure case.
*
* @throws Exception
* - on error.
*/
@Test(expected = Exception.class)
public void testSetFollowingError() throws Exception
{
context.checking(new Expectations()
{
{
oneOf(getPersonIdFromAccountIdMapper).execute(with(any(String.class)));
will(throwException(new Exception("BAD")));
}
});
SetFollowingStatusRequest currentRequest = new SetFollowingStatusRequest("ntaccount", "groupshortname",
EntityType.GROUP, false, Follower.FollowerStatus.FOLLOWING);
ServiceActionContext currentContext = new ServiceActionContext(currentRequest, principalMock);
TaskHandlerActionContext currentTaskHandlerActionContext = new TaskHandlerActionContext<PrincipalActionContext>(
currentContext, new ArrayList<UserActionRequest>());
sut.execute(currentTaskHandlerActionContext);
context.assertIsSatisfied();
}
/**
* Test an unexpected following status.
*
* @throws Exception
* - on error.
*/
@Test
public void testOtherFollowing() throws Exception
{
context.checking(new Expectations()
{
{
oneOf(getPersonIdFromAccountIdMapper).execute(with(any(String.class)));
will(returnValue(FOLLOWER_ID));
oneOf(groupByShortNameMapperMock).fetchUniqueResult(with(any(String.class)));
will(returnValue(group));
oneOf(groupFollowerIdsMapperMock).execute(GROUP_ID);
will(returnValue(followerIds));
}
});
SetFollowingStatusRequest currentRequest = new SetFollowingStatusRequest("ntaccount", "groupshortname",
EntityType.GROUP, false, Follower.FollowerStatus.NOTSPECIFIED);
TaskHandlerActionContext<PrincipalActionContext> actionContext = TestContextCreator
.createTaskHandlerContextWithPrincipal(currentRequest, principal);
Serializable result = sut.execute(actionContext);
context.assertIsSatisfied();
assertEquals(5, result);
assertEquals(0, actionContext.getUserActionRequests().size());
}
}