/*************************************************************************** * Copyright (C) 2003-2009 eXo Platform SAS. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Affero General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see<http://www.gnu.org/licenses/>. * **************************************************************************/ package org.exoplatform.services.ecm.dms.cms; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.Map; import javax.jcr.Node; import javax.jcr.PathNotFoundException; import javax.jcr.RepositoryException; import javax.jcr.Session; import org.exoplatform.commons.utils.ISO8601; import org.exoplatform.services.cms.CmsService; import org.exoplatform.services.cms.JcrInputProperty; import org.exoplatform.services.wcm.BaseWCMTestCase; import org.junit.FixMethodOrder; import org.junit.runners.MethodSorters; /** * Created by The eXo Platform SARL * Author : Hoang Van Hung * hunghvit@gmail.com * Jun 12, 2009 */ @FixMethodOrder(MethodSorters.JVM) public class TestCmsService extends BaseWCMTestCase { private CmsService cmsService; private static final String ARTICLE = "exo:article"; private static final String NTRESOURCE = "nt:resource"; public void setUp() throws Exception { super.setUp(); cmsService = (CmsService) container.getComponentInstanceOfType(CmsService.class); applySystemSession(); } public void tearDown() throws Exception { super.tearDown(); } /** * Create data for String with String property */ private Map<String, JcrInputProperty> createArticleMapInput() { Map<String, JcrInputProperty> map = new HashMap<String, JcrInputProperty>(); String titlePath = CmsService.NODE + "/" + "exo:title"; String summaryPath = CmsService.NODE + "/" + "exo:summary"; String textPath = CmsService.NODE + "/" + "exo:text"; JcrInputProperty inputProperty = new JcrInputProperty(); inputProperty.setJcrPath(CmsService.NODE); inputProperty.setValue("document_1"); map.put(CmsService.NODE, inputProperty); inputProperty = new JcrInputProperty(); inputProperty.setJcrPath(titlePath); inputProperty.setValue("this is title"); map.put(titlePath, inputProperty); inputProperty = new JcrInputProperty(); inputProperty.setJcrPath(summaryPath); inputProperty.setValue("this is summary"); map.put(summaryPath, inputProperty); inputProperty = new JcrInputProperty(); inputProperty.setJcrPath(textPath); inputProperty.setValue("this is article content"); map.put(textPath, inputProperty); return map; } /** * Add mixin for node */ private Map<String, JcrInputProperty> createArticleEditMapInput() { Map<String, JcrInputProperty> map = new HashMap<String, JcrInputProperty>(); String titlePath = CmsService.NODE + "/" + "exo:title"; String categoryPath = CmsService.NODE + "/" + "exo:category"; JcrInputProperty inputProperty = new JcrInputProperty(); inputProperty.setJcrPath(CmsService.NODE); inputProperty.setMixintype("exo:categorized"); inputProperty.setValue("document_1"); map.put(CmsService.NODE, inputProperty); inputProperty = new JcrInputProperty(); inputProperty.setJcrPath(titlePath); inputProperty.setValue("this is title edit"); map.put(titlePath, inputProperty); inputProperty = new JcrInputProperty(); inputProperty.setJcrPath(categoryPath); inputProperty.setValue(new String[] {COLLABORATION_WS + ":/referencedNodeArticle"}); map.put(categoryPath, inputProperty); return map; } /** * Create data for Node with String and date time property */ private Map<String, JcrInputProperty> createSampleMapInput() { Map<String, JcrInputProperty> map = new HashMap<String, JcrInputProperty>(); String titlePath = CmsService.NODE + "/" + "exo:title"; String descriptPath = CmsService.NODE + "/" + "exo:description"; String datePath = CmsService.NODE + "/" + "exo:date"; String datetimePath = CmsService.NODE + "/" + "exo:datetime"; String summaryPath = CmsService.NODE + "/" + "exo:summary"; String contentPath = CmsService.NODE + "/" + "exo:content"; String totalScorePath = CmsService.NODE + "/" + "exo:totalScore"; String averageScorePath = CmsService.NODE + "/" + "exo:averageScore"; String moveablePath = CmsService.NODE + "/" + "exo:moveable"; JcrInputProperty inputProperty = new JcrInputProperty(); inputProperty.setValue("document_2"); inputProperty.setJcrPath(CmsService.NODE); //inputProperty.setMixintype("mix:cms"); map.put(CmsService.NODE, inputProperty); inputProperty = new JcrInputProperty(); inputProperty.setJcrPath(titlePath); inputProperty.setValue("this is title"); map.put(titlePath, inputProperty); inputProperty = new JcrInputProperty(); inputProperty.setJcrPath(descriptPath); inputProperty.setValue("this is description"); map.put(descriptPath, inputProperty); inputProperty = new JcrInputProperty(); inputProperty.setJcrPath(datePath); inputProperty.setValue(ISO8601.parse("06/12/2009")); map.put(datePath, inputProperty); inputProperty = new JcrInputProperty(); inputProperty.setJcrPath(datetimePath); inputProperty.setValue(ISO8601.parse("06/12/2009 14:58:49")); map.put(datetimePath, inputProperty); inputProperty = new JcrInputProperty(); inputProperty.setJcrPath(summaryPath); inputProperty.setValue("this is summary"); map.put(summaryPath, inputProperty); inputProperty = new JcrInputProperty(); inputProperty.setJcrPath(contentPath); inputProperty.setValue("this is sample's content"); map.put(contentPath, inputProperty); inputProperty = new JcrInputProperty(); inputProperty.setJcrPath(totalScorePath); inputProperty.setValue(new Long(15)); map.put(totalScorePath, inputProperty); inputProperty = new JcrInputProperty(); inputProperty.setJcrPath(averageScorePath); inputProperty.setValue(new Double(1.23)); map.put(averageScorePath, inputProperty); inputProperty = new JcrInputProperty(); inputProperty.setJcrPath(moveablePath); inputProperty.setValue("true"); map.put(moveablePath, inputProperty); return map; } /** * Create data for Node with String and date time property */ private Map<String, JcrInputProperty> createSampleMapInputEdit() { Map<String, JcrInputProperty> map = new HashMap<String, JcrInputProperty>(); String titlePath = CmsService.NODE + "/" + "exo:title"; String descriptPath = CmsService.NODE + "/" + "exo:description"; String datePath = CmsService.NODE + "/" + "exo:date"; String datetimePath = CmsService.NODE + "/" + "exo:datetime"; String summaryPath = CmsService.NODE + "/" + "exo:summary"; String contentPath = CmsService.NODE + "/" + "exo:content"; String totalScorePath = CmsService.NODE + "/" + "exo:totalScore"; String averageScorePath = CmsService.NODE + "/" + "exo:averageScore"; String moveablePath = CmsService.NODE + "/" + "exo:moveable"; String linkPath = CmsService.NODE + "/" + "exo:linkdata"; JcrInputProperty inputProperty = new JcrInputProperty(); inputProperty.setValue("document_2"); inputProperty.setJcrPath(CmsService.NODE); //inputProperty.setMixintype("mix:cms"); map.put(CmsService.NODE, inputProperty); inputProperty = new JcrInputProperty(); inputProperty.setJcrPath(titlePath); inputProperty.setValue("this is title edit"); map.put(titlePath, inputProperty); inputProperty = new JcrInputProperty(); inputProperty.setJcrPath(descriptPath); inputProperty.setValue("this is description"); map.put(descriptPath, inputProperty); inputProperty = new JcrInputProperty(); inputProperty.setJcrPath(datePath); inputProperty.setValue(ISO8601.parse("06/12/2009")); map.put(datePath, inputProperty); inputProperty = new JcrInputProperty(); inputProperty.setJcrPath(datetimePath); inputProperty.setValue(ISO8601.parse("06/12/2009 14:58:49")); map.put(datetimePath, inputProperty); inputProperty = new JcrInputProperty(); inputProperty.setJcrPath(summaryPath); inputProperty.setValue("this is summary"); map.put(summaryPath, inputProperty); inputProperty = new JcrInputProperty(); inputProperty.setJcrPath(contentPath); inputProperty.setValue("this is sample's content"); map.put(contentPath, inputProperty); inputProperty = new JcrInputProperty(); inputProperty.setJcrPath(totalScorePath); inputProperty.setValue(new Long(16)); map.put(totalScorePath, inputProperty); inputProperty = new JcrInputProperty(); inputProperty.setJcrPath(averageScorePath); inputProperty.setValue(new Double(2.34)); map.put(averageScorePath, inputProperty); inputProperty = new JcrInputProperty(); inputProperty.setJcrPath(moveablePath); inputProperty.setValue("false"); map.put(moveablePath, inputProperty); inputProperty = new JcrInputProperty(); inputProperty.setJcrPath(linkPath); inputProperty.setValue(COLLABORATION_WS + ":/referencedNode"); map.put(linkPath, inputProperty); return map; } /** * Create data for Node with String and date time property */ private Map<String, JcrInputProperty> createReferenceMapInput() { Map<String, JcrInputProperty> map = new HashMap<String, JcrInputProperty>(); String categoryPath = CmsService.NODE + "/" + "exo:category"; JcrInputProperty inputProperty = new JcrInputProperty(); inputProperty.setValue("document_3"); inputProperty.setJcrPath(CmsService.NODE); inputProperty.setMixintype("exo:categorized"); map.put(CmsService.NODE, inputProperty); inputProperty = new JcrInputProperty(); inputProperty.setJcrPath(categoryPath); inputProperty.setValue(new String[] {COLLABORATION_WS + ":/referencedNode"}); map.put(categoryPath, inputProperty); return map; } /** * Test property value is string with * CmsService.storeNode(String nodetypeName, Node storeNode, Map inputProperties, boolean isAddNew,String repository) * Input: property for node: exo:title = "this is title";exo:summary="this is summary";exo:text="this is article content" * name = "document_1"; * Expect: node: name = "document_1";property for node: exo:title = "this is title"; * exo:summary="this is summary";exo:text="this is article content" */ public void testStoreNodeArticle() throws RepositoryException, Exception { Node storeNode = session.getRootNode(); Map<String, JcrInputProperty> map = createArticleMapInput(); String path = cmsService.storeNode(ARTICLE, storeNode, map, true); assertTrue(session.itemExists(path)); Node articleNode = (Node)session.getItem(path); assertEquals("document_1", articleNode.getName()); assertEquals("this is title", articleNode.getProperty("exo:title").getString()); assertEquals("this is summary", articleNode.getProperty("exo:summary").getString()); assertEquals("this is article content", articleNode.getProperty("exo:text").getString()); } /** * Test add mixin * CmsService.storeNode(String nodetypeName, Node storeNode, Map inputProperties, boolean isAddNew,String repository)} * Input: property for node: exo:title = "this is title";exo:summary="this is summary";exo:text="this is article content" * exo:category = uuid of one reference node; name = "document_1"; * Expect: node: name = "document_1";property for node: exo:title = "this is title"; * exo:summary="this is summary";exo:text="this is article content"; exo:category = uuid of one reference node above; */ public void testStoreNodeArticleEdit() throws RepositoryException, Exception { Node storeNode = session.getRootNode(); Node referencedNode = storeNode.addNode("referencedNodeArticle"); if (referencedNode.canAddMixin("mix:referenceable")) { referencedNode.addMixin("mix:referenceable"); } session.save(); Map<String, JcrInputProperty> map = createArticleMapInput(); String path1 = cmsService.storeNode(ARTICLE, storeNode, map, true); assertTrue(session.itemExists(path1)); Node articleNode = (Node)session.getItem(path1); assertEquals("document_1", articleNode.getName()); assertEquals("this is title", articleNode.getProperty("exo:title").getValue().getString()); map = createArticleEditMapInput(); String path2 = cmsService.storeNode(ARTICLE, storeNode, map, false); assertTrue(session.itemExists(path2)); session.getItem(path1).remove(); session.getItem(path2).remove(); referencedNode.remove(); session.save(); } /** * Test property value is string with * CmsService.storeNode(String workspace, String nodetypeName, String storePath, Map inputProperties,String repository) * Input: property for node: exo:title = "this is title";exo:summary="this is summary";exo:text="this is article content" * name = "document_1"; * Expect: node: name = "document_1";property for node: exo:title = "this is title"; * exo:summary="this is summary";exo:text="this is article content" */ // public void testStoreNodeArticleByPath1() throws RepositoryException, Exception { // Node storeNode = session.getRootNode().addNode("storeNode"); // session.save(); // Map<String, JcrInputProperty> map = createArticleMapInput(); // String path = cmsService.storeNode(COLLABORATION_WS, ARTICLE, storeNode.getPath(), map, REPO_NAME); // assertTrue(session.itemExists(path)); // Node articleNode = (Node)session.getItem(path); // assertEquals("document_1", articleNode.getName()); // assertEquals("this is title", articleNode.getProperty("exo:title").getString()); // assertEquals("this is summary", articleNode.getProperty("exo:summary").getString()); // assertEquals("this is article content", articleNode.getProperty("exo:text").getString()); // // articleNode.remove(); // storeNode.remove(); // session.save(); // } /** * Create binary data * @throws IOException */ private Map<String, JcrInputProperty> createBinaryMapInput() throws IOException { Map<String, JcrInputProperty> map = new HashMap<String, JcrInputProperty>(); String data = CmsService.NODE + "/" + "jcr:data"; JcrInputProperty inputProperty = new JcrInputProperty(); inputProperty.setJcrPath(CmsService.NODE); inputProperty.setValue("BinaryData"); map.put(CmsService.NODE, inputProperty); inputProperty = new JcrInputProperty(); inputProperty.setJcrPath(data); inputProperty.setValue("test"); map.put(data, inputProperty); return map; } /** * Test property value is binary * input: data of file /conf/standalone/system-configuration.xml * output: value in property jcr:data of one nt:resource node = value in file /conf/standalone/system-configuration.xml * @throws RepositoryException * @throws Exception */ public void testStoreNodeBinaryProperty() throws RepositoryException, Exception { Node rootNode = session.getRootNode(); Map<String, JcrInputProperty> map = createBinaryMapInput(); if ((rootNode != null) && (map != null)) { try { System.out.println("NTRESOURCE: " + NTRESOURCE); System.out.println("rootNode: " + rootNode.getPath()); System.out.println("map: " + map); System.out.println("REPO_NAME: " + REPO_NAME); String path1 = cmsService.storeNode(NTRESOURCE, rootNode, map, true); System.out.println("path1: " + path1); assertTrue(session.itemExists(path1)); Node binaryNode = (Node)session.getItem(path1); assertEquals("BinaryData", binaryNode.getName()); InputStream is = getClass().getResource("/conf/standalone/system-configuration.xml").openStream(); assertEquals("test", binaryNode.getProperty("jcr:data").getString()); binaryNode.remove(); session.save(); } catch (NullPointerException e) { // TODO: handle exception } } } /** * Test with path does not existed, * Input: /temp: path does not exist * Expect: PathNotFoundException * @throws RepositoryException * @throws Exception */ public void testStoreNodeArticleByPath2() throws RepositoryException, Exception { Map<String, JcrInputProperty> map = createArticleMapInput(); try { MockCmsServiceImpl mock = (MockCmsServiceImpl) container.getComponentInstanceOfType(MockCmsServiceImpl.class); String path = mock.storeNode(COLLABORATION_WS, ARTICLE, "/temp", map); session.getItem(path).remove(); session.save(); } catch (PathNotFoundException ex) { } } /** * Test create property with reference type * Input: property for node: exo:category = uuid of one reference node; name = "document_3"; * Expect: node: name = "document_3";property for node: exo:category = uuid of one reference node above; * @throws RepositoryException * @throws Exception */ public void testStoreNodeWithReference() throws RepositoryException, Exception { Node storeNode = session.getRootNode(); Node referencedNode = storeNode.addNode("referencedNode"); session.save(); if (referencedNode.canAddMixin("mix:referenceable")) { referencedNode.addMixin("mix:referenceable"); } session.save(); String uuid = referencedNode.getUUID(); Map<String, JcrInputProperty> map = createReferenceMapInput(); String path1 = cmsService.storeNode(ARTICLE, storeNode, map, true); assertTrue(session.itemExists(path1)); Node sampleNode = (Node)session.getItem(path1); assertEquals("document_3", sampleNode.getName()); assertEquals(uuid, sampleNode.getProperty("exo:category").getValues()[0].getString()); sampleNode.remove(); referencedNode.remove(); session.save(); } /** * Test method CmsService.moveNode() * Move node test1 to test2 node, clean test1 node * Expect: node test1 does not exist, node test2/test1 exits * @throws Exception */ public void testMoveNode() throws Exception { Node test1 = session.getRootNode().addNode("test1"); session.save(); Session session2 = sessionProviderService_.getSystemSessionProvider(null).getSession(SYSTEM_WS, repository); Node test2 = session.getRootNode().addNode("test2"); session2.save(); String destPath = test2.getPath() + test1.getPath(); cmsService.moveNode(test1.getPath(), COLLABORATION_WS, SYSTEM_WS, destPath); assertTrue(session2.itemExists(destPath)); assertTrue(!session.itemExists("/test1")); test2.remove(); session.save(); session2.save(); } /** * Compare two input stream, return true if bytes of is1 equal bytes of is2 * @param is1 * @param is2 * @return * @throws IOException */ private boolean compareInputStream(InputStream is1, InputStream is2) throws IOException { int b1, b2; do { b1 = is1.read(); b2 = is2.read(); if (b1 != b2) return false; } while ((b1 !=-1) && (b2!=-1)); return true; } }