package fr.ippon.tatami.service; import fr.ippon.tatami.AbstractCassandraTatamiTest; import fr.ippon.tatami.domain.User; import fr.ippon.tatami.security.AuthenticationService; import org.junit.Before; import org.junit.FixMethodOrder; import org.junit.Test; import org.junit.runners.MethodSorters; import org.mockito.ArgumentCaptor; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.springframework.test.util.ReflectionTestUtils; import javax.inject.Inject; import java.util.ArrayList; import java.util.List; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyCollection; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyList; import static org.mockito.Mockito.*; /** * @author Pierre Rust */ @SuppressWarnings("unchecked") @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class MailDigestServiceTest extends AbstractCassandraTatamiTest { @Mock MailService mailServiceMock; // Note : see the mail text in the console, you need to comment out the InjectMocks annotation // the test will fail but it's still useful during development if you want to work on the template @Inject @InjectMocks public MailDigestService mailDigestService; @Inject public UserService userService; @Inject public TimelineService timelineService; @Inject public StatusUpdateService statusUpdateService; @Inject public FriendshipService friendshipService; static final String DAILY_DIGEST_USER = "userWhoSubscribeToDigests@ippon.fr"; static final String WEEKLY_DIGEST_USER = "userWhoSubscribeToWeeklyDigests@ippon.fr"; @Before public void initMocks() { // we need to call initMocks explicitly because we use // SpringJUnit4ClassRunner instead of MockitoJUnitRunner // (to get spring injection before mockito mocking with @InjectMocks) MockitoAnnotations.initMocks(this); // reset users registrations : mockAuthenticationOnUserService(DAILY_DIGEST_USER); userService.updateDailyDigestRegistration(false); mockAuthenticationOnUserService(WEEKLY_DIGEST_USER); userService.updateWeeklyDigestRegistration(false); } @Test public void order_00_shouldNotGenerateDailyDigest() { log.debug("In shouldNotGenerateDailyDigest"); // Test data set has no user subscribed to weekly Digest // no mail should be sent. mailDigestService.dailyDigest(); verifyZeroInteractions(mailServiceMock); } @Test public void order_01_shouldNotGenerateWeeklyDigest() { log.debug("In shouldNotGenerateWeeklyDigest"); // Test data set has no user subscribed to weekly Digest // no mail should be sent. mailDigestService.dailyDigest(); verifyZeroInteractions(mailServiceMock); } @Test public void order_03_shouldGenerateDailyDigestNoMessage() { log.debug("In shouldGenerateDailyDigestNoMessage"); mockAuthenticationOnUserService(DAILY_DIGEST_USER); userService.updateDailyDigestRegistration(true); ArgumentCaptor<List> statuses = ArgumentCaptor.forClass(List.class); mailDigestService.dailyDigest(); verify(mailServiceMock).sendDailyDigestEmail(any(User.class), statuses.capture(), anyInt(), anyCollection()); assertThat(statuses.getValue().size() == 0, is(true)); } @Test public void order_04_shouldGenerateDailyDigestOneMessage() { log.debug("In shouldGenerateDailyDigestOneMessage"); mockAuthenticationOnUserService(DAILY_DIGEST_USER); userService.updateDailyDigestRegistration(true); mockAuthenticationOnFriendshipService(DAILY_DIGEST_USER); friendshipService.followUser("userWhoPostForDigests"); mockAuthenticationOnTimelineServiceWithACurrentUser("userWhoPostForDigests@ippon.fr"); mockAuthenticationOnStatusUpdateServiceWithACurrentUser("userWhoPostForDigests@ippon.fr"); String content = "voilà un message qui devrait se retrouver dans le digest ! "; statusUpdateService.postStatus(content, false, new ArrayList<String>()); ArgumentCaptor<List> statuses = ArgumentCaptor.forClass(List.class); mailDigestService.dailyDigest(); verify(mailServiceMock).sendDailyDigestEmail(any(User.class), statuses.capture(), anyInt(), anyCollection()); assertThat(statuses.getValue().size() == 1, is(true)); } @Test public void order_04_shouldGenerateDailyDigestWithTwoMessages() { log.debug("In shouldGenerateDailyDigestWithTwoMessages"); mockAuthenticationOnUserService(DAILY_DIGEST_USER); userService.updateDailyDigestRegistration(true); mockAuthenticationOnFriendshipService(DAILY_DIGEST_USER); friendshipService.followUser("userWhoPostForDigests"); mockAuthenticationOnTimelineServiceWithACurrentUser("userWhoPostForDigests@ippon.fr"); mockAuthenticationOnStatusUpdateServiceWithACurrentUser("userWhoPostForDigests@ippon.fr"); String content2 = "voilà un message 2 qui devrait se retrouver dans le digest ! "; statusUpdateService.postStatus(content2, false, new ArrayList<String>()); ArgumentCaptor<List> statuses = ArgumentCaptor.forClass(List.class); mailDigestService.dailyDigest(); verify(mailServiceMock).sendDailyDigestEmail(any(User.class), statuses.capture(), anyInt(), anyCollection()); assertThat(statuses.getValue().size() == 2, is(true)); } @Test public void order_05_shouldGenerateDailyDigestWithManyMessages() { log.debug("In shouldGenerateDailyDigestWithManyMessages"); mockAuthenticationOnUserService(DAILY_DIGEST_USER); userService.updateDailyDigestRegistration(true); mockAuthenticationOnFriendshipService(DAILY_DIGEST_USER); friendshipService.followUser("userWhoPostForDigests"); mockAuthenticationOnTimelineServiceWithACurrentUser("userWhoPostForDigests@ippon.fr"); mockAuthenticationOnStatusUpdateServiceWithACurrentUser("userWhoPostForDigests@ippon.fr"); for (int i = 0; i < 20; i++) { String content2 = "voilà un message " + i + " qui devrait se retrouver dans le digest ! "; statusUpdateService.postStatus(content2, false, new ArrayList<String>()); } ArgumentCaptor<List> statuses = ArgumentCaptor.forClass(List.class); mailDigestService.dailyDigest(); verify(mailServiceMock).sendDailyDigestEmail(any(User.class), statuses.capture(), anyInt(), anyCollection()); assertThat(statuses.getValue().size() == 10, is(true)); } @Test public void order_06_shouldGenerateWeeklyDigest() { log.debug("In shouldGenerateWeeklyDigest"); mockAuthenticationOnUserService(WEEKLY_DIGEST_USER); userService.updateWeeklyDigestRegistration(true); mailDigestService.weeklyDigest(); verify(mailServiceMock).sendWeeklyDigestEmail(any(User.class), anyList(), anyInt(), anyCollection(), anyCollection()); } @Test public void order_07_shouldGenerateWeeklyDigestNoMessage() { log.debug("In shouldGenerateWeeklyDigestNoMessage"); mockAuthenticationOnUserService(WEEKLY_DIGEST_USER); userService.updateWeeklyDigestRegistration(true); ArgumentCaptor<List> statuses = ArgumentCaptor.forClass(List.class); mailDigestService.weeklyDigest(); verify(mailServiceMock).sendWeeklyDigestEmail(any(User.class), statuses.capture(), anyInt(), anyCollection(), anyCollection()); assertThat(statuses.getValue().size() == 0, is(true)); } @Test public void order_08_shouldGenerateWeeklyDigestOneMessage() { log.debug("In shouldGenerateWeeklyDigestOneMessage"); mockAuthenticationOnUserService(WEEKLY_DIGEST_USER); userService.updateWeeklyDigestRegistration(true); mockAuthenticationOnFriendshipService(WEEKLY_DIGEST_USER); friendshipService.followUser("userWhoPostForDigests"); mockAuthenticationOnTimelineServiceWithACurrentUser("userWhoPostForDigests@ippon.fr"); mockAuthenticationOnStatusUpdateServiceWithACurrentUser("userWhoPostForDigests@ippon.fr"); String content = "voilà un message qui devrait se retrouver dans le digest ! "; statusUpdateService.postStatus(content, false, new ArrayList<String>()); ArgumentCaptor<List> statuses = ArgumentCaptor.forClass(List.class); mailDigestService.weeklyDigest(); verify(mailServiceMock).sendWeeklyDigestEmail(any(User.class), statuses.capture(), anyInt(), anyCollection(), anyCollection()); assertThat(statuses.getValue().size() == 1, is(true)); } @Test public void order_09_shouldGenerateWeeklyDigestWithTwoMessages() { log.debug("In shouldGenerateWeeklyDigestWithTwoMessages"); mockAuthenticationOnUserService(WEEKLY_DIGEST_USER); userService.updateWeeklyDigestRegistration(true); mockAuthenticationOnFriendshipService(WEEKLY_DIGEST_USER); friendshipService.followUser("userWhoPostForDigests"); mockAuthenticationOnTimelineServiceWithACurrentUser("userWhoPostForDigests@ippon.fr"); mockAuthenticationOnStatusUpdateServiceWithACurrentUser("userWhoPostForDigests@ippon.fr"); String content2 = "voilà un message 2 qui devrait se retrouver dans le digest ! "; statusUpdateService.postStatus(content2, false, new ArrayList<String>()); ArgumentCaptor<List> statuses = ArgumentCaptor.forClass(List.class); mailDigestService.weeklyDigest(); verify(mailServiceMock).sendWeeklyDigestEmail(any(User.class), statuses.capture(), anyInt(), anyCollection(), anyCollection()); assertThat(statuses.getValue().size() == 2, is(true)); } @Test public void order_10_shouldGenerateWeeklyDigestWithManyMessages() { log.debug("In shouldGenerateWeeklyDigestWithManyMessages"); mockAuthenticationOnUserService(WEEKLY_DIGEST_USER); userService.updateWeeklyDigestRegistration(true); mockAuthenticationOnFriendshipService(WEEKLY_DIGEST_USER); friendshipService.followUser("userWhoPostForDigests"); mockAuthenticationOnTimelineServiceWithACurrentUser("userWhoPostForDigests@ippon.fr"); mockAuthenticationOnStatusUpdateServiceWithACurrentUser("userWhoPostForDigests@ippon.fr"); for (int i = 0; i < 20; i++) { String content2 = "voilà un message " + i + " qui devrait se retrouver dans le digest ! "; statusUpdateService.postStatus(content2, false, new ArrayList<String>()); } ArgumentCaptor<List> statuses = ArgumentCaptor.forClass(List.class); mailDigestService.weeklyDigest(); verify(mailServiceMock).sendWeeklyDigestEmail(any(User.class), statuses.capture(), anyInt(), anyCollection(), anyCollection()); assertThat(statuses.getValue().size() == 10, is(true)); } private void mockAuthenticationOnUserService(String login) { User authenticateUser = constructAUser(login); AuthenticationService mockAuthenticationService = mock(AuthenticationService.class); when(mockAuthenticationService.getCurrentUser()).thenReturn(authenticateUser); ReflectionTestUtils.setField(userService, "authenticationService", mockAuthenticationService); } private void mockAuthenticationOnFriendshipService(String login) { User authenticateUser = constructAUser(login); AuthenticationService mockAuthenticationService = mock(AuthenticationService.class); when(mockAuthenticationService.getCurrentUser()).thenReturn(authenticateUser); ReflectionTestUtils.setField(friendshipService, "authenticationService", mockAuthenticationService); ReflectionTestUtils.setField(userService, "authenticationService", mockAuthenticationService); } private void mockAuthenticationOnTimelineServiceWithACurrentUser(String login) { User authenticateUser = constructAUser(login); AuthenticationService mockAuthenticationService = mock(AuthenticationService.class); when(mockAuthenticationService.getCurrentUser()).thenReturn(authenticateUser); ReflectionTestUtils.setField(timelineService, "authenticationService", mockAuthenticationService); } private void mockAuthenticationOnStatusUpdateServiceWithACurrentUser(String login) { User authenticateUser = constructAUser(login); AuthenticationService mockAuthenticationService = mock(AuthenticationService.class); when(mockAuthenticationService.getCurrentUser()).thenReturn(authenticateUser); ReflectionTestUtils.setField(statusUpdateService, "authenticationService", mockAuthenticationService); } }