/* * (C) Copyright 2009 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: * Thomas Roger */ package org.nuxeo.ecm.platform.publisher.task.test; 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 java.util.HashMap; import java.util.List; import javax.inject.Inject; 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.CoreSession; import org.nuxeo.ecm.core.api.DocumentModel; import org.nuxeo.ecm.core.api.DocumentRef; 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.test.CoreFeature; 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.impl.core.SimpleCorePublishedDocument; import org.nuxeo.runtime.test.runner.Deploy; import org.nuxeo.runtime.test.runner.Features; import org.nuxeo.runtime.test.runner.FeaturesRunner; /** * @author <a href="mailto:troger@nuxeo.com">Thomas Roger</a> */ @RunWith(FeaturesRunner.class) @Features(CoreFeature.class) @Deploy({ "org.nuxeo.ecm.directory", // "org.nuxeo.ecm.directory.sql", // "org.nuxeo.ecm.directory.types.contrib", // "org.nuxeo.ecm.platform.query.api", // "org.nuxeo.ecm.platform.content.template", // "org.nuxeo.ecm.platform.types.api", // "org.nuxeo.ecm.platform.types.core", // "org.nuxeo.ecm.platform.versioning.api", // "org.nuxeo.ecm.platform.versioning", // "org.nuxeo.ecm.relations", // "org.nuxeo.ecm.relations.jena", // "org.nuxeo.ecm.platform.usermanager", // "org.nuxeo.ecm.platform.publisher.core.contrib", // "org.nuxeo.ecm.platform.publisher.core", // "org.nuxeo.ecm.platform.publisher.task", // "org.nuxeo.ecm.platform.publisher.task.test", // "org.nuxeo.ecm.platform.task.api", // "org.nuxeo.ecm.platform.task.core", // "org.nuxeo.ecm.platform.task.testing", // }) public abstract class TestCorePublicationWithWorkflow { @Inject protected CoreFeature coreFeature; @Inject protected CoreSession session; @Inject private PublisherService publisherService; private DocumentModel doc2Publish; protected HashMap<String, String> factoryParams = new HashMap<String, String>(); protected String defaultTreeName; @Before public void setUp() throws Exception { defaultTreeName = publisherService.getAvailablePublicationTree().get(0); createDocumentToPublish(); initializeACP(); } private void 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); 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(); } private void initializeACP() throws Exception { DocumentModel sectionsRoot = session.getDocument(new PathRef("/default-domain/sections")); DocumentModel section1 = session.createDocumentModel(sectionsRoot.getPathAsString(), "section1", "Section"); section1.setProperty("dublincore", "title", "section1"); section1 = session.createDocument(section1); session.save(); 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("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 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)); acp.addACL(existingACL); session.setACP(ws1.getRef(), acp, true); 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(); } @Test public void testRights() throws Exception { // myuser1 requests publishing DocumentRef publishedDocumentRef; try (CoreSession sessionUser1 = coreFeature.openCoreSession("myuser1")) { PublicationTree treeUser1 = publisherService.getPublicationTree(defaultTreeName, sessionUser1, factoryParams); List<PublicationNode> nodes = treeUser1.getChildrenNodes(); PublicationNode targetNode = nodes.get(0); PublishedDocument publishedDocument = treeUser1.publish(doc2Publish, targetNode); sessionUser1.save(); assertFalse(treeUser1.canUnpublish(publishedDocument)); publishedDocumentRef = new PathRef(publishedDocument.getPath()); } // myuser3 has no rights on proxy try (CoreSession sessionUser3 = coreFeature.openCoreSession("myuser3")) { assertFalse(sessionUser3.exists(publishedDocumentRef)); } // myuser4 has no rights on proxy try (CoreSession sessionUser4 = coreFeature.openCoreSession("myuser4")) { assertFalse(sessionUser4.exists(publishedDocumentRef)); } // myuser2 can unpublish or validate try (CoreSession sessionUser2 = coreFeature.openCoreSession("myuser2")) { PublishedDocument publishedDocument = new SimpleCorePublishedDocument(sessionUser2.getDocument(publishedDocumentRef)); PublicationTree treeUser2 = publisherService.getPublicationTree(defaultTreeName, sessionUser2, factoryParams); assertTrue(treeUser2.canUnpublish(publishedDocument)); assertTrue(treeUser2.hasValidationTask(publishedDocument)); } } @Test public void testApprovePublication() throws Exception { // myuser1 requests publishing try (CoreSession sessionUser1 = coreFeature.openCoreSession("myuser1")) { PublicationTree treeUser1 = publisherService.getPublicationTree(defaultTreeName, sessionUser1, factoryParams); List<PublicationNode> 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); assertTrue(publishedDocument.isPending()); assertEquals(1, treeUser1.getExistingPublishedDocument(new DocumentLocationImpl(doc2Publish)).size()); sessionUser1.save(); } // myuser3 can't see the document waiting for validation try (CoreSession sessionUser3 = coreFeature.openCoreSession("myuser3")) { PublicationTree treeUser3 = publisherService.getPublicationTree(defaultTreeName, sessionUser3, factoryParams); assertEquals(0, treeUser3.getExistingPublishedDocument(new DocumentLocationImpl(doc2Publish)).size()); } // myuser2 can see it, it's the validator try (CoreSession sessionUser2 = coreFeature.openCoreSession("myuser2")) { PublicationTree treeUser2 = publisherService.getPublicationTree(defaultTreeName, sessionUser2, factoryParams); List<PublishedDocument> publishedDocuments = treeUser2.getExistingPublishedDocument( new DocumentLocationImpl(doc2Publish)); assertEquals(1, publishedDocuments.size()); PublishedDocument publishedDocument = publishedDocuments.get(0); assertTrue(publishedDocument.isPending()); // myuser2 must be able to validate without having Read permission on the live document 'doc2publish' treeUser2.validatorPublishDocument(publishedDocument, "Approved!"); assertFalse(publishedDocument.isPending()); } // published so myuser3 can see it try (CoreSession sessionUser3 = coreFeature.openCoreSession("myuser3")) { PublicationTree treeUser3 = publisherService.getPublicationTree(defaultTreeName, sessionUser3, factoryParams); assertEquals(1, treeUser3.getExistingPublishedDocument(new DocumentLocationImpl(doc2Publish)).size()); sessionUser3.save(); } } @Test public void testRejectPublication() throws Exception { // myuser1 requests publishing try (CoreSession sessionUser1 = coreFeature.openCoreSession("myuser1")) { PublicationTree treeUser1 = publisherService.getPublicationTree(defaultTreeName, sessionUser1, factoryParams); List<PublicationNode> nodes = treeUser1.getChildrenNodes(); assertEquals(1, nodes.size()); assertEquals("section1", nodes.get(0).getTitle()); PublicationNode targetNode = nodes.get(0); PublishedDocument publishedDocument = treeUser1.publish(doc2Publish, targetNode); assertTrue(publishedDocument.isPending()); assertEquals(1, treeUser1.getExistingPublishedDocument(new DocumentLocationImpl(doc2Publish)).size()); sessionUser1.save(); // so that canManagePublishing's search works } // myuser3 can't see the document waiting for validation try (CoreSession sessionUser3 = coreFeature.openCoreSession("myuser3")) { PublicationTree treeUser3 = publisherService.getPublicationTree(defaultTreeName, sessionUser3, factoryParams); assertEquals(0, treeUser3.getExistingPublishedDocument(new DocumentLocationImpl(doc2Publish)).size()); } // myuser2 can see it, it's the validator DocumentRef proxyRef; try (CoreSession sessionUser2 = coreFeature.openCoreSession("myuser2")) { PublicationTree treeUser2 = publisherService.getPublicationTree(defaultTreeName, sessionUser2, factoryParams); List<PublishedDocument> publishedDocuments = treeUser2.getExistingPublishedDocument( new DocumentLocationImpl(doc2Publish)); assertEquals(1, publishedDocuments.size()); PublishedDocument publishedDocument = publishedDocuments.get(0); assertTrue(publishedDocument.isPending()); assertTrue(treeUser2.canManagePublishing(publishedDocument)); assertTrue(treeUser2.hasValidationTask(publishedDocument)); // reject publication treeUser2.validatorRejectPublication(publishedDocument, "Rejected!"); assertTrue(publishedDocument.isPending()); proxyRef = ((SimpleCorePublishedDocument) publishedDocument).getProxy().getRef(); // No more document to approve assertEquals(0, treeUser2.getExistingPublishedDocument(new DocumentLocationImpl(doc2Publish)).size()); } // not published so myuser3 still can't see it try (CoreSession sessionUser3 = coreFeature.openCoreSession("myuser3")) { PublicationTree treeUser3 = publisherService.getPublicationTree(defaultTreeName, sessionUser3, factoryParams); assertEquals(0, treeUser3.getExistingPublishedDocument(new DocumentLocationImpl(doc2Publish)).size()); } // No more document published for myuser1 try (CoreSession sessionUser1 = coreFeature.openCoreSession("myuser1")) { PublicationTree treeUser1 = publisherService.getPublicationTree(defaultTreeName, sessionUser1, factoryParams); assertEquals(0, treeUser1.getExistingPublishedDocument(new DocumentLocationImpl(doc2Publish)).size()); assertFalse(sessionUser1.exists(proxyRef)); } } @Test public void testFirstPublicationByValidator() throws Exception { // myuser2 directly publishes a doc // TODO not sure it should, as it has no read access on the doc... try (CoreSession sessionUser2 = coreFeature.openCoreSession("myuser2")) { PublicationTree treeUser2 = publisherService.getPublicationTree(defaultTreeName, sessionUser2, factoryParams); List<PublicationNode> nodes = treeUser2.getChildrenNodes(); assertEquals(1, nodes.size()); assertEquals("section1", nodes.get(0).getTitle()); PublicationNode targetNode = nodes.get(0); assertTrue(treeUser2.canPublishTo(targetNode)); PublishedDocument publishedDocument = treeUser2.publish(doc2Publish, targetNode); assertFalse(publishedDocument.isPending()); } // myuser3 can see the document try (CoreSession sessionUser3 = coreFeature.openCoreSession("myuser3")) { PublicationTree treeUser3 = publisherService.getPublicationTree(defaultTreeName, sessionUser3, factoryParams); assertEquals(1, treeUser3.getExistingPublishedDocument(new DocumentLocationImpl(doc2Publish)).size()); } } @Test public void testFirstPublicationByNonValidator() throws Exception { // myuser1 requests publishing try (CoreSession sessionUser1 = coreFeature.openCoreSession("myuser1")) { PublicationTree treeUser1 = publisherService.getPublicationTree(defaultTreeName, sessionUser1, factoryParams); List<PublicationNode> 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); assertTrue(publishedDocument.isPending()); } // myuser3 can't see the document try (CoreSession sessionUser3 = coreFeature.openCoreSession("myuser3")) { PublicationTree treeUser3 = publisherService.getPublicationTree(defaultTreeName, sessionUser3, factoryParams); assertEquals(0, treeUser3.getExistingPublishedDocument(new DocumentLocationImpl(doc2Publish)).size()); } } @Test public void testPublishOfAlreadyWaitingToBePublishedDocByNonValidator() throws Exception { // my user1 ask for publication try (CoreSession sessionUser1 = coreFeature.openCoreSession("myuser1")) { PublicationTree treeUser1 = publisherService.getPublicationTree(defaultTreeName, sessionUser1, factoryParams); List<PublicationNode> 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); assertTrue(publishedDocument.isPending()); assertEquals(1, treeUser1.getExistingPublishedDocument(new DocumentLocationImpl(doc2Publish)).size()); sessionUser1.save(); } // my user3 ask for publication try (CoreSession sessionUser3 = coreFeature.openCoreSession("myuser3")) { PublicationTree treeUser3 = publisherService.getPublicationTree(defaultTreeName, sessionUser3, factoryParams); List<PublicationNode> nodes = treeUser3.getChildrenNodes(); assertEquals(1, nodes.size()); assertEquals("section1", nodes.get(0).getTitle()); PublicationNode targetNode = nodes.get(0); assertTrue(treeUser3.canPublishTo(targetNode)); PublishedDocument publishedDocument = treeUser3.publish(doc2Publish, targetNode); assertTrue(publishedDocument.isPending()); sessionUser3.save(); } // my user1 can still see the document try (CoreSession sessionUser1 = coreFeature.openCoreSession("myuser1")) { PublicationTree treeUser1 = publisherService.getPublicationTree(defaultTreeName, sessionUser1, factoryParams); List<PublicationNode> nodes = treeUser1.getChildrenNodes(); assertEquals(1, nodes.size()); assertEquals("section1", nodes.get(0).getTitle()); assertEquals(1, treeUser1.getExistingPublishedDocument(new DocumentLocationImpl(doc2Publish)).size()); } // my user 2 publish the document try (CoreSession sessionUser2 = coreFeature.openCoreSession("myuser2")) { PublicationTree treeUser2 = publisherService.getPublicationTree(defaultTreeName, sessionUser2, factoryParams); List<PublishedDocument> publishedDocuments = treeUser2.getExistingPublishedDocument( new DocumentLocationImpl(doc2Publish)); assertEquals(1, publishedDocuments.size()); PublishedDocument publishedDocument = publishedDocuments.get(0); assertTrue(publishedDocument.isPending()); treeUser2.validatorPublishDocument(publishedDocument, "Approved!"); assertFalse(publishedDocument.isPending()); sessionUser2.save(); } } @Test public void testMultiplePublishThenPublishByValidator() throws Exception { // my user1 ask for publication try (CoreSession sessionUser1 = coreFeature.openCoreSession("myuser1")) { PublicationTree treeUser1 = publisherService.getPublicationTree(defaultTreeName, sessionUser1, factoryParams); List<PublicationNode> 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); assertTrue(publishedDocument.isPending()); assertEquals(1, treeUser1.getExistingPublishedDocument(new DocumentLocationImpl(doc2Publish)).size()); sessionUser1.save(); } // my user3 ask for publication try (CoreSession sessionUser3 = coreFeature.openCoreSession("myuser3")) { PublicationTree treeUser3 = publisherService.getPublicationTree(defaultTreeName, sessionUser3, factoryParams); List<PublicationNode> nodes = treeUser3.getChildrenNodes(); assertEquals(1, nodes.size()); assertEquals("section1", nodes.get(0).getTitle()); PublicationNode targetNode = nodes.get(0); assertTrue(treeUser3.canPublishTo(targetNode)); PublishedDocument publishedDocument = treeUser3.publish(doc2Publish, targetNode); assertTrue(publishedDocument.isPending()); sessionUser3.save(); } // my user1 can still see the document try (CoreSession sessionUser1 = coreFeature.openCoreSession("myuser1")) { PublicationTree treeUser1 = publisherService.getPublicationTree(defaultTreeName, sessionUser1, factoryParams); List<PublicationNode> nodes = treeUser1.getChildrenNodes(); assertEquals(1, nodes.size()); assertEquals("section1", nodes.get(0).getTitle()); assertEquals(1, treeUser1.getExistingPublishedDocument(new DocumentLocationImpl(doc2Publish)).size()); } // my user4 don't see the document try (CoreSession sessionUser4 = coreFeature.openCoreSession("myuser4")) { PublicationTree treeUser4 = publisherService.getPublicationTree(defaultTreeName, sessionUser4, factoryParams); List<PublicationNode> nodes = treeUser4.getChildrenNodes(); assertEquals(1, nodes.size()); assertEquals("section1", nodes.get(0).getTitle()); assertEquals(0, treeUser4.getExistingPublishedDocument(new DocumentLocationImpl(doc2Publish)).size()); } // my user 2 publish the document try (CoreSession sessionUser2 = coreFeature.openCoreSession("myuser2")) { PublicationTree treeUser2 = publisherService.getPublicationTree(defaultTreeName, sessionUser2, factoryParams); List<PublishedDocument> publishedDocuments = treeUser2.getExistingPublishedDocument( new DocumentLocationImpl(doc2Publish)); assertEquals(1, publishedDocuments.size()); PublishedDocument publishedDocument = publishedDocuments.get(0); assertTrue(publishedDocument.isPending()); treeUser2.validatorPublishDocument(publishedDocument, "Approved!"); assertFalse(publishedDocument.isPending()); sessionUser2.save(); } // my user4 see the document try (CoreSession sessionUser4 = coreFeature.openCoreSession("myuser4")) { PublicationTree treeUser4 = publisherService.getPublicationTree(defaultTreeName, sessionUser4, factoryParams); List<PublicationNode> nodes = treeUser4.getChildrenNodes(); assertEquals(1, nodes.size()); assertEquals("section1", nodes.get(0).getTitle()); assertEquals(1, treeUser4.getExistingPublishedDocument(new DocumentLocationImpl(doc2Publish)).size()); } } }