package enhancedsnapshots.service.impl;
import com.sungardas.enhancedsnapshots.aws.dynamodb.Roles;
import com.sungardas.enhancedsnapshots.aws.dynamodb.model.User;
import com.sungardas.enhancedsnapshots.aws.dynamodb.repository.UserRepository;
import com.sungardas.enhancedsnapshots.dto.UserDto;
import com.sungardas.enhancedsnapshots.dto.converter.UserDtoConverter;
import com.sungardas.enhancedsnapshots.exception.DataAccessException;
import com.sungardas.enhancedsnapshots.exception.OperationNotAllowedException;
import com.sungardas.enhancedsnapshots.exception.UniqueConstraintViolationException;
import com.sungardas.enhancedsnapshots.service.impl.UserServiceImpl;
import org.apache.commons.codec.digest.DigestUtils;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static org.mockito.Mockito.*;
@Ignore
@RunWith(MockitoJUnitRunner.class)
public class UserServiceImplTest {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserServiceImpl userService;
private String adminEmail = "admin@super.com";
private String userEmail = "user@user.com";
private String psw = "psw";
@Before
public void setUp() {
when(userRepository.findOne(userEmail)).thenReturn(UserDtoConverter.convert(createUserDto(userEmail)));
when(userRepository.findOne(adminEmail)).thenReturn(UserDtoConverter.convert(createAdminDto(adminEmail)));
}
/**
* Check admin can create new user accounts
*/
@Test
public void adminCanCreateNewUsers() {
User newUser = createUser(userEmail);
userService.createUser(createUserDto(userEmail), psw);
// email should be converted to lowercase before user saving in DB
newUser.setEmail(newUser.getEmail().toLowerCase());
verify(userRepository, times(1)).save(newUser);
}
/**
* Admin can create another admin account
*/
@Test
public void adminCanCreateAnotherAdminAccount() {
User newAdmin = createAdmin("new@admin");
userService.createUser(createAdminDto("new@admin"), psw);
verify(userRepository, times(1)).save(newAdmin);
}
/**
* There can not be several users registered with the same account
*/
@Test(expected = UniqueConstraintViolationException.class)
public void thereCanNotBeSeveralUsersWithTheSameAccount() {
when(userRepository.findByEmail(userEmail)).thenReturn(Arrays.asList(createUser(userEmail)));
userService.createUser(createUserDto(userEmail), psw);
}
/**
* Admin can remove user accounts
*/
@Test
public void adminCanRemoveUserAccount() {
when(userRepository.findByEmail(userEmail)).thenReturn(Arrays.asList(createUser(userEmail)));
userService.removeUser(userEmail);
verify(userRepository, times(1)).delete(Arrays.asList(createUser(userEmail)));
}
/**
* In case there ia an attempt to remove non existing account DataAccessException should be thrown
*/
@Test(expected = DataAccessException.class)
public void nonExistingAccountCanNotBeRemoved() {
userService.removeUser("nonExistingUser");
}
/**
* Admin can remove another admin account
*/
@Test
public void adminCanRemoveAnotherAdminAccount() {
String email = "some@admin";
User admin = createAdmin(email);
when(userRepository.findByEmail(email)).thenReturn(Arrays.asList(admin));
when(userRepository.findOne(email)).thenReturn(admin);
userService.removeUser(email);
verify(userRepository, times(1)).delete(Arrays.asList(admin));
}
/**
* Admin can update user account
*/
@Test
public void adminCanUpdateUserAccount() {
when(userRepository.findByEmail(adminEmail)).thenReturn(Arrays.asList(createAdmin(adminEmail)));
when(userRepository.findByEmail(userEmail)).thenReturn(Arrays.asList(createUser(userEmail)));
// updating password
userService.updateUser(createUserDto(userEmail), "newPassword", adminEmail);
User user = createUser(userEmail);
user.setPassword(DigestUtils.sha512Hex("newPassword"));
verify(userRepository, times(1)).save(user);
}
/**
* User can not update another user account
*/
@Test(expected = OperationNotAllowedException.class)
public void userCanNotUpdateAnotherUserAccount() {
when(userRepository.findByEmail("user2@user2")).thenReturn(Arrays.asList(createUser("user2@user2")));
when(userRepository.findByEmail(userEmail)).thenReturn(Arrays.asList(createUser(userEmail)));
// updating password
userService.updateUser(createUserDto("user2@user2"), "newPassword", userEmail);
}
/**
* User can update his account
*/
@Test
public void userCanUpdateHisAccount() {
when(userRepository.findByEmail(userEmail)).thenReturn(Arrays.asList(createUser(userEmail)));
// updating password
userService.updateUser(createUserDto(userEmail), "newPassword", userEmail);
User user = createUser(userEmail);
user.setPassword(DigestUtils.sha512Hex("newPassword"));
verify(userRepository, times(1)).save(user);
}
/**
* Not existing user can not be updated
*/
@Test(expected = DataAccessException.class)
public void nonExistingAccountCanNotBeUpdated() {
userService.updateUser(createUserDto("unreal@user"), "psw", adminEmail);
}
/**
* Admin can update other admin account
*/
@Test
public void adminCanUpdateAnotherAdminAccount() {
String anotherAdminEmail = "another@admin";
User user = createAdmin(anotherAdminEmail);
when(userRepository.findByEmail(adminEmail)).thenReturn(Arrays.asList(createAdmin(adminEmail)));
when(userRepository.findByEmail(anotherAdminEmail)).thenReturn(Arrays.asList(user));
// when(userRepository.findOne(createUserDto(anotherAdminEmail).getEmail())).thenReturn(user);
// updating password
userService.updateUser(createAdminDto(anotherAdminEmail), "newPassword", adminEmail);
user.setPassword(DigestUtils.sha512Hex("newPassword"));
verify(userRepository, times(1)).save(user);
}
/**
* Admin account can not be removed in case it's last admin in system
*/
@Test(expected = OperationNotAllowedException.class)
public void lastAdminCanNotBeRemoved() {
when(userRepository.findByEmail(adminEmail)).thenReturn(Arrays.asList(createAdmin(adminEmail)));
List<User> admins = new ArrayList<>();
admins.add(UserDtoConverter.convert(createAdminDto(adminEmail)));
when(userRepository.findByRole(Roles.ADMIN.getName())).thenReturn(admins);
userService.removeUser(adminEmail);
}
/**
* Admin role can not be changed in case it's last admin in system
*/
@Test(expected = OperationNotAllowedException.class)
public void lastAdminCanNotChangeHisRoleToUser() {
when(userRepository.findByEmail(adminEmail)).thenReturn(Arrays.asList(createAdmin(adminEmail)));
List<User> admins = new ArrayList<>();
admins.add(UserDtoConverter.convert(createAdminDto(adminEmail)));
when(userRepository.findByRole(Roles.ADMIN.getName())).thenReturn(admins);
UserDto adminDto = createAdminDto(adminEmail);
adminDto.setAdmin(false);
userService.updateUser(adminDto, psw, adminEmail);
}
/**
* Users are not allowed to change their roles to admin
*/
@Test(expected = OperationNotAllowedException.class)
public void userCanNotChangHisRoleToAdmin() {
when(userRepository.findByEmail(userEmail)).thenReturn(Arrays.asList(createUser(adminEmail)));
UserDto dto = createAdminDto(userEmail);
dto.setAdmin(true);
userService.updateUser(dto, "777", userEmail);
}
/**
* In case password was not provided it should not be changed
*/
@Test
public void useOldPasswordInCaseItWasNotProvided() {
User user = createUser(userEmail);
when(userRepository.findByEmail(adminEmail)).thenReturn(Arrays.asList(createAdmin(adminEmail)));
when(userRepository.findByEmail(userEmail)).thenReturn(Arrays.asList(user));
user.setPassword("777");
when(userRepository.findOne(userEmail)).thenReturn(user);
userService.updateUser(createUserDto(userEmail), "", adminEmail);
verify(userRepository, times(1)).save(user);
}
/**
* Email should be case insensitive
*/
@Test(expected = UniqueConstraintViolationException.class)
public void emailsShouldBeCaseInsensitive() {
UserDto userDto = createUserDto(userEmail);
userDto.setEmail(userDto.getEmail().toUpperCase());
when(userRepository.findByEmail(userEmail)).thenReturn(Arrays.asList(createUser(userEmail)));
userService.createUser(userDto, psw);
}
private UserDto createUserDto(String email) {
UserDto user = new UserDto();
user.setAdmin(false);
user.setFirstName("Michael");
user.setLastName("Smith");
user.setEmail(email);
return user;
}
private UserDto createAdminDto(String email) {
UserDto user = new UserDto();
user.setAdmin(true);
user.setFirstName("admin");
user.setLastName("super");
user.setEmail(email);
return user;
}
private User createUser(String email) {
UserDto dto = createUserDto(email);
User user = UserDtoConverter.convert(dto);
user.setPassword(DigestUtils.sha512Hex(psw));
return user;
}
private User createAdmin(String email) {
UserDto dto = createAdminDto(email);
User user = UserDtoConverter.convert(dto);
user.setPassword(DigestUtils.sha512Hex(psw));
return user;
}
}