package com.dfire.platform.alchemy.service; import com.dfire.platform.alchemy.AlchemyApp; import com.dfire.platform.alchemy.common.Constants; import com.dfire.platform.alchemy.domain.User; import com.dfire.platform.alchemy.repository.UserRepository; import com.dfire.platform.alchemy.service.dto.UserDTO; import com.dfire.platform.alchemy.service.util.RandomUtil; import org.apache.commons.lang3.RandomStringUtils; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.Mock; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.auditing.AuditingHandler; import org.springframework.data.auditing.DateTimeProvider; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.transaction.annotation.Transactional; import java.time.Instant; import java.time.temporal.ChronoUnit; import java.time.LocalDateTime; import java.util.Optional; import java.util.List; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.when; /** * Integration tests for {@link UserService}. */ @SpringBootTest(classes = AlchemyApp.class) @Transactional public class UserServiceIT { private static final String DEFAULT_LOGIN = "johndoe"; private static final String DEFAULT_EMAIL = "[email protected]"; private static final String DEFAULT_FIRSTNAME = "john"; private static final String DEFAULT_LASTNAME = "doe"; private static final String DEFAULT_IMAGEURL = "http://placehold.it/50x50"; private static final String DEFAULT_LANGKEY = "en"; @Autowired private UserRepository userRepository; @Autowired private UserService userService; @Autowired private AuditingHandler auditingHandler; @Mock private DateTimeProvider dateTimeProvider; private User user; @BeforeEach public void init() { user = new User(); user.setLogin(DEFAULT_LOGIN); user.setPassword(RandomStringUtils.random(60)); user.setActivated(true); user.setEmail(DEFAULT_EMAIL); user.setFirstName(DEFAULT_FIRSTNAME); user.setLastName(DEFAULT_LASTNAME); user.setImageUrl(DEFAULT_IMAGEURL); user.setLangKey(DEFAULT_LANGKEY); when(dateTimeProvider.getNow()).thenReturn(Optional.of(LocalDateTime.now())); auditingHandler.setDateTimeProvider(dateTimeProvider); } @Test @Transactional public void assertThatUserMustExistToResetPassword() { userRepository.saveAndFlush(user); Optional<User> maybeUser = userService.requestPasswordReset("[email protected]"); assertThat(maybeUser).isNotPresent(); maybeUser = userService.requestPasswordReset(user.getEmail()); assertThat(maybeUser).isPresent(); assertThat(maybeUser.orElse(null).getEmail()).isEqualTo(user.getEmail()); assertThat(maybeUser.orElse(null).getResetDate()).isNotNull(); assertThat(maybeUser.orElse(null).getResetKey()).isNotNull(); } @Test @Transactional public void assertThatOnlyActivatedUserCanRequestPasswordReset() { user.setActivated(false); userRepository.saveAndFlush(user); Optional<User> maybeUser = userService.requestPasswordReset(user.getLogin()); assertThat(maybeUser).isNotPresent(); userRepository.delete(user); } @Test @Transactional public void assertThatResetKeyMustNotBeOlderThan24Hours() { Instant daysAgo = Instant.now().minus(25, ChronoUnit.HOURS); String resetKey = RandomUtil.generateResetKey(); user.setActivated(true); user.setResetDate(daysAgo); user.setResetKey(resetKey); userRepository.saveAndFlush(user); Optional<User> maybeUser = userService.completePasswordReset("johndoe2", user.getResetKey()); assertThat(maybeUser).isNotPresent(); userRepository.delete(user); } @Test @Transactional public void assertThatResetKeyMustBeValid() { Instant daysAgo = Instant.now().minus(25, ChronoUnit.HOURS); user.setActivated(true); user.setResetDate(daysAgo); user.setResetKey("1234"); userRepository.saveAndFlush(user); Optional<User> maybeUser = userService.completePasswordReset("johndoe2", user.getResetKey()); assertThat(maybeUser).isNotPresent(); userRepository.delete(user); } @Test @Transactional public void assertThatUserCanResetPassword() { String oldPassword = user.getPassword(); Instant daysAgo = Instant.now().minus(2, ChronoUnit.HOURS); String resetKey = RandomUtil.generateResetKey(); user.setActivated(true); user.setResetDate(daysAgo); user.setResetKey(resetKey); userRepository.saveAndFlush(user); Optional<User> maybeUser = userService.completePasswordReset("johndoe2", user.getResetKey()); assertThat(maybeUser).isPresent(); assertThat(maybeUser.orElse(null).getResetDate()).isNull(); assertThat(maybeUser.orElse(null).getResetKey()).isNull(); assertThat(maybeUser.orElse(null).getPassword()).isNotEqualTo(oldPassword); userRepository.delete(user); } @Test @Transactional public void testFindNotActivatedUsersByCreationDateBefore() { Instant now = Instant.now(); when(dateTimeProvider.getNow()).thenReturn(Optional.of(now.minus(4, ChronoUnit.DAYS))); user.setActivated(false); User dbUser = userRepository.saveAndFlush(user); dbUser.setCreatedDate(now.minus(4, ChronoUnit.DAYS)); userRepository.saveAndFlush(user); List<User> users = userRepository.findAllByActivatedIsFalseAndCreatedDateBefore(now.minus(3, ChronoUnit.DAYS)); assertThat(users).isNotEmpty(); userService.removeNotActivatedUsers(); users = userRepository.findAllByActivatedIsFalseAndCreatedDateBefore(now.minus(3, ChronoUnit.DAYS)); assertThat(users).isEmpty(); } @Test @Transactional public void assertThatAnonymousUserIsNotGet() { user.setLogin(Constants.ANONYMOUS_USER); if (!userRepository.findOneByLogin(Constants.ANONYMOUS_USER).isPresent()) { userRepository.saveAndFlush(user); } final PageRequest pageable = PageRequest.of(0, (int) userRepository.count()); final Page<UserDTO> allManagedUsers = userService.getAllManagedUsers(pageable); assertThat(allManagedUsers.getContent().stream() .noneMatch(user -> Constants.ANONYMOUS_USER.equals(user.getLogin()))) .isTrue(); } @Test @Transactional public void testRemoveNotActivatedUsers() { // custom "now" for audit to use as creation date when(dateTimeProvider.getNow()).thenReturn(Optional.of(Instant.now().minus(30, ChronoUnit.DAYS))); user.setActivated(false); userRepository.saveAndFlush(user); assertThat(userRepository.findOneByLogin(DEFAULT_LOGIN)).isPresent(); userService.removeNotActivatedUsers(); assertThat(userRepository.findOneByLogin(DEFAULT_LOGIN)).isNotPresent(); } }