org.eurekastreams.server.persistence.TabGroupMapperTest.java Source code

Java tutorial

Introduction

Here is the source code for org.eurekastreams.server.persistence.TabGroupMapperTest.java

Source

/*
 * Copyright (c) 2009-2010 Lockheed Martin Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.eurekastreams.server.persistence;

import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertSame;
import static junit.framework.Assert.assertTrue;

import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;

import org.apache.commons.logging.Log;
import org.eurekastreams.commons.logging.LogFactory;
import org.eurekastreams.server.domain.Layout;
import org.eurekastreams.server.domain.Tab;
import org.eurekastreams.server.domain.TabGroup;
import org.eurekastreams.server.persistence.exceptions.TabDeletionException;
import org.eurekastreams.server.persistence.exceptions.TabUndeletionException;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * This class is responsible for testing the JPA Implementation of the TabGroup Mapper interface. The tests contained in
 * here ensure proper interaction with the database.
 */
public class TabGroupMapperTest extends DomainEntityMapperTest {
    /**
     * Log.
     */
    Log log = LogFactory.make();

    /**
     * JpaTabGroupMapper - the system under test.
     */
    @Autowired
    private TabGroupMapper jpaTabGroupMapper;

    /**
     * JpaTabMapper - a mapper we need to help assert tab existence.
     */
    @Autowired
    private TabMapper jpaTabMapper;

    /**
     * Reset the deleted tab expiration before each test.
     */
    @Before
    public void setup() {
        jpaTabGroupMapper.setUndeleteTabWindowInMinutes(undeleteWindowInMinutes);
    }

    /**
     * Test the DBUnit XML Dataset - Tabs.
     */
    @Test
    public void testDBUnitDatasetTabs() {
        final int expectedTabCount = 3;

        TabGroup tabGroup = jpaTabGroupMapper.findById(fordsStartPageId);
        List<Tab> tabs = tabGroup.getTabs();

        assertEquals("Expected the DBUnit-loaded TabGroup with ID=" + fordsStartPageId + " to have "
                + expectedTabCount + "(non-deleted) tabs", expectedTabCount, tabs.size());

        // Assert the order is 1,2,3
        assertEquals("Expected Ford's first tab in his first TabGroup to be called 'Ford Tab 1' from DBUnit setup.",
                "Ford Tab 1", tabs.get(0).getTabName());
        assertEquals("Expected Ford's first tab in his first TabGroup to be called 'Ford Tab 2' from DBUnit setup.",
                "Ford Tab 2", tabs.get(1).getTabName());
        assertEquals("Expected Ford's first tab in his first TabGroup to be called 'Ford Tab 3' from DBUnit setup.",
                "Ford Tab 3", tabs.get(2).getTabName());
    }

    /**
     * Test the domain entity name of the mapper - used for parent class generic operations.
     */
    @Test
    public void testGetDomainEntityName() {
        assertEquals("Domain entity name should be 'TabGroup'", "TabGroup",
                jpaTabGroupMapper.getDomainEntityName());
    }

    /**
     * Test persisting a start tabGroup.
     */
    @Test
    public void testInsert() {
        TabGroup p = new TabGroup();
        jpaTabGroupMapper.insert(p);
        assertTrue(p.getId() > 0);
    }

    /**
     * Test inserting a tab group, then finding the user by ID when the object is still in object cache.
     */
    @Test
    public void testFindByIdWhenCached() {
        assertSame(
                "When finding a Person by ID and that object exists in object cache, "
                        + "expected the cached instance to be returned.",
                jpaTabGroupMapper.findById(fordsStartPageId), jpaTabGroupMapper.findById(fordsStartPageId));
    }

    /**
     * Test adding a tab to a tab group persists when we update the tab group.
     */
    @Test
    public void testUpdateAddNewTab() {
        TabGroup tabGroup = jpaTabGroupMapper.findById(fordsStartPageId);
        tabGroup.getTabs().add(new Tab("Foo", Layout.THREECOLUMN));
        jpaTabGroupMapper.insert(tabGroup);

        getEntityManager().flush();
        getEntityManager().clear();

        tabGroup = jpaTabGroupMapper.findById(fordsStartPageId);
        assertEquals(
                "Attemped updating a Person after adding a Tab to his first "
                        + "TabGroup, then flushing and clearing the EntityManager.  "
                        + "Expected to see the new tab after re-loading the Person.",
                "Foo", tabGroup.getTabs().get(tabGroup.getTabs().size() - 1).getTabName());
    }

    /**
     * This test deletes a record and then ensures that the record still remains in the database so that it can be
     * undeleted.
     * 
     * @throws TabDeletionException
     *             thrown on error during tab deletion.
     */
    @Test
    public void testDeletedRecordRemainsAvailableinDBForUndelete() throws TabDeletionException {
        TabGroup fordsTabGroup = jpaTabGroupMapper.findById(fordsStartPageId);
        Tab fordTab1 = jpaTabMapper.findById(fordsFirstTabId);

        long pageId = fordsTabGroup.getId();
        long tabId = fordTab1.getId();
        int tabIndex = fordTab1.getTabIndex();

        // delete the first tab
        jpaTabGroupMapper.deleteTab(fordTab1);
        jpaTabGroupMapper.flush();

        Boolean deletedFlag = (Boolean) getEntityManager()
                .createQuery("select deleted from Tab where id = :tabId and "
                        + "tabGroupId = :tabGroupId and deleted = true and tabIndex = :tabIndex")
                .setParameter("tabGroupId", pageId).setParameter("tabId", tabId).setParameter("tabIndex", tabIndex)
                .getSingleResult();

        assertEquals(
                "Expected that after deleting a tab, it's still tied to the "
                        + "tabGroup, the tabIndex is null, and the tab is marked as deleted",
                true, deletedFlag.booleanValue());
    }

    /**
     * Test deleting the first tab in a collection leaves the collection with the other tabs intact.
     * 
     * @throws TabDeletionException
     *             thrown on error during tab deletion.
     */
    @Test
    public void testDeletingTabRemovesFromCollection() throws TabDeletionException {
        TabGroup tabGroup = jpaTabGroupMapper.findById(fordsStartPageId);
        Tab fordTab1 = jpaTabMapper.findById(fordsFirstTabId);

        // delete the first tab
        jpaTabGroupMapper.deleteTab(fordTab1);
        jpaTabGroupMapper.flush();

        // clear the entityManager so we can re-query the collection
        getEntityManager().clear();

        // re-get and assert
        tabGroup = jpaTabGroupMapper.findById(fordsStartPageId);

        assertEquals("Expected 2 tabs after deleting the first one.", 2, tabGroup.getTabs().size());

        assertEquals("Expected the previously second tab to be the first now after deleting the first one.",
                fordsSecondTabId, tabGroup.getTabs().get(0).getId());
    }

    /**
     * Test deleting a tab, then undeleting it.
     */
    @Test
    public void testDeleteThenUndelete() {
        TabGroup tabGroup = jpaTabGroupMapper.findById(fordsStartPageId);
        Tab fordTab2 = jpaTabMapper.findById(fordsSecondTabId);

        final int expectedTabCountAfterDeletingAndUndeleting = 3;

        // delete the first tab
        try {
            jpaTabGroupMapper.deleteTab(fordTab2);
        } catch (TabDeletionException e) {
            throw new RuntimeException(e);
        }
        jpaTabGroupMapper.flush();

        // clear the entityManager so we can re-query the collection
        getEntityManager().clear();

        try {
            jpaTabGroupMapper.undeleteTab(fordsSecondTabId);
        } catch (TabUndeletionException e) {
            log.error(e);
        }
        jpaTabGroupMapper.flush();

        // clear the entityManager so we can re-query the collection
        getEntityManager().clear();

        // re-get and assert
        tabGroup = jpaTabGroupMapper.findById(fordsStartPageId);
        assertEquals("Expected 3 tabs in Ford's startPage after deleting and undeleting.",
                expectedTabCountAfterDeletingAndUndeleting, tabGroup.getTabs().size());

        assertEquals(
                "Expected the previously 1st tab to still be 1st after deleting and undeleting the original second tab",
                fordsFirstTabId, tabGroup.getTabs().get(0).getId());

        assertEquals("Expected the original 2nd tab to 2nd again after deleting and undeleting it",
                fordsSecondTabId, tabGroup.getTabs().get(1).getId());

        assertEquals(
                "Expected the previously 2nd tab to be 3rd after deleting and undeleting the original second tab",
                fordsThirdTabId, tabGroup.getTabs().get(2).getId());
    }

    /**
     * Test that undeleting a tab that's not deleted throws a TabUndeleteException.
     * 
     * @throws TabUndeletionException
     *             thrown on error during tab undeletion.
     */
    @Test
    public void testUndeleteThrowsExceptionWhenNotDeleted() throws TabUndeletionException {
        // try the deletion of the tab that's not deleted - should throw a
        // TabUndeletionException
        boolean exceptionOccurred = false;
        try {
            jpaTabGroupMapper.undeleteTab(fordsFirstTabId);
        } catch (TabUndeletionException ex) {
            exceptionOccurred = true;

            assertEquals("TabUndeletionException was thrown, but didn't contain the "
                    + " tab id that the caller was trying to delete from.", fordsFirstTabId, ex.getTabId());
        }

        assertTrue("TabUndeletionException didn't occur when trying to delete a Tab that wasn't deleted.",
                exceptionOccurred);
    }

    /**
     * This test is trying to undelete the Tab that is designated as delete in the DBUnit Test Database.
     * 
     * @throws TabUndeletionException
     *             thrown during tab undeletion.
     */
    @Test
    public void testUndeleteTab() throws TabUndeletionException {
        Boolean deletedFlag;

        jpaTabGroupMapper.undeleteTab(fordsDeletedTabId);
        jpaTabGroupMapper.flush();

        deletedFlag = (Boolean) getEntityManager()
                .createQuery("select de.deleted from Tab de " + "where de.id = :tabId")
                .setParameter("tabId", new Long(fordsDeletedTabId)).getSingleResult();
        assertEquals(false, deletedFlag.booleanValue());

        assertEquals("The tab name of the undeleted tab was not as expected.", "Ford Tab 4",
                jpaTabMapper.findById(fordsDeletedTabId).getTabName());

    }

    /**
     * Test that undeleting a tab restores the tab to its original position and bumps the other tabs back one.
     * 
     * @throws TabUndeletionException
     *             thrown on error during tab undeletion.
     */
    @Test
    public void testUndeleteTabRestoresTabToItsOriginalPosition() throws TabUndeletionException {
        final int expectedTabCountBeforeUndelete = 3;

        // undelete the previously deleted tab
        TabGroup tabGroup = jpaTabGroupMapper.findById(fordsStartPageId);
        assertEquals("Expected 3 tabs in Ford's first tabGroup before undeleting the previously-deleted tab.",
                expectedTabCountBeforeUndelete, tabGroup.getTabs().size());

        jpaTabGroupMapper.undeleteTab(fordsDeletedTabId);
        jpaTabGroupMapper.flush();

        // clear the getEntityManager()'s cache so we're going back to the
        // databGroupase.
        tabGroup = jpaTabGroupMapper.findById(fordsStartPageId);
        assertEquals("Expected 4 tabs in Ford's third tabGroup after undeleting the previously-deleted tab.",
                expectedTabCountBeforeUndelete + 1, tabGroup.getTabs().size());

        assertEquals(
                "Expected the previously 1st tab to still be 1st after deleting and undeleting the original 2nd tab",
                fordsFirstTabId, tabGroup.getTabs().get(0).getId());

        assertEquals("Expected the undeleted original 2nd tab to be 2nd again.", fordsDeletedTabId,
                tabGroup.getTabs().get(1).getId());

        assertEquals("Expected the previously 2nd tab to be 3rd after deleting and undeleting the original 2nd tab",
                fordsSecondTabId, tabGroup.getTabs().get(2).getId());

        assertEquals("Expected the previously 3rd tab to be 4th after deleting and undeleting the original 2nd tab",
                fordsThirdTabId, tabGroup.getTabs().get(3).getId());
    }

    /**
     * This test verifies that deleted items expire and are purged from the database after a period of time.
     * 
     * @throws TabDeletionException
     *             thrown on error during tab deletion.
     */
    @Test
    public void testUndeleteExpiration() throws TabDeletionException {
        long fordsActiveTabId = fordsFirstTabId;

        int resultCount = getEntityManager()
                .createQuery("select version from Tab where id = :tabId and deleted = true")
                .setParameter("tabId", fordsDeletedTabId).getResultList().size();

        assertEquals("Could not find the already-deleted Tab", 1, resultCount);

        // delete an item other than the one that is already deleted.
        jpaTabGroupMapper.deleteTab(jpaTabMapper.findById(fordsActiveTabId));

        // now make sure that the already-deleted tab is gone - it should have
        // expired away
        resultCount = getEntityManager().createQuery("select version from Tab where id = :tabId and deleted = true")
                .setParameter("tabId", fordsDeletedTabId).getResultList().size();

        assertEquals(
                "After deleting a Tab, the Tab that was deleted a long time ago should have been permanently deleted.",
                0, resultCount);

        // TODO: make sure none of the gadgets from that tab exist
    }

    /**
     * Verify the configurable time window for permanent deletion of a Tab - for a tab that's still within the window.
     * 
     * @throws TabDeletionException
     *             thrown on exception deleting the tab.
     */
    @Test
    public void testDeletedTabWithinWindowShouldRemainAfterAnotherDelete() throws TabDeletionException {
        final int undeleteTabWindowInMinutes = 110;
        final int minutesSinceTestTabWasDeleted = 100;

        // set the undelete tab window
        jpaTabGroupMapper.setUndeleteTabWindowInMinutes(undeleteTabWindowInMinutes);

        // set the date the tab was deleted
        GregorianCalendar tabDeletionDate = new GregorianCalendar();
        tabDeletionDate.add(Calendar.MINUTE, -minutesSinceTestTabWasDeleted);
        getEntityManager()
                .createQuery("update versioned Tab set " + "dateDeleted = :deletedTimestamp " + "where id = :tabId")
                .setParameter("deletedTimestamp", tabDeletionDate.getTime())
                .setParameter("tabId", fordsDeletedTabId).executeUpdate();

        // delete the active tab
        jpaTabGroupMapper.deleteTab(jpaTabMapper.findById(fordsFirstTabId));

        // make sure that the deleted tab is still available
        int resultCount = getEntityManager()
                .createQuery("select version from Tab where id = :tabId and deleted = true")
                .setParameter("tabId", fordsDeletedTabId).getResultList().size();

        assertEquals(
                "After deleting a Tab, the Tab that was deleted within the undo window should still be present.", 1,
                resultCount);
    }

    /**
     * Verify the configurable time window for permanent deletion of a Tab - for a tab that's outside the window.
     * 
     * @throws TabDeletionException
     *             thrown on exception deleting the tab.
     */
    @Test
    public void testDeletedTabOutsideWindowShouldBePermanentlyDeletedAfterAnotherDelete()
            throws TabDeletionException {
        final int undeleteTabWindowInMinutes = 90;
        final int minutesSinceTestTabWasDeleted = 100;

        // set the undelete tab window
        jpaTabGroupMapper.setUndeleteTabWindowInMinutes(undeleteTabWindowInMinutes);

        // set the date the tab was deleted
        GregorianCalendar tabDeletionDate = new GregorianCalendar();
        tabDeletionDate.add(Calendar.MINUTE, -minutesSinceTestTabWasDeleted);
        getEntityManager()
                .createQuery("update versioned Tab set " + "dateDeleted = :deletedTimestamp " + "where id = :tabId")
                .setParameter("deletedTimestamp", tabDeletionDate.getTime())
                .setParameter("tabId", fordsDeletedTabId).executeUpdate();

        // delete the active tab
        jpaTabGroupMapper.deleteTab(jpaTabMapper.findById(fordsFirstTabId));

        // make sure that the deleted tab is still available
        int resultCount = getEntityManager()
                .createQuery("select version from Tab where id = :tabId and deleted = true")
                .setParameter("tabId", fordsDeletedTabId).getResultList().size();

        assertEquals("After deleting a Tab, the Tab that was deleted outside the undo "
                + "window should still be permanently deleted.", 0, resultCount);
    }

    /**
     * Test that when we add a tab to the end of a Page's Tabs collection, then flush, clear, and re-get, the Tab's
     * tabIndex is set to the last index.
     */
    @Test
    public void testAddTabSetsTabIndexToLast() {
        TabGroup tabGroup = jpaTabGroupMapper.findById(fordsStartPageId);
        Tab tab = new Tab("FooBar", Layout.THREECOLUMN);

        tabGroup.getTabs().add(tab);

        jpaTabGroupMapper.flush();
        jpaTabGroupMapper.clear();

        int expectedIndex = tabGroup.getTabs().size() - 1;
        long tabId = tab.getId();

        tab = jpaTabMapper.findById(tabId);

        assertEquals("Expected tabIndex to be tabs.size()-1 when adding a tab to a tabGroup, after flush()",
                expectedIndex, tab.getTabIndex());
    }

}