package org.molgenis.security.account; import org.mockito.ArgumentCaptor; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.molgenis.auth.Group; import org.molgenis.auth.GroupMember; import org.molgenis.auth.GroupMemberFactory; import org.molgenis.auth.User; import org.molgenis.data.DataService; import org.molgenis.data.Query; import org.molgenis.data.settings.AppSettings; import org.molgenis.security.user.MolgenisUserException; import org.molgenis.security.user.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.testng.AbstractTestNGSpringContextTests; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import javax.mail.internet.MimeMessage; import java.net.URISyntaxException; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.*; import static org.molgenis.auth.GroupMetaData.GROUP; import static org.molgenis.auth.GroupMetaData.NAME; import static org.molgenis.auth.UserMetaData.*; import static org.molgenis.security.account.AccountService.ALL_USER_GROUP; import static org.testng.Assert.assertNotNull; @ContextConfiguration public class AccountServiceImplTest extends AbstractTestNGSpringContextTests { @Autowired private AccountService accountService; @Autowired private DataService dataService; @Autowired private JavaMailSender javaMailSender; @Autowired private AppSettings appSettings; @BeforeMethod public void setUp() { reset(dataService); when(appSettings.getSignUpModeration()).thenReturn(false); Group allUsersGroup = mock(Group.class); @SuppressWarnings("unchecked") Query<Group> q = mock(Query.class); when(q.eq(NAME, ALL_USER_GROUP)).thenReturn(q); when(q.findOne()).thenReturn(allUsersGroup); when(dataService.query(GROUP, Group.class)).thenReturn(q); reset(javaMailSender); MimeMessage mimeMessage = mock(MimeMessage.class); when(javaMailSender.createMimeMessage()).thenReturn(mimeMessage); } @Test public void activateUser() { User user = mock(User.class); @SuppressWarnings("unchecked") Query<User> q = mock(Query.class); when(q.eq(ACTIVE, false)).thenReturn(q); when(q.and()).thenReturn(q); when(q.eq(ACTIVATIONCODE, "123")).thenReturn(q); when(q.findOne()).thenReturn(user); when(dataService.query(USER, User.class)).thenReturn(q); accountService.activateUser("123"); ArgumentCaptor<User> argument = ArgumentCaptor.forClass(User.class); verify(dataService).update(eq(USER), argument.capture()); verify(user).setActive(true); verify(javaMailSender).send(any(SimpleMailMessage.class)); // TODO improve test } @Test(expectedExceptions = MolgenisUserException.class) public void activateUser_invalidActivationCode() { @SuppressWarnings("unchecked") Query<User> q = mock(Query.class); when(q.eq(ACTIVE, false)).thenReturn(q); when(q.and()).thenReturn(q); when(q.eq(ACTIVATIONCODE, "invalid")).thenReturn(q); when(q.findOne()).thenReturn(null); when(dataService.query(USER, User.class)).thenReturn(q); accountService.activateUser("invalid"); } @Test(expectedExceptions = MolgenisUserException.class) public void activateUser_alreadyActivated() { @SuppressWarnings("unchecked") Query<User> q = mock(Query.class); when(q.eq(ACTIVE, false)).thenReturn(q); when(q.and()).thenReturn(q); when(q.eq(ACTIVATIONCODE, "456")).thenReturn(q); when(q.findOne()).thenReturn(null); when(dataService.query(USER, User.class)).thenReturn(q); accountService.activateUser("456"); } @Test public void createUser() throws URISyntaxException, UsernameAlreadyExistsException, EmailAlreadyExistsException { User user = mock(User.class); when(user.getEmail()).thenReturn("user@molgenis.org"); accountService.createUser(user, "http://molgenis.org/activate"); ArgumentCaptor<User> argument = ArgumentCaptor.forClass(User.class); verify(dataService).add(eq(USER), argument.capture()); verify(argument.getValue()).setActive(false); // TODO improve test } @SuppressWarnings("unchecked") @Test public void resetPassword() { User user = mock(User.class); when(user.getPassword()).thenReturn("password"); Query<User> q = mock(Query.class); when(q.eq(EMAIL, "user@molgenis.org")).thenReturn(q); when(q.findOne()).thenReturn(user); when(dataService.query(USER, User.class)).thenReturn(q); accountService.resetPassword("user@molgenis.org"); ArgumentCaptor<User> argument = ArgumentCaptor.forClass(User.class); verify(dataService).update(eq(USER), argument.capture()); assertNotNull(argument.getValue().getPassword()); verify(javaMailSender).send(any(SimpleMailMessage.class)); } @Test(expectedExceptions = MolgenisUserException.class) public void resetPassword_invalidEmailAddress() { User user = mock(User.class); when(user.getPassword()).thenReturn("password"); @SuppressWarnings("unchecked") Query<User> q = mock(Query.class); when(q.eq(EMAIL, "invalid-user@molgenis.org")).thenReturn(q); when(q.findOne()).thenReturn(null); when(dataService.query(USER, User.class)).thenReturn(q); accountService.resetPassword("invalid-user@molgenis.org"); } @Test public void changePassword() { User user = mock(User.class); when(user.getUsername()).thenReturn("test"); when(user.getPassword()).thenReturn("oldpass"); @SuppressWarnings("unchecked") Query<User> q = mock(Query.class); when(q.eq(USERNAME, "test")).thenReturn(q); when(q.findOne()).thenReturn(user); when(dataService.query(USER, User.class)).thenReturn(q); accountService.changePassword("test", "newpass"); ArgumentCaptor<User> captor = ArgumentCaptor.forClass(User.class); verify(dataService).update(eq(USER), captor.capture()); verify(captor.getValue()).setPassword("newpass"); } @Configuration static class Config { @Bean public AccountService accountService() { return new AccountServiceImpl(dataService(), mailSender(), molgenisUserService(), appSettings(), molgenisGroupMemberFactory()); } @Bean public DataService dataService() { return mock(DataService.class); } @Bean public AppSettings appSettings() { return mock(AppSettings.class); } @Bean public JavaMailSender mailSender() { return mock(JavaMailSender.class); } @Bean public UserService molgenisUserService() { return mock(UserService.class); } @Bean public GroupMemberFactory molgenisGroupMemberFactory() { GroupMemberFactory groupMemberFactory = mock(GroupMemberFactory.class); when(groupMemberFactory.create()).thenAnswer(new Answer<GroupMember>() { @Override public GroupMember answer(InvocationOnMock invocationOnMock) throws Throwable { return mock(GroupMember.class); } }); return groupMemberFactory; } } }