package exo.exoplatform.services.wcm.extensions.publication; import java.util.Date; import java.util.LinkedList; import javax.jcr.Node; import org.exoplatform.container.PortalContainer; import org.exoplatform.container.component.RequestLifeCycle; import org.exoplatform.portal.config.DataStorage; import org.exoplatform.portal.config.model.Page; import org.exoplatform.portal.config.model.PortalConfig; import org.exoplatform.portal.mop.EventType; import org.exoplatform.portal.mop.navigation.NavigationService; import org.exoplatform.portal.pom.config.POMSessionManager; import org.exoplatform.portal.pom.spi.portlet.Portlet; import org.exoplatform.services.ecm.publication.PublicationPlugin; import org.exoplatform.services.listener.Event; import org.exoplatform.services.listener.Listener; import org.exoplatform.services.listener.ListenerService; import org.exoplatform.services.organization.OrganizationService; import org.exoplatform.services.security.ConversationState; import org.exoplatform.services.security.Identity; import org.exoplatform.services.wcm.core.NodetypeConstant; import org.exoplatform.services.wcm.publication.PublicationDefaultStates; import org.exoplatform.services.wcm.publication.WCMPublicationService; import org.exoplatform.services.wcm.publication.WebpagePublicationPlugin; import org.exoplatform.services.wcm.extensions.publication.lifecycle.authoring.AuthoringPublicationPlugin; import org.exoplatform.services.wcm.utils.WCMCoreUtils; public class TestWCMPublicationService extends BasePublicationTestCase { private static final String CURRENT_STATE = "publication:currentState"; private static final String TEST = "test"; private static final String ENROLLED = "enrolled"; private static final String PUBLISHED = "published"; private WCMPublicationService publicationService_; private WebpagePublicationPlugin plugin_; private Node node_; private Node testSite; private Node documentTest; // ----------------- /** . */ private final String testPage = "portal::classic::testPage"; /** . */ private final String testPortletPreferences = "portal#classic:/web/BannerPortlet/testPortletPreferences"; /** . */ private DataStorage storage_; /** . */ private NavigationService navService; /** . */ private POMSessionManager mgr; /** . */ private LinkedList<Event> events; /** . */ private ListenerService listenerService; /** . */ private OrganizationService org; public void setUp() throws Exception { super.setUp(); publicationService_ = WCMCoreUtils.getService(WCMPublicationService.class); RequestLifeCycle.begin(PortalContainer.getInstance()); applySystemSession(); Node rootSite = (Node) session.getItem("/sites content/live"); testSite = rootSite.addNode(TEST); documentTest = testSite.addNode("documents"); node_ = testSite.addNode(TEST); node_.addMixin(NodetypeConstant.MIX_REFERENCEABLE); session.save(); ConversationState c = new ConversationState(new Identity(session.getUserID())); ConversationState.setCurrent(c); plugin_ = new AuthoringPublicationPlugin(); plugin_.setName("Authoring publication"); plugin_.setDescription("Authoring publication"); publicationService_.addPublicationPlugin(plugin_); // -------------------------------- Listener listener = new Listener() { @Override public void onEvent(Event event) throws Exception { events.add(event); } }; PortalContainer container = PortalContainer.getInstance(); storage_ = (DataStorage) container.getComponentInstanceOfType(DataStorage.class); mgr = (POMSessionManager) container.getComponentInstanceOfType(POMSessionManager.class); navService = (NavigationService) container.getComponentInstanceOfType(NavigationService.class); events = new LinkedList<Event>(); listenerService = (ListenerService) container.getComponentInstanceOfType(ListenerService.class); org = WCMCoreUtils.getService(OrganizationService.class); listenerService.addListener(DataStorage.PAGE_CREATED, listener); listenerService.addListener(DataStorage.PAGE_REMOVED, listener); listenerService.addListener(DataStorage.PAGE_UPDATED, listener); listenerService.addListener(EventType.NAVIGATION_CREATED, listener); listenerService.addListener(EventType.NAVIGATION_DESTROYED, listener); listenerService.addListener(EventType.NAVIGATION_UPDATED, listener); listenerService.addListener(DataStorage.PORTAL_CONFIG_CREATED, listener); listenerService.addListener(DataStorage.PORTAL_CONFIG_UPDATED, listener); listenerService.addListener(DataStorage.PORTAL_CONFIG_REMOVED, listener); } public void tearDown() throws Exception { publicationService_.getWebpagePublicationPlugins().clear(); node_.remove(); testSite.remove(); session.save(); RequestLifeCycle.end(); super.tearDown(); } /** * Test if a node is enrolled into a lifecycle * * @result current state of enrolled node is "enrolled" */ public void testEnrollNodeInLifecycle1() throws Exception { publicationService_.enrollNodeInLifecycle(node_, plugin_.getLifecycleName()); assertEquals(ENROLLED, node_.getProperty(CURRENT_STATE).getString()); } /** * Test if a node in site is enrolled into a lifecycle * * @result current state of enrolled is node "draft" */ public void testEnrollNodeInLifecycle2() throws Exception { publicationService_.enrollNodeInLifecycle(node_, "test", node_.getSession().getUserID()); assertEquals(PublicationDefaultStates.DRAFT, node_.getProperty(CURRENT_STATE).getString()); } /** * Test if a node is enrolled into WCM Lifecyle * * @result node is enrolled into WCM Lifecycle */ public void testIsEnrolledWCMInLifecycle() throws Exception { assertFalse(publicationService_.isEnrolledInWCMLifecycle(node_)); publicationService_.enrollNodeInLifecycle(node_, plugin_.getLifecycleName()); assertTrue(publicationService_.isEnrolledInWCMLifecycle(node_)); } /** * Test the getContentState function * * @result getContentState returns the "enrolled" status when a node is * enrolled into a lifecycle. */ public void testGetContentState() throws Exception { publicationService_.enrollNodeInLifecycle(node_, plugin_.getLifecycleName()); assertEquals(ENROLLED, publicationService_.getContentState(node_)); } /** * Test the unsubcribeLifecycle function * * @result Node is no longer enrolled into any lifecycle */ public void testUnsubscribeLifecycle() throws Exception { publicationService_.enrollNodeInLifecycle(node_, plugin_.getLifecycleName()); publicationService_.unsubcribeLifecycle(node_); assertFalse(publicationService_.isEnrolledInWCMLifecycle(node_)); } /** * Test if the state of a node can be changed in a lifecycle * * @result state of node can be changed */ public void testUpdateLifecyleOnChangeContent1() throws Exception { publicationService_.updateLifecyleOnChangeContent(node_, "test", node_.getSession().getUserID(), PublicationDefaultStates.PUBLISHED); assertEquals(PublicationDefaultStates.PUBLISHED, publicationService_.getContentState(node_)); publicationService_.updateLifecyleOnChangeContent(node_, "test", node_.getSession().getUserID(), PublicationDefaultStates.DRAFT); assertEquals(PublicationDefaultStates.DRAFT, publicationService_.getContentState(node_)); } /** * Test if the state of a node can be changed into default state * * @result state of node is in "draft" */ public void testUpdateLifecyleOnChangeContent2() throws Exception { publicationService_.updateLifecyleOnChangeContent(node_, "test", node_.getSession().getUserID()); assertEquals(PublicationDefaultStates.DRAFT, publicationService_.getContentState(node_)); } /** * Test if child node of webcontent cannot be enrolled into a lifecycle * * @result child node of webcontent cannot be enrolled into a lifecyle */ public void testUpdateLifecyleOnChangeContent3() throws Exception { String htmlData = "This is the default.html file."; Node webContent = createWebcontentNode(documentTest, "webcontent", "html", "css", "js"); Node documentFolder = webContent.getNode("documents"); Node htmlNode; try { htmlNode = documentFolder.getNode("default.html"); } catch (Exception ex) { htmlNode = documentFolder.addNode("default.html", "nt:file"); } if (!htmlNode.isNodeType("exo:htmlFile")) htmlNode.addMixin("exo:htmlFile"); Node htmlContent; try { htmlContent = htmlNode.getNode("jcr:content"); } catch (Exception ex) { htmlContent = htmlNode.addNode("jcr:content", "nt:resource"); } htmlContent.setProperty("jcr:encoding", "UTF-8"); htmlContent.setProperty("jcr:mimeType", "text/html"); htmlContent.setProperty("jcr:lastModified", new Date().getTime()); htmlContent.setProperty("jcr:data", htmlData); documentFolder.save(); publicationService_.updateLifecyleOnChangeContent(webContent, "test", webContent.getSession().getUserID()); assertEquals(PublicationDefaultStates.DRAFT, publicationService_.getContentState(webContent)); publicationService_.updateLifecyleOnChangeContent(htmlNode, "test", webContent.getSession().getUserID()); // ECMS-6460: Do not allow publishing children of webcontent assertEquals(null, publicationService_.getContentState(htmlNode)); } /** * Creates the webcontent node. * * @param parentNode * the parent node * @param nodeName * the node name * @param htmlData * the html data * @param cssData * the css data * @param jsData * the js data * * @return the node * * @throws Exception * the exception */ protected Node createWebcontentNode(Node parentNode, String nodeName, String htmlData, String cssData, String jsData) throws Exception { Node webcontent = parentNode.addNode(nodeName, "exo:webContent"); webcontent.setProperty("exo:title", nodeName); Node htmlNode; try { htmlNode = webcontent.getNode("default.html"); } catch (Exception ex) { htmlNode = webcontent.addNode("default.html", "nt:file"); } if (!htmlNode.isNodeType("exo:htmlFile")) htmlNode.addMixin("exo:htmlFile"); Node htmlContent; try { htmlContent = htmlNode.getNode("jcr:content"); } catch (Exception ex) { htmlContent = htmlNode.addNode("jcr:content", "nt:resource"); } htmlContent.setProperty("jcr:encoding", "UTF-8"); htmlContent.setProperty("jcr:mimeType", "text/html"); htmlContent.setProperty("jcr:lastModified", new Date().getTime()); if (htmlData == null) htmlData = "This is the default.html file."; htmlContent.setProperty("jcr:data", htmlData); Node jsFolder; try { jsFolder = webcontent.getNode("js"); } catch (Exception ex) { jsFolder = webcontent.addNode("js", "exo:jsFolder"); } Node documentsFolder; try { documentsFolder = webcontent.getNode("documents"); } catch (Exception ex) { documentsFolder = webcontent.addNode("documents", "nt:folder"); } Node jsNode; try { jsNode = jsFolder.getNode("default.js"); } catch (Exception ex) { jsNode = jsFolder.addNode("default.js", "nt:file"); } if (!jsNode.isNodeType("exo:jsFile")) jsNode.addMixin("exo:jsFile"); jsNode.setProperty("exo:active", true); jsNode.setProperty("exo:priority", 1); jsNode.setProperty("exo:sharedJS", true); Node jsContent; try { jsContent = jsNode.getNode("jcr:content"); } catch (Exception ex) { jsContent = jsNode.addNode("jcr:content", "nt:resource"); } jsContent.setProperty("jcr:encoding", "UTF-8"); jsContent.setProperty("jcr:mimeType", "text/javascript"); jsContent.setProperty("jcr:lastModified", new Date().getTime()); if (jsData == null) jsData = "This is the default.js file."; jsContent.setProperty("jcr:data", jsData); Node cssFolder; try { cssFolder = webcontent.getNode("css"); } catch (Exception ex) { cssFolder = webcontent.addNode("css", "exo:cssFolder"); } Node cssNode; try { cssNode = cssFolder.getNode("default.css"); } catch (Exception ex) { cssNode = cssFolder.addNode("default.css", "nt:file"); } if (!cssNode.isNodeType("exo:cssFile")) cssNode.addMixin("exo:cssFile"); cssNode.setProperty("exo:active", true); cssNode.setProperty("exo:priority", 1); cssNode.setProperty("exo:sharedCSS", true); Node cssContent; try { cssContent = cssNode.getNode("jcr:content"); } catch (Exception ex) { cssContent = cssNode.addNode("jcr:content", "nt:resource"); } cssContent.setProperty("jcr:encoding", "UTF-8"); cssContent.setProperty("jcr:mimeType", "text/css"); cssContent.setProperty("jcr:lastModified", new Date().getTime()); if (cssData == null) cssData = "This is the default.css file."; cssContent.setProperty("jcr:data", cssData); Node mediaFolder; try { mediaFolder = webcontent.getNode("medias"); } catch (Exception ex) { mediaFolder = webcontent.addNode("medias"); } if (!mediaFolder.hasNode("images")) mediaFolder.addNode("images", "nt:folder"); if (!mediaFolder.hasNode("videos")) mediaFolder.addNode("videos", "nt:folder"); if (!mediaFolder.hasNode("audio")) mediaFolder.addNode("audio", "nt:folder"); session.save(); return webcontent; } }