/*
* Copyright (c) 2010-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.action.execution.notification;
import static org.junit.Assert.assertEquals;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eurekastreams.commons.test.EasyMatcher;
import org.eurekastreams.server.action.execution.notification.translator.NotificationTranslator;
import org.eurekastreams.server.action.request.notification.CreateNotificationsRequest;
import org.eurekastreams.server.action.request.notification.CreateNotificationsRequest.RequestType;
import org.eurekastreams.server.domain.EntityType;
import org.eurekastreams.server.domain.NotificationDTO;
import org.eurekastreams.server.domain.NotificationFilterPreference.Category;
import org.eurekastreams.server.domain.NotificationFilterPreferenceDTO;
import org.eurekastreams.server.domain.NotificationType;
import org.eurekastreams.server.persistence.mappers.DomainMapper;
import org.eurekastreams.server.persistence.mappers.db.GetNotificationFilterPreferencesByPeopleIds;
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;
/**
* Test suite for the {@link CreateNotificationsExecution} class.
*
*/
public class CreateNotificationsExecutionTest
{
/**
* System under test.
*/
private CreateNotificationsExecution sut;
/**
* Context for building mock objects.
*/
private final Mockery context = new JUnit4Mockery()
{
{
setImposteriser(ClassImposteriser.INSTANCE);
}
};
/** Mock comment translator. */
private final NotificationTranslator commentTranslator = context.mock(NotificationTranslator.class,
"commentTranslator");
/** Mock follower translator. */
private final NotificationTranslator followerTranslator = context.mock(NotificationTranslator.class,
"followerTranslator");
/** Fixture: populator. */
private final NotificationPopulator populator = context.mock(NotificationPopulator.class);
/** Mock application alert notifier. */
private final Notifier applicationNotifier = context.mock(Notifier.class, "appAlertNotifier");
/** Mock email notifier. */
private final Notifier emailNotifier = context.mock(Notifier.class, "emailNotifier");
/** The mock preferences mapper. */
private final GetNotificationFilterPreferencesByPeopleIds preferencesMapper = context
.mock(GetNotificationFilterPreferencesByPeopleIds.class);
/** Mapper to get people for determining locked users. */
private final DomainMapper<Long, PersonModelView> personMapper = context.mock(DomainMapper.class, "personMapper");
/** Fixture: person. */
private final PersonModelView person = context.mock(PersonModelView.class);
/** Fixture: person. */
private final PersonModelView person2 = context.mock(PersonModelView.class, "person2");
/** Fixture: filter. */
private final RecipientFilter filterAppAlert = context.mock(RecipientFilter.class, "filterAppAlert");
/** Fixture: filter. */
private final RecipientFilter filterEmail = context.mock(RecipientFilter.class, "filterEmail");
/**
* Setup the test.
*/
@Before
public final void setUp()
{
Map<RequestType, NotificationTranslator> translators = new HashMap<RequestType, NotificationTranslator>();
translators.put(RequestType.FOLLOWER, followerTranslator);
translators.put(RequestType.COMMENT, commentTranslator);
Map<String, Notifier> notifiers = new HashMap<String, Notifier>();
notifiers.put("APP_ALERT", applicationNotifier);
notifiers.put("EMAIL", emailNotifier);
Map<String, Iterable<RecipientFilter>> filters = new HashMap<String, Iterable<RecipientFilter>>();
filters.put("APP_ALERT", Collections.singletonList(filterAppAlert));
filters.put("EMAIL", Collections.singletonList(filterEmail));
Map<NotificationType, Category> notificationTypeToCategory = new HashMap<NotificationType, Category>();
notificationTypeToCategory.put(NotificationType.FOLLOW_PERSON, Category.FOLLOW_PERSON);
notificationTypeToCategory.put(NotificationType.COMMENT_TO_COMMENTED_POST, Category.COMMENT);
sut = new CreateNotificationsExecution(translators, populator, notifiers, preferencesMapper, personMapper,
notificationTypeToCategory, filters);
context.checking(new Expectations()
{
{
// make filters by default not reject anything
allowing(filterAppAlert).shouldFilter(with(any(PersonModelView.class)),
with(any(NotificationDTO.class)), with(any(String.class)));
will(returnValue(false));
allowing(filterEmail).shouldFilter(with(same(person)), with(any(NotificationDTO.class)),
with(any(String.class)));
will(returnValue(false));
}
});
}
/**
* Tests execute.
*
* @throws Exception
* Shouldn't.
*/
@SuppressWarnings("unchecked")
@Test
public void testExecute() throws Exception
{
final List<Long> recipients = Collections.singletonList(4L);
final NotificationDTO notification = new NotificationDTO(recipients, NotificationType.FOLLOW_PERSON, 1L, 2L,
EntityType.PERSON, 3L);
context.checking(new Expectations()
{
{
oneOf(followerTranslator).translate(1, 2, 3);
will(returnValue(Collections.singletonList(notification)));
allowing(personMapper).execute(with(equal(4L)));
will(returnValue(person));
oneOf(populator).populate(with(same(notification)));
oneOf(preferencesMapper).execute(with(any(List.class)));
will(returnValue(new ArrayList<NotificationFilterPreferenceDTO>()));
oneOf(applicationNotifier).notify(with(any(NotificationDTO.class)));
will(returnValue(null));
oneOf(emailNotifier).notify(with(any(NotificationDTO.class)));
}
});
CreateNotificationsRequest request = new CreateNotificationsRequest(RequestType.FOLLOWER, 1, 2, 3);
sut.execute(TestContextCreator.createTaskHandlerAsyncContext(request));
context.assertIsSatisfied();
}
/**
* Tests execute.
*
* @throws Exception
* Shouldn't.
*/
@SuppressWarnings("unchecked")
@Test
public void testExecuteNoFilters() throws Exception
{
final List<Long> recipients = Collections.singletonList(4L);
final NotificationDTO notification = new NotificationDTO(recipients, NotificationType.FOLLOW_PERSON, 1L, 2L,
EntityType.PERSON, 3L);
context.checking(new Expectations()
{
{
oneOf(followerTranslator).translate(1, 2, 3);
will(returnValue(Collections.singletonList(notification)));
allowing(personMapper).execute(with(equal(4L)));
will(returnValue(person));
oneOf(populator).populate(with(same(notification)));
oneOf(preferencesMapper).execute(with(any(List.class)));
will(returnValue(new ArrayList<NotificationFilterPreferenceDTO>()));
oneOf(emailNotifier).notify(with(any(NotificationDTO.class)));
}
});
sut = new CreateNotificationsExecution(Collections.singletonMap(RequestType.FOLLOWER, followerTranslator),
populator, Collections.singletonMap("EMAIL", emailNotifier), preferencesMapper, personMapper,
Collections.singletonMap(NotificationType.FOLLOW_PERSON, Category.FOLLOW_PERSON),
Collections.EMPTY_MAP);
CreateNotificationsRequest request = new CreateNotificationsRequest(RequestType.FOLLOWER, 1, 2, 3);
sut.execute(TestContextCreator.createTaskHandlerAsyncContext(request));
context.assertIsSatisfied();
}
/**
* Tests execute where users have notification filter preferences for this event type. Insures the preferences don't
* interact between notifiers.
*
* @throws Exception
* Shouldn't.
*/
@SuppressWarnings("unchecked")
@Test
public void testExecuteWithPrefernceFilteredResults() throws Exception
{
final List<Long> recipients = Arrays.asList(4L, 5L);
final NotificationDTO notification = new NotificationDTO(recipients,
NotificationType.COMMENT_TO_COMMENTED_POST, 1L, 2L, EntityType.PERSON, 3L);
final List<NotificationFilterPreferenceDTO> prefs = new ArrayList<NotificationFilterPreferenceDTO>();
prefs.add(new NotificationFilterPreferenceDTO(4L, "EMAIL", Category.COMMENT));
prefs.add(new NotificationFilterPreferenceDTO(5L, "APP_ALERT", Category.COMMENT));
context.checking(new Expectations()
{
{
oneOf(commentTranslator).translate(1, 2, 3);
will(returnValue(Collections.singletonList(notification)));
allowing(personMapper).execute(with(equal(4L)));
will(returnValue(person));
allowing(personMapper).execute(with(equal(5L)));
will(returnValue(person2));
oneOf(preferencesMapper).execute(with(any(List.class)));
will(returnValue(prefs));
oneOf(populator).populate(with(same(notification)));
allowing(filterEmail).shouldFilter(with(any(PersonModelView.class)), with(any(NotificationDTO.class)),
with(any(String.class)));
will(returnValue(false));
oneOf(applicationNotifier).notify(with(new EasyMatcher<NotificationDTO>()
{
@Override
protected boolean isMatch(final NotificationDTO inTestObject)
{
return inTestObject.getRecipientIds().contains(4L)
&& !inTestObject.getRecipientIds().contains(5L);
}
}));
will(returnValue(null));
oneOf(emailNotifier).notify(with(new EasyMatcher<NotificationDTO>()
{
@Override
protected boolean isMatch(final NotificationDTO inTestObject)
{
return inTestObject.getRecipientIds().contains(5L)
&& !inTestObject.getRecipientIds().contains(4L);
}
}));
}
});
CreateNotificationsRequest request = new CreateNotificationsRequest(RequestType.COMMENT, 1, 2, 3);
sut.execute(TestContextCreator.createTaskHandlerAsyncContext(request));
context.assertIsSatisfied();
}
/**
* Tests execute where one recipient gets filtered.
*
* @throws Exception
* Shouldn't.
*/
@SuppressWarnings("unchecked")
@Test
public void testExecuteWithFilteredRecipient() throws Exception
{
final List<Long> recipients = Arrays.asList(4L, 5L);
final NotificationDTO notification = new NotificationDTO(recipients, NotificationType.FOLLOW_PERSON, 1L, 2L,
EntityType.PERSON, 3L);
context.checking(new Expectations()
{
{
oneOf(followerTranslator).translate(1, 2, 3);
will(returnValue(Collections.singletonList(notification)));
allowing(personMapper).execute(with(equal(4L)));
will(returnValue(person));
allowing(personMapper).execute(with(equal(5L)));
will(returnValue(person2));
allowing(filterEmail).shouldFilter(person2, notification, "EMAIL");
will(returnValue(true));
oneOf(preferencesMapper).execute(with(any(List.class)));
will(returnValue(Collections.EMPTY_LIST));
oneOf(populator).populate(with(same(notification)));
oneOf(applicationNotifier).notify(with(new EasyMatcher<NotificationDTO>()
{
@Override
protected boolean isMatch(final NotificationDTO inTestObject)
{
return inTestObject.getRecipientIds().containsAll(Arrays.asList(4L, 5L));
}
}));
will(returnValue(null));
oneOf(emailNotifier).notify(with(new EasyMatcher<NotificationDTO>()
{
@Override
protected boolean isMatch(final NotificationDTO inTestObject)
{
return inTestObject.getRecipientIds().contains(4L)
&& !inTestObject.getRecipientIds().contains(5L);
}
}));
}
});
CreateNotificationsRequest request = new CreateNotificationsRequest(RequestType.FOLLOWER, 1, 2, 3);
sut.execute(TestContextCreator.createTaskHandlerAsyncContext(request));
context.assertIsSatisfied();
}
/**
* Tests execute with a notifier exception (for coverage).
*
* @throws Exception
* Shouldn't.
*/
@Test
@SuppressWarnings("unchecked")
public void testExecuteNotifierError() throws Exception
{
final List<Long> recipients = Collections.singletonList(4L);
final NotificationDTO notification = new NotificationDTO(recipients, NotificationType.FOLLOW_PERSON, 1L, 2L,
EntityType.PERSON, 3L);
context.checking(new Expectations()
{
{
oneOf(followerTranslator).translate(1, 2, 3);
will(returnValue(Collections.singletonList(notification)));
allowing(personMapper).execute(with(equal(4L)));
will(returnValue(person));
oneOf(populator).populate(with(same(notification)));
oneOf(preferencesMapper).execute(with(any(List.class)));
will(returnValue(new ArrayList<NotificationFilterPreferenceDTO>()));
oneOf(applicationNotifier).notify(with(any(NotificationDTO.class)));
will(returnValue(null));
oneOf(emailNotifier).notify(with(any(NotificationDTO.class)));
will(throwException(new Exception("BAD")));
}
});
CreateNotificationsRequest request = new CreateNotificationsRequest(RequestType.FOLLOWER, 1, 2, 3);
sut.execute(TestContextCreator.createTaskHandlerAsyncContext(request));
context.assertIsSatisfied();
}
/**
* Tests when the translator returns null.
*/
@Test
public void testExecuteTranslateNull()
{
context.checking(new Expectations()
{
{
oneOf(followerTranslator).translate(1, 2, 3);
will(returnValue(null));
}
});
CreateNotificationsRequest request = new CreateNotificationsRequest(RequestType.FOLLOWER, 1, 2, 3);
Serializable result = sut.execute(TestContextCreator.createTaskHandlerAsyncContext(request));
context.assertIsSatisfied();
assertEquals(Boolean.TRUE, result);
}
/**
* Tests when the translator returns an empty list.
*/
@Test
public void testExecuteTranslateNone()
{
context.checking(new Expectations()
{
{
oneOf(followerTranslator).translate(1, 2, 3);
will(returnValue(Collections.EMPTY_LIST));
}
});
CreateNotificationsRequest request = new CreateNotificationsRequest(RequestType.FOLLOWER, 1, 2, 3);
Serializable result = sut.execute(TestContextCreator.createTaskHandlerAsyncContext(request));
context.assertIsSatisfied();
assertEquals(Boolean.TRUE, result);
}
/**
* Tests when there is no translator for the request type.
*/
@Test
public void testExecuteUnlistedRequestType()
{
CreateNotificationsRequest request = new CreateNotificationsRequest(RequestType.FLAG_ACTIVITY, 1, 2, 3);
assertEquals(Boolean.FALSE, sut.execute(TestContextCreator.createTaskHandlerAsyncContext(request)));
context.assertIsSatisfied();
}
}