package it.com.atlassian.stash.notification;

import com.atlassian.bitbucket.hamcrest.EmailMatcher;
import com.atlassian.bitbucket.test.BatchNotificationTestHelper;
import org.junit.Test;

import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.containsString;

/**
 * Integration tests for the comment like notifications.
 *
 * @see it.com.atlassian.stash.rest.pull.PullRequestCommentLikeResourceTest
 * @see it.com.atlassian.stash.pull.PullRequestBatchNotificationTest
 * @see it.com.atlassian.stash.pull.PullRequestImmediateNotificationTest
 */
public class PullRequestLikeNotificationTest extends AbstractPullRequestNotificationTest {

    @Test
    public void testImmediateNotificationToCommentAuthor() throws Exception {
        String commentText = "test comment for immediate notification";
        long commentId = addComment(IMMEDIATE_REVIEWER, commentText);
        likeComment(PR_AUTHOR, commentId);

        smtpServer.waitForEmail(new EmailMatcher()
                .addressedTo(IMMEDIATE_REVIEWER_EMAIL)
                .withBodyAsText(allOf(containsString(PR_AUTHOR + " LIKED your comment"),
                        containsString(commentText))));
    }

    @Test
    public void testBatchNotificationToCommentAuthor() throws Exception {
        String commentText = "test comment for batched notification";
        long commentId = addComment(BATCHED_REVIEWER, commentText);
        likeComment(PR_AUTHOR, commentId);

        BatchNotificationTestHelper.flushBatchNotificationQueue();

        smtpServer.waitForEmail(new EmailMatcher()
                .addressedTo(BATCHED_REVIEWER_EMAIL)
                .withBodyAsText(allOf(containsString(PR_AUTHOR + " LIKED your comment"),
                        containsString(commentText))));
    }

    @Test
    public void testBatchNotificationToPullRequestAndCommentAuthors() throws Exception {
        String commentText = "test comment for multiple recipients";
        long commentId = addComment(BATCHED_REVIEWER, commentText);
        likeComment(IMMEDIATE_REVIEWER, commentId);

        BatchNotificationTestHelper.flushBatchNotificationQueue();

        // note the following checks will succeed irrespective of which notification is first received
        smtpServer.waitForEmail(new EmailMatcher()
                .addressedTo(PR_AUTHOR_EMAIL)
                .withBodyAsText(allOf(containsString(IMMEDIATE_REVIEWER + " LIKED a comment from " + BATCHED_REVIEWER),
                        containsString(commentText))));
        smtpServer.waitForEmail(new EmailMatcher()
                .addressedTo(BATCHED_REVIEWER_EMAIL)
                .withBodyAsText(allOf(containsString(IMMEDIATE_REVIEWER + " LIKED your comment"),
                        containsString(commentText))));
    }

    @Test
    public void testBatchNotificationForMultipleLikes() throws Exception {
        String commentText = "test comment for multiple likes";
        long commentId = addComment(PR_AUTHOR, commentText);
        likeComment(IMMEDIATE_REVIEWER, commentId);
        likeComment(BATCHED_REVIEWER, commentId);

        BatchNotificationTestHelper.flushBatchNotificationQueue();

        smtpServer.waitForEmail(new EmailMatcher()
                .addressedTo(PR_AUTHOR_EMAIL)
                .withBodyAsText(allOf(containsString(IMMEDIATE_REVIEWER + " and 1 other LIKED your comment"),
                        containsString(commentText))));
    }

    @Test
    public void testBatchNotificationForRemovedLike() throws Exception {
        String commentText = "test comment for removed like";
        long commentId = addComment(PR_AUTHOR, commentText);
        likeComment(IMMEDIATE_REVIEWER, commentId);
        likeComment(BATCHED_REVIEWER, commentId);
        unlikeComment(IMMEDIATE_REVIEWER, commentId); // cancel the first like

        BatchNotificationTestHelper.flushBatchNotificationQueue();

        smtpServer.waitForEmail(new EmailMatcher()
                .addressedTo(PR_AUTHOR_EMAIL)
                .withBodyAsText(allOf(
                        containsString(BATCHED_REVIEWER + " LIKED your comment"), // no mention of the first like
                        containsString(commentText))));
    }

}
