/* * (C) Copyright 2010 Nuxeo SA (http://nuxeo.com/) and others. * * 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. * Contributors: * Nuxeo - initial API and implementation */ package org.nuxeo.ecm.platform.rendition.publisher; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.nuxeo.ecm.platform.publisher.impl.core.SectionPublicationTree.CAN_ASK_FOR_PUBLISHING; import static org.nuxeo.ecm.platform.rendition.publisher.RenditionPublicationFactory.RENDITION_NAME_PARAMETER_KEY; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.inject.Inject; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.nuxeo.ecm.core.api.Blob; import org.nuxeo.ecm.core.api.Blobs; import org.nuxeo.ecm.core.api.CoreInstance; import org.nuxeo.ecm.core.api.CoreSession; import org.nuxeo.ecm.core.api.DocumentModel; import org.nuxeo.ecm.core.api.PathRef; import org.nuxeo.ecm.core.api.impl.DocumentLocationImpl; import org.nuxeo.ecm.core.api.security.ACE; import org.nuxeo.ecm.core.api.security.ACL; import org.nuxeo.ecm.core.api.security.ACP; import org.nuxeo.ecm.core.api.security.SecurityConstants; import org.nuxeo.ecm.core.event.EventService; import org.nuxeo.ecm.core.test.CoreFeature; import org.nuxeo.ecm.core.test.annotations.Granularity; import org.nuxeo.ecm.core.test.annotations.RepositoryConfig; import org.nuxeo.ecm.directory.api.DirectoryService; import org.nuxeo.ecm.platform.publisher.api.PublicationNode; import org.nuxeo.ecm.platform.publisher.api.PublicationTree; import org.nuxeo.ecm.platform.publisher.api.PublishedDocument; import org.nuxeo.ecm.platform.publisher.api.PublisherService; import org.nuxeo.ecm.platform.publisher.task.CoreProxyWithWorkflowFactory; import org.nuxeo.ecm.platform.task.test.TaskUTConstants; import org.nuxeo.runtime.test.runner.Deploy; import org.nuxeo.runtime.test.runner.Features; import org.nuxeo.runtime.test.runner.FeaturesRunner; import org.nuxeo.runtime.test.runner.LocalDeploy; /** * @author <a href="mailto:tdelprat@nuxeo.com">Tiry</a> */ @RunWith(FeaturesRunner.class) @Features(CoreFeature.class) @RepositoryConfig(init = RenditionPublicationRepositoryInit.class, cleanup = Granularity.METHOD) @Deploy({ "org.nuxeo.ecm.core.convert.api", "org.nuxeo.ecm.core.convert", "org.nuxeo.ecm.core.convert.plugins", "org.nuxeo.ecm.platform.convert", "org.nuxeo.ecm.platform.query.api", "org.nuxeo.ecm.platform.rendition.api", "org.nuxeo.ecm.platform.rendition.core", "org.nuxeo.ecm.automation.core", "org.nuxeo.ecm.directory", "org.nuxeo.ecm.directory.sql", "org.nuxeo.ecm.directory.types.contrib", "org.nuxeo.ecm.platform.versioning.api", "org.nuxeo.ecm.platform.versioning", "org.nuxeo.ecm.relations", "org.nuxeo.ecm.relations.jena", "org.nuxeo.ecm.platform.publisher.core.contrib", "org.nuxeo.ecm.platform.publisher.core", "org.nuxeo.ecm.platform.publisher.task", "org.nuxeo.ecm.platform.usermanager", TaskUTConstants.CORE_BUNDLE_NAME, TaskUTConstants.TESTING_BUNDLE_NAME, "org.nuxeo.ecm.platform.rendition.publisher", "org.nuxeo.ecm.actions" }) @LocalDeploy({ "org.nuxeo.ecm.platform.rendition.publisher:relations-default-jena-contrib.xml", "org.nuxeo.ecm.platform.rendition.publisher:test-sql-directories-contrib.xml" }) public class TestRenditionPublicationWFAprove { @Inject protected CoreSession session; @Inject protected PublisherService publisherService; @Inject protected DirectoryService directoryService; @Inject protected CoreFeature coreFeature; @Inject protected EventService eventService; protected HashMap<String, String> factoryParams = new HashMap<String, String>(); protected DocumentModel doc2Publish = null; @Before public void initPublishTestCase() throws Exception { if (doc2Publish != null) { session.removeChildren(session.getRootDocument().getRef()); eventService.waitForAsyncCompletion(); doc2Publish = null; } if (doc2Publish == null) { doc2Publish = createDocumentToPublish(); initializeACP(); factoryParams.put(CoreProxyWithWorkflowFactory.LOOKUP_STATE_PARAM_KEY, CoreProxyWithWorkflowFactory.LOOKUP_STATE_PARAM_BYTASK); } } private DocumentModel createDocumentToPublish() throws Exception { DocumentModel wsRoot = session.getDocument(new PathRef("/default-domain/workspaces")); DocumentModel ws = session.createDocumentModel(wsRoot.getPathAsString(), "ws1", "Workspace"); ws.setProperty("dublincore", "title", "test WS"); ws = session.createDocument(ws); DocumentModel doc2Publish = session.createDocumentModel(ws.getPathAsString(), "file", "File"); doc2Publish.setProperty("dublincore", "title", "MyDoc"); Blob blob = Blobs.createBlob("SomeDummyContent"); blob.setFilename("dummyBlob.txt"); doc2Publish.setProperty("file", "content", blob); doc2Publish = session.createDocument(doc2Publish); session.save(); return doc2Publish; } private void initializeACP() throws Exception { DocumentModel root = session.getRootDocument(); ACP acp = session.getACP(root.getRef()); ACL existingACL = acp.getOrCreateACL(); existingACL.clear(); existingACL.add(new ACE("myuser1", SecurityConstants.READ, true)); existingACL.add(new ACE("myuser2", SecurityConstants.READ, true)); existingACL.add(new ACE("myuser3", SecurityConstants.READ, true)); existingACL.add(new ACE("myuser4", SecurityConstants.READ, true)); acp.addACL(existingACL); session.setACP(root.getRef(), acp, true); // give explicit CanAskForPublishing permission because // the users are not in the members group DocumentModel sectionsRoot = session.getDocument(new PathRef("/default-domain/sections")); acp = session.getACP(sectionsRoot.getRef()); existingACL = acp.getOrCreateACL(); existingACL.add(new ACE("myuser1", CAN_ASK_FOR_PUBLISHING, true)); existingACL.add(new ACE("myuser2", CAN_ASK_FOR_PUBLISHING, true)); existingACL.add(new ACE("myuser3", CAN_ASK_FOR_PUBLISHING, true)); existingACL.add(new ACE("myuser4", CAN_ASK_FOR_PUBLISHING, true)); acp.addACL(existingACL); session.setACP(sectionsRoot.getRef(), acp, true); DocumentModel ws1 = session.getDocument(new PathRef("/default-domain/workspaces/ws1")); acp = session.getACP(ws1.getRef()); existingACL = acp.getOrCreateACL(); existingACL.clear(); existingACL.add(new ACE("myuser1", SecurityConstants.READ_WRITE, true)); existingACL.add(new ACE("myuser2", SecurityConstants.EVERYTHING, true)); acp.addACL(existingACL); session.setACP(ws1.getRef(), acp, true); DocumentModel section1 = session.getDocument(new PathRef("/default-domain/sections/section")); acp = session.getACP(section1.getRef()); existingACL = acp.getOrCreateACL(); existingACL.clear(); existingACL.add(new ACE("myuser1", SecurityConstants.READ, true)); existingACL.add(new ACE("myuser2", SecurityConstants.EVERYTHING, true)); acp.addACL(existingACL); session.setACP(section1.getRef(), acp, true); session.save(); } protected final Set<CoreSession> others = new HashSet<CoreSession>(); private void changeUser(String userName) throws Exception { session = coreFeature.openCoreSession(userName); session.save(); // synch with previous others.add(session); } @After public void closeOthers() { for (CoreSession session : others) { CoreInstance.closeCoreSession(session); } } @Test public void testApproveRenditionPublishing() throws Exception { String defaultTreeName = publisherService.getAvailablePublicationTree().get(0); PublicationTree tree = publisherService.getPublicationTree(defaultTreeName, session, null); List<PublicationNode> nodes = tree.getChildrenNodes(); assertEquals(1, nodes.size()); assertEquals("Section1", nodes.get(0).getTitle()); // start real testing changeUser("myuser1"); defaultTreeName = publisherService.getAvailablePublicationTree().get(0); PublicationTree treeUser1 = publisherService.getPublicationTree(defaultTreeName, session, factoryParams); nodes = treeUser1.getChildrenNodes(); assertEquals(1, nodes.size()); assertEquals("Section1", nodes.get(0).getTitle()); PublicationNode targetNode = nodes.get(0); assertTrue(treeUser1.canPublishTo(targetNode)); PublishedDocument publishedDocument = treeUser1.publish(doc2Publish, targetNode, Collections.singletonMap(RENDITION_NAME_PARAMETER_KEY, "pdf")); assertTrue(publishedDocument.isPending()); assertEquals(1, treeUser1.getExistingPublishedDocument(new DocumentLocationImpl(doc2Publish)).size()); // myuser3 can't see the document waiting for validation session.save(); // Save session to get modifications made by other changeUser("myuser3"); // sessions PublicationTree treeUser3 = publisherService.getPublicationTree(defaultTreeName, session, factoryParams); assertEquals(0, treeUser3.getExistingPublishedDocument(new DocumentLocationImpl(doc2Publish)).size()); // myuser2 can see it, it's the validator changeUser("myuser2"); PublicationTree treeUser2 = publisherService.getPublicationTree(defaultTreeName, session, factoryParams); List<PublishedDocument> publishedDocuments = treeUser2.getExistingPublishedDocument(new DocumentLocationImpl( doc2Publish)); assertEquals(1, publishedDocuments.size()); publishedDocument = publishedDocuments.get(0); assertTrue(publishedDocument.isPending()); treeUser2.validatorPublishDocument(publishedDocument, "Approved!"); assertFalse(publishedDocument.isPending()); // published so myuser3 can see it changeUser("myuser3"); // sessions (here, removing workflow ACL) assertEquals(1, treeUser3.getExistingPublishedDocument(new DocumentLocationImpl(doc2Publish)).size()); } }