Package in.partake.daemon.impl

Source Code of in.partake.daemon.impl.SendMessageEnvelopeTaskTest

package in.partake.daemon.impl;

import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import in.partake.app.PartakeApp;
import in.partake.app.PartakeTestApp;
import in.partake.base.DateTime;
import in.partake.base.PartakeException;
import in.partake.base.TimeUtil;
import in.partake.controller.AbstractPartakeControllerTest;
import in.partake.model.IPartakeDAOs;
import in.partake.model.UserEx;
import in.partake.model.access.Transaction;
import in.partake.model.dao.DAOException;
import in.partake.model.dao.PartakeConnection;
import in.partake.model.dto.Event;
import in.partake.model.dto.EventTicket;
import in.partake.model.dto.MessageEnvelope;
import in.partake.model.dto.TwitterMessage;
import in.partake.model.dto.UserNotification;
import in.partake.model.dto.auxiliary.MessageDelivery;
import in.partake.model.dto.auxiliary.NotificationType;
import in.partake.model.fixture.TestDataProviderConstants;
import in.partake.view.util.Helper;

import java.io.IOException;
import java.util.List;
import java.util.UUID;

import org.junit.Before;
import org.junit.Test;

import twitter4j.TwitterException;
import twitter4j.internal.http.HttpResponse;

public class SendMessageEnvelopeTaskTest extends AbstractPartakeControllerTest implements TestDataProviderConstants {
    private static final String TWITTER_MESSAGE_WILLFAIL_MESSAGE = "Sending this message should fail";

    @Before
    public void setUp() throws Exception {
        super.setUp();

        PartakeTestApp.getTestService().setDefaultFixtures();

        // Removes MessageEnvelope.
        new Transaction<Void>() {
            @Override
            protected Void doExecute(PartakeConnection con, IPartakeDAOs daos) throws DAOException, PartakeException {
                daos.getMessageEnvelopeAccess().truncate(con);
                return null;
            }
        }.execute();

        PartakeTestApp.instance().reinitializeTwitterService();
    }

    @Test
    public void sendEmpty() throws Exception {
        new SendMessageEnvelopeTask().run();
    }

    @Test
    public void sendTwitterMessage() throws Exception {
        UUID uuid = UUID.randomUUID();
        MessageEnvelope envelope = MessageEnvelope.createForTwitterMessage(uuid.toString(), TWITTER_MESSAGE_INQUEUE_ID, null);
        queueEnvelope(envelope);

        new SendMessageEnvelopeTask().run();

        List<MessageEnvelope> rest = loadEnvelopes();
        assertThat(rest.isEmpty(), is(true));
        verify(PartakeApp.getTwitterService()).updateStatus(anyString(), anyString(), eq("message"));

        assertThat(loadTwitterMessage(TWITTER_MESSAGE_INQUEUE_ID).getDelivery(), is(MessageDelivery.SUCCESS));
    }

    @Test
    public void sendTwitterMessageBeforeTryAfter() throws Exception {
        DateTime now = TimeUtil.getCurrentDateTime();
        TimeUtil.setCurrentDateTime(now);

        String twitterMessageId = UUID.randomUUID().toString();
        TwitterMessage message = new TwitterMessage(twitterMessageId, DEFAULT_USER_ID, TWITTER_MESSAGE_WILLFAIL_MESSAGE, MessageDelivery.INQUEUE, new DateTime(0), null);
        storeTwitterMessage(message);

        UUID envelopeId = UUID.randomUUID();
        MessageEnvelope envelope = new MessageEnvelope(envelopeId.toString(), null, twitterMessageId, null, 0, null, null, now.nHourAfter(1), now, null);
        queueEnvelope(envelope);

        new SendMessageEnvelopeTask().run();

        // |modified| should not be changed.
        MessageEnvelope modified = loadEnvelope(envelopeId.toString());
        assertThat(modified.getNumTried(), is(0));
        assertThat(modified.getLastTriedAt(), is(nullValue()));
    }

    @Test
    public void sendTwitterMessageWithTwitterException() throws Exception {
        DateTime now = TimeUtil.getCurrentDateTime();
        TimeUtil.setCurrentDateTime(now);

        HttpResponse res = mock(HttpResponse.class);
        doReturn(null).when(res).getResponseHeader(eq("X-RateLimit-Limit"));
        doReturn(null).when(res).getResponseHeader(eq("X-RateLimit-Remaining"));
        doReturn(null).when(res).getResponseHeader(eq("X-RateLimit-Reset"));
        doThrow(new TwitterException("message", res)).when(PartakeApp.getTwitterService()).updateStatus(anyString(), anyString(), eq(TWITTER_MESSAGE_WILLFAIL_MESSAGE));

        String twitterMessageId = UUID.randomUUID().toString();
        TwitterMessage message = new TwitterMessage(twitterMessageId, DEFAULT_USER_ID, TWITTER_MESSAGE_WILLFAIL_MESSAGE, MessageDelivery.INQUEUE, new DateTime(0), null);
        storeTwitterMessage(message);

        UUID envelopeId = UUID.randomUUID();
        MessageEnvelope envelope = MessageEnvelope.createForTwitterMessage(envelopeId.toString(), twitterMessageId, null);
        queueEnvelope(envelope);

        new SendMessageEnvelopeTask().run();

        MessageEnvelope modified = loadEnvelope(envelopeId.toString());
        assertThat(modified.getNumTried(), is(1));
        assertThat(modified.getLastTriedAt(), is(now));
        assertThat(modified.getTryAfter(), is(now.nSecAfter(600)));
    }

    @Test
    public void sendTwitterMessageWithTwitterExceptionCausedByNetworkError() throws Exception {
        DateTime now = TimeUtil.getCurrentDateTime();
        TimeUtil.setCurrentDateTime(now);

        // When |cause| is IOException, TwitterException thinks it's a network error.
        doThrow(new TwitterException("message", new IOException(""))).when(PartakeApp.getTwitterService()).updateStatus(anyString(), anyString(), eq(TWITTER_MESSAGE_WILLFAIL_MESSAGE));

        String twitterMessageId = UUID.randomUUID().toString();
        TwitterMessage message = new TwitterMessage(twitterMessageId, DEFAULT_USER_ID, TWITTER_MESSAGE_WILLFAIL_MESSAGE, MessageDelivery.INQUEUE, new DateTime(0), null);
        storeTwitterMessage(message);

        UUID envelopeId = UUID.randomUUID();
        MessageEnvelope envelope = MessageEnvelope.createForTwitterMessage(envelopeId.toString(), twitterMessageId, null);
        queueEnvelope(envelope);

        new SendMessageEnvelopeTask().run();

        MessageEnvelope modified = loadEnvelope(envelopeId.toString());
        assertThat(modified.getNumTried(), is(1));
        assertThat(modified.getLastTriedAt(), is(now));
        assertThat(modified.getTryAfter(), is(now.nSecAfter(600))); // 5 min later
    }

    @Test
    public void sendTwitterMessageWithTwitterExceptionExceededLimit() throws Exception {
        DateTime now = TimeUtil.getCurrentDateTime();
        TimeUtil.setCurrentDateTime(now);

        HttpResponse res = mock(HttpResponse.class);
        doReturn(400).when(res).getStatusCode();
        doReturn("100").when(res).getResponseHeader(eq("X-RateLimit-Limit"));
        doReturn("100").when(res).getResponseHeader(eq("X-RateLimit-Remaining"));
        doReturn("1").when(res).getResponseHeader(eq("X-RateLimit-Reset"));
        doThrow(new TwitterException("message", res)).when(PartakeApp.getTwitterService()).updateStatus(anyString(), anyString(), eq(TWITTER_MESSAGE_WILLFAIL_MESSAGE));

        String twitterMessageId = UUID.randomUUID().toString();
        TwitterMessage message = new TwitterMessage(twitterMessageId, DEFAULT_USER_ID, TWITTER_MESSAGE_WILLFAIL_MESSAGE, MessageDelivery.INQUEUE, new DateTime(0), null);
        storeTwitterMessage(message);

        UUID envelopeId = UUID.randomUUID();
        MessageEnvelope envelope = MessageEnvelope.createForTwitterMessage(envelopeId.toString(), twitterMessageId, null);
        queueEnvelope(envelope);

        new SendMessageEnvelopeTask().run();

        MessageEnvelope modified = loadEnvelope(envelopeId.toString());
        assertThat(modified.getNumTried(), is(1));
        assertThat(modified.getLastTriedAt(), is(now));
        // TODO: We should think how to test this.
        // assertThat(modified.getTryAfter(), is(now.nSecAfter(1))); // 1 sec after.
    }

    @Test
    public void sendTwitterMessageWithTwitterExceptionCausedByUnauthorized() throws Exception {
        DateTime now = TimeUtil.getCurrentDateTime();
        TimeUtil.setCurrentDateTime(now);

        HttpResponse res = mock(HttpResponse.class);
        doReturn(401).when(res).getStatusCode();
        doReturn(null).when(res).getResponseHeader(eq("X-RateLimit-Limit"));
        doReturn(null).when(res).getResponseHeader(eq("X-RateLimit-Remaining"));
        doReturn(null).when(res).getResponseHeader(eq("X-RateLimit-Reset"));
        doThrow(new TwitterException("message", res)).when(PartakeApp.getTwitterService()).updateStatus(anyString(), anyString(), eq(TWITTER_MESSAGE_WILLFAIL_MESSAGE));

        String twitterMessageId = UUID.randomUUID().toString();
        TwitterMessage message = new TwitterMessage(twitterMessageId, DEFAULT_USER_ID, TWITTER_MESSAGE_WILLFAIL_MESSAGE, MessageDelivery.INQUEUE, new DateTime(0), null);
        storeTwitterMessage(message);

        UUID envelopeId = UUID.randomUUID();
        MessageEnvelope envelope = MessageEnvelope.createForTwitterMessage(envelopeId.toString(), twitterMessageId, null);
        queueEnvelope(envelope);

        new SendMessageEnvelopeTask().run();

        // Message Envelop should be removed.
        MessageEnvelope modified = loadEnvelope(envelopeId.toString());
        assertThat(modified, is(nullValue()));

        // User should be unauthorized.
        UserEx user = loadUserEx(DEFAULT_USER_ID);
        assertThat(user.getTwitterLinkage().getAccessToken(), is(nullValue()));
        assertThat(user.getTwitterLinkage().getAccessTokenSecret(), is(nullValue()));
    }

    @Test
    public void sendTwitterMessageWithInvalidId() throws Exception {
        DateTime now = TimeUtil.getCurrentDateTime();
        TimeUtil.setCurrentDateTime(now);

        HttpResponse res = mock(HttpResponse.class);
        doReturn(null).when(res).getResponseHeader(eq("X-RateLimit-Limit"));
        doReturn(null).when(res).getResponseHeader(eq("X-RateLimit-Remaining"));
        doReturn(null).when(res).getResponseHeader(eq("X-RateLimit-Reset"));
        doThrow(new TwitterException("message", res)).when(PartakeApp.getTwitterService()).updateStatus(anyString(), anyString(), eq(TWITTER_MESSAGE_WILLFAIL_MESSAGE));

        UUID envelopeId = UUID.randomUUID();
        MessageEnvelope envelope = MessageEnvelope.createForTwitterMessage(envelopeId.toString(), UUID.randomUUID().toString(), null);
        queueEnvelope(envelope);

        new SendMessageEnvelopeTask().run();

        // The message should be removed from the queue.
        MessageEnvelope modified = loadEnvelope(envelopeId.toString());
        assertThat(modified, is(nullValue()));
    }

    @Test
    public void sendTwitterMessageWithInvalidUserId() throws Exception {
        DateTime now = TimeUtil.getCurrentDateTime();
        TimeUtil.setCurrentDateTime(now);

        HttpResponse res = mock(HttpResponse.class);
        doReturn(null).when(res).getResponseHeader(eq("X-RateLimit-Limit"));
        doReturn(null).when(res).getResponseHeader(eq("X-RateLimit-Remaining"));
        doReturn(null).when(res).getResponseHeader(eq("X-RateLimit-Reset"));
        doThrow(new TwitterException("message", res)).when(PartakeApp.getTwitterService()).updateStatus(anyString(), anyString(), eq(TWITTER_MESSAGE_WILLFAIL_MESSAGE));

        String twitterMessageId = UUID.randomUUID().toString();
        TwitterMessage message = new TwitterMessage(twitterMessageId, INVALID_USER_ID, TWITTER_MESSAGE_WILLFAIL_MESSAGE, MessageDelivery.INQUEUE, new DateTime(0), null);
        storeTwitterMessage(message);

        UUID envelopeId = UUID.randomUUID();
        MessageEnvelope envelope = MessageEnvelope.createForTwitterMessage(envelopeId.toString(), twitterMessageId, null);
        queueEnvelope(envelope);

        new SendMessageEnvelopeTask().run();

        // The message should be removed from the queue.
        MessageEnvelope modified = loadEnvelope(envelopeId.toString());
        assertThat(modified, is(nullValue()));
    }

    @Test
    public void sendTwitterMessageWithNoTwitterLinkUser() throws Exception {
        DateTime now = TimeUtil.getCurrentDateTime();
        TimeUtil.setCurrentDateTime(now);

        HttpResponse res = mock(HttpResponse.class);
        doReturn(null).when(res).getResponseHeader(eq("X-RateLimit-Limit"));
        doReturn(null).when(res).getResponseHeader(eq("X-RateLimit-Remaining"));
        doReturn(null).when(res).getResponseHeader(eq("X-RateLimit-Reset"));
        doThrow(new TwitterException("message", res)).when(PartakeApp.getTwitterService()).updateStatus(anyString(), anyString(), eq(TWITTER_MESSAGE_WILLFAIL_MESSAGE));

        String twitterMessageId = UUID.randomUUID().toString();
        TwitterMessage message = new TwitterMessage(twitterMessageId, USER_NO_TWITTER_LINK_ID, TWITTER_MESSAGE_WILLFAIL_MESSAGE, MessageDelivery.INQUEUE, new DateTime(0), null);
        storeTwitterMessage(message);

        UUID envelopeId = UUID.randomUUID();
        MessageEnvelope envelope = MessageEnvelope.createForTwitterMessage(envelopeId.toString(), twitterMessageId, null);
        queueEnvelope(envelope);

        new SendMessageEnvelopeTask().run();

        // The message should be removed from the queue.
        MessageEnvelope modified = loadEnvelope(envelopeId.toString());
        assertThat(modified, is(nullValue()));
    }

    @Test
    public void sendTwitterMessageWithNoAuthorizedTwitterLinkUser() throws Exception {
        DateTime now = TimeUtil.getCurrentDateTime();
        TimeUtil.setCurrentDateTime(now);

        HttpResponse res = mock(HttpResponse.class);
        doReturn(null).when(res).getResponseHeader(eq("X-RateLimit-Limit"));
        doReturn(null).when(res).getResponseHeader(eq("X-RateLimit-Remaining"));
        doReturn(null).when(res).getResponseHeader(eq("X-RateLimit-Reset"));
        doThrow(new TwitterException("message", res)).when(PartakeApp.getTwitterService()).updateStatus(anyString(), anyString(), eq(TWITTER_MESSAGE_WILLFAIL_MESSAGE));

        String twitterMessageId = UUID.randomUUID().toString();
        TwitterMessage message = new TwitterMessage(twitterMessageId, USER_TWITTER_NOAUTH_ID, TWITTER_MESSAGE_WILLFAIL_MESSAGE, MessageDelivery.INQUEUE, new DateTime(0), null);
        storeTwitterMessage(message);

        UUID envelopeId = UUID.randomUUID();
        MessageEnvelope envelope = MessageEnvelope.createForTwitterMessage(envelopeId.toString(), twitterMessageId, null);
        queueEnvelope(envelope);

        new SendMessageEnvelopeTask().run();

        // The message should be removed from the queue.
        MessageEnvelope modified = loadEnvelope(envelopeId.toString());
        assertThat(modified, is(nullValue()));
    }

    // ----------------------------------------------------------------------

    @Test
    public void sendUserNotification() throws Exception {
        UUID uuid = UUID.randomUUID();
        MessageEnvelope envelope = MessageEnvelope.createForUserNotification(uuid.toString(), USER_NOTIFICATION_INQUEUE_ID, null);
        queueEnvelope(envelope);

        new SendMessageEnvelopeTask().run();

        List<MessageEnvelope> rest = loadEnvelopes();
        assertThat(rest.isEmpty(), is(true));
        verify(PartakeApp.getTwitterService()).sendDirectMesage(anyString(), anyString(), eq(DEFAULT_TWITTER_ID), anyString());

        assertThat(loadUserNotification(USER_NOTIFICATION_INQUEUE_ID).getDelivery(), is(MessageDelivery.SUCCESS));
    }

    @Test
    public void sendUserMessage() throws Exception {
        UUID uuid = UUID.randomUUID();
        MessageEnvelope envelope = MessageEnvelope.createForUserMessage(uuid.toString(), USER_RECEIVED_MESSAGE_INQUEUE_ID.toString(), null);
        queueEnvelope(envelope);

        new SendMessageEnvelopeTask().run();

        List<MessageEnvelope> rest = loadEnvelopes();
        assertThat(rest.isEmpty(), is(true));
        verify(PartakeApp.getTwitterService()).sendDirectMesage(anyString(), anyString(), eq(DEFAULT_RECEIVER_TWITTER_ID), anyString());

        assertThat(loadUserReceivedMessage(USER_RECEIVED_MESSAGE_INQUEUE_ID).getDelivery(), is(MessageDelivery.SUCCESS));
    }

    @Test
    public void sendInvalidatedMessage() throws Exception {
        DateTime now = TimeUtil.getCurrentDateTime();
        DateTime before = now.nDayBefore(1);

        UUID uuid = UUID.randomUUID();
        MessageEnvelope envelope = MessageEnvelope.createForTwitterMessage(uuid.toString(), TWITTER_MESSAGE_INQUEUE_ID, before);
        queueEnvelope(envelope);

        new SendMessageEnvelopeTask().run();

        List<MessageEnvelope> rest = loadEnvelopes();
        assertThat(rest.isEmpty(), is(true));
        verify(PartakeApp.getTwitterService(), never()).updateStatus(anyString(), anyString(), anyString());
        assertThat(loadTwitterMessage(TWITTER_MESSAGE_INQUEUE_ID).getDelivery(), is(MessageDelivery.FAIL));
    }

    // ----------------------------------------------------------------------

    @Test
    public void testToBuildUserNotificationMessageBodyForOnedayBeforeReminder() throws Exception{
        UserNotification notification = loadUserNotification(USER_NOTIFICATION_INQUEUE_ID);
        Event event = loadEvent(DEFAULT_EVENT_ID);
        EventTicket ticket = loadEventTicket(DEFAULT_EVENT_TICKET_ID);

        UserNotification userNotification = new UserNotification(notification);
        userNotification.setNotificationType(NotificationType.EVENT_ONEDAY_BEFORE_REMINDER);

        String messageBody = SendMessageEnvelopeTask.buildUserNotificationMessageBody(userNotification, event, ticket);
        String expected = String.format("[PRTK] 「title」は%sに開始です。あなたの参加は確定しています。 http://127.0.0.1:9000/events/00000000-0000-0002-0000-000000000000", Helper.readableDate(event.getBeginDate()));
        assertThat(messageBody, is(expected));
    }

    @Test
    public void testToBuildUserNotificationMessageBodyForOnedayBeforeReservationReminder() throws Exception{
        UserNotification notification = loadUserNotification(USER_NOTIFICATION_INQUEUE_ID);
        Event event = loadEvent(DEFAULT_EVENT_ID);
        EventTicket ticket = loadEventTicket(DEFAULT_EVENT_TICKET_ID);

        UserNotification userNotification = new UserNotification(notification);
        userNotification.setNotificationType(NotificationType.ONE_DAY_BEFORE_REMINDER_FOR_RESERVATION);

        String messageBody = SendMessageEnvelopeTask.buildUserNotificationMessageBody(userNotification, event, ticket);
        String expected = String.format("[PRTK] 「title」の締め切りは%sです。参加・不参加を確定してください。 http://127.0.0.1:9000/events/00000000-0000-0002-0000-000000000000", Helper.readableDate(event.getBeginDate()));
        assertThat(messageBody, is(expected));
    }

    @Test
    public void testToBuildUserNotificationMessageBodyForHalfdayBeforeReservationReminder() throws Exception{
        UserNotification notification = loadUserNotification(USER_NOTIFICATION_INQUEUE_ID);
        Event event = loadEvent(DEFAULT_EVENT_ID);
        EventTicket ticket = loadEventTicket(DEFAULT_EVENT_TICKET_ID);

        UserNotification userNotification = new UserNotification(notification);
        userNotification.setNotificationType(NotificationType.HALF_DAY_BEFORE_REMINDER_FOR_RESERVATION);

        String messageBody = SendMessageEnvelopeTask.buildUserNotificationMessageBody(userNotification, event, ticket);
        String expected = String.format("[PRTK] 「title」の締め切りは%sです。参加・不参加を確定してください。 http://127.0.0.1:9000/events/00000000-0000-0002-0000-000000000000", Helper.readableDate(event.getBeginDate()));
        assertThat(messageBody, is(expected));
    }

    @Test
    public void testToBuildUserNotificationMessageBodyForEnrolledReminder() throws Exception{
        UserNotification notification = loadUserNotification(USER_NOTIFICATION_INQUEUE_ID);
        Event event = loadEvent(DEFAULT_EVENT_ID);
        EventTicket ticket = loadEventTicket(DEFAULT_EVENT_TICKET_ID);

        UserNotification userNotification = new UserNotification(notification);
        userNotification.setNotificationType(NotificationType.BECAME_TO_BE_ENROLLED);

        String messageBody = SendMessageEnvelopeTask.buildUserNotificationMessageBody(userNotification, event, ticket);
        String expected = "[PRTK] 「title」で補欠から参加者へ繰り上がりました。 http://127.0.0.1:9000/events/00000000-0000-0002-0000-000000000000";
        assertThat(messageBody, is(expected));
    }

    @Test
    public void testToBuildUserNotificationMessageBodyForCancelledReminder() throws Exception{
        UserNotification notification = loadUserNotification(USER_NOTIFICATION_INQUEUE_ID);
        Event event = loadEvent(DEFAULT_EVENT_ID);
        EventTicket ticket = loadEventTicket(DEFAULT_EVENT_TICKET_ID);

        UserNotification userNotification = new UserNotification(notification);
        userNotification.setNotificationType(NotificationType.BECAME_TO_BE_CANCELLED);

        String messageBody = SendMessageEnvelopeTask.buildUserNotificationMessageBody(userNotification, event, ticket);
        String expected = "[PRTK] 「title」で参加者から補欠へ繰り下がりました。 http://127.0.0.1:9000/events/00000000-0000-0002-0000-000000000000";
        assertThat(messageBody, is(expected));
    }



    // ----------------------------------------------------------------------

    private void storeTwitterMessage(final TwitterMessage message) throws Exception {
        new Transaction<Void>() {
            @Override
            protected Void doExecute(PartakeConnection con, IPartakeDAOs daos) throws DAOException, PartakeException {
                daos.getTwitterMessageAccess().put(con, message);
                return null;
            }
        }.execute();
    }

    private void queueEnvelope(final MessageEnvelope envelope) throws Exception {
        new Transaction<Void>() {
            @Override
            protected Void doExecute(PartakeConnection con, IPartakeDAOs daos) throws DAOException, PartakeException {
                daos.getMessageEnvelopeAccess().put(con, envelope);
                return null;
            }
        }.execute();
    }
}
TOP

Related Classes of in.partake.daemon.impl.SendMessageEnvelopeTaskTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.