/* * 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.type.EventType; import com.jeanchampemont.wtfdyum.dto.type.UserLimitType; import com.jeanchampemont.wtfdyum.service.impl.UserServiceImpl; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.data.redis.core.ListOperations; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.SetOperations; import org.springframework.data.redis.core.ValueOperations; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import java.time.Clock; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.*; import static org.mockito.MockitoAnnotations.initMocks; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = WTFDYUMApplication.class) public class UserServiceTest { private UserService sut; @Mock private RedisTemplate<String, Long> longRedisTemplate; @Mock private RedisTemplate<String, Event> eventRedisTemplate; @Mock private RedisTemplate<String, Feature> featureRedisTemplate; @Mock private SetOperations<String, Long> longSetOperations; @Mock private ValueOperations<String, Long> longValueOperations; @Mock private SetOperations<String, Feature> featureSetOperations; @Mock private ListOperations<String, Event> eventListOperations; @Mock private FeatureService featureService; private final Clock clock = Clock.fixed(Instant.parse("2007-12-03T10:15:30.00Z"), ZoneId.of("Z")); @Before public void _init() { initMocks(this); sut = new UserServiceImpl(eventRedisTemplate, featureRedisTemplate, longRedisTemplate, featureService, clock); } @Test public void addEventTest() { when(eventRedisTemplate.opsForList()).thenReturn(eventListOperations); final Event event = new Event(EventType.REGISTRATION, "data"); sut.addEvent(31L, event); verify(eventListOperations, times(1)).leftPush("EVENTS_31", event); assertThat(event.getCreationDateTime()).isEqualTo(LocalDateTime.now(clock)); } @Test public void applyLimitTestNotReached() { when(longRedisTemplate.opsForValue()).thenReturn(longValueOperations); when(longValueOperations.increment(UserLimitType.CREDENTIALS_INVALID.name() + "_442", 1)).thenReturn(4L); final boolean result = sut.applyLimit(442L, UserLimitType.CREDENTIALS_INVALID); assertThat(result).isFalse(); } @Test public void applyLimitTestReached() { when(longRedisTemplate.opsForValue()).thenReturn(longValueOperations); when(eventRedisTemplate.opsForList()).thenReturn(eventListOperations); when(longValueOperations.increment(UserLimitType.CREDENTIALS_INVALID.name() + "_442", 1)).thenReturn(5L); final boolean result = sut.applyLimit(442L, UserLimitType.CREDENTIALS_INVALID); assertThat(result).isTrue(); for (final Feature f : Feature.values()) { verify(featureService, times(1)).disableFeature(442L, f); } final ArgumentCaptor<Event> eventCaptor = ArgumentCaptor.forClass(Event.class); verify(eventListOperations, times(1)).leftPush(eq("EVENTS_442"), eventCaptor.capture()); assertThat(eventCaptor.getValue().getType()).isEqualTo(EventType.CREDENTIALS_INVALID_LIMIT_REACHED); assertThat(eventCaptor.getValue().getAdditionalData()).isEmpty(); assertThat(eventCaptor.getValue().getCreationDateTime()).isEqualTo(LocalDateTime.now(clock)); } @Test public void getEnabledFeaturesTest() { when(featureRedisTemplate.opsForSet()).thenReturn(featureSetOperations); when(featureSetOperations.members("FEATURES_1234")).thenReturn(new HashSet<>(Arrays.asList(Feature.NOTIFY_UNFOLLOW, Feature.TWEET_UNFOLLOW))); final Set<Feature> result = sut.getEnabledFeatures(1234L); assertThat(result).isEqualTo(new HashSet<>(Arrays.asList(Feature.NOTIFY_UNFOLLOW, Feature.TWEET_UNFOLLOW))); } @Test public void getRecentEventsTest() { final List<Event> result = Arrays.asList(new Event(EventType.REGISTRATION, "reg"), new Event(EventType.UNFOLLOW, "unfoll")); when(eventRedisTemplate.opsForList()).thenReturn(eventListOperations); when(eventListOperations.range("EVENTS_1249", 0, 12)).thenReturn(result); final List<Event> returnedResult = sut.getRecentEvents(1249L, 12); assertThat(returnedResult).isNotNull(); assertThat(returnedResult.size()).isEqualTo(2); assertThat(returnedResult).isEqualTo(result); } @Test public void getRecentEventsWithStartTest() { final List<Event> result = Arrays.asList(new Event(EventType.REGISTRATION, "reg"), new Event(EventType.UNFOLLOW, "unfoll")); when(eventRedisTemplate.opsForList()).thenReturn(eventListOperations); when(eventListOperations.range("EVENTS_1249", 10, 15)).thenReturn(result); final List<Event> returnedResult = sut.getRecentEvents(1249L, 5, 10); assertThat(returnedResult).isNotNull(); assertThat(returnedResult.size()).isEqualTo(2); assertThat(returnedResult).isEqualTo(result); } @Test public void resetLimitTest() { sut.resetLimit(199L, UserLimitType.CREDENTIALS_INVALID); verify(longRedisTemplate, times(1)).delete(UserLimitType.CREDENTIALS_INVALID.name() + "_199"); } }