/*
* Copyright 2000-2013 Enonic AS
* http://www.enonic.com/license
*/
package com.enonic.cms.itest.client;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.jdom.Document;
import org.jdom.Element;
import org.joda.time.DateTime;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockHttpServletRequest;
import com.enonic.cms.framework.xml.XMLDocumentFactory;
import com.enonic.cms.api.client.model.GetRelatedContentsParams;
import com.enonic.cms.core.client.InternalClientImpl;
import com.enonic.cms.core.client.InternalLocalClient;
import com.enonic.cms.core.content.ContentEntity;
import com.enonic.cms.core.content.ContentKey;
import com.enonic.cms.core.content.ContentService;
import com.enonic.cms.core.content.ContentStatus;
import com.enonic.cms.core.content.command.CreateContentCommand;
import com.enonic.cms.core.content.contentdata.ContentData;
import com.enonic.cms.core.content.contentdata.custom.CustomContentData;
import com.enonic.cms.core.content.contentdata.custom.contentkeybased.RelatedContentDataEntry;
import com.enonic.cms.core.content.contentdata.custom.relationdataentrylistbased.RelatedContentsDataEntry;
import com.enonic.cms.core.content.contentdata.custom.stringbased.TextDataEntry;
import com.enonic.cms.core.content.contenttype.ContentHandlerName;
import com.enonic.cms.core.content.contenttype.ContentTypeConfigBuilder;
import com.enonic.cms.core.content.contenttype.dataentryconfig.DataEntryConfig;
import com.enonic.cms.core.portal.livetrace.LivePortalTraceService;
import com.enonic.cms.core.preview.PreviewService;
import com.enonic.cms.core.security.PortalSecurityHolder;
import com.enonic.cms.core.security.SecurityService;
import com.enonic.cms.core.security.user.User;
import com.enonic.cms.core.servlet.ServletRequestAccessor;
import com.enonic.cms.core.time.MockTimeService;
import com.enonic.cms.itest.AbstractSpringTest;
import com.enonic.cms.itest.util.DomainFactory;
import com.enonic.cms.itest.util.DomainFixture;
import com.enonic.cms.store.dao.ContentDao;
import com.enonic.cms.store.dao.UserDao;
import static com.enonic.cms.itest.util.AssertTool.assertXPathEquals;
import static org.junit.Assert.*;
public class InternalClientImpl_getRelatedContentTest
extends AbstractSpringTest
{
private static final DateTime DATE_TIME_2010_01_01 = new DateTime( 2010, 1, 1, 0, 0, 0, 0 );
private static final DateTime DATE_TIME_2010_07_01_12_00_00_0 = new DateTime( 2010, 7, 1, 12, 0, 0, 0 );
@Autowired
private DomainFixture fixture;
@Autowired
private SecurityService securityService;
@Autowired
private ContentService contentService;
@Autowired
private ContentDao contentDao;
@Autowired
private UserDao userDao;
private InternalClientImpl internalClient;
@Autowired
private PreviewService previewService;
@Autowired
private LivePortalTraceService livePortalTraceService;
private ContentKey[] departments = new ContentKey[3];
@Before
public void setUp()
{
DomainFactory factory = fixture.getFactory();
// setup needed common data for each test
fixture.initSystemData();
fixture.save( factory.createContentHandler( "Custom content", ContentHandlerName.CUSTOM.getHandlerClassShortName() ) );
ServletRequestAccessor.setRequest( new MockHttpServletRequest( "GET", "/" ) );
fixture.createAndStoreNormalUserWithUserGroup( "content-creator", "Creator", "testuserstore" );
fixture.createAndStoreNormalUserWithUserGroup( "content-querier", "Querier", "testuserstore" );
// setup content types: Person and Department
ContentTypeConfigBuilder personCtyConf = new ContentTypeConfigBuilder( "Person", "name" );
personCtyConf.startBlock( "Person" );
personCtyConf.addInput( "name", "text", "contentdata/name", "Name", true );
personCtyConf.endBlock();
Document personConfigAsXmlBytes = XMLDocumentFactory.create( personCtyConf.toString() ).getAsJDOMDocument();
fixture.save( factory.createContentType( "Person", ContentHandlerName.CUSTOM.getHandlerClassShortName(), personConfigAsXmlBytes ) );
ContentTypeConfigBuilder deptCtyConf = new ContentTypeConfigBuilder( "Department", "name" );
deptCtyConf.startBlock( "Department" );
deptCtyConf.addInput( "name", "text", "contentdata/name", "Name", true );
deptCtyConf.addRelatedContentInput( "employee", "contentdata/employee", "Employee", false, true, "Person" );
deptCtyConf.endBlock();
Document deptConfigAsXmlBytes = XMLDocumentFactory.create( deptCtyConf.toString() ).getAsJDOMDocument();
fixture.save(
factory.createContentType( "Department", ContentHandlerName.CUSTOM.getHandlerClassShortName(), deptConfigAsXmlBytes ) );
// setup archive: Company Unit with 2 categories: Employees and Departments.
fixture.save( factory.createUnit( "Company", "en" ) );
fixture.save( factory.createCategory( "Employees", null, "Person", "Company", User.ANONYMOUS_UID, User.ANONYMOUS_UID, false ) );
fixture.save(
factory.createCategory( "Departments", null, "Department", "Company", User.ANONYMOUS_UID, User.ANONYMOUS_UID, false ) );
fixture.save( factory.createCategoryAccessForUser( "Employees", "content-creator", "read, create, approve, admin_browse" ) );
fixture.save( factory.createCategoryAccessForUser( "Employees", "content-querier", "read, admin_browse" ) );
fixture.save( factory.createCategoryAccessForUser( "Departments", "content-creator", "read, create, approve, admin_browse" ) );
fixture.save( factory.createCategoryAccessForUser( "Departments", "content-querier", "read, admin_browse" ) );
// create test data: 8 persons in 3 departments:
// dept A with persons Anne, Birger, Cecilie, Daniel, Even og Frank
// dept B with persons Anne, Cecilie, Even, Frank og Hanne
// dept C with persons Anne, Cecilie, Even og Grete
ContentKey empAnneKey = createAndStorePersonContent( "Anne" );
ContentKey empBirgerKey = createAndStorePersonContent( "Birger" );
ContentKey empCecilieKey = createAndStorePersonContent( "Cecilie" );
ContentKey empDanielKey = createAndStorePersonContent( "Daniel" );
ContentKey empEvenKey = createAndStorePersonContent( "Even" );
ContentKey empFrankKey = createAndStorePersonContent( "Frank" );
ContentKey empGreteKey = createAndStorePersonContent( "Grete" );
ContentKey empHanneKey = createAndStorePersonContent( "Hanne" );
departments[0] =
createAndStoreDepartmentContent( "dept A", empAnneKey, empBirgerKey, empCecilieKey, empDanielKey, empEvenKey, empFrankKey );
departments[1] =
createAndStoreDepartmentContent( "dept B", empAnneKey, empBirgerKey, empCecilieKey, empEvenKey, empFrankKey, empHanneKey );
departments[2] = createAndStoreDepartmentContent( "dept C", empAnneKey, empCecilieKey, empEvenKey, empGreteKey );
fixture.flushAndClearHibernateSession();
fixture.flushIndexTransaction();
PortalSecurityHolder.setLoggedInUser( fixture.findUserByName( "content-querier" ).getKey() );
PortalSecurityHolder.setImpersonatedUser( fixture.findUserByName( "content-querier" ).getKey() );
internalClient = new InternalLocalClient();
internalClient.setSecurityService( securityService );
internalClient.setContentService( contentService );
internalClient.setPreviewService( previewService );
internalClient.setContentDao( contentDao );
internalClient.setUserDao( userDao );
internalClient.setTimeService( new MockTimeService( DATE_TIME_2010_07_01_12_00_00_0 ) );
internalClient.setLivePortalTraceService( livePortalTraceService );
}
@Test
public void get_single_related_parent()
{
ContentEntity greteEntity = fixture.findContentByName( "Grete" );
GetRelatedContentsParams params = new GetRelatedContentsParams();
params.contentKeys = new int[]{greteEntity.getKey().toInt()};
params.relation = -1;
params.requireAll = false;
Document resultAsJDom = internalClient.getRelatedContent( params );
assertXPathEquals( "/contents/content/@key", resultAsJDom, departments[2].toString() );
assertXPathEquals( "/contents/content/name", resultAsJDom, "dept C" );
}
@Test
public void get_all_eight_related_children()
{
GetRelatedContentsParams params = new GetRelatedContentsParams();
params.contentKeys = new int[]{departments[0].toInt(), departments[1].toInt(), departments[2].toInt()};
params.relation = 1;
params.requireAll = false;
Document resultAsJDom = internalClient.getRelatedContent( params );
Element rootElement = resultAsJDom.getRootElement();
List persons = rootElement.getChildren( "content" );
assertEquals( "Union of all department members", 8, persons.size() );
}
@Test
public void get_three_out_of_eight_related_children_requireAll()
{
GetRelatedContentsParams params = new GetRelatedContentsParams();
params.contentKeys = new int[]{departments[0].toInt(), departments[1].toInt(), departments[2].toInt()};
params.relation = 1;
params.requireAll = true;
Document resultAsJDom = internalClient.getRelatedContent( params );
Element rootElement = resultAsJDom.getRootElement();
List<Element> persons = rootElement.getChildren( "content" );
assertEquals( "Intersection of all department members", 3, persons.size() );
Set<String> names = new HashSet<String>();
for ( Element person : persons )
{
names.add( person.getChild( "name" ).getText() );
}
assertEquals( "3 different names are in alle departments", 3, names.size() );
assertTrue( "Anne is in all departments", names.contains( "Anne" ) );
assertTrue( "Cecilie is in all departments", names.contains( "Cecilie" ) );
assertTrue( "Even is in all departments", names.contains( "Even" ) );
}
@Test
public void get_all_three_related_parents()
{
ContentEntity birgerEntity = fixture.findContentByName( "Birger" );
ContentEntity cecilieEntity = fixture.findContentByName( "Cecilie" );
ContentEntity evenEntity = fixture.findContentByName( "Even" );
ContentEntity frankEntity = fixture.findContentByName( "Frank" );
GetRelatedContentsParams params = new GetRelatedContentsParams();
params.contentKeys = new int[]{birgerEntity.getKey().toInt(), cecilieEntity.getKey().toInt(), evenEntity.getKey().toInt(),
frankEntity.getKey().toInt()};
params.relation = -1;
params.requireAll = false;
Document resultAsJDom = internalClient.getRelatedContent( params );
Element rootElement = resultAsJDom.getRootElement();
List departments = rootElement.getChildren( "content" );
assertEquals( "Union of all employee departments", 3, departments.size() );
}
@Test
public void get_two_out_of_three_related_parents_requireAll()
{
ContentEntity birgerEntity = fixture.findContentByName( "Birger" );
ContentEntity cecilieEntity = fixture.findContentByName( "Cecilie" );
ContentEntity evenEntity = fixture.findContentByName( "Even" );
ContentEntity frankEntity = fixture.findContentByName( "Frank" );
GetRelatedContentsParams params = new GetRelatedContentsParams();
params.contentKeys = new int[]{birgerEntity.getKey().toInt(), cecilieEntity.getKey().toInt(), evenEntity.getKey().toInt(),
frankEntity.getKey().toInt()};
params.relation = -1;
params.requireAll = true;
Document resultAsJDom = internalClient.getRelatedContent( params );
Element rootElement = resultAsJDom.getRootElement();
List<Element> departments = rootElement.getChildren( "content" );
assertEquals( "Union of all employee departments", 2, departments.size() );
Set<String> names = new HashSet<String>();
for ( Element department : departments )
{
names.add( department.getChild( "name" ).getText() );
}
assertEquals( "2 different represents all of these employees", 2, names.size() );
assertTrue( "dept A represents all", names.contains( "dept A" ) );
assertTrue( "dept B represents all", names.contains( "dept B" ) );
}
private ContentKey createAndStoreDepartmentContent( String name, ContentKey... employeeKeys )
{
CustomContentData deptContentData = new CustomContentData( fixture.findContentTypeByName( "Department" ).getContentTypeConfig() );
DataEntryConfig nameInputConfig = deptContentData.getInputConfig( "name" );
deptContentData.add( new TextDataEntry( nameInputConfig, name ) );
RelatedContentsDataEntry relatedEmployeeList = new RelatedContentsDataEntry( deptContentData.getInputConfig( "employee" ) );
for ( ContentKey employeeKey : employeeKeys )
{
relatedEmployeeList.add( new RelatedContentDataEntry( deptContentData.getInputConfig( "employee" ), employeeKey ) );
}
deptContentData.add( relatedEmployeeList );
return contentService.createContent(
createDepartmentCreateContentCommand( "content-creator", ContentStatus.APPROVED, name, deptContentData, DATE_TIME_2010_01_01,
null ) );
}
private CreateContentCommand createDepartmentCreateContentCommand( String creatorUid, ContentStatus contentStatus, String contentName,
CustomContentData contentData, DateTime availableFrom,
DateTime availableTo )
{
CreateContentCommand createContentCommand = new CreateContentCommand();
createContentCommand.setCategory( fixture.findCategoryByName( "Departments" ) );
createContentCommand.setCreator( fixture.findUserByName( creatorUid ).getKey() );
createContentCommand.setLanguage( fixture.findLanguageByCode( "en" ) );
createContentCommand.setStatus( contentStatus );
createContentCommand.setPriority( 0 );
createContentCommand.setAccessRightsStrategy( CreateContentCommand.AccessRightsStrategy.INHERIT_FROM_CATEGORY );
createContentCommand.setContentData( contentData );
createContentCommand.setContentName( contentName );
if ( availableFrom != null )
{
createContentCommand.setAvailableFrom( availableFrom.toDate() );
}
if ( availableTo != null )
{
createContentCommand.setAvailableTo( availableTo.toDate() );
}
return createContentCommand;
}
private ContentKey createAndStorePersonContent( String name )
{
CustomContentData empContentData = new CustomContentData( fixture.findContentTypeByName( "Person" ).getContentTypeConfig() );
empContentData.add( new TextDataEntry( empContentData.getInputConfig( "name" ), name ) );
return contentService.createContent(
createPersonCreateContentCommand( "content-creator", ContentStatus.APPROVED, name, empContentData, DATE_TIME_2010_01_01,
null ) );
}
private CreateContentCommand createPersonCreateContentCommand( String creatorUid, ContentStatus contentStatus, String contentName,
ContentData contentData, DateTime availableFrom, DateTime availableTo )
{
CreateContentCommand createContentCommand = new CreateContentCommand();
createContentCommand.setCategory( fixture.findCategoryByName( "Employees" ) );
createContentCommand.setCreator( fixture.findUserByName( creatorUid ).getKey() );
createContentCommand.setLanguage( fixture.findLanguageByCode( "en" ) );
createContentCommand.setStatus( contentStatus );
createContentCommand.setPriority( 0 );
createContentCommand.setAccessRightsStrategy( CreateContentCommand.AccessRightsStrategy.INHERIT_FROM_CATEGORY );
createContentCommand.setContentData( contentData );
createContentCommand.setContentName( contentName );
if ( availableFrom != null )
{
createContentCommand.setAvailableFrom( availableFrom.toDate() );
}
if ( availableTo != null )
{
createContentCommand.setAvailableTo( availableTo.toDate() );
}
return createContentCommand;
}
}