package org.jstanier;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.util.ArrayList;
import java.util.List;

import org.joda.time.DateTime;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.runners.MockitoJUnitRunner;

import com.jstanier.Tweet;
import com.jstanier.TweetRanker;

@RunWith(MockitoJUnitRunner.class)
public class TweetRankerTest {

    private static String PLACEHOLDER_CONTENT = "@jstanier Hey man!";
    private static final int DEFAULT_FAVOURITES = 0;
    private static final int DEFAULT_RETWEETS = 0;

    @InjectMocks
    private TweetRanker tweetRanker;

    @Test(expected = NullPointerException.class)
    public void tweetRanker_givenANullInput_throwsAnNPE() {
        tweetRanker.rankTweets(null);
    }

    @Test
    public void tweetRanker_givenAnEmptyInputList_returnsAnEmptyList() {
        List<Tweet> tweets = new ArrayList<Tweet>();
        List<Tweet> rankedTweets = tweetRanker.rankTweets(tweets);
        assertTrue("The list contains no elements", rankedTweets.isEmpty());
    }

    @Test
    public void tweetRanker_givenASingleElementInputList_returnsASingleElementList() {
        List<Tweet> tweets = new ArrayList<Tweet>();
        Tweet tweet = createPlaceholderTweet();
        tweets.add(tweet);
        List<Tweet> rankedTweets = tweetRanker.rankTweets(tweets);
        assertTrue("The list is the same size as the input (1)",
                rankedTweets.size() == tweets.size());
        assertEquals("The tweet in the list is the same object", tweet, rankedTweets.get(0));
    }

    @Test
    public void tweetRanker_givenAListOfTweetsWhereOneIsPopular_thenThePopularTweetIsAtIndexOne() {
        List<Tweet> tweets = new ArrayList<Tweet>();
        Tweet popularTweet = createTweet(PLACEHOLDER_CONTENT, 100, 100);
        tweets.add(popularTweet);
        Tweet unpopularTweet = createPlaceholderTweet();
        tweets.add(unpopularTweet);
        List<Tweet> rankedTweets = tweetRanker.rankTweets(tweets);
        assertTrue("The list is the same size as the input (2)",
                rankedTweets.size() == tweets.size());
        assertEquals("The tweet at index 0 is the unpopular tweet", unpopularTweet,
                rankedTweets.get(0));
        assertEquals("The tweet at index 1 is the popular tweet", popularTweet, rankedTweets.get(1));
    }

    @Test
    public void tweetRanker_givenATweetWithFavouritesAndAnotherWithRetweets_thenTheMostPopularTweetIsTheRetweetedOne() {
        List<Tweet> tweets = new ArrayList<Tweet>();
        Tweet retweetedTweet = createTweet(PLACEHOLDER_CONTENT, 100, 0);
        tweets.add(retweetedTweet);
        Tweet favouritedTweet = createTweet(PLACEHOLDER_CONTENT, 0, 100);
        tweets.add(favouritedTweet);
        List<Tweet> rankedTweets = tweetRanker.rankTweets(tweets);
        assertTrue("The list is the same size as the input (2)",
                rankedTweets.size() == tweets.size());
        assertEquals("The tweet at index 0 is the favourited tweet", favouritedTweet,
                rankedTweets.get(0));
        assertEquals("The tweet at index 1 is the retweeted tweet", retweetedTweet,
                rankedTweets.get(1));
    }

    private Tweet createPlaceholderTweet() {
        return createTweet(PLACEHOLDER_CONTENT, DEFAULT_RETWEETS, DEFAULT_FAVOURITES);
    }

    private Tweet createTweet(String content, Integer retweets, Integer favourites) {
        Tweet tweet = new Tweet();
        tweet.setTime(new DateTime());
        tweet.setContent(content);
        tweet.setRetweets(retweets);
        tweet.setFavourites(favourites);
        return tweet;
    }
}

@@ -1067,20 +1067,41 @@
 The 
-list
+ranked tweets list should
  contain
 s no
@@ -1096,17 +1096,16 @@
  contain
-s
  no elem
@@ -1451,39 +1451,60 @@
 assertTrue(%22The 
-list is
+ranked tweets list should be
  the same size a
@@ -1619,33 +1619,79 @@
 the 
-list is the same object%22,
+ranked tweets list should be the same object as input%22,%0A               
  twe
@@ -2174,34 +2174,58 @@
 tTrue(%22The list 
-is
+of ranked tweets should be
  the same size a
@@ -2336,26 +2336,33 @@
  at index 0 
-i
 s
+hould be
  the unpopul
@@ -2465,26 +2465,33 @@
  at index 1 
-i
 s
+hould be
  the popular
@@ -2508,24 +2508,40 @@
 opularTweet,
+%0A               
  rankedTweet
@@ -3058,18 +3058,25 @@
 he list 
-i
 s
+hould be
  the sam
@@ -3199,18 +3199,25 @@
 index 0 
-i
 s
+hould be
  the fav
@@ -3330,18 +3330,25 @@
 index 1 
-i
 s
+hould be
  the ret

Improve wording in TweetRanker tests