org.jtalks.jcommune.model.dao.hibernate.LastReadPostHibernateDaoTest.java Source code

Java tutorial

Introduction

Here is the source code for org.jtalks.jcommune.model.dao.hibernate.LastReadPostHibernateDaoTest.java

Source

/**
 * 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.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.joda.time.DateTime;
import org.jtalks.jcommune.model.entity.PersistedObjectsFactory;
import org.jtalks.jcommune.model.dao.LastReadPostDao;
import org.jtalks.jcommune.model.entity.JCUser;
import org.jtalks.jcommune.model.entity.LastReadPost;
import org.jtalks.jcommune.model.entity.Topic;
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.*;

import static org.testng.Assert.*;

/**
 * @author Evgeniy Naumenko
 * @author Anuar Nurmakanov
 */
@ContextConfiguration(locations = { "classpath:/org/jtalks/jcommune/model/entity/applicationContext-dao.xml" })
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
@Transactional
public class LastReadPostHibernateDaoTest extends AbstractTransactionalTestNGSpringContextTests {
    @Autowired
    private LastReadPostDao lastReadPostDao;
    @Autowired
    private SessionFactory sessionFactory;
    private Session session;

    @BeforeMethod
    public void setUp() {
        session = sessionFactory.getCurrentSession();
        PersistedObjectsFactory.setSession(session);
    }

    /*===== Common methods =====*/
    @Test
    public void testGet() {
        LastReadPost expected = PersistedObjectsFactory.getDefaultLastReadPost();
        session.save(expected);

        LastReadPost actual = lastReadPostDao.get(expected.getId());

        assertNotNull(actual, "Get returns null.");
        assertEquals(actual.getId(), expected.getId(), "Get return incorrect object");
    }

    @Test
    public void dateOfTheLastReadPostShouldBeUpdated() {
        LastReadPost post = PersistedObjectsFactory.getDefaultLastReadPost();
        post.setPostCreationDate(new DateTime());
        session.save(post);
        DateTime newPostDate = post.getPostCreationDate().plusMinutes(34);
        post.setPostCreationDate(newPostDate);

        lastReadPostDao.saveOrUpdate(post);
        LastReadPost updatedPost = (LastReadPost) session.get(LastReadPost.class, post.getId());

        assertEquals(updatedPost.getPostCreationDate(), newPostDate,
                "Update doesn't work, because field value didn't change.");
    }

    @Test(expectedExceptions = DataIntegrityViolationException.class)
    public void saveOrUpdateShouldFailWhenSavingDuplicate() {
        LastReadPost post = PersistedObjectsFactory.getDefaultLastReadPost();
        session.save(post);

        // Create entity with the same user_id and post_id
        LastReadPost otherPost = new LastReadPost(post.getUser(), post.getTopic(), new DateTime());
        lastReadPostDao.saveOrUpdate(otherPost);
    }

    @Test
    public void testMarkAsReadTopicsToUser() {
        List<Topic> topics = PersistedObjectsFactory.createAndSaveTopicListWithPosts(10);
        JCUser user = PersistedObjectsFactory.getDefaultUser();

        //records of posts in topics
        Map<Long, DateTime> listCountPostsToTopics = markAllTopicsASRead(topics, user);
        //records in database about read topic
        Map<Long, DateTime> actualCountPostsToTopics = getActualListCountPostsToTopics(topics, user);

        assertEquals(actualCountPostsToTopics, listCountPostsToTopics);
    }

    @Test
    public void testDeleteMarksTopicsToUser() {
        List<Topic> topics = PersistedObjectsFactory.createAndSaveTopicListWithPosts(10);
        JCUser user = PersistedObjectsFactory.getDefaultUser();
        SQLQuery deletedEntities = (SQLQuery) session.getNamedQuery("deleteAllMarksReadToUser");
        deletedEntities.addSynchronizedEntityClass(LastReadPost.class).setParameter("user", user.getId())
                .setParameter("branch", topics.get(0).getBranch().getId()).setCacheable(false).executeUpdate();

        List<LastReadPost> lastReadPostList = lastReadPostDao.getLastReadPosts(user, topics);

        //check delete record about read posts for user
        assertTrue(lastReadPostList.isEmpty());
    }

    @Test
    public void testGetTopicAndLatestPostDateInBranch() {
        List<Topic> topics = PersistedObjectsFactory.createAndSaveTopicListWithPosts(10);
        //records of posts in topics
        Map<Long, DateTime> actualCountOfPosts = getTopicAndLatestPostDateInBranch(topics);
        Map<Long, DateTime> resultOfGetTopics = new HashMap<>();
        @SuppressWarnings("unchecked")
        List<Object[]> resultCheckGetTopics = session.getNamedQuery("getTopicAndLatestPostDateInBranch")
                .setParameter("branch", topics.get(0).getBranch().getId()).setCacheable(false).list();

        for (Object[] record : resultCheckGetTopics) {
            resultOfGetTopics.put(new Long(record[0].toString()), (DateTime) record[1]);
        }

        assertEquals(resultOfGetTopics, actualCountOfPosts);
    }

    @Test
    public void testMarkAllReadToUserInTwoBranches() {
        JCUser user = PersistedObjectsFactory.getDefaultUser();
        List<Topic> topicsOfFirstBranch = PersistedObjectsFactory.createAndSaveTopicListWithPosts(10);
        List<Topic> topicsOfSecondBranch = PersistedObjectsFactory.createAndSaveTopicListWithPosts(10);
        //records of posts in topics
        Map<Long, DateTime> listCountPostsToTopicsInFBranch = new HashMap<>();
        Map<Long, DateTime> listCountPostsToTopicsInSBranch = new HashMap<>();
        //records in database about read topic
        Map<Long, DateTime> actualCountPostsToTopicsInFBranch = new HashMap<>();
        Map<Long, DateTime> actualCountPostsToTopicsInSBranch = new HashMap<>();

        listCountPostsToTopicsInFBranch = markAllTopicsASRead(topicsOfFirstBranch, user);
        listCountPostsToTopicsInSBranch = markAllTopicsASRead(topicsOfSecondBranch, user);
        actualCountPostsToTopicsInFBranch = getActualListCountPostsToTopics(topicsOfFirstBranch, user);
        actualCountPostsToTopicsInSBranch = getActualListCountPostsToTopics(topicsOfSecondBranch, user);

        //concatenate  results from first and second branches
        listCountPostsToTopicsInFBranch.putAll(listCountPostsToTopicsInSBranch);
        actualCountPostsToTopicsInFBranch.putAll(actualCountPostsToTopicsInSBranch);

        assertEquals(listCountPostsToTopicsInFBranch, actualCountPostsToTopicsInFBranch);
    }

    /*===== Specific methods =====*/
    @Test
    public void testListLastReadPostsForTopic() {
        LastReadPost post = PersistedObjectsFactory.getDefaultLastReadPost();
        session.save(post);

        List<LastReadPost> lastReadPosts = lastReadPostDao.getLastReadPostsInTopic(post.getTopic());

        assertTrue(lastReadPosts.size() == 1, "Result list has incorrect size");
        assertEquals(lastReadPosts.get(0).getId(), post.getId(), "Results contains invalid data.");
    }

    @Test
    public void testGetLastReadPost() {
        LastReadPost expected = PersistedObjectsFactory.getDefaultLastReadPost();
        session.save(expected);

        LastReadPost actual = lastReadPostDao.getLastReadPost(expected.getUser(), expected.getTopic());

        assertEquals(actual.getId(), expected.getId(), "Found incorrect last read post.");
    }

    @Test
    public void getLastReadPostsForUserInTopicsShouldReturnThem() {
        int topicsSize = 10;
        JCUser user = PersistedObjectsFactory.getDefaultUser();
        List<Topic> userTopics = PersistedObjectsFactory.createAndSaveTopicListWithPosts(topicsSize);
        markAllTopicsASRead(userTopics, user);

        List<LastReadPost> lastReadPosts = lastReadPostDao.getLastReadPosts(user, userTopics);

        assertEquals(lastReadPosts.size(), topicsSize, "For every passed topic it should return last read post.");

    }

    @Test
    public void getLastReadPostsForUserShouldReturnEmptyListForEmptyListOfTopics() {
        List<Topic> userTopics = Collections.emptyList();
        JCUser user = new JCUser("user", "user@gmail.com", "password");

        List<LastReadPost> lastReadPosts = lastReadPostDao.getLastReadPosts(user, userTopics);

        assertTrue(lastReadPosts.isEmpty(), "For passed empty list of topics it should return empty list.");

    }

    /**
     * Method marks topics as read to user
     *
     * @param topics List of topics to mark
     * @param user   User for which threads are marked as read
     * @return list of count posts for each topic, for verification
     */
    private Map<Long, DateTime> markAllTopicsASRead(List<Topic> topics, JCUser user) {
        SQLQuery insertQuery = (SQLQuery) session.getNamedQuery("markAllTopicsRead");
        insertQuery.setCacheable(false);
        Map<Long, DateTime> listCountPostsToTopics = new HashMap<Long, DateTime>();

        for (Topic tp : topics) {
            insertQuery.setParameter("uuid", UUID.randomUUID().toString()).setParameter("user", user.getId())
                    .setParameter("lastPostDate", ((DateTime) tp.getLastPost().getCreationDate()).toDate())
                    .setParameter("topic", tp.getId()).executeUpdate();
            listCountPostsToTopics.put(tp.getId(), tp.getLastPost().getCreationDate());
        }
        return listCountPostsToTopics;
    }

    /**
     * Method returns the data read topics that are stored in the database
     *
     * @param topics List of topics, which marked as read to user
     * @param user   User for which threads are marked as read
     * @return List of last read dates for each topic, for verification, stored in the database
     */
    private Map<Long, DateTime> getActualListCountPostsToTopics(List<Topic> topics, JCUser user) {
        Map<Long, DateTime> listCountPostsToTopics = new HashMap<>();

        SQLQuery checkInsert = (SQLQuery) session.createSQLQuery("select TOPIC_ID, "
                + "LAST_READ_POST_DATE FROM LAST_READ_POSTS where TOPIC_ID IN (select TOPIC_ID from TOPIC where "
                + "BRANCH_ID=:branch) and USER_ID = :user");
        checkInsert.setParameter("user", user.getId());
        checkInsert.setParameter("branch", topics.get(0).getBranch().getId());
        @SuppressWarnings("unchecked")
        List<Object[]> resultCheckInsert = checkInsert.list();

        for (Object[] record : resultCheckInsert) {
            listCountPostsToTopics.put(new Long(record[0].toString()), new DateTime(record[1]));
        }
        return listCountPostsToTopics;
    }

    /**
     * Method returns the data for each topics, which marked as read
     *
     * @param topics List of topics in branch
     * @return List of count posts for each topic
     */
    private Map<Long, DateTime> getTopicAndLatestPostDateInBranch(List<Topic> topics) {
        Map<Long, DateTime> result = new HashMap<>();
        for (Topic topic : topics) {
            //second parameter it's index of last post
            result.put(topic.getId(), topic.getLastPost().getCreationDate());
        }
        return result;
    }
}