/* * Copyright (C) 2015, 2016 WTFDYUM * * This file is part of the WTFDYUM project. * * 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 com.jeanchampemont.wtfdyum.service; import com.jeanchampemont.wtfdyum.WTFDYUMApplication; import com.jeanchampemont.wtfdyum.dto.Principal; import com.jeanchampemont.wtfdyum.service.impl.TwitterServiceImpl; import com.jeanchampemont.wtfdyum.utils.ResponseListMockForTest; import com.jeanchampemont.wtfdyum.utils.TwitterFactoryHolder; import com.jeanchampemont.wtfdyum.utils.WTFDYUMException; import com.jeanchampemont.wtfdyum.utils.WTFDYUMExceptionType; import org.assertj.core.api.Assertions; import org.dozer.Mapper; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import twitter4j.*; import twitter4j.api.UsersResources; import twitter4j.auth.AccessToken; import twitter4j.auth.RequestToken; import java.util.List; import java.util.Optional; import java.util.Random; import java.util.Set; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.*; import static org.mockito.MockitoAnnotations.initMocks; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = WTFDYUMApplication.class) public class TwitterServiceTest { private static final String DEFAULT_BASE_URL = "http://url/toto/"; private static final String DEFAULT_PATH = "default/path"; @Autowired private Mapper mapper; private TwitterService sut; @Mock private Twitter twitter; @Mock private UsersResources usersResources; @Mock private TwitterFactoryHolder twitterFactory; @Before public void ainit() { initMocks(this); when(twitterFactory.getInstance()).thenReturn(twitter); sut = new TwitterServiceImpl(twitterFactory, mapper, DEFAULT_BASE_URL, "appId", "appSecret"); } @Test public void completeSigninTestNominal() throws Exception { final AccessToken returnedToken = new AccessToken("TOKTOK", "TOK_secret"); final RequestToken paramToken = new RequestToken("TOK", "SECRET_tok"); final String verifier = "VERiFy"; when(twitter.getOAuthAccessToken(paramToken, verifier)).thenReturn(returnedToken); final AccessToken accessToken = sut.completeSignin(paramToken, verifier); verify(twitter, times(1)).getOAuthAccessToken(paramToken, verifier); assertThat(accessToken).isNotNull(); assertThat(accessToken).isEqualTo(returnedToken); } @Test(expected = WTFDYUMException.class) public void completeSigninTestTwitterException() throws Exception { final RequestToken paramToken = new RequestToken("TOK", "SECRET_tok"); final String verifier = "VERiFy"; when(twitter.getOAuthAccessToken(paramToken, verifier)).thenThrow(new TwitterException("dummy")); sut.completeSignin(paramToken, verifier); Assertions.fail("Exception not throwned"); } @Test public void getFollowersTest() throws Exception { final Optional<Principal> principal = Optional.of(new Principal(123L, "toktok", "secsecret")); final IDs idsMock = mock(IDs.class); when(twitter.getFollowersIDs(444L, -1)).thenReturn(idsMock); final RateLimitStatus rateLimitStatusMock = mock(RateLimitStatus.class); when(idsMock.getRateLimitStatus()).thenReturn(rateLimitStatusMock); when(rateLimitStatusMock.getRemaining()).thenReturn(1); when(idsMock.getIDs()).thenReturn(new long[]{12L, 34L, 44L, 42L, 42L, 999L}); final Set<Long> followers = sut.getFollowers(444L, principal); assertThat(followers).isNotNull(); assertThat(followers.contains(12L)); assertThat(followers.contains(34L)); assertThat(followers.contains(44L)); assertThat(followers.contains(42L)); assertThat(followers.contains(999L)); verify(twitter, times(1)).setOAuthAccessToken(new AccessToken("toktok", "secsecret")); } @Test public void getFollowersMultiplePageTest() throws Exception { final Optional<Principal> principal = Optional.of(new Principal(123L, "toktok", "secsecret")); final IDs firstPageMock = mock(IDs.class); final IDs secondPageMock = mock(IDs.class); final RateLimitStatus firstPageRateLimitMock = mock(RateLimitStatus.class); when(firstPageRateLimitMock.getRemaining()).thenReturn(1); when(firstPageMock.getRateLimitStatus()).thenReturn(firstPageRateLimitMock); when(firstPageMock.hasNext()).thenReturn(true); when(firstPageMock.getIDs()).thenReturn(new long[]{12L, 34L, 44L, 42L, 42L, 999L}); when(firstPageMock.getNextCursor()).thenReturn(42L); final RateLimitStatus secondPageRateLimitMock = mock(RateLimitStatus.class); when(secondPageRateLimitMock.getRemaining()).thenReturn(0); when(secondPageMock.getRateLimitStatus()).thenReturn(secondPageRateLimitMock); when(secondPageMock.hasNext()).thenReturn(false); when(secondPageMock.getIDs()).thenReturn(new long[]{1001L, 1002L, 1003L}); when(twitter.getFollowersIDs(444L, -1)).thenReturn(firstPageMock); when(twitter.getFollowersIDs(444L, 42)).thenReturn(secondPageMock); final Set<Long> followers = sut.getFollowers(444L, principal); assertThat(followers).isNotNull(); assertThat(followers).containsOnly(12L, 34L, 44L, 42L, 999L, 1001L, 1002L, 1003L); verify(twitter, times(1)).setOAuthAccessToken(new AccessToken("toktok", "secsecret")); } @Test public void getFollowersTestWithoutPrincipal() throws Exception { final IDs idsMock = mock(IDs.class); when(twitter.getFollowersIDs(444L, -1)).thenReturn(idsMock); final RateLimitStatus rateLimitStatusMock = mock(RateLimitStatus.class); when(idsMock.getRateLimitStatus()).thenReturn(rateLimitStatusMock); when(rateLimitStatusMock.getRemaining()).thenReturn(1); when(idsMock.getIDs()).thenReturn(new long[]{12L, 34L, 44L, 42L, 42L, 999L}); final Set<Long> followers = sut.getFollowers(444L, Optional.<Principal> empty()); assertThat(followers).isNotNull(); assertThat(followers.contains(12L)); assertThat(followers.contains(34L)); assertThat(followers.contains(44L)); assertThat(followers.contains(42L)); assertThat(followers.contains(999L)); } @Test public void getUsersEmptyTest() throws Exception { final List<com.jeanchampemont.wtfdyum.dto.User> result = sut.getUsers(new Principal(1L, "", ""), new long[0]); assertThat(result).isNotNull(); assertThat(result.size()).isEqualTo(0); } @Test public void getUsersMultiplePageTest() throws Exception { final User userMock = mock(User.class); when(userMock.getName()).thenReturn("name"); when(userMock.getScreenName()).thenReturn("screenName"); when(userMock.getProfileImageURL()).thenReturn("profile img url"); when(userMock.getURL()).thenReturn("user url"); final ResponseList<User> users = new ResponseListMockForTest<User>(); final long[] ids = new long[150]; final long[] first100 = new long[100]; final long[] next50 = new long[50]; final Random rand = new Random(); for (int i = 0; i < 150; i++) { users.add(userMock); final long id = rand.nextLong(); when(userMock.getId()).thenReturn(id); ids[i] = id; if (i < 100) { first100[i] = id; } else { next50[i - 100] = id; } } final ResponseList<User> first100Users = new ResponseListMockForTest<>(); first100Users.addAll(users.subList(0, 100)); final ResponseList<User> next50Users = new ResponseListMockForTest<>(); next50Users.addAll(users.subList(100, 150)); when(twitter.users()).thenReturn(usersResources); when(usersResources.lookupUsers(first100)).thenReturn(first100Users); when(usersResources.lookupUsers(next50)).thenReturn(next50Users); final List<com.jeanchampemont.wtfdyum.dto.User> result = sut.getUsers(new Principal(1L, "", ""), ids); assertThat(result).isNotNull(); assertThat(result.size()).isEqualTo(150); } @Test public void getUsersTest() throws Exception { final User userMock = mock(User.class); when(userMock.getName()).thenReturn("name"); when(userMock.getScreenName()).thenReturn("screenName"); when(userMock.getProfileImageURL()).thenReturn("profile img url"); when(userMock.getURL()).thenReturn("user url"); final ResponseList<User> users = new ResponseListMockForTest<User>(); final long[] ids = new long[100]; final Random rand = new Random(); for(int i = 0; i < 100; i++) { users.add(userMock); final long id = rand.nextLong(); when(userMock.getId()).thenReturn(id); ids[i] = id; } when(twitter.users()).thenReturn(usersResources); when(usersResources.lookupUsers(ids)).thenReturn(users); final List<com.jeanchampemont.wtfdyum.dto.User> result = sut.getUsers(new Principal(1L, "", ""), ids); assertThat(result).isNotNull(); assertThat(result.size()).isEqualTo(100); } @Test public void getUsersTwitterExceptionTest() throws Exception { final User userMock = mock(User.class); when(userMock.getName()).thenReturn("name"); when(userMock.getScreenName()).thenReturn("screenName"); when(userMock.getProfileImageURL()).thenReturn("profile img url"); when(userMock.getURL()).thenReturn("user url"); final ResponseList<User> users = new ResponseListMockForTest<User>(); final long[] ids = new long[100]; final Random rand = new Random(); for(int i = 0; i < 100; i++) { users.add(userMock); final long id = rand.nextLong(); when(userMock.getId()).thenReturn(id); ids[i] = id; } when(twitter.users()).thenReturn(usersResources); when(usersResources.lookupUsers(ids)).thenThrow(TwitterException.class); try { sut.getUsers(new Principal(1L, "", ""), ids); Assertions.failBecauseExceptionWasNotThrown(WTFDYUMException.class); } catch (WTFDYUMException e) { assertThat(e.getType()).isEqualTo(WTFDYUMExceptionType.TWITTER_ERROR); } } @Test public void getFollowersTestWithoutPrincipalRateLimit() throws Exception { final IDs idsMock = mock(IDs.class); when(twitter.getFollowersIDs(444L, -1)).thenReturn(idsMock); final RateLimitStatus rateLimitStatusMock = mock(RateLimitStatus.class); when(idsMock.hasNext()).thenReturn(true); when(idsMock.getRateLimitStatus()).thenReturn(rateLimitStatusMock); when(rateLimitStatusMock.getRemaining()).thenReturn(0); try { sut.getFollowers(444L, Optional.<Principal> empty()); Assertions.failBecauseExceptionWasNotThrown(WTFDYUMException.class); } catch (final WTFDYUMException e) { assertThat(e.getType()).isEqualTo(WTFDYUMExceptionType.GET_FOLLOWERS_RATE_LIMIT_EXCEEDED); } } @Test public void getFollowersTestWithoutPrincipalTwitterException() throws Exception { when(twitter.getFollowersIDs(444L, -1)).thenThrow(new TwitterException("msg")); try { sut.getFollowers(444L, Optional.<Principal> empty()); Assertions.failBecauseExceptionWasNotThrown(WTFDYUMException.class); } catch (final WTFDYUMException e) { assertThat(e.getType()).isEqualTo(WTFDYUMExceptionType.TWITTER_ERROR); } } @Test public void getUserTest() throws Exception { final User userMock = mock(User.class); when(twitter.users()).thenReturn(usersResources); when(usersResources.showUser(123L)).thenReturn(userMock); when(userMock.getId()).thenReturn(123L); when(userMock.getName()).thenReturn("name"); when(userMock.getScreenName()).thenReturn("screenName"); when(userMock.getProfileImageURL()).thenReturn("profile img url"); when(userMock.getURL()).thenReturn("user url"); final com.jeanchampemont.wtfdyum.dto.User result = sut.getUser(new Principal(1L, "", ""), 123L); assertThat(result).isNotNull(); assertThat(result.getId()).isEqualTo(123L); assertThat(result.getName()).isEqualTo("name"); assertThat(result.getScreenName()).isEqualTo("screenName"); assertThat(result.getProfileImageURL()).isEqualTo("profile img url"); assertThat(result.getURL()).isEqualTo("user url"); } @Test(expected = WTFDYUMException.class) public void getUserTestException() throws Exception { when(twitter.users()).thenReturn(usersResources); when(usersResources.showUser(123L)).thenThrow(new TwitterException("msg")); sut.getUser(new Principal(1L, "", ""), 123L); } @Test public void sendDirectMessageTest() throws Exception { final Principal principal = new Principal(123L, "toktok", "secsecret"); sut.sendDirectMessage(principal, 555L, "text"); verify(twitter, times(1)).sendDirectMessage(555L, "text"); } @Test public void sendDirectMessageTestException() throws Exception { when(twitter.sendDirectMessage(444L, "text")).thenThrow(new TwitterException("msg")); try { sut.sendDirectMessage(new Principal(412L, "", ""), 444L, "text"); Assertions.failBecauseExceptionWasNotThrown(WTFDYUMException.class); } catch (final WTFDYUMException e) { assertThat(e.getType()).isEqualTo(WTFDYUMExceptionType.TWITTER_ERROR); } } @Test public void signinTestNominal() throws Exception { final RequestToken returnedToken = new RequestToken("TOK", "SECRET_tok"); when(twitter.getOAuthRequestToken(DEFAULT_BASE_URL + DEFAULT_PATH)).thenReturn(returnedToken); final RequestToken requestToken = sut.signin(DEFAULT_PATH); verify(twitter, times(1)).getOAuthRequestToken(DEFAULT_BASE_URL + DEFAULT_PATH); assertThat(requestToken).isNotNull(); assertThat(requestToken).isEqualTo(returnedToken); } @Test(expected = WTFDYUMException.class) public void signinTestTwitterException() throws Exception { when(twitter.getOAuthRequestToken(DEFAULT_BASE_URL + DEFAULT_PATH)).thenThrow(new TwitterException("dummy")); sut.signin(DEFAULT_PATH); Assertions.fail("Exception not throwned"); } @Test public void tweetTest() throws Exception { sut.tweet(new Principal(144L, "tok", "toksec"), "my brand new tweet"); verify(twitter, times(1)).updateStatus("my brand new tweet"); } @Test(expected = WTFDYUMException.class) public void tweetTestException() throws Exception { when(twitter.updateStatus("my brand new tweet")).thenThrow(new TwitterException("")); sut.tweet(new Principal(144L, "tok", "toksec"), "my brand new tweet"); } @Test public void verifyCredentialsTestFalse() throws TwitterException { when(twitter.verifyCredentials()).thenThrow(new TwitterException("")); final boolean result = sut.verifyCredentials(new Principal(12L, "tre", "tr")); assertThat(result).isFalse(); } @Test public void verifyCredentialsTestTrue() throws TwitterException { when(twitter.verifyCredentials()).thenReturn(null); final boolean result = sut.verifyCredentials(new Principal(12L, "tre", "tr")); assertThat(result).isTrue(); } }