/*
* Copyright (c) 2011 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.service.utility.authorization;
import static junit.framework.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.util.Collections;
import java.util.List;
import org.eurekastreams.server.domain.EntityType;
import org.eurekastreams.server.domain.stream.ActivityDTO;
import org.eurekastreams.server.domain.stream.StreamEntityDTO;
import org.eurekastreams.server.persistence.mappers.DomainMapper;
import org.eurekastreams.server.persistence.mappers.GetAllPersonIdsWhoHaveGroupCoordinatorAccess;
import org.eurekastreams.server.search.modelview.DomainGroupModelView;
import org.eurekastreams.server.search.modelview.PersonModelView;
import org.eurekastreams.server.service.actions.strategies.ActivityInteractionType;
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;
/**
* Tests ActivityInteractionAuthorizationStrategy.
*
* Note that post and comment authorization checks are almost alike; so testing both for each type of entity would be
* redundant. Thus testing post with person and comment with groups.
*/
public class ActivityInteractionAuthorizationStrategyTest
{
/** Test data. */
private static final long PERSON_STREAM_OWNER = 100L;
/** Test data. */
private static final long PERSON_COORD_ADMIN = 101L;
/** Test data. */
private static final long PERSON_MEMBER = 102L;
/** Test data. */
private static final long PERSON_ANYONE = 103L;
/** Test data. */
private static final long GROUP_ID = 104L;
/** Used for mocking objects. */
private final Mockery mockery = new JUnit4Mockery()
{
{
setImposteriser(ClassImposteriser.INSTANCE);
}
};
/** DAO to get person by ID. */
private final DomainMapper<Long, PersonModelView> getPersonByIdDAO = mockery.mock(DomainMapper.class,
"getPersonByIdDAO");
/** DAO to get group by ID. */
private final DomainMapper<Long, DomainGroupModelView> getGroupByIdDAO = mockery.mock(DomainMapper.class,
"getGroupByIdDAO");
/** DAO to get group follower IDs. */
private final DomainMapper<Long, List<Long>> groupFollowersDAO = mockery.mock(DomainMapper.class,
"groupFollowersDAO");
/** DAO to get all coordinators of a group. */
private final GetAllPersonIdsWhoHaveGroupCoordinatorAccess groupCoordDAO = mockery.mock(
GetAllPersonIdsWhoHaveGroupCoordinatorAccess.class, "groupCoordDAO");
/** Fixture: stream. */
private final StreamEntityDTO stream = mockery.mock(StreamEntityDTO.class, "stream");
/** Fixture: activity. */
private final ActivityDTO activity = mockery.mock(ActivityDTO.class, "activity");
/** SUT. */
private ActivityInteractionAuthorizationStrategy sut;
/**
* Setup before each test.
*/
@Before
public void setUp()
{
sut = new ActivityInteractionAuthorizationStrategy(getPersonByIdDAO, getGroupByIdDAO, groupFollowersDAO,
groupCoordDAO);
mockery.checking(new Expectations()
{
{
allowing(activity).getDestinationStream();
will(returnValue(stream));
}
});
}
// ---------- PERSON TESTS ----------
/**
* Sets up expectations common to all person stream tests.
*
* @return Person.
*/
private PersonModelView expectPersonStream()
{
final PersonModelView person = mockery.mock(PersonModelView.class);
mockery.checking(new Expectations()
{
{
allowing(stream).getType();
will(returnValue(EntityType.PERSON));
allowing(stream).getEntityId();
will(returnValue(PERSON_STREAM_OWNER));
allowing(getPersonByIdDAO).execute(PERSON_STREAM_OWNER);
will(returnValue(person));
}
});
return person;
}
// ---------- PERSON GENERAL VIEW TESTS ----------
/**
* Core of all users-in-general person stream tests.
*
* @param strict
* Use SUT's strict checking (must be true for ALL users).
* @return SUT result.
*/
private boolean corePersonStreamInGeneralTest(final boolean strict)
{
expectPersonStream();
boolean result = sut.authorize(activity, ActivityInteractionType.VIEW, strict);
mockery.assertIsSatisfied();
return result;
}
/**
* Test.
*/
@Test
public void testPersonStreamViewStrict()
{
assertTrue(corePersonStreamInGeneralTest(true));
}
/**
* Test.
*/
@Test
public void testPersonStreamViewRelaxed()
{
assertTrue(corePersonStreamInGeneralTest(false));
}
// ---------- PERSON GENERAL POST TESTS ----------
/**
* Core of all users-in-general user person stream action tests.
*
* @param streamAllowsAction
* If the stream should allow posting.
* @param strict
* Use SUT's strict checking (must be true for ALL users).
* @return Result of SUT.
*/
private boolean corePersonStreamInGeneralPostTest(final boolean streamAllowsAction, final boolean strict)
{
final PersonModelView person = expectPersonStream();
mockery.checking(new Expectations()
{
{
allowing(person).isStreamPostable();
will(returnValue(streamAllowsAction));
}
});
boolean result = sut.authorize(activity, ActivityInteractionType.POST, strict);
mockery.assertIsSatisfied();
return result;
}
/**
* Test.
*/
@Test
public void testPersonStreamPostAllowStrict()
{
assertTrue(corePersonStreamInGeneralPostTest(true, true));
}
/**
* Test.
*/
@Test
public void testPersonStreamPostAllowRelaxed()
{
assertTrue(corePersonStreamInGeneralPostTest(true, false));
}
/**
* Test.
*/
@Test
public void testPersonStreamPostForbidStrict()
{
assertFalse(corePersonStreamInGeneralPostTest(false, true));
}
/**
* Test.
*/
@Test
public void testPersonStreamPostForbidRelaxed()
{
assertFalse(corePersonStreamInGeneralPostTest(false, false));
}
// ---------- PERSON VIEW TESTS ----------
/**
* Core of all individual user person stream view tests.
*
* @param testUser
* User ID to run test with.
* @return Result of SUT.
*/
private boolean corePersonStreamViewTest(final long testUser)
{
expectPersonStream();
boolean result = sut.authorize(testUser, activity, ActivityInteractionType.VIEW);
mockery.assertIsSatisfied();
return result;
}
/**
* Test.
*/
@Test
public void testPersonStreamAnyoneView()
{
assertTrue(corePersonStreamViewTest(PERSON_ANYONE));
}
/**
* Test.
*/
@Test
public void testPersonStreamSelfView()
{
assertTrue(corePersonStreamViewTest(PERSON_STREAM_OWNER));
}
/**
* Test.
*/
@Test
public void testPersonStreamAdminView()
{
assertTrue(corePersonStreamViewTest(PERSON_COORD_ADMIN));
}
// ---------- PERSON POST TESTS ----------
/**
* Core of all individual user person stream action tests.
*
* @param testUser
* User ID to run test with.
* @param streamAllowsAction
* If the stream should allow posting.
* @return Result of SUT.
*/
private boolean corePersonStreamPostTest(final long testUser, final boolean streamAllowsAction)
{
final PersonModelView person = expectPersonStream();
mockery.checking(new Expectations()
{
{
allowing(person).isStreamPostable();
will(returnValue(streamAllowsAction));
}
});
boolean result = sut.authorize(testUser, activity, ActivityInteractionType.POST);
mockery.assertIsSatisfied();
return result;
}
/**
* Test.
*/
@Test
public void testPersonStreamAnyoneAllow()
{
assertTrue(corePersonStreamPostTest(PERSON_ANYONE, true));
}
/**
* Test.
*/
@Test
public void testPersonStreamAnyoneForbid()
{
assertFalse(corePersonStreamPostTest(PERSON_ANYONE, false));
}
/**
* Test.
*/
@Test
public void testPersonStreamSelfAllow()
{
assertTrue(corePersonStreamPostTest(PERSON_STREAM_OWNER, true));
}
/**
* Test.
*/
@Test
public void testPersonStreamSelfForbid()
{
assertTrue(corePersonStreamPostTest(PERSON_STREAM_OWNER, false));
}
/**
* Test.
*/
@Test
public void testPersonStreamAdminAllow()
{
assertTrue(corePersonStreamPostTest(PERSON_COORD_ADMIN, true));
}
/**
* Test.
*/
@Test
public void testPersonStreamAdminForbid()
{
assertFalse(corePersonStreamPostTest(PERSON_COORD_ADMIN, false));
}
// ---------- GROUP TESTS ----------
/**
* Sets up expectations common to all group stream tests.
*
* @param isStreamPublic
* If stream is public.
* @return The group.
*/
private DomainGroupModelView expectGroupStream(final boolean isStreamPublic)
{
final DomainGroupModelView group = mockery.mock(DomainGroupModelView.class);
mockery.checking(new Expectations()
{
{
allowing(stream).getType();
will(returnValue(EntityType.GROUP));
allowing(stream).getEntityId();
will(returnValue(GROUP_ID));
allowing(getGroupByIdDAO).execute(GROUP_ID);
will(returnValue(group));
allowing(groupFollowersDAO).execute(GROUP_ID);
will(returnValue(Collections.singletonList(PERSON_MEMBER)));
allowing(groupCoordDAO).execute(GROUP_ID);
will(returnValue(Collections.singleton(PERSON_COORD_ADMIN)));
allowing(group).isPublic();
will(returnValue(isStreamPublic));
}
});
return group;
}
// ---------- GROUP GENERAL VIEW TESTS ----------
/**
* Core of all users-in-general user group stream view tests.
*
* @param isStreamPublic
* If stream is public.
* @param strict
* Use SUT's strict checking (must be true for ALL users).
* @return Result of SUT.
*/
private boolean coreGroupStreamInGeneralViewTest(final boolean isStreamPublic, final boolean strict)
{
expectGroupStream(isStreamPublic);
boolean result = sut.authorize(activity, ActivityInteractionType.VIEW, strict);
mockery.assertIsSatisfied();
return result;
}
/**
* Test.
*/
@Test
public void testPublicGroupStreamViewStrict()
{
assertTrue(coreGroupStreamInGeneralViewTest(true, true));
}
/**
* Test.
*/
@Test
public void testPublicGroupStreamViewRelaxed()
{
assertTrue(coreGroupStreamInGeneralViewTest(true, false));
}
/**
* Test.
*/
@Test
public void testPrivateGroupStreamViewStrict()
{
assertFalse(coreGroupStreamInGeneralViewTest(false, true));
}
/**
* Test.
*/
@Test
public void testPrivateGroupStreamViewRelaxed()
{
assertTrue(coreGroupStreamInGeneralViewTest(false, false));
}
// ---------- GROUP VIEW TESTS ----------
/**
* Core of all individual user group stream view tests.
*
* @param testUser
* User ID to run test with.
* @param isStreamPublic
* If stream is public.
* @return Result of SUT.
*/
private boolean coreGroupStreamViewTest(final long testUser, final boolean isStreamPublic)
{
expectGroupStream(isStreamPublic);
boolean result = sut.authorize(testUser, activity, ActivityInteractionType.VIEW);
mockery.assertIsSatisfied();
return result;
}
/**
* Test.
*/
@Test
public void testPublicGroupAnyoneView()
{
assertTrue(coreGroupStreamViewTest(PERSON_ANYONE, true));
}
/**
* Test.
*/
@Test
public void testPublicGroupMemberView()
{
assertTrue(coreGroupStreamViewTest(PERSON_MEMBER, true));
}
/**
* Test.
*/
@Test
public void testPublicGroupCoordView()
{
assertTrue(coreGroupStreamViewTest(PERSON_COORD_ADMIN, true));
}
/**
* Test.
*/
@Test
public void testPrivateGroupAnyoneView()
{
assertFalse(coreGroupStreamViewTest(PERSON_ANYONE, false));
}
/**
* Test.
*/
@Test
public void testPrivateGroupMemberView()
{
assertTrue(coreGroupStreamViewTest(PERSON_MEMBER, false));
}
/**
* Test.
*/
@Test
public void testPrivateGroupCoordView()
{
assertTrue(coreGroupStreamViewTest(PERSON_COORD_ADMIN, false));
}
// ---------- GROUP GENERAL COMMENT TESTS ----------
/**
* Core of all users-in-general user group stream view tests.
*
* @param isStreamPublic
* If stream is public.
* @param streamAllowsAction
* If the stream should allow posting.
* @param strict
* Use SUT's strict checking (must be true for ALL users).
* @return Result of SUT.
*/
private boolean coreGroupStreamInGeneralCommentTest(final boolean isStreamPublic,
final boolean streamAllowsAction, final boolean strict)
{
final DomainGroupModelView group = expectGroupStream(isStreamPublic);
mockery.checking(new Expectations()
{
{
allowing(group).isCommentable();
will(returnValue(streamAllowsAction));
}
});
boolean result = sut.authorize(activity, ActivityInteractionType.COMMENT, strict);
mockery.assertIsSatisfied();
return result;
}
/**
* Test.
*/
@Test
public void testPublicGroupStreamCommentAllowStrict()
{
assertTrue(coreGroupStreamInGeneralCommentTest(true, true, true));
}
/**
* Test.
*/
@Test
public void testPublicGroupStreamCommentAllowRelaxed()
{
assertTrue(coreGroupStreamInGeneralCommentTest(true, true, false));
}
/**
* Test.
*/
@Test
public void testPrivateGroupStreamCommentAllowStrict()
{
assertFalse(coreGroupStreamInGeneralCommentTest(false, true, true));
}
/**
* Test.
*/
@Test
public void testPrivateGroupStreamCommentAllowRelaxed()
{
assertTrue(coreGroupStreamInGeneralCommentTest(false, true, false));
}
/**
* Test.
*/
@Test
public void testPublicGroupStreamCommentForbidStrict()
{
assertFalse(coreGroupStreamInGeneralCommentTest(true, false, true));
}
/**
* Test.
*/
@Test
public void testPublicGroupStreamCommentForbidRelaxed()
{
assertFalse(coreGroupStreamInGeneralCommentTest(true, false, false));
}
/**
* Test.
*/
@Test
public void testPrivateGroupStreamCommentForbidStrict()
{
assertFalse(coreGroupStreamInGeneralCommentTest(false, false, true));
}
/**
* Test.
*/
@Test
public void testPrivateGroupStreamCommentForbidRelaxed()
{
assertFalse(coreGroupStreamInGeneralCommentTest(false, false, false));
}
// ---------- GROUP COMMENT TESTS ----------
/**
* Core of all individual user group stream action tests.
*
* @param testUser
* User ID to run test with.
* @param isStreamPublic
* If stream is public.
* @param streamAllowsAction
* If the stream should allow posting.
* @return Result of SUT.
*/
private boolean coreGroupStreamActionTest(final long testUser, final boolean isStreamPublic,
final boolean streamAllowsAction)
{
final DomainGroupModelView group = expectGroupStream(isStreamPublic);
mockery.checking(new Expectations()
{
{
allowing(group).isCommentable();
will(returnValue(streamAllowsAction));
}
});
boolean result = sut.authorize(testUser, activity, ActivityInteractionType.COMMENT);
mockery.assertIsSatisfied();
return result;
}
/**
* Test.
*/
@Test
public void testPublicGroupAnyoneAllow()
{
assertTrue(coreGroupStreamActionTest(PERSON_ANYONE, true, true));
}
/**
* Test.
*/
@Test
public void testPublicGroupAnyoneForbid()
{
assertFalse(coreGroupStreamActionTest(PERSON_ANYONE, true, false));
}
/**
* Test.
*/
@Test
public void testPublicGroupMemberAllow()
{
assertTrue(coreGroupStreamActionTest(PERSON_MEMBER, true, true));
}
/**
* Test.
*/
@Test
public void testPublicGroupMemberForbid()
{
assertFalse(coreGroupStreamActionTest(PERSON_MEMBER, true, false));
}
/**
* Test.
*/
@Test
public void testPublicGroupCoordAllow()
{
assertTrue(coreGroupStreamActionTest(PERSON_COORD_ADMIN, true, true));
}
/**
* Test.
*/
@Test
public void testPublicGroupCoordForbid()
{
assertTrue(coreGroupStreamActionTest(PERSON_COORD_ADMIN, true, false));
}
/**
* Test.
*/
@Test
public void testPrivateGroupAnyoneAllow()
{
assertFalse(coreGroupStreamActionTest(PERSON_ANYONE, false, true));
}
/**
* Test.
*/
@Test
public void testPrivateGroupAnyoneForbid()
{
assertFalse(coreGroupStreamActionTest(PERSON_ANYONE, false, false));
}
/**
* Test.
*/
@Test
public void testPrivateGroupMemberAllow()
{
assertTrue(coreGroupStreamActionTest(PERSON_MEMBER, false, true));
}
/**
* Test.
*/
@Test
public void testPrivateGroupMemberForbid()
{
assertFalse(coreGroupStreamActionTest(PERSON_MEMBER, false, false));
}
/**
* Test.
*/
@Test
public void testPrivateGroupCoordAllow()
{
assertTrue(coreGroupStreamActionTest(PERSON_COORD_ADMIN, false, true));
}
/**
* Test.
*/
@Test
public void testPrivateGroupCoordForbid()
{
assertTrue(coreGroupStreamActionTest(PERSON_COORD_ADMIN, false, false));
}
// ---------- OTHER TESTS ----------
/**
* Test.
*/
@Test
public void testResource()
{
mockery.checking(new Expectations()
{
{
allowing(stream).getType();
will(returnValue(EntityType.RESOURCE));
}
});
boolean result = sut.authorize(PERSON_ANYONE, activity, ActivityInteractionType.COMMENT);
mockery.assertIsSatisfied();
assertTrue(result);
}
/**
* Test.
*/
@Test
public void testResourceGeneral()
{
mockery.checking(new Expectations()
{
{
allowing(stream).getEntityId();
allowing(stream).getType();
will(returnValue(EntityType.RESOURCE));
}
});
boolean result = sut.authorize(activity, ActivityInteractionType.COMMENT, true);
mockery.assertIsSatisfied();
assertTrue(result);
}
// ---------- ANOMALY TESTS ----------
/**
* Test.
*/
@Test
public void testUnhandledStreamType()
{
mockery.checking(new Expectations()
{
{
allowing(stream).getType();
will(returnValue(EntityType.APPLICATION));
}
});
boolean result = sut.authorize(PERSON_ANYONE, activity, ActivityInteractionType.COMMENT);
mockery.assertIsSatisfied();
assertFalse(result);
}
/**
* Test.
*/
@Test
public void testUnhandledStreamTypeGeneral()
{
mockery.checking(new Expectations()
{
{
allowing(stream).getEntityId();
allowing(stream).getType();
will(returnValue(EntityType.APPLICATION));
}
});
boolean result = sut.authorize(activity, ActivityInteractionType.COMMENT, false);
mockery.assertIsSatisfied();
assertFalse(result);
}
/**
* Test.
*/
@Test
public void testPersonError()
{
mockery.checking(new Expectations()
{
{
allowing(stream).getType();
will(returnValue(EntityType.PERSON));
allowing(stream).getEntityId();
will(throwException(new RuntimeException("BAD")));
}
});
boolean result = sut.authorize(PERSON_ANYONE, activity, ActivityInteractionType.COMMENT);
mockery.assertIsSatisfied();
assertFalse(result);
}
/**
* Test.
*/
@Test
public void testGroupError()
{
mockery.checking(new Expectations()
{
{
allowing(stream).getType();
will(returnValue(EntityType.GROUP));
allowing(stream).getEntityId();
will(throwException(new RuntimeException("BAD")));
}
});
boolean result = sut.authorize(PERSON_ANYONE, activity, ActivityInteractionType.POST);
mockery.assertIsSatisfied();
assertFalse(result);
}
}