/**
* @Created Nov 24, 2010 9:53:13 AM
* @author cry30
*/
package com.philip.journal.home.service;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import com.philip.journal.common.DateUtils;
import com.philip.journal.core.Constant;
import com.philip.journal.core.JournalTestCommon;
import com.philip.journal.core.bean.AbstractAuditableBean;
import com.philip.journal.core.exception.JournalException;
import com.philip.journal.core.service.AbstractPowerMockJournalTestService;
import com.philip.journal.home.bean.Branch;
import com.philip.journal.home.bean.Entry;
import com.philip.journal.home.dao.BranchDAO;
/**
* Test class for {@link HomeServiceImpl}.
*
* <pre>
* /Root
* /SubBranch1(/b-2)
* /Entry1(/l-1)
* /SubBranch11(/b-4)
* /SubBranch2(/b-3)
* </pre>
*
* @see com.philip.journal.home.service.HomeServiceImpl2Test
* @author Royce
*/
public class HomeServiceImplTest extends AbstractPowerMockJournalTestService<HomeServiceImpl> {
/** Test Artifact. Root Sub Branch. */
private transient Branch testSubBranch1;
/** Test Artifact. Root Sub Branch. */
private transient Branch testSubBranch2;
/** Test Artifact. Sub Branch under Root Sub Branch. Spy! */
private transient Branch testSubBranch11;
/** Test Artifact. RTFC. */
private static final String TEST_BRANCH_NAME1 = "Test Branch Name 1";
/** Test Artifact. RTFC. */
private static final String TEST_BRANCH_NAME11 = "Test Branch Name 11";
/** Test Artifact. RTFC. */
private static final String TEST_BRANCH_NAME2 = "Test Branch Name 2";
/** Test Artifact. RTFC. */
private static final String TEST_NBRANCH_NAME = "Test New Branch Name";
/** Test Artifact. RTFC. */
private static final String TEST_BRANCH_PATH11 = "/Root/" + TEST_BRANCH_NAME1 + "/" + TEST_BRANCH_NAME11;
/** Test Artifact. Entry. */
private transient Entry testEntry;
/** Test Artifact. Entry ID. */
private static final long TEST_ENTRY_ID = 3L;
/** Test Artifact. Entry Title. */
private static final String TEST_ENTRY_TITLE = "Test Entry Title";
/** Test Artifact. Entry Path. */
private static final String TEST_ENTRY_PATH = "/Root/" + TEST_BRANCH_NAME1 + "/" + TEST_ENTRY_TITLE;
/** Test Artifact. Entry Detail. */
private static final String TEST_ENTRY_DETAIL = "Test Entry Details";
/** Test Artifact. Root Sub Branch ID. */
private static final long TEST_SUBBRANCH1_ID = 2L;
/** Test Artifact. Root Sub Branch ID. */
private static final long TEST_SUBBRANCH2_ID = 3L;
/** Test Artifact. Root Sub Branch ID. */
private static final long TEST_SUBBRANCH11_ID = 4L;
/** Test Artifact. Non-existent Branch ID. */
private static final long TEST_BOGUS_ID = 666L;
@Override
@Before
public final void setUp()
{
super.setUp();
testSubBranch1 = new Branch(TEST_BRANCH_NAME1, getTestRootBranch());
testSubBranch1.setBranchId(TEST_SUBBRANCH1_ID);
testEntry = new Entry(null, null, testSubBranch1);
testEntry.setNodeId(TEST_ENTRY_ID);
testEntry.setTitle(TEST_ENTRY_TITLE);
testEntry.setDescription(TEST_ENTRY_DETAIL);
testSubBranch2 = new Branch(TEST_BRANCH_NAME2, getTestRootBranch());
testSubBranch2.setBranchId(TEST_SUBBRANCH2_ID);
testSubBranch11 = spy(new Branch(TEST_BRANCH_NAME11, testSubBranch1));
testSubBranch11.setBranchId(TEST_SUBBRANCH11_ID);
when(getDaoFacade().getEntryDAO().read(TEST_ENTRY_ID)).thenReturn(testEntry);
when(getDaoFacade().getBranchDAO().read(TEST_SUBBRANCH1_ID)).thenReturn(testSubBranch1);
when(getDaoFacade().getBranchDAO().read(TEST_SUBBRANCH2_ID)).thenReturn(testSubBranch2);
when(getDaoFacade().getBranchDAO().read(TEST_SUBBRANCH11_ID)).thenReturn(testSubBranch11);
final BranchDAO mockBranchDAO = getDaoFacade().getBranchDAO();
when(mockBranchDAO.readAllByParent(Constant.ROOT_ID)).thenAnswer(new Answer<List<Branch>>() {
@Override
public List<Branch> answer(final InvocationOnMock invocation) throws Throwable
{
final List<Branch> retval = new ArrayList<Branch>();
if (Long.valueOf(Constant.ROOT_ID).equals(invocation.getArguments()[0])) {
retval.add(testSubBranch1);
retval.add(testSubBranch2);
} else if (Long.valueOf(TEST_SUBBRANCH1_ID).equals(invocation.getArguments()[0])) {
retval.add(testSubBranch11);
}
return retval;
}
});
doAnswer(new Answer<Object>() {
/** Simulate an exception if rename conflicted with a sibling. */
public Object answer(final InvocationOnMock invocation) throws Throwable
{
final Branch param = (Branch) invocation.getArguments()[0];
final Branch parent = param.getParent();
if (parent != null) {//not Root.
final List<Branch> siblings = mockBranchDAO.readAllByParent(parent.getBranchId());
for (final Branch branch : siblings) {
if (branch.getBranchId() != param.getBranchId() && branch.getName().equals(param.getName())) {
throw new JournalException(JournalTestCommon.TEST_JRNL_ERRORMSG);
}
}
}
return null;
}
}).when(mockBranchDAO).save((Branch) any());
}
/**
* Case 1: Null Entry.
*
* Test method for
* {@link com.philip.journal.home.service.HomeServiceImpl#getEntryTreePath(com.philip.journal.home.bean.Entry)}.
*/
@Test(expected = JournalException.class)
public void testGetEntryTreePathCase1()
{
getTestInstance().getEntryTreePath(getSession(), null);
}
/**
* Case 2: Expected.
*/
@Test
public void testGetEntryTreePathCase2()
{
assertEquals("Case 2: Expected.", Constant.BRANCHID_PREFIX + Constant.ROOT_ID + Constant.BRANCHID_PREFIX
+ TEST_SUBBRANCH1_ID + Constant.ENTRYID_PREFIX + TEST_ENTRY_ID,
getTestInstance().getEntryTreePath(getSession(), testEntry));
}
/**
* Case 1: Add null Branch name to Root.
*
* Test method for
* {@link com.philip.journal.home.service.HomeServiceImpl#addBranch(java.util.Map, long, java.lang.String)}.
*/
@Test(expected = JournalException.class)
public void testAddBranchCase1()
{
getTestInstance().addBranch(getSession(), Constant.ROOT_ID, null);
}
/**
* Case 2: Add empty String Branch name to Root.
*/
@Test(expected = JournalException.class)
public void testAddBranchCase2()
{
getTestInstance().addBranch(getSession(), Constant.ROOT_ID, "");
}
/**
* Case 3: Supplied parentId does not exist.
*/
@Test(expected = JournalException.class)
public void testAddBranchCase3()
{
getTestInstance().addBranch(getSession(), TEST_BOGUS_ID, TEST_BRANCH_NAME1);
}
/**
* Case 4: Normal flow. Case 4.1: Creator was set.
*/
@Test(expected = JournalException.class)
public void testAddBranchCase4()
{
getTestInstance().addBranch(getSession(), TEST_BOGUS_ID, TEST_BRANCH_NAME1);
final ArgumentCaptor<Branch> argument = ArgumentCaptor.forClass(Branch.class);
verify(getDaoFacade().getBranchDAO(), times(1)).save(argument.capture());
assertNotNull("Case 4.1: Creator was set.", argument.getValue().getCreator());
}
/**
* Case 1: Non existent Branch ID.
*
* Test method for {@link com.philip.journal.home.service.HomeServiceImpl#deleteBranch(java.util.Map, long)}.
*/
@Test(expected = JournalException.class)
public void testDeleteBranchCase1()
{
getTestInstance().deleteBranch(getSession(), TEST_BOGUS_ID);
}
/** Case 2: Attempt to delete Root branch. */
@Test(expected = JournalException.class)
public void testDeleteBranchCase2()
{
getTestInstance().deleteBranch(getSession(), Constant.ROOT_ID);
}
/**
* TODO: Complex, with cascade.<br/>
* Case 3: Normal flow.
*/
@SuppressWarnings("unchecked")
@Test
public void testDeleteBranchCase3()
{
final BranchDAO mockBranchDAO = getDaoFacade().getBranchDAO();
doAnswer(new Answer<Object>() {
@Override
public Object answer(final InvocationOnMock invocation) throws Throwable
{
final List<Branch> argument = (List<Branch>) invocation.getArguments()[0];
if (!argument.contains(testSubBranch1)) {
Assert.fail("Case 3: Normal flow.");
}
return null;
}
}).when(mockBranchDAO).deleteAll((List<Branch>) any());
getTestInstance().deleteBranch(getSession(), TEST_SUBBRANCH1_ID);
}
/**
* Case 1: Invalid branch ID.
*
* Test method for
* {@link com.philip.journal.home.service.HomeServiceImpl#renameBranch(java.util.Map, long, java.lang.String)}.
*/
@Test(expected = JournalException.class)
public void testRenameBranchCase1()
{
getTestInstance().renameBranch(getSession(), TEST_BOGUS_ID, null);
}
/** Case 2: Existing branch name. */
@Test(expected = JournalException.class)
public void testRenameBranchCase2()
{
getTestInstance().renameBranch(getSession(), TEST_SUBBRANCH1_ID, TEST_BRANCH_NAME2);
}
/** Case 3: Positive scenario. */
@Test
public void testRenameBranchCase3()
{
getTestInstance().renameBranch(getSession(), Constant.ROOT_ID, TEST_NBRANCH_NAME);
final ArgumentCaptor<Branch> argCaptor = ArgumentCaptor.forClass(Branch.class);
verify(getDaoFacade().getBranchDAO(), times(1)).save(argCaptor.capture());
assertEquals("Case 3: Positive scenario.", TEST_NBRANCH_NAME, argCaptor.getValue().getName());
}
/**
* Case 1: Not found Branch ID.
*
* Test method for {@link com.philip.journal.home.service.HomeServiceImpl#getChildren(java.util.Map, long)}.
*/
@Test
public void testGetChildrenCase1()
{
assertSame("Case 1: Not found Branch ID.", 0, getTestInstance().getChildren(getSession(), TEST_BOGUS_ID).size());
}
/** Case 2: Positive scenario. */
@Test
public void testGetChildrenCase2()
{
final List<Branch> branchList = getTestInstance().getChildren(getSession(), Constant.ROOT_ID);
assertSame("Case 2: Positive scenario.", testSubBranch1, branchList.get(0));
}
/**
* Case 1: Non-existent parent ID.<br/>
* Test method for {@link com.philip.journal.home.service.HomeServiceImpl#moveBranch(java.util.Map, long, long)}.
*/
@Test(expected = JournalException.class)
public void testMoveBranchCase1()
{
getTestInstance().moveBranch(getSession(), TEST_BOGUS_ID, TEST_SUBBRANCH2_ID);
}
/** Case 2: Non-existent Branch ID. */
@Test(expected = JournalException.class)
public void testMoveBranchCase2()
{
getTestInstance().moveBranch(getSession(), TEST_SUBBRANCH1_ID, TEST_BOGUS_ID);
}
/** Case 3(N): Move parent to child, orphaning recursively =( . */
@Test(expected = JournalException.class)
public void testMoveBranchCase3()
{
getTestInstance().moveBranch(getSession(), TEST_SUBBRANCH11_ID, TEST_SUBBRANCH1_ID);
}
/** Case 4(P): Move child to parent's branch, making them siblings. */
@Test
public void testMoveBranchCase4()
{
getTestInstance().moveBranch(getSession(), Constant.ROOT_ID, TEST_SUBBRANCH11_ID);
verify(testSubBranch11, times(1)).setParent(getTestRootBranch());
verify(getDaoFacade().getBranchDAO(), times(1)).save(testSubBranch11);
}
/** Case 5(P): Move child to Uncle. */
@Test
public void testMoveBranchCase5()
{
getTestInstance().moveBranch(getSession(), TEST_SUBBRANCH2_ID, TEST_SUBBRANCH11_ID);
verify(testSubBranch11, times(1)).setParent(testSubBranch2);
verify(getDaoFacade().getBranchDAO(), times(1)).save(testSubBranch11);
}
/**
* Case 1(N): Invalid Entry ID.
*
* Test method for
* {@link com.philip.journal.home.service.HomeServiceImpl#getNodeProperties(java.util.Map, long, boolean)}.
*/
@Test(expected = JournalException.class)
public void testGetNodePropertiesCase1()
{
getTestInstance().getNodeProperties(getSession(), TEST_BOGUS_ID, true);
}
/** Case 2(N): Invalid Branch ID. */
@Test(expected = JournalException.class)
public void testGetNodePropertiesCase2()
{
getTestInstance().getNodeProperties(getSession(), TEST_BOGUS_ID, false);
}
/**
* TODO: Complete all the map properties. Case 3(P): Normal flow, Entry.
* <ol>
* <li>Case 3.1: Correct path
* <li>Case 3.2: Correct size.
* </ol>
*/
@Test
public void testGetNodePropertiesCase3()
{
final HomeServiceImpl spy = spy(getTestInstance());
doReturn(new Date[] {
new Date(),
new Date() }).when(spy).getActionDates((AbstractAuditableBean) any());
final Map<String, Object> map = spy.getNodeProperties(getSession(), TEST_ENTRY_ID, true);
assertEquals("Case 3.1: Correct path", TEST_ENTRY_PATH, map.get(Constant.NodeProperty.PATH));
assertEquals("Case 3.2: Correct size", String.valueOf(TEST_ENTRY_TITLE.length() + TEST_ENTRY_DETAIL.length()),
map.get(Constant.NodeProperty.SIZE));
}
/**
* Case 4(P): Normal flow, Branch.
*
* TODO: Complete all the map properties.
*/
@Test
public void testGetNodePropertiesCase4()
{
final HomeServiceImpl spy = spy(getTestInstance());
doReturn(new Date[] {
new Date(),
new Date() }).when(spy).getActionDates((AbstractAuditableBean) any());
final Map<String, Object> map = spy.getNodeProperties(getSession(), TEST_SUBBRANCH11_ID, false);
assertEquals("Case 4.1: Correct path", TEST_BRANCH_PATH11, map.get(Constant.NodeProperty.PATH));
assertEquals("Case 4.2: Correct size", String.valueOf(TEST_BRANCH_NAME11.length()),
map.get(Constant.NodeProperty.SIZE));
}
/**
* Case 1(N): Null StringBuilder
*
* Test method for {@link com.philip.journal.home.service.HomeServiceImpl#getEntryNodeProperty(StringBuilder, long)}
* .
*/
@Test(expected = JournalException.class)
public void testGetEntryNodePropertyCase1()
{
getTestInstance().getEntryNodeProperty(null, 0);
}
/** Case 2(N): Entry ID not found. */
@Test(expected = JournalException.class)
public void testGetEntryNodePropertyCase2()
{
getTestInstance().getEntryNodeProperty(new StringBuilder(), TEST_BOGUS_ID);
}
// * <li>Case 3.3: Correct create date.
// * <li>Case 3.4: Correct update date, when update date is null.
// * <li>Case 3.6: Correct update date, when update date is not null.
// assertEquals("Case 3.3: Correct create date.", createDate.getTime(),
// ((Date) objectArr1[HomeServiceImpl.IDX_CREATED]).getTime());
// assertEquals("Case 3.4: Correct update date, when update date is null.", createDate.getTime(),
// ((Date) objectArr1[HomeServiceImpl.IDX_MODIFIED]).getTime());
/**
* Case 3(P): Normal flow. 2x execution.
* <ol>
* <li>Case 3.1: Entity passed back.
* <li>Case 3.2: Correct size.
* <li>Case 3.3: StringBuilder has correct value.
* </ol>
*/
@Test
public void testGetEntryNodePropertyCase3()
{
//Setup 1
final Date createDate = getCommon().getCurrentDate();
testEntry.setCreateDate(DateUtils.getInstance().removeTime(createDate));
testEntry.setCreateTime(DateUtils.getInstance().toTimeOnly(createDate));
final StringBuilder param1 = new StringBuilder();
//Begin
final Object[] objectArr1 = getTestInstance().getEntryNodeProperty(param1, TEST_ENTRY_ID);
assertSame("Case 3.1: Entity passed back.", testEntry, objectArr1[HomeServiceImpl.IDX_BEAN]);
assertEquals("Case 3.2: Correct size.", Long.valueOf(TEST_ENTRY_TITLE.length() + TEST_ENTRY_DETAIL.length()),
objectArr1[HomeServiceImpl.IDX_SIZE]);
assertEquals("Case 3.5: StringBuilder has correct value.", "/" + TEST_ENTRY_TITLE, param1.toString());
// //Setup 2
// final Date updateDate = getCommon().getTomorrowDate();
// testEntry.setUpdateDate(DateUtils.getInstance().removeTime(updateDate));
// testEntry.setUpdateTime(DateUtils.getInstance().toTimeOnly(updateDate));
// final StringBuilder param2 = new StringBuilder();
//
// //Begin
// final Object[] objectArr2 = getTestInstance().getEntryNodeProperty(param2, TEST_ENTRY_ID);
// assertEquals("Case 3.6: Correct update date, when update date is not null.", updateDate.getTime(),
// ((Date) objectArr2[HomeServiceImpl.IDX_MODIFIED]).getTime());
}
/**
* Case 1(P): Null StringBuilder param.
*
* Test method for
* {@link com.philip.journal.home.service.HomeServiceImpl#getBranchNodeProperty(StringBuilder, long)}.
*/
@Test
public void testGetBranchNodePropertyCase1()
{
getTestInstance().getBranchNodeProperty(null, TEST_SUBBRANCH11_ID);
}
/** Case 2(N): ID not found. */
@Test(expected = JournalException.class)
public void testGetBranchNodePropertyCase2()
{
getTestInstance().getBranchNodeProperty(new StringBuilder(), TEST_BOGUS_ID);
}
// * <li>Case 3.3: Correct create date.
// * <li>Case 3.4: Correct update date, when update date is null.
// * <li>Case 3.6: Correct update date, when update date is not null.
// assertEquals("Case 3.3: Correct create date.", createDate.getTime(),
// ((Date) objectArr1[HomeServiceImpl.IDX_CREATED]).getTime());
// assertEquals("Case 3.4: Correct update date, when update date is null.", createDate.getTime(),
// ((Date) objectArr1[HomeServiceImpl.IDX_MODIFIED]).getTime());
/**
* Case 3(P): Normal flow. 2x execution.
* <ol>
* <li>Case 3.1: Entity passed back.
* <li>Case 3.2: Correct size.
* <li>Case 3.5: StringBuilder has correct value.
* </ol>
*/
@Test
public void testGetBranchNodePropertyCase3()
{
//Setup 1
final Date createDate = getCommon().getCurrentDate();
testSubBranch11.setCreateDate(DateUtils.getInstance().removeTime(createDate));
testSubBranch11.setCreateTime(DateUtils.getInstance().toTimeOnly(createDate));
final StringBuilder param1 = new StringBuilder();
//Begin
final Object[] objectArr1 = getTestInstance().getBranchNodeProperty(param1, TEST_SUBBRANCH11_ID);
assertSame("Case 3.1: Entity passed back.", testSubBranch11, objectArr1[HomeServiceImpl.IDX_BEAN]);
assertEquals("Case 3.2: Correct size.", Long.valueOf(TEST_BRANCH_NAME11.length()),
objectArr1[HomeServiceImpl.IDX_SIZE]);
assertEquals("Case 3.5: StringBuilder has correct value.", "/" + TEST_BRANCH_NAME11, param1.toString());
//Setup 2
// final Date updateDate = getCommon().getTomorrowDate();
// testSubBranch11.setUpdateDate(DateUtils.getInstance().removeTime(updateDate));
// testSubBranch11.setUpdateTime(DateUtils.getInstance().toTimeOnly(updateDate));
// final StringBuilder param2 = new StringBuilder();
// //Begin
// final Object[] objectArr2 = getTestInstance().getBranchNodeProperty(param2, TEST_SUBBRANCH11_ID);
// assertEquals("Case 3.6: Correct update date, when update date is not null.", updateDate.getTime(),
// ((Date) objectArr2[HomeServiceImpl.IDX_MODIFIED]).getTime());
}
/*
* (non-Javadoc)
* @see com.philip.journal.core.service.AbstractPowerMockJournalTestService#getTestInstanceClass()
*/
@Override
protected Class<HomeServiceImpl> getTestInstanceClass()
{
return HomeServiceImpl.class;
}
}