/* * 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.Event; import com.jeanchampemont.wtfdyum.dto.Feature; import com.jeanchampemont.wtfdyum.dto.Principal; import com.jeanchampemont.wtfdyum.dto.type.EventType; import com.jeanchampemont.wtfdyum.dto.type.UserLimitType; import com.jeanchampemont.wtfdyum.service.impl.CronServiceImpl; import com.jeanchampemont.wtfdyum.utils.WTFDYUMException; import com.jeanchampemont.wtfdyum.utils.WTFDYUMExceptionType; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import java.util.Arrays; import java.util.HashSet; import static org.mockito.Mockito.*; import static org.mockito.MockitoAnnotations.initMocks; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = WTFDYUMApplication.class) public class CronServiceTest { @Mock private PrincipalService principalService; @Mock private UserService userService; @Mock private TwitterService twitterService; @Mock private FeatureService featureService; private CronService sut; @Before public void _init() { initMocks(this); sut = new CronServiceImpl(principalService, userService, twitterService, featureService); } @Test public void checkCredentialsTest() throws Exception { final Principal principal = principal(1L); when(twitterService.verifyCredentials(principal)).thenReturn(true); sut.checkCredentials(); verify(userService, times(1)).resetLimit(1L, UserLimitType.CREDENTIALS_INVALID); } @Test public void checkCredentialsTestInvalid() throws Exception { final Principal principal = principal(1L); when(twitterService.verifyCredentials(principal)).thenReturn(false); sut.checkCredentials(); verify(userService, times(1)).addEvent(1L, new Event(EventType.INVALID_TWITTER_CREDENTIALS, "")); verify(userService, times(1)).applyLimit(1L, UserLimitType.CREDENTIALS_INVALID); } @Test public void cronTestDisabled() throws Exception { principal(5L); featureEnabled(5L, true, Feature.NOTIFY_UNFOLLOW); sut.cron(); } @Test public void cronTestEvents() throws Exception { principal(12L); featureEnabled(12L, true, Feature.NOTIFY_UNFOLLOW, Feature.TWEET_UNFOLLOW); when(featureService.cron(12L, Feature.NOTIFY_UNFOLLOW)) .thenReturn(new HashSet<>(Arrays.asList(new Event(EventType.UNFOLLOW, "toto")))); when(featureService.cron(12L, Feature.TWEET_UNFOLLOW)) .thenReturn(new HashSet<>(Arrays.asList(new Event(EventType.UNFOLLOW, "toto")))); sut.cron(); verify(featureService, times(1)).cron(12L, Feature.NOTIFY_UNFOLLOW); verify(featureService, times(1)).cron(12L, Feature.TWEET_UNFOLLOW); verify(featureService, times(1)).completeCron(12L, Feature.NOTIFY_UNFOLLOW); verify(featureService, times(1)).completeCron(12L, Feature.TWEET_UNFOLLOW); verify(userService, times(1)).addEvent(12L, new Event(EventType.UNFOLLOW, "toto")); } @Test public void cronTestNominal() throws Exception { principal(1L); featureEnabled(1L, true, Feature.NOTIFY_UNFOLLOW); sut.cron(); verify(featureService, times(1)).cron(1L, Feature.NOTIFY_UNFOLLOW); verify(featureService, times(1)).completeCron(1L, Feature.NOTIFY_UNFOLLOW); } @Test public void cronTestNPEError() throws Exception { principal(4L); featureEnabled(4L, true, Feature.NOTIFY_UNFOLLOW); when(featureService.cron(4L, Feature.NOTIFY_UNFOLLOW)).thenThrow(new NullPointerException()); sut.cron(); // should have an event UNKNOWN_ERROR verify(userService, times(1)).addEvent(4L, new Event(EventType.UNKNOWN_ERROR, null)); } @Test public void cronTestRateLimitError() throws Exception { principal(3L); featureEnabled(3L, true, Feature.NOTIFY_UNFOLLOW); when(featureService.cron(3L, Feature.NOTIFY_UNFOLLOW)).thenThrow(new WTFDYUMException(WTFDYUMExceptionType.GET_FOLLOWERS_RATE_LIMIT_EXCEEDED)); sut.cron(); // should have an event RATE_LIMIT_EXCEEDED verify(userService, times(1)).addEvent(3L, new Event(EventType.RATE_LIMIT_EXCEEDED, null)); } @Test public void cronTestTwitterError() throws Exception { principal(2L); featureEnabled(2L, true, Feature.NOTIFY_UNFOLLOW); when(featureService.cron(2L, Feature.NOTIFY_UNFOLLOW)).thenThrow(new WTFDYUMException(WTFDYUMExceptionType.TWITTER_ERROR)); sut.cron(); // should have an event TWITTER_ERROR verify(userService, times(1)).addEvent(2L, new Event(EventType.TWITTER_ERROR, null)); } private void featureEnabled(final long userId, final boolean value, final Feature... feature) { when(userService.getEnabledFeatures(userId)).thenReturn(new HashSet<>(Arrays.asList(feature))); } private Principal principal(final long id) { when(principalService.getMembers()).thenReturn(new HashSet<>(Arrays.asList(id))); final Principal principal = new Principal(id, "Principal 1 Token", "Principal 1 Token Secret"); when(principalService.get(id)).thenReturn(principal); return principal; } }