/**
* Copyright (C) 2011 JTalks.org Team
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package org.jtalks.jcommune.model.dao.hibernate;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.jtalks.common.model.dao.GroupDao;
import org.jtalks.common.model.entity.Group;
import org.jtalks.common.model.entity.User;
import org.jtalks.jcommune.model.entity.PersistedObjectsFactory;
import org.jtalks.jcommune.model.dao.UserDao;
import org.jtalks.jcommune.model.entity.JCUser;
import org.jtalks.jcommune.model.entity.ObjectsFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.testng.AbstractTransactionalTestNGSpringContextTests;
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.transaction.annotation.Transactional;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static java.util.Arrays.asList;
import static org.testng.Assert.*;
import static org.unitils.reflectionassert.ReflectionAssert.assertReflectionEquals;
/**
* @author Kirill Afonin
* @author Osadchuck Eugeny
*/
@ContextConfiguration(locations = {"classpath:/org/jtalks/jcommune/model/entity/applicationContext-dao.xml"})
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
@Transactional
public class UserHibernateDaoTest extends AbstractTransactionalTestNGSpringContextTests {
@Autowired
private UserDao dao;
@Autowired
private GroupDao groupDao;
@Autowired
private SessionFactory sessionFactory;
private Session session;
@BeforeMethod
public void setUp() throws Exception {
session = sessionFactory.getCurrentSession();
PersistedObjectsFactory.setSession(session);
}
/*===== Common methods =====*/
@Test
public void testSave() {
JCUser user = ObjectsFactory.getDefaultUser();
dao.saveOrUpdate(user);
assertNotSame(user.getId(), 0, "Id not created");
session.evict(user);
JCUser result = (JCUser) session.get(JCUser.class, user.getId());
assertReflectionEquals(user, result);
}
@Test(expectedExceptions = DataIntegrityViolationException.class)
public void testSaveUserWithUniqueViolation() {
JCUser user = ObjectsFactory.getDefaultUser();
JCUser user2 = ObjectsFactory.getDefaultUser();
dao.saveOrUpdate(user);
dao.saveOrUpdate(user2);
}
@Test
public void testGet() {
JCUser user = ObjectsFactory.getDefaultUser();
session.save(user);
JCUser result = dao.get(user.getId());
assertNotNull(result);
assertEquals(result.getId(), user.getId());
}
@Test
public void testGetInvalidId() {
JCUser result = dao.get(-567890L);
assertNull(result);
}
@Test
public void testUpdate() {
String newName = "new name";
JCUser user = ObjectsFactory.getDefaultUser();
session.save(user);
user.setFirstName(newName);
dao.saveOrUpdate(user);
session.flush();
session.evict(user);
JCUser result = (JCUser) session.get(JCUser.class, user.getId());//!
assertEquals(result.getFirstName(), newName);
}
@Test(expectedExceptions = org.hibernate.exception.ConstraintViolationException.class)
public void testUpdateNotNullViolation() {
JCUser user = ObjectsFactory.getDefaultUser();
session.save(user);
user.setEmail(null);
dao.saveOrUpdate(user);
session.flush();
}
@Test
public void testDelete() {
JCUser user = ObjectsFactory.getDefaultUser();
session.save(user);
boolean result = dao.delete(user.getId());
int userCount = getCount();
assertTrue(result, "Entity is not deleted");
assertEquals(userCount, 0);
}
@Test
public void testDeleteInvalidId() {
boolean result = dao.delete(-100500L);
assertFalse(result, "Entity deleted");
}
/*===== UserDao specific methods =====*/
@Test
public void testGetByUsernameSameCase() {
JCUser user = ObjectsFactory.getDefaultUser();
session.save(user);
JCUser result = dao.getByUsername(user.getUsername());
assertNotNull(result);
assertReflectionEquals(user, result);
}
@Test
public void testGetByUsernameDifferentCases() {
JCUser user = ObjectsFactory.getDefaultUser();
session.save(user);
JCUser result = dao.getByUsername(user.getUsername().toUpperCase());
assertNotNull(result);
assertReflectionEquals(user, result);
}
@Test
public void testGetByUsernameMultipleUsersWithSameNameWhenIgnoringCase() {
JCUser user = ObjectsFactory.getUser("usernamE", "username@mail.com");
session.save(user);
session.save(ObjectsFactory.getUser("Username", "Username@mail.com"));
JCUser result = dao.getByUsername("usernamE");
assertNotNull(result);
assertReflectionEquals(user, result);
}
@Test
public void testGetByUsernameNotExist() {
JCUser user = ObjectsFactory.getDefaultUser();
session.save(user);
JCUser result = dao.getByUsername("Name");
assertNull(result);
}
@Test
public void testGetByUsernameNotFoundWhenMultipleUsersWithSameNameWhenIgnoringCase() {
session.save(ObjectsFactory.getUser("usernamE", "username@mail.com"));
session.save(ObjectsFactory.getUser("Username", "Username@mail.com"));
JCUser result = dao.getByUsername("username");
assertNull(result);
}
@Test
public void getCommonUserByUsernameShouldFindOne() {
User expected = givenCommonUserWithUsernameStoredInDb("username");
User actual = dao.getCommonUserByUsername("username");
assertNotNull(actual);
assertReflectionEquals(actual, expected);
}
@Test
public void getCommonUserByUsernameShouldNotFind() {
givenCommonUserWithUsernameStoredInDb("username");
User actual = dao.getCommonUserByUsername("wrong username there is no such user");
assertNull(actual);
}
@Test
public void getCommonUserByUsernameShouldNotFindInEmptyDb() {
User actual = dao.getCommonUserByUsername("username");
assertNull(actual);
}
@Test
public void testGetByUuid() {
JCUser user = ObjectsFactory.getDefaultUser();
String uuid = user.getUuid();
session.save(user);
JCUser result = dao.getByUuid(uuid);
assertReflectionEquals(user, result);
}
@Test
public void testGetByUuidNotExist() {
JCUser user = ObjectsFactory.getDefaultUser();
session.save(user);
JCUser result = dao.getByUuid("uuid");
assertNull(result);
}
@Test
public void testFetchByEMail() {
JCUser user = ObjectsFactory.getDefaultUser();
session.save(user);
assertNotNull(dao.getByEmail(user.getEmail()));
}
@Test
public void testFetchNonActivatedAccounts() {
JCUser activated = new JCUser("login", "email@mail.com", "password");
activated.setEnabled(true);
JCUser nonActivated = ObjectsFactory.getDefaultUser();
session.save(activated);
session.save(nonActivated);
Collection<JCUser> users = dao.getNonActivatedUsers();
assertTrue(users.contains(nonActivated));
assertEquals(users.size(), 1);
}
/**
* Creates a user with the specified username, stores it into database and clears the session so that we won't get
* the same object from the session, but rather a new one will be returned from database.
*
* @param username a username to store the user with, other properties will be pretty random
* @return a user that was stored in the database and removed from the Hibernate session
*/
private User givenCommonUserWithUsernameStoredInDb(String username) {
User expected = new User(username, "mail@mail.com", "pass", null);//salt will be null anyway after retrieval
session.save(expected);
session.clear();
return expected;
}
private int getCount() {
return ((Number) session
.createQuery("select count(*) from org.jtalks.jcommune.model.entity.JCUser")
.uniqueResult())
.intValue();
}
@Test
public void getByUsernamesShouldReturnExistsInRepoUsers() {
String firstExistsUsername = "Shogun";
JCUser firstExistsUser = givenJCUserWithUsernameStoredInDb(firstExistsUsername);
Set<String> existsUsernames = new HashSet<>(asList(firstExistsUsername));
List<JCUser> foundByUsernames = dao.getByUsernames(existsUsernames);
assertTrue(foundByUsernames.size() == existsUsernames.size(), "It should return all users by their names.");
assertTrue(foundByUsernames.contains(firstExistsUser), firstExistsUser.getUsername() + "should be found by his name.");
}
@Test
public void addingValidUserToValidGroupShouldSucceed() {
JCUser user = givenJCUserWithUsernameStoredInDb("test-user");
Group group = PersistedObjectsFactory.group("test-group");
user.addGroup(group);
dao.saveOrUpdate(user);
flushAndClearSession(session);
Group selected = groupDao.get(group.getId());
assertEquals(selected.getUsers().size(), 1);
assertReflectionEquals(selected.getUsers().get(0), user);
}
@Test
public void getByUsernamesShouldReturnEmptyListWhenFoundUsersDoNotExist() {
Set<String> existsUsernames = new HashSet<>(asList("Shogun", "jk1", "masyan"));
List<JCUser> foundByUsernames = dao.getByUsernames(existsUsernames);
assertTrue(foundByUsernames.isEmpty(), "It should return empty list, cause found users not exist.");
}
@Test
public void getUsernamesResultCount() {
String usernamePattern = "Us";
int resultCount = 2;
createUser("User1", true);
createUser("uSer2", true);
createUser("user3", true);
assertEquals(dao.getUsernames(usernamePattern, resultCount).size(), 2);
}
@Test
public void getUsernamesEnabledUsers() {
String usernamePattern = "Us";
int resultCount = 5;
createUser("User1", true);
createUser("uSer2", true);
createUser("user3", false);
assertEquals(dao.getUsernames(usernamePattern, resultCount).size(), 2);
}
@Test
public void getUsernamesWithSpecialCharacters() {
String usernamePattern = "@/|\"&' <>#${}()";
int resultCount = 5;
createUserWithMail("Some_user1", "user1@mail.com", true);
createUserWithMail("user2", "user2@mail.com", true);
createUserWithMail("@/|\"&' <>#${}()", "user3@mail.com", true);
assertEquals(dao.getUsernames(usernamePattern, resultCount).size(), 1);
}
@Test
public void specialCharactersShouldBeEscapedCorrectly() {
String usernamePattern = "_us%";
int resultCount = 5;
createUserWithMail("Some_user1", "user1@mail.com", true);
createUserWithMail("user2", "user2@mail.com", true);
createUserWithMail("Some_us%2r", "user3@mail.com", true);
assertEquals(dao.getUsernames(usernamePattern, resultCount).size(), 1);
}
@Test
public void findByUsernameOrEmailShouldSearchByUsername() {
JCUser user1 = createUserWithMail("Arthur", "email1@mail.com", true);
JCUser user2 = createUserWithMail("Barbara", "email2@mail.com", true);
createUserWithMail("Epolit", "email3@mail.com", true);
List<JCUser> result = dao.findByUsernameOrEmail("ar", 20);
assertEquals(result.size(), 2);
assertTrue(result.contains(user1));
assertTrue(result.contains(user2));
}
@Test
public void findByUsernameOrEmailShouldSearchByEmail() {
JCUser user1 = createUserWithMail("Arthur", "emAIL1@mail.com", true);
JCUser user2 = createUserWithMail("Barbara", "email2@mail.com", true);
createUserWithMail("Epolit", "post@google.com", true);
List<JCUser> result = dao.findByUsernameOrEmail("email", 20);
assertEquals(result.size(), 2);
assertTrue(result.contains(user1));
assertTrue(result.contains(user2));
}
@Test
public void findByUsernameOrEmailShouldSearchDisabledUsers() {
JCUser user1 = createUserWithMail("Arthur", "emAIL1@mail.com", true);
JCUser user2 = createUserWithMail("Barbara", "email2@mail.com", false);
List<JCUser> result = dao.findByUsernameOrEmail("email", 20);
assertEquals(result.size(), 2);
assertTrue(result.contains(user1));
assertTrue(result.contains(user2));
}
@Test
public void findByUsernameShouldNotReturnMoreUsersThanSpecified() {
createUserWithMail("user1", "emai1@mail.com", true);
createUserWithMail("user2", "email2@mail.com", true);
createUserWithMail("user3", "email3@mail.com", true);
List<JCUser> result = dao.findByUsernameOrEmail("user", 2);
assertEquals(result.size(), 2);
}
@Test
public void findByUsernameOrEmailShouldCorrectlyEscapeSpecialCharacters() {
String usernamePattern = "_us%";
createUserWithMail("Some_user1", "user1@mail.com", true);
createUserWithMail("user2", "user2@mail.com", true);
JCUser user = createUserWithMail("Some_us%2r", "user3@mail.com", true);
List<JCUser> result = dao.findByUsernameOrEmail(usernamePattern, 20);
assertEquals(result.size(), 1);
assertTrue(result.contains(user));
}
@Test
public void testFindByUsernameOrEmailWihSpecialCharacters() {
String usernamePattern = "@/|\"&' <>#${}()";
createUserWithMail("Some_user1", "user1@mail.com", true);
createUserWithMail("user2", "user2@mail.com", true);
JCUser user = createUserWithMail("@/|\"&' <>#${}()", "user3@mail.com", true);
List<JCUser> result = dao.findByUsernameOrEmail(usernamePattern, 20);
assertEquals(result.size(), 1);
assertTrue(result.contains(user));
}
@Test
public void findByUsernameOrEmailTestPrimaryOrderUsername() {
String keyWord = "keyword@email.com";
JCUser user4 = createUserWithMail("1" + keyWord , "user4@email.com", true);
JCUser user3 = createUserWithMail("1" + keyWord + "1", "user3@email.com", true);
JCUser user2 = createUserWithMail(keyWord + "1", "user2@email.com", true);
JCUser user1 = createUserWithMail(keyWord, "user1@email.com", true);
List<JCUser> result = dao.findByUsernameOrEmail(keyWord, 20);
assertEquals(result.get(0), user1);
assertEquals(result.get(1), user2);
assertEquals(result.get(2), user3);
assertEquals(result.get(3), user4);
}
@Test
public void findByUsernameOrEmailTestPrimaryOrderEmail() {
String keyWord = "keyword@email.com";
JCUser user4 = createUserWithMail("user4", "a" + keyWord, true);
JCUser user3 = createUserWithMail("user3", "a" + keyWord + "a", true);
JCUser user2 = createUserWithMail("user2", keyWord + "a", true);
JCUser user1 = createUserWithMail("user1", keyWord, true);
List<JCUser> result = dao.findByUsernameOrEmail(keyWord, 20);
assertEquals(result.get(0), user1);
assertEquals(result.get(1), user2);
assertEquals(result.get(2), user3);
assertEquals(result.get(3), user4);
}
@Test
public void findByUsernameOrEmailTestPrimaryOrderMixed() {
String keyWord = "keyword@email.com";
JCUser user4 = createUserWithMail("a" + keyWord, "user4@email.com", true);
JCUser user3 = createUserWithMail("user3", "a" + keyWord + "a", true);
JCUser user2 = createUserWithMail(keyWord + "a", "user2@email.com", true);
JCUser user1 = createUserWithMail("user1", keyWord, true);
List<JCUser> result = dao.findByUsernameOrEmail(keyWord, 20);
assertEquals(result.get(0), user1);
assertEquals(result.get(1), user2);
assertEquals(result.get(2), user3);
assertEquals(result.get(3), user4);
}
@Test
public void testSecondaryOrderExactMatch() {
String keyWord = "keyword@email.com";
JCUser user2 = createUserWithMail("user2", keyWord, true);
JCUser user1 = createUserWithMail(keyWord, "user1@email.com", true);
List<JCUser> result = dao.findByUsernameOrEmail(keyWord, 20);
assertEquals(result.get(0), user1);
assertEquals(result.get(1), user2);
}
@Test
public void testSecondaryOrderStartFromKeyWord() {
String keyWord = "keyword";
JCUser user2 = createUserWithMail("user2", keyWord + "@email.com", true);
JCUser user1 = createUserWithMail(keyWord + "1", "user1@email.com", true);
JCUser user3 = createUserWithMail(keyWord + "11", keyWord + "1@email.com", true);
List<JCUser> result = dao.findByUsernameOrEmail(keyWord, 20);
assertEquals(result.get(0), user3);
assertEquals(result.get(1), user1);
assertEquals(result.get(2), user2);
}
@Test
public void testThirdaryOrderUsernameStartsFromKeyWord() {
String keyWord = "keyword";
JCUser user2 = createUserWithMail(keyWord + "z", "user2@email.com", true);
JCUser user1 = createUserWithMail(keyWord + "a", "user1@email.com", true);
List<JCUser> result = dao.findByUsernameOrEmail(keyWord, 20);
assertEquals(result.get(0), user1);
assertEquals(result.get(1), user2);
}
@Test
public void testThirdaryOrderEmailStartsFromKeyWord() {
String keyWord = "keyword";
JCUser user3 = createUserWithMail("bbbb", keyWord + "3@email.com", true);
JCUser user2 = createUserWithMail("zzzz", keyWord + "1@email.com", true);
JCUser user1 = createUserWithMail("aaaa", keyWord + "2@email.com", true);
List<JCUser> result = dao.findByUsernameOrEmail(keyWord, 20);
assertEquals(result.get(0), user1);
assertEquals(result.get(1), user3);
assertEquals(result.get(2), user2);
}
@Test
public void testSecondaryOrderKeywordInTheMiddle() {
String keyWord = "keyword";
JCUser user3 = createUserWithMail("1" + keyWord + "1", "user1@email.com", true);
JCUser user2 = createUserWithMail("user2", "a" + keyWord + "@email.com", true);
JCUser user1 = createUserWithMail("1" + keyWord + "11", "a" + keyWord + "1@email.com", true);
List<JCUser> result = dao.findByUsernameOrEmail(keyWord, 20);
assertEquals(result.get(0), user1);
assertEquals(result.get(1), user3);
assertEquals(result.get(2), user2);
}
@Test
public void testThirdaryOrderUsernameWithKeywordItTheMiddle() {
String keyWord = "keyword";
JCUser user2 = createUserWithMail("z" + keyWord + "aa", "user2@email.com", true);
JCUser user1 = createUserWithMail("a" + keyWord + "aa", "user1@email.com", true);
List<JCUser> result = dao.findByUsernameOrEmail(keyWord, 20);
assertEquals(result.get(0), user1);
assertEquals(result.get(1), user2);
}
@Test
public void testThirdaryOrderEmailWithKeyWordInTheMiddle() {
String keyWord = "keyword";
JCUser user2 = createUserWithMail("zuser", "11" + keyWord + "@email.com", true);
JCUser user1 = createUserWithMail("auser", "1" + keyWord + "@email.com", true);
List<JCUser> result = dao.findByUsernameOrEmail(keyWord, 20);
assertEquals(result.get(0), user1);
assertEquals(result.get(1), user2);
}
@Test
public void testSecondaryOrderKeywordAtTheEnd() {
String keyWord = "keyword";
JCUser user3 = createUserWithMail("user3", "user3@email." + keyWord, true);
JCUser user2 = createUserWithMail("user2" + keyWord, "user2@email.com", true);
JCUser user1 = createUserWithMail("1" + keyWord, "user1@email." + keyWord, true);
List<JCUser> result = dao.findByUsernameOrEmail(keyWord, 20);
assertEquals(result.get(0), user1);
assertEquals(result.get(1), user2);
assertEquals(result.get(2), user3);
}
@Test
public void testThirdaryOrderKeyWordAtTheEndOfUsername() {
String keyWord = "keyword";
JCUser user2 = createUserWithMail("z" + keyWord, "user2@email.com", true);
JCUser user1 = createUserWithMail("a" + keyWord, "user1@email.com", true);
List<JCUser> result = dao.findByUsernameOrEmail(keyWord, 20);
assertEquals(result.get(0), user1);
assertEquals(result.get(1), user2);
}
@Test
public void testThirdaryOrderEmailWithKeywordInTheEnd() {
String keyWord = "keyword";
JCUser user2 = createUserWithMail("zuser", "user2@email." + keyWord, true);
JCUser user1 = createUserWithMail("auser", "user1@email." + keyWord, true);
List<JCUser> result = dao.findByUsernameOrEmail(keyWord, 20);
assertEquals(result.get(0), user1);
assertEquals(result.get(1), user2);
}
private JCUser givenJCUserWithUsernameStoredInDb(String username) {
JCUser expected = new JCUser(username, username + "@mail.com", username + "pass");
session.save(expected);
session.clear();
return expected;
}
private JCUser createUserWithMail(String username, String email, boolean enabled) {
JCUser user = new JCUser(username, email, username + "pass");
user.setEnabled(enabled);
session.persist(user);
return user;
}
private JCUser createUser(String username, boolean enabled) {
return createUserWithMail(username, username + "@mail.com", enabled);
}
private void flushAndClearSession(Session session) {
session.flush();
session.clear();
}
}