/** * This Source Code Form is subject to the terms of the Mozilla Public License, * v. 2.0. If a copy of the MPL was not distributed with this file, You can * obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under * the terms of the Healthcare Disclaimer located at http://openmrs.org/license. * * Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS * graphic logo is a trademark of OpenMRS Inc. */ package org.openmrs.api; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.openmrs.test.TestUtil.containsId; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.junit.AfterClass; import org.junit.Assert; import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.Before; import org.junit.rules.ExpectedException; import org.openmrs.Patient; import org.openmrs.Person; import org.openmrs.PersonName; import org.openmrs.Privilege; import org.openmrs.Role; import org.openmrs.User; import org.openmrs.api.context.Context; import org.openmrs.api.db.DAOException; import org.openmrs.messagesource.MessageSourceService; import org.openmrs.patient.impl.LuhnIdentifierValidator; import org.openmrs.test.BaseContextSensitiveTest; import org.openmrs.test.SkipBaseSetup; import org.openmrs.util.PrivilegeConstants; import org.openmrs.util.RoleConstants; import org.openmrs.util.Security; /** * TODO add more tests to cover the methods in <code>UserService</code> */ public class UserServiceTest extends BaseContextSensitiveTest { protected static final String XML_FILENAME = "org/openmrs/api/include/UserServiceTest.xml"; protected static final String XML_FILENAME_WITH_DATA_FOR_CHANGE_PASSWORD_ACTION = "org/openmrs/api/include/UserServiceTest-changePasswordAction.xml"; protected static final String SOME_VALID_PASSWORD = "s0mePassword"; public static final String SOME_USERNAME = "butch"; private final String ADMIN_USERNAME = "admin"; private UserService userService; private MessageSourceService messages; @Rule public ExpectedException expectedException = ExpectedException.none(); @Before public void setup() { userService = Context.getUserService(); messages = Context.getMessageSourceService(); } /** * Methods in this class might authenticate with a different user, so log that user out after * this whole junit class is done. */ @AfterClass public static void logOutAfterThisTest() { Context.logout(); } @Test public void createUser_shouldCreateNewUserWithBasicElements() { assertTrue("The context needs to be correctly authenticated to by a user", Context.isAuthenticated()); User u = new User(); u.setPerson(new Person()); u.addName(new PersonName("Benjamin", "A", "Wolfe")); u.setUsername("bwolfe"); u.getPerson().setGender("M"); User createdUser = userService.createUser(u, "Openmr5xy"); // if we're returning the object from create methods, check validity assertTrue("The user returned by the create user method should equal the passed in user", createdUser.equals(u)); createdUser = userService.getUserByUsername("bwolfe"); assertTrue("The created user should equal the passed in user", createdUser.equals(u)); } @Test @SkipBaseSetup public void createUser_shouldShouldCreateUserWhoIsPatientAlready() throws SQLException { // create the basic user and give it full rights initializeInMemoryDatabase(); // authenticate to the temp database authenticate(); assertTrue("The context needs to be correctly authenticated to by a user", Context.isAuthenticated()); // add in some basic data executeDataSet(XML_FILENAME); // the user should not exist yet User preliminaryFetchedUser = userService.getUser(2); assertNull(preliminaryFetchedUser); // get the person object we'll make into a user Person personToMakeUser = Context.getPersonService().getPerson(2); // this avoids a lazy init exception, since we're going to clear the session ((Patient) personToMakeUser).getIdentifiers().size(); Context.clearSession(); // this is the user object we'll be saving User user = new User(personToMakeUser); user.setUsername("bwolfe"); user.setSystemId("asdf"); user.addRole(new Role("Some Role", "This is a test role")); //included in xml file // make sure everything was added to the user correctly assertTrue(user.getUsername().equals("bwolfe")); assertTrue(user.hasRole("Some Role")); // do the actual creating of the user object userService.createUser(user, "Openmr5xy"); Assert.assertNotNull("User was not created", userService.getUser(user.getUserId())); Integer shouldCreateUserWhoIsPatientAlreadyTestUserIdCreated = user.getUserId(); Context.flushSession(); // get the same user we just created and make sure the user portion exists User fetchedUser = userService.getUser(shouldCreateUserWhoIsPatientAlreadyTestUserIdCreated); User fetchedUser3 = userService.getUser(3); if (fetchedUser3 != null) { throw new RuntimeException("There is a user with id #3"); } assertNotNull("Uh oh, the user object was not created", fetchedUser); assertNotNull("Uh oh, the username was not saved", fetchedUser.getUsername()); assertTrue("Uh oh, the username was not saved", fetchedUser.getUsername().equals("bwolfe")); assertTrue("Uh oh, the role was not assigned", fetchedUser.hasRole("Some Role")); Context.clearSession(); List<User> allUsers = userService.getAllUsers(); assertEquals(11, allUsers.size()); // there should still only be the one patient we created in the xml file List<Patient> allPatientsSet = Context.getPatientService().getAllPatients(); assertEquals(1, allPatientsSet.size()); } @Test public void createUser_shouldNotAllowExistingUser() { User someUser = userService.getUserByUsername(SOME_USERNAME); expectedException.expect(APIException.class); expectedException.expectMessage("This method can be used for only creating new users"); userService.createUser(someUser, SOME_VALID_PASSWORD); } @Test public void createUser_shouldNotAllowBlankPassword() { User unsavedUser = new User(); expectedException.expect(ValidationException.class); userService.createUser(unsavedUser, ""); } @Test public void createUser_shouldNotAllowNullPassword() { User unsavedUser = new User(); expectedException.expect(ValidationException.class); userService.createUser(unsavedUser, null); } @Test public void createUser_shouldNotAllowForDuplicatedUsername() { User someUser = userService.getUserByUsername(SOME_USERNAME); User newUser = userWithValidPerson(); newUser.setUsername(someUser.getUsername()); expectedException.expect(DAOException.class); expectedException.expectMessage( String.format("Username %s or system id %s is already in use.", newUser.getUsername(), Context.getUserService().generateSystemId())); userService.createUser(newUser, SOME_VALID_PASSWORD); } @Test public void createUser_shouldNotAllowDuplicatedSystemId() { User someUser = userService.getUserByUsername(SOME_USERNAME); User newUser = userWithValidPerson(); newUser.setSystemId(someUser.getSystemId()); expectedException.expect(DAOException.class); expectedException.expectMessage( String.format("Username %s or system id %s is already in use.", newUser.getUsername(), newUser.getSystemId())); userService.createUser(newUser, SOME_VALID_PASSWORD); } @Test public void createUser_shouldNotAllowUsernameEqualsExistingSystemId() { User someUser = userService.getUserByUsername(SOME_USERNAME); User newUser = userWithValidPerson(); newUser.setUsername(someUser.getSystemId()); expectedException.expect(DAOException.class); expectedException.expectMessage( String.format("Username %s or system id %s is already in use.", newUser.getUsername(), Context.getUserService().generateSystemId())); userService.createUser(newUser, SOME_VALID_PASSWORD); } @Test public void createUser_shouldNotAllowSystemIdEqualsExistingUsername() { User someUser = userService.getUserByUsername(SOME_USERNAME); User newUser = userWithValidPerson(); newUser.setSystemId(someUser.getUsername()); expectedException.expect(DAOException.class); expectedException.expectMessage( String.format("Username %s or system id %s is already in use.", newUser.getUsername(), newUser.getSystemId())); userService.createUser(newUser, SOME_VALID_PASSWORD); } @Test public void createUser_shouldNotAllowSystemIdEqualsUsernameWithLuhnCheckDigit() { User someUser = userService.getUserByUsername(SOME_USERNAME); User newUser = userWithValidPerson(); newUser.setUsername(someUser.getUsername()); newUser.setSystemId(decorateWithLuhnIdentifier(someUser.getUsername())); expectedException.expect(DAOException.class); expectedException.expectMessage( String.format("Username %s or system id %s is already in use.", newUser.getUsername(), newUser.getSystemId())); userService.createUser(newUser, SOME_VALID_PASSWORD); } private User userWithValidPerson() { Person person = new Person(); person.addName(new PersonName("jane", "sue", "doe")); person.setGender("F"); return new User(person); } private String decorateWithLuhnIdentifier(String value) { return new LuhnIdentifierValidator().getValidIdentifier(value); } @Test public void saveUser_shouldUpdateUsersUsername() { User u = userService.getUserByUsername(ADMIN_USERNAME); assertNotNull("There needs to be a user with username 'admin' in the database", u); u.setUsername("admin2"); userService.saveUser(u); User u2 = userService.getUserByUsername("admin2"); assertEquals("The fetched user should equal the user we tried to update", u, u2); } /** * Test changing a user's password multiple times in the same transaction * * @see UserService#changePassword(String,String) */ @Test public void changePassword_shouldBeAbleToUpdatePasswordMultipleTimes() { User u = userService.getUserByUsername(ADMIN_USERNAME); assertNotNull("There needs to be a user with username 'admin' in the database", u); userService.changePassword("test", "Tester12"); userService.changePassword("Tester12", "Tester13"); } @Test public void saveUser_shouldGrantNewRolesInRolesListToUser() { // add in some basic properties executeDataSet(XML_FILENAME); User u = userService.getUserByUsername(ADMIN_USERNAME); Role role1 = new Role(); role1.setDescription("testing1"); role1.setRole("test1"); Privilege p1 = userService.getAllPrivileges().get(0); Set<Privilege> privileges1 = new HashSet<>(); privileges1.add(p1); role1.setPrivileges(privileges1); Role role2 = new Role(); role2.setDescription("testing2"); role2.setRole("test2"); Privilege p2 = userService.getAllPrivileges().get(0); Set<Privilege> privileges2 = new HashSet<>(); privileges2.add(p2); role2.setPrivileges(privileges2); userService.saveUser(u.addRole(role1)); userService.saveUser(u.addRole(role2)); // so the contents are fetched from the db Context.evictFromSession(u); userService.getUser(u.getUserId()).hasRole("test1"); userService.getUser(u.getUserId()).hasRole("test2"); } /** * @see UserService#getUserByUsername(String) */ @Test public void getUserByUsername_shouldGetUserByUsername() { User user = userService.getUserByUsername(ADMIN_USERNAME); assertNotNull("username not found " + ADMIN_USERNAME, user); } /** * @see UserService#changePassword(String,String) */ @Test public void changePassword_shouldMatchOnIncorrectlyHashedSha1StoredPassword() { executeDataSet(XML_FILENAME); Context.logout(); Context.authenticate("incorrectlyhashedSha1", "test"); userService.changePassword("test", "Tester12"); Context.logout(); // so that the next test reauthenticates } /** * @see UserService#changeQuestionAnswer(String,String,String) */ @Test public void changeQuestionAnswer_shouldMatchOnCorrectlyHashedStoredPassword() { executeDataSet(XML_FILENAME); Context.logout(); Context.authenticate("correctlyhashedSha1", "test"); userService.changeQuestionAnswer("test", "some question", "some answer"); Context.logout(); // so that the next test reauthenticates } /** * @see UserService#changeQuestionAnswer(String,String,String) */ @Test public void changeQuestionAnswer_shouldMatchOnIncorrectlyHashedStoredPassword() { executeDataSet(XML_FILENAME); Context.logout(); Context.authenticate("incorrectlyhashedSha1", "test"); userService.changeQuestionAnswer("test", "some question", "some answer"); Context.logout(); // so that the next test reauthenticates } /** * @see UserService#changePassword(String,String) */ @Test public void changePassword_shouldMatchOnCorrectlyHashedSha1StoredPassword() { executeDataSet(XML_FILENAME); Context.logout(); Context.authenticate("correctlyhashedSha1", "test"); userService.changePassword("test", "Tester12"); Context.logout(); // so that the next test reauthenticates } /** * @see UserService#getUsers(String,List,boolean) */ @Test public void getUsers_shouldMatchSearchToFamilyName2() { executeDataSet("org/openmrs/api/include/PersonServiceTest-extranames.xml"); List<User> users = userService.getUsers("Johnson", null, false); Assert.assertEquals(3, users.size()); Assert.assertTrue(containsId(users, 2)); Assert.assertTrue(containsId(users, 4)); Assert.assertTrue(containsId(users, 5)); } /** * @see UserService#changePassword(String,String) */ @Test public void changePassword_shouldMatchOnSha512HashedPassword() { executeDataSet(XML_FILENAME); Context.logout(); Context.authenticate("userWithSha512Hash", "test"); userService.changePassword("test", "Tester12"); Context.logout(); // so that the next test reauthenticates } /** * This test verifies that {@link PersonName}s are fetched correctly from the hibernate cache. * (Or really, not fetched from the cache but instead are mapped with lazy=false. For some * reason Hibernate isn't able to find objects in the cache if a parent object was the one that * loaded them) * * @throws Exception */ @Test public void shouldFetchNamesForPersonsThatWereFirstFetchedAsUsers() { Person person = Context.getPersonService().getPerson(1); User user = userService.getUser(1); user.getNames().size(); person.getNames().size(); } /** * @see UserService#getPrivilegeByUuid(String) */ @Test public void getPrivilegeByUuid_shouldFindObjectGivenValidUuid() { executeDataSet(XML_FILENAME); String uuid = "d979d066-15e6-467c-9d4b-cb575ef97f0f"; Privilege privilege = userService.getPrivilegeByUuid(uuid); Assert.assertEquals("Some Privilege", privilege.getPrivilege()); } /** * @see UserService#getPrivilegeByUuid(String) */ @Test public void getPrivilegeByUuid_shouldReturnNullIfNoObjectFoundWithGivenUuid() { Assert.assertNull(userService.getPrivilegeByUuid("some invalid uuid")); } /** * @see UserService#getRoleByUuid(String) */ @Test public void getRoleByUuid_shouldFindObjectGivenValidUuid() { String uuid = "3480cb6d-c291-46c8-8d3a-96dc33d199fb"; Role role = userService.getRoleByUuid(uuid); Assert.assertEquals("Provider", role.getRole()); } /** * @see UserService#getRoleByUuid(String) */ @Test public void getRoleByUuid_shouldReturnNullIfNoObjectFoundWithGivenUuid() { Assert.assertNull(userService.getRoleByUuid("some invalid uuid")); } /** * @see UserService#getUserByUuid(String) */ @Test public void getUserByUuid_shouldFindObjectGivenValidUuid() { String uuid = "c1d8f5c2-e131-11de-babe-001e378eb67e"; User user = userService.getUserByUuid(uuid); Assert.assertEquals(501, (int) user.getUserId()); } /** * @see UserService#getUserByUuid(String) */ @Test public void getUserByUuid_shouldReturnNullIfNoObjectFoundWithGivenUuid() { Assert.assertNull(userService.getUserByUuid("some invalid uuid")); } /** * @see UserService#changeHashedPassword(User,String,String) */ @Test public void changeHashedPassword_shouldChangeTheHashedPasswordForTheGivenUser() { User user = userService.getUser(1); String salt = Security.getRandomToken(); String hash = Security.encodeString("new password" + salt); userService.changeHashedPassword(user, hash, salt); // TODO Review this a little further // This is the assert - checks to see if current user can use the new password userService.changePassword("new password", "Another new password1"); // try to change the password with the new one } /** * @see UserService#changePassword(User,String) */ @Test public void changePassword_shouldChangePasswordForTheGivenUserAndPassword() { userService.changePassword("test", "Another new password1"); userService.changePassword("Another new password1", "Yet another new password1"); // try to change the password with the new one } /** * @see UserService#changeQuestionAnswer(User,String,String) */ @Test @Ignore // TODO fix: the question not sticking - null expected:<[the question]> but was:<[]> public void changeQuestionAnswer_shouldChangeTheSecretQuestionAndAnswerForGivenUser() { User u = userService.getUser(501); userService.changeQuestionAnswer(u, "the question", "the answer"); // need to retrieve the user since the service method does not modify the given user object User o = userService.getUser(501); Assert.assertTrue(userService.isSecretAnswer(o, "the answer")); } /** * @see UserService#getAllPrivileges() */ @Test public void getAllPrivileges_shouldReturnAllPrivilegesInTheSystem() { executeDataSet(XML_FILENAME); List<Privilege> privileges = userService.getAllPrivileges(); Assert.assertEquals(1, privileges.size()); } /** * @see UserService#getAllRoles() */ @Test public void getAllRoles_shouldReturnAllRolesInTheSystem() { executeDataSet(XML_FILENAME); List<Role> roles = userService.getAllRoles(); Assert.assertEquals(7, roles.size()); } /** * @see UserService#getAllUsers() */ @Test public void getAllUsers_shouldFetchAllUsersInTheSystem() { List<User> users = userService.getAllUsers(); Assert.assertEquals(4, users.size()); } /** * @see UserService#getAllUsers() */ @Test public void getAllUsers_shouldNotContainsAnyDuplicateUsers() { executeDataSet(XML_FILENAME); List<User> users = userService.getAllUsers(); Assert.assertEquals(12, users.size()); // TODO Need to test with duplicate data in the dataset (not sure if that's possible) } @Test @SkipBaseSetup public void getUserByUuid_shouldFetchUserWithGivenUuid() throws SQLException { initializeInMemoryDatabase(); executeDataSet(XML_FILENAME); authenticate(); User user = userService.getUserByUuid("013c49c6-e132-11de-babe-001e378eb67e"); assertEquals("Did not fetch user with given uuid", user, userService.getUser(5505)); } @Test @SkipBaseSetup public void getUsersByName_shouldFetchUsersExactlyMatchingTheGivenGivenNameAndFamilyName() throws SQLException { initializeInMemoryDatabase(); executeDataSet(XML_FILENAME); authenticate(); // this generates an error: // org.hibernate.QueryException: illegal attempt to dereference // collection [user0_.user_id.names] with element property reference [givenName] // [from org.openmrs.User u where u.names.givenName = :givenName and u.names.familyName // = :familyName and u.voided = false] List<User> users = userService.getUsersByName("Susy", "Kingman", false); assertEquals(1, users.size()); } @Test public void getUsersByName_shouldFetchVoidedUsersWhenincludeVoidedIsTrue() { User voidedUser = userService.getUser(501); // assertTrue(voidedUser.getVoided()); // this generates an error: // org.hibernate.QueryException: illegal attempt to dereference // collection [user0_.user_id.names] with element property reference [givenName] // [from org.openmrs.User u where u.names.givenName = :givenName and u.names.familyName // = :familyName] List<User> users = userService.getUsersByName("Bruno", "Otterbourg", true); assertTrue(users.contains(voidedUser)); } @Test public void getUsersByName_shouldNotFetchAnyVoidedUsersWhenIncludeVoidedIsFalse() { User voidedUser = userService.getUser(501); // assertTrue(voidedUser.getVoided()); // this generates an error: // org.hibernate.QueryException: illegal attempt to dereference // collection [user0_.user_id.names] with element property reference [givenName] // [from org.openmrs.User u where u.names.givenName = :givenName and u.names.familyName // = :familyName and u.voided = false] List<User> users = userService.getUsersByName("Bruno", "Otterbourg", false); assertFalse(users.contains(voidedUser)); } @Test @SkipBaseSetup public void getUsersByName_shouldNotFetchAnyDuplicateUsers() throws SQLException { initializeInMemoryDatabase(); executeDataSet(XML_FILENAME); authenticate(); // user with ID 4 has a preferred name "John Doe" and a not preferred name "John Doe." // If this method does not fetch any duplicate users, this user should only // appear once in the list of users that are returned with this method. // this generates an error: // org.hibernate.QueryException: illegal attempt to dereference // collection [user0_.user_id.names] with element property reference [givenName] // [from org.openmrs.User u where u.names.givenName = :givenName and u.names.familyName // = :familyName and u.voided = false] List<User> users = userService.getUsersByName("John", "Doe", false); assertEquals(1, users.size()); } /** * @see UserService#getPrivilege(String) */ @Test public void getPrivilege_shouldFetchPrivilegeForGivenName() { executeDataSet(XML_FILENAME); Privilege privilege = userService.getPrivilege("Some Privilege"); Assert.assertEquals("Some Privilege", privilege.getPrivilege()); } /** * @see UserService#getRole(String) */ @Test public void getRole_shouldFetchRoleForGivenRoleName() { executeDataSet(XML_FILENAME); Role role = userService.getRole("Some Role"); Assert.assertEquals("Some Role", role.getRole()); } /** * @see UserService#getUser(Integer) */ @Test public void getUser_shouldFetchUserWithGivenUserId() { User user = userService.getUser(501); Assert.assertEquals(501, user.getUserId().intValue()); } /** * @see UserService#getUsers(String,List,boolean) */ @Test public void getUsers_shouldFetchUsersWithAtLeastOneOfTheGivenRoleObjects() { executeDataSet(XML_FILENAME); List<Role> roles = Collections.singletonList(new Role("Some Role")); Assert.assertEquals(1, userService.getUsers("Susy Kingman", roles, false).size()); } /** * @see UserService#getUsers(String,List,boolean) */ @Test public void getUsers_shouldFetchUsersWithNameThatContainsGivenNameSearch() { Assert.assertEquals(1, userService.getUsers("Hippocrates", null, false).size()); } /** * @see UserService#getUsers(String,List,boolean) */ @Test public void getUsers_shouldFetchUsersWithSystemIdThatContainsGivenNameSearch() { Assert.assertEquals(1, userService.getUsers("2-6", null, true).size()); } /** * @see UserService#getUsers(String,List,boolean) */ @Test public void getUsers_shouldFetchVoidedUsersIfIncludedVoidedIsTrue() { Assert.assertEquals(1, userService.getUsers("Bruno", null, true).size()); } /** * @see UserService#getUsers(String,List,boolean) */ @Test public void getUsers_shouldFetchAllUsersIfNameSearchIsEmptyOrNull() { Assert.assertEquals(4, userService.getUsers("", null, true).size()); Assert.assertEquals(4, userService.getUsers(null, null, true).size()); } /** * @see UserService#getUsers(String,List,boolean) */ @Test public void getUsers_shouldNotFetchDuplicateUsers() { executeDataSet(XML_FILENAME); List<User> users = userService.getUsers("John Doe", null, false); Assert.assertEquals(1, users.size()); } /** * @see UserService#getUsers(String,List,boolean) */ @Test public void getUsers_shouldNotFetchVoidedUsersIfIncludedVoidedIsFalse() { Assert.assertEquals(0, userService.getUsers("Bruno", null, false).size()); } /** * @see UserService#getUsersByRole(Role) */ @Test public void getUsersByRole_shouldFetchUsersAssignedGivenRole() { executeDataSet(XML_FILENAME); Assert.assertEquals(2, userService.getUsersByRole(new Role("Some Role")).size()); } /** * @see UserService#getUsersByRole(Role) */ @Test public void getUsersByRole_shouldNotFetchUserThatDoesNotBelongToGivenRole() { executeDataSet(XML_FILENAME); Assert.assertEquals(0, userService.getUsersByRole(new Role("Nonexistent role")).size()); } /** * @see UserService#hasDuplicateUsername(User) */ @Test public void hasDuplicateUsername_shouldVerifyThatUsernameAndSystemIdIsUnique() { executeDataSet(XML_FILENAME); User user = new User(); user.setSystemId("8-3"); user.setUsername("a unique username"); Assert.assertTrue(userService.hasDuplicateUsername(user)); user = new User(); user.setSystemId("a unique system id"); user.setUsername("userWithSha512Hash"); Assert.assertTrue(userService.hasDuplicateUsername(user)); } /** * @see UserService#isSecretAnswer(User,String) */ @Test public void isSecretAnswer_shouldReturnFalseWhenGivenAnswerDoesNotMatchTheStoredSecretAnswer() { User user = userService.getUser(502); Assert.assertFalse(userService.isSecretAnswer(user, "not the answer")); } /** * @see UserService#isSecretAnswer(User,String) */ @Test public void isSecretAnswer_shouldReturnTrueWhenGivenAnswerMatchesStoredSecretAnswer() { executeDataSet(XML_FILENAME); User user = userService.getUser(5507); userService.changeQuestionAnswer(user, "question", "answer"); Assert.assertTrue(userService.isSecretAnswer(user, "answer")); } /** * @see UserService#purgePrivilege(Privilege) */ @Test public void purgePrivilege_shouldDeleteGivenPrivilegeFromTheDatabase() { userService.purgePrivilege(new Privilege("Some Privilege")); Assert.assertNull(userService.getPrivilege("Some Privilege")); } /** * @see UserService#purgePrivilege(Privilege) */ @Test public void purgePrivilege_shouldThrowErrorWhenPrivilegeIsCorePrivilege() { expectedException.expect(APIException.class); userService.purgePrivilege(new Privilege(PrivilegeConstants.ADD_COHORTS)); } /** * @see UserService#purgeRole(Role) */ @Test public void purgeRole_shouldDeleteGivenRoleFromDatabase() { executeDataSet(XML_FILENAME); Role role = userService.getRole("Some Role To Delete"); userService.purgeRole(role); Assert.assertNull(userService.getRole("Some Role To Delete")); } /** * @see UserService#purgeRole(Role) */ @Test public void purgeRole_shouldReturnIfRoleIsNull() { userService.purgeRole(null); } /** * @see UserService#purgeRole(Role) */ @Test public void purgeRole_shouldThrowErrorWhenRoleIsACoreRole() { Role role = new Role(RoleConstants.ANONYMOUS); expectedException.expect(APIException.class); userService.purgeRole(role); } /** * @see UserService#purgeUser(User) */ @Test public void purgeRole_shouldThrowErrorWhenRoleHasChildRoles() { Set<Role> childRole = new HashSet<>(); Role role1 = new Role("role_parent"); Role role2 = new Role("role_child"); childRole.add(role1); role2.setChildRoles(childRole); expectedException.expect(CannotDeleteRoleWithChildrenException.class); userService.purgeRole(role2); } /** * @see UserService#purgeUser(User) */ @Test public void purgeUser_shouldDeleteGivenUser() { User user = userService.getUser(502); userService.purgeUser(user); Assert.assertNull(userService.getUser(2)); } /** * @see UserService#purgeUser(User,boolean) */ @Test public void purgeUser_shouldDeleteGivenUserWhenCascadeEqualsFalse() { User user = userService.getUser(502); userService.purgeUser(user, false); Assert.assertNull(userService.getUser(502)); } /** * @see UserService#purgeUser(User,boolean) */ @Test public void purgeUser_shouldThrowAPIExceptionIfCascadeIsTrue() { User user = userService.getUser(502); expectedException.expect(APIException.class); userService.purgeUser(user, true); } /** * @see UserService#removeUserProperty(User,String) */ @Test public void removeUserProperty_shouldRemoveUserPropertyForGivenUserAndKey() { executeDataSet(XML_FILENAME); User user = userService.getUser(5505); Assert.assertNotSame("", user.getUserProperty("some key")); userService.removeUserProperty(user, "some key"); user = userService.getUser(5505); Assert.assertEquals("", user.getUserProperty("some key")); } /** * @see UserService#removeUserProperty(User,String) */ @Test public void removeUserProperty_shouldReturnNullIfUserIsNull() { Assert.assertNull(userService.setUserProperty(null, "some key", "some new value")); } /** * @see UserService#removeUserProperty(User,String) */ @Test public void removeUserProperty_shouldThrowErrorWhenUserIsNotAuthorizedToEditUsers() { executeDataSet(XML_FILENAME); User user = userService.getUser(5505); Context.logout(); expectedException.expect(APIException.class); userService.removeUserProperty(user, "some key"); } /** * @see UserService#savePrivilege(Privilege) */ @Test public void savePrivilege_shouldSaveGivenPrivilegeToTheDatabase() { Privilege p = new Privilege("new privilege name", "new privilege desc"); userService.savePrivilege(p); Privilege savedPrivilege = userService.getPrivilege("new privilege name"); Assert.assertNotNull(savedPrivilege); } /** * @see UserService#setUserProperty(User,String,String) */ @Test public void setUserProperty_shouldAddPropertyWithGivenKeyAndValueWhenKeyDoesNotAlreadyExist() { executeDataSet(XML_FILENAME); User user = userService.getUser(5505); // Check that it doesn't already exist Assert.assertEquals(user.getUserProperty("some new key"), ""); userService.setUserProperty(user, "some new key", "some new value"); user = userService.getUser(5505); Assert.assertEquals("some new value", user.getUserProperty("some new key")); } /** * @see UserService#setUserProperty(User,String,String) */ @Test public void setUserProperty_shouldModifyPropertyWithGivenKeyAndValueWhenKeyAlreadyExists() { executeDataSet(XML_FILENAME); User user = userService.getUser(5505); // Check that it already exists Assert.assertEquals(user.getUserProperty("some key"), "some value"); userService.setUserProperty(user, "some key", "some new value"); user = userService.getUser(5505); Assert.assertEquals("some new value", user.getUserProperty("some key")); } /** * @see UserService#setUserProperty(User,String,String) */ @Test public void setUserProperty_shouldReturnNullIfUserIsNull() { Assert.assertNull(userService.setUserProperty(null, "some key", "some value")); } /** * @see UserService#setUserProperty(User,String,String) */ @Test public void setUserProperty_shouldThrowErrorWhenUserIsNotAuthorizedToEditUsers() { User user = userService.getUser(502); Context.logout(); expectedException.expect(APIException.class); userService.setUserProperty(user, "some key", "some value"); } /** * @see UserService#saveRole(Role) */ @Test public void saveRole_shouldSaveGivenRoleToTheDatabase() { Role role = new Role("new role", "new desc"); userService.saveRole(role); Assert.assertNotNull(userService.getRole("new role")); } /** * @see UserService#saveRole(Role) */ @Test public void saveRole_shouldThrowErrorIfRoleInheritsFromItself() { Role parentRole = new Role("parent role"); // Have child inherit parent role Role childRole = new Role("child role"); Set<Role> inheritsFromParent = new HashSet<>(); inheritsFromParent.add(parentRole); childRole.setInheritedRoles(inheritsFromParent); // Now have parent try to inherit the child role. Set<Role> inheritsFromChild = new HashSet<>(); inheritsFromChild.add(childRole); parentRole.setInheritedRoles(inheritsFromChild); expectedException.expect(APIException.class); expectedException.expectMessage(messages.getMessage("Role.cannot.inherit.descendant")); userService.saveRole(parentRole); } /** * @see UserService#getUsersByPerson(Person,null) */ @Test public void getUsersByPerson_shouldFetchAllAccountsForAPersonWhenIncludeRetiredIsTrue() { executeDataSet(XML_FILENAME); Person person = new Person(5508); List<User> users = userService.getUsersByPerson(person, true); Assert.assertEquals(3, users.size()); } /** * @see UserService#getUsersByPerson(Person,null) */ @Test public void getUsersByPerson_shouldNotFetchRetiredAccountsWhenIncludeRetiredIsFalse() { executeDataSet(XML_FILENAME); Person person = new Person(5508); List<User> users = userService.getUsersByPerson(person, false); Assert.assertEquals(2, users.size()); } /** * @see UserService#retireUser(User,String) */ @Test public void retireUser_shouldRetireUserAndSetAttributes() { User user = userService.getUser(502); userService.retireUser(user, "because"); Assert.assertTrue(user.getRetired()); Assert.assertNotNull(user.getDateRetired()); Assert.assertNotNull(user.getRetiredBy()); Assert.assertEquals("because", user.getRetireReason()); } /** * @see UserService#unretireUser(User) */ @Test public void unretireUser_shouldUnretireAndUnmarkAllAttributes() { User user = userService.getUser(501); userService.unretireUser(user); Assert.assertFalse(user.getRetired()); Assert.assertNull(user.getDateRetired()); Assert.assertNull(user.getRetiredBy()); Assert.assertNull(user.getRetireReason()); } @Test public void saveUser_shouldFailToCreateTheUserWithAWeakPassword() { assertTrue("The context needs to be correctly authenticated to by a user", Context.isAuthenticated()); UserService us = userService; User u = new User(); u.setPerson(new Person()); u.addName(new PersonName("Benjamin", "A", "Wolfe")); u.setUsername("bwolfe"); u.getPerson().setGender("M"); expectedException.expect(PasswordException.class); us.createUser(u, "short"); } /** * This is a regression test for TRUNK-2108 <br> * * @see UserService#getUsers(String,List,boolean) */ @Test public void getUsers_shouldNotFailIfRolesAreSearchedButNameIsEmpty() { Role role = new Role("Provider"); List<Role> roles = new ArrayList<>(); roles.add(role); Assert.assertEquals(2, userService.getUsers("", roles, true).size()); } /** * @see UserService#getUsers(String, List, boolean, Integer, Integer) */ @Test public void getUsers_shouldReturnUsersWhoseRolesInheritRequestedRoles() { executeDataSet(XML_FILENAME); List<Role> roles = new ArrayList<>(); roles.add(userService.getRole("Parent")); Assert.assertEquals(3, userService.getUsers(null, roles, true, null, null).size()); } @Test public void saveUserProperty_shouldAddNewPropertyToExistingUserProperties() { executeDataSet(XML_FILENAME); // retrieve a user who has UserProperties User user = userService.getUser(5511); // Authenticate the test user so that Context.getAuthenticatedUser() method returns above user Context.authenticate(user.getUsername(), "testUser1234"); final int numberOfUserProperties = user.getUserProperties().size(); assertEquals(1, user.getUserProperties().size()); final String USER_PROPERTY_KEY = "test-key"; final String USER_PROPERTY_VALUE = "test-value"; User updatedUser = userService.saveUserProperty(USER_PROPERTY_KEY, USER_PROPERTY_VALUE); assertNotNull(updatedUser.getUserProperty(USER_PROPERTY_KEY)); assertEquals(USER_PROPERTY_VALUE, updatedUser.getUserProperty(USER_PROPERTY_KEY)); //make sure that properties count is incremented by one assertEquals((numberOfUserProperties + 1), updatedUser.getUserProperties().size()); } @Test public void saveUserProperties_shouldRemoveAllExistingPropertiesAndAssignNewProperties() { executeDataSet(XML_FILENAME); // retrieve a user who has UserProperties User user = userService.getUser(5511); assertEquals(1, user.getUserProperties().size()); // Authenticate the test user so that Context.getAuthenticatedUser() method returns above user Context.authenticate(user.getUsername(), "testUser1234"); final String USER_PROPERTY_KEY_1 = "test-key1"; final String USER_PROPERTY_VALUE_1 = "test-value1"; final String USER_PROPERTY_KEY_2 = "test-key2"; final String USER_PROPERTY_VALUE_2 = "test-value2"; Map<String, String> propertiesMap = new HashMap<>(); propertiesMap.put(USER_PROPERTY_KEY_1, USER_PROPERTY_VALUE_1); propertiesMap.put(USER_PROPERTY_KEY_2, USER_PROPERTY_VALUE_2); propertiesMap = Collections.unmodifiableMap(propertiesMap); User updatedUser = userService.saveUserProperties(propertiesMap); //we should have only the new properties assertEquals(2, updatedUser.getUserProperties().size()); //Verify that the new properties were saved assertEquals(USER_PROPERTY_VALUE_1, updatedUser.getUserProperty(USER_PROPERTY_KEY_1)); assertEquals(USER_PROPERTY_VALUE_2, updatedUser.getUserProperty(USER_PROPERTY_KEY_2)); } /** * @see UserService#changePassword(User,String,String) */ @Test public void changePassword_shouldChangePasswordForGivenUserIfOldPasswordIsCorrectlyPassed() { executeDataSet(XML_FILENAME_WITH_DATA_FOR_CHANGE_PASSWORD_ACTION); //user 6001 has password userServiceTest User user6001 = userService.getUser(6001); String oldPassword = "userServiceTest"; String newPassword = "newPasswordString123"; userService.changePassword(user6001, oldPassword, newPassword); //try to authenticate with new password Context.authenticate(user6001.getUsername(), newPassword); } /** * @see UserService#changePassword(User,String,String) */ @Test public void changePassword_shouldChangePasswordForGivenUserIfOldPasswordIsNullAndChangingUserHavePrivileges() { executeDataSet(XML_FILENAME_WITH_DATA_FOR_CHANGE_PASSWORD_ACTION); //user 6001 has password userServiceTest User user6001 = userService.getUser(6001); String oldPassword = null; String newPassword = "newPasswordString123"; userService.changePassword(user6001, oldPassword, newPassword); Context.authenticate(user6001.getUsername(), newPassword); } /** * @see UserService#changePassword(User,String,String) */ @Test public void changePassword_shouldThrowAPIExceptionIfOldPasswordIsNotCorrect() { executeDataSet(XML_FILENAME_WITH_DATA_FOR_CHANGE_PASSWORD_ACTION); //user 6001 has password userServiceTest User user6001 = userService.getUser(6001); String wrongPassword = "wrong password!"; String newPassword = "newPasswordString"; //log in user without change user passwords privileges //user6001 has not got required priviliges Context.authenticate(user6001.getUsername(), "userServiceTest"); expectedException.expect(APIAuthenticationException.class); expectedException.expectMessage(messages .getMessage("error.privilegesRequired", new Object[] {PrivilegeConstants.EDIT_USER_PASSWORDS}, null)); userService.changePassword(user6001, wrongPassword, newPassword); } /** * @see UserService#changePassword(User,String,String) */ @Test public void changePassword_shouldThrowExceptionIfOldPasswordIsNullAndChangingUserHaveNotPrivileges() { executeDataSet(XML_FILENAME_WITH_DATA_FOR_CHANGE_PASSWORD_ACTION); //user 6001 has password userServiceTest User user6001 = userService.getUser(6001); assertFalse(user6001.hasPrivilege(PrivilegeConstants.EDIT_USER_PASSWORDS)); String oldPassword = null; String newPassword = "newPasswordString"; //log in user without change user passwords privileges //user6001 has not got required priviliges Context.authenticate(user6001.getUsername(), "userServiceTest"); expectedException.expect(APIException.class); expectedException.expectMessage(messages .getMessage("error.privilegesRequired", new Object[] {PrivilegeConstants.EDIT_USER_PASSWORDS}, null)); userService.changePassword(user6001, oldPassword, newPassword); } /** * @see UserService#changePassword(User,String,String) */ @Test public void changePassword_shouldThrowExceptionIfNewPasswortIsTooShort() { executeDataSet(XML_FILENAME_WITH_DATA_FOR_CHANGE_PASSWORD_ACTION); //user 6001 has password userServiceTest User user6001 = userService.getUser(6001); String oldPassword = "userServiceTest"; String weakPassword = "weak"; expectedException.expectMessage( messages.getMessage("error.password.length", new Object[] {"8"}, null)); userService.changePassword(user6001, oldPassword, weakPassword); } /** * @see UserService#changePassword(User,String,String) */ @Test public void changePassword_shouldThrowAPIExceptionIfGivenUserDoesNotExist() { //user.getUserId is null - so it is not existing user User notExistingUser = new User(); String anyString = "anyString"; expectedException.expect(APIException.class); expectedException.expectMessage(messages.getMessage("user.must.exist")); userService.changePassword(notExistingUser, anyString, anyString); } @Test public void changePassword_shouldThrowShortPasswordExceptionWithShortPassword() { expectedException.expect(ShortPasswordException.class); expectedException.expectMessage( messages.getMessage("error.password.length", new Object[] {"8"}, null)); userService.changePassword("test", ""); } @Test public void changePassword_shouldUpdatePasswordOfGivenUserWhenLoggedInUserHasEditUsersPasswordPrivilege() { User user = userService.getUserByUsername(ADMIN_USERNAME); assertNotNull("There needs to be a user with username 'admin' in the database", user); userService.changePassword(user, "testTest123"); Context.authenticate(user.getUsername(), "testTest123"); } @Test public void changePassword_shouldNotUpdatePasswordOfGivenUserWhenLoggedInUserDoesNotHaveEditUsersPasswordPrivilege() { executeDataSet(XML_FILENAME_WITH_DATA_FOR_CHANGE_PASSWORD_ACTION); User user = userService.getUser(6001); assertFalse(user.hasPrivilege(PrivilegeConstants.EDIT_USER_PASSWORDS)); Context.authenticate(user.getUsername(), "userServiceTest"); expectedException.expect(APIAuthenticationException.class); expectedException.expectMessage( messages.getMessage("error.privilegesRequired", new Object[] {PrivilegeConstants.EDIT_USER_PASSWORDS}, null)); userService.changePassword(user, "testTest123"); } @Test public void changePasswordUsingSecretAnswer_shouldUpdatePasswordIfSecretIsCorrect() { executeDataSet(XML_FILENAME_WITH_DATA_FOR_CHANGE_PASSWORD_ACTION); User user = userService.getUser(6001); assertFalse(user.hasPrivilege(PrivilegeConstants.EDIT_USER_PASSWORDS)); Context.authenticate(user.getUsername(), "userServiceTest"); userService.changePasswordUsingSecretAnswer("answer", "userServiceTest2"); Context.authenticate(user.getUsername(), "userServiceTest2"); } @Test public void changePasswordUsingSecretAnswer_shouldNotUpdatePasswordIfSecretIsNotCorrect() { executeDataSet(XML_FILENAME_WITH_DATA_FOR_CHANGE_PASSWORD_ACTION); User user = userService.getUser(6001); assertFalse(user.hasPrivilege(PrivilegeConstants.EDIT_USER_PASSWORDS)); Context.authenticate(user.getUsername(), "userServiceTest"); expectedException.expect(APIException.class); expectedException.expectMessage(messages.getMessage("secret.answer.not.correct")); userService.changePasswordUsingSecretAnswer("wrong answer", "userServiceTest2"); } }