/* * (C) Copyright 2017 Nuxeo (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: * Kevin Leturc */ package org.nuxeo.ecm.core.version.test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.io.Serializable; import java.util.List; import java.util.Objects; import javax.inject.Inject; import org.junit.Test; import org.nuxeo.ecm.core.api.DocumentModel; import org.nuxeo.ecm.core.api.VersioningOption; import org.nuxeo.ecm.core.test.TransactionalFeature; import org.nuxeo.ecm.core.versioning.VersioningPolicyFilter; import org.nuxeo.ecm.core.versioning.VersioningService; import org.nuxeo.runtime.test.runner.Deploy; import org.nuxeo.runtime.test.runner.LocalDeploy; /** * @since 9.1 */ @Deploy({"org.nuxeo.ecm.core.test.tests"}) @LocalDeploy("org.nuxeo.ecm.core.test.tests:test-auto-versioning-document-type.xml") public class TestAutoVersioning extends AbstractTestVersioning { @Inject protected TransactionalFeature txFeature; @Test @LocalDeploy("org.nuxeo.ecm.core.test.tests:test-auto-versioning-initial-version.xml") public void testInitialVersion() { DocumentModel doc = session.createDocumentModel("/", "testfile1", "File"); doc = session.createDocument(doc); assertTrue(doc.isCheckedOut()); assertEquals("2.5+", doc.getVersionLabel()); doc.setPropertyValue("dc:title", "A"); doc = session.saveDocument(doc); assertTrue(doc.isCheckedOut()); assertEquals("2.5+", doc.getVersionLabel()); } @Test @LocalDeploy("org.nuxeo.ecm.core.test.tests:test-auto-versioning-always-minor.xml") public void testAlwaysVersionMinor() { // No initial state defined by policy DocumentModel doc = session.createDocumentModel("/", "testfile1", "File"); // creation should create a version doc.setPropertyValue("dc:title", "A"); doc = session.createDocument(doc); assertFalse(doc.isCheckedOut()); assertEquals("0.1", doc.getVersionLabel()); // an edition should create a version doc.setPropertyValue("dc:title", "B"); doc = session.saveDocument(doc); assertFalse(doc.isCheckedOut()); assertEquals("0.2", doc.getVersionLabel()); } @Test @LocalDeploy("org.nuxeo.ecm.core.test.tests:test-auto-versioning-always-major.xml") public void testAlwaysVersionMajor() { // No initial state defined by policy DocumentModel doc = session.createDocumentModel("/", "testfile1", "File"); // creation should create a version doc.setPropertyValue("dc:title", "A"); doc = session.createDocument(doc); assertFalse(doc.isCheckedOut()); assertEquals("1.0", doc.getVersionLabel()); // an edition should create a version doc.setPropertyValue("dc:title", "B"); doc = session.saveDocument(doc); assertFalse(doc.isCheckedOut()); assertEquals("2.0", doc.getVersionLabel()); } @Test @LocalDeploy("org.nuxeo.ecm.core.test.tests:test-auto-versioning-always-major.xml") public void testAlwaysVersionMajorTwoSaves() { // No initial state defined by policy DocumentModel doc = session.createDocumentModel("/", "testfile1", "File"); // creation should create a version doc.setPropertyValue("dc:title", "A"); doc = session.createDocument(doc); assertFalse(doc.isCheckedOut()); assertEquals("1.0", doc.getVersionLabel()); // an edition should create a version doc.setPropertyValue("dc:title", "B"); doc = session.saveDocument(doc); assertFalse(doc.isCheckedOut()); assertEquals("2.0", doc.getVersionLabel()); // second update without edition shouldn't create a version doc = session.saveDocument(doc); assertFalse(doc.isCheckedOut()); assertEquals("2.0", doc.getVersionLabel()); } @Test @LocalDeploy("org.nuxeo.ecm.core.test.tests:test-auto-versioning-custom-filter.xml") public void testWithCustomFilter() { // No initial state defined by policy DocumentModel doc = session.createDocumentModel("/", "testfile1", "File"); doc = session.createDocument(doc); // Update of dc:title should trigger a new version doc.setPropertyValue("dc:title", "A"); doc = session.saveDocument(doc); assertFalse(doc.isCheckedOut()); assertEquals("0.1", doc.getVersionLabel()); // an edition to dc:description should not trigger a new version doc.setPropertyValue("dc:description", "New Description"); doc = session.saveDocument(doc); assertTrue(doc.isCheckedOut()); assertEquals("0.1+", doc.getVersionLabel()); } @Test @LocalDeploy("org.nuxeo.ecm.core.test.tests:test-auto-versioning-standard-filter-types.xml") public void testWithStandardFilterAndTypes() { // No initial state defined by policy // Document of type File or Note should have a new version for each update DocumentModel doc = session.createDocumentModel("/", "testfile1", "File"); doc = session.createDocument(doc); doc = session.saveDocument(doc); assertFalse(doc.isCheckedOut()); assertEquals("0.1", doc.getVersionLabel()); doc = session.createDocumentModel("/", "testfile1", "Note"); doc = session.createDocument(doc); doc = session.saveDocument(doc); assertFalse(doc.isCheckedOut()); assertEquals("0.1", doc.getVersionLabel()); doc = session.createDocumentModel("/", "testfile1", "Note2"); doc = session.createDocument(doc); doc = session.saveDocument(doc); assertTrue(doc.isCheckedOut()); assertEquals("0.0", doc.getVersionLabel()); } @Test @LocalDeploy("org.nuxeo.ecm.core.test.tests:test-auto-versioning-standard-filter-facets.xml") public void testWithStandardFilterAndFacets() { // No initial state defined by policy // Document with facet Downloadable or Note3Facet should have a new version for each update DocumentModel doc = session.createDocumentModel("/", "testfile1", "File"); doc = session.createDocument(doc); doc = session.saveDocument(doc); assertFalse(doc.isCheckedOut()); assertEquals("0.1", doc.getVersionLabel()); doc = session.createDocumentModel("/", "testfile1", "Note2"); doc = session.createDocument(doc); doc = session.saveDocument(doc); assertTrue(doc.isCheckedOut()); assertEquals("0.0", doc.getVersionLabel()); doc = session.createDocumentModel("/", "testfile1", "Note3"); doc = session.createDocument(doc); doc = session.saveDocument(doc); assertFalse(doc.isCheckedOut()); assertEquals("0.1", doc.getVersionLabel()); } @Test @LocalDeploy("org.nuxeo.ecm.core.test.tests:test-auto-versioning-standard-filter-schemas.xml") public void testWithStandardFilterAndSchemas() { // No initial state defined by policy // Document with file schema should have a new version for each update DocumentModel doc = session.createDocumentModel("/", "testfile1", "File"); doc = session.createDocument(doc); doc = session.saveDocument(doc); assertFalse(doc.isCheckedOut()); assertEquals("0.1", doc.getVersionLabel()); doc = session.createDocumentModel("/", "testfile1", "Note2"); doc = session.createDocument(doc); doc = session.saveDocument(doc); assertTrue(doc.isCheckedOut()); assertEquals("0.0", doc.getVersionLabel()); } @Test @LocalDeploy("org.nuxeo.ecm.core.test.tests:test-auto-versioning-standard-filter-condition.xml") public void testWithStandardFilterAndCondition() { // No initial state defined by policy // Same condition as the custom filter below DocumentModel doc = session.createDocumentModel("/", "testfile1", "File"); doc = session.createDocument(doc); // Update of dc:title should trigger a new version doc.setPropertyValue("dc:title", "A"); doc = session.saveDocument(doc); assertFalse(doc.isCheckedOut()); assertEquals("0.1", doc.getVersionLabel()); // an edition to dc:description should not trigger a new version doc.setPropertyValue("dc:description", "New Description"); doc = session.saveDocument(doc); assertTrue(doc.isCheckedOut()); assertEquals("0.1+", doc.getVersionLabel()); } @Test @LocalDeploy("org.nuxeo.ecm.core.test.tests:test-auto-versioning-ordering.xml") public void testAutoVersioningOrdering() { DocumentModel doc = session.createDocumentModel("/", "testfile1", "File"); doc = session.createDocument(doc); doc = session.saveDocument(doc); assertFalse(doc.isCheckedOut()); assertEquals("0.1", doc.getVersionLabel()); doc = session.createDocumentModel("/", "testfile2", "Note"); doc = session.createDocument(doc); doc = session.saveDocument(doc); assertFalse(doc.isCheckedOut()); assertEquals("1.0", doc.getVersionLabel()); } @Test @LocalDeploy("org.nuxeo.ecm.core.test.tests:test-auto-versioning-before-always-minor.xml") public void testAutoVersioningBeforeAlwaysMinor() { // No initial state defined by policy DocumentModel doc = session.createDocumentModel("/", "testfile1", "File"); doc = session.createDocument(doc); doc.setPropertyValue("dc:title", "A"); doc = session.saveDocument(doc); // get last version (document before update) // here we use getVersions instead of getLastDocumentVersion because on mem repository created date could the // same and we don't retrieve the right versions List<DocumentModel> versions = session.getVersions(doc.getRef()); assertEquals(1, versions.size()); DocumentModel lastVersion = versions.get(0); assertFalse(lastVersion.isCheckedOut()); assertEquals("0.1", lastVersion.getVersionLabel()); assertTrue(doc.isCheckedOut()); assertEquals("0.1+", doc.getVersionLabel()); // an edition should create a version doc.setPropertyValue("dc:title", "B"); maybeSleepToNextSecond(); doc = session.saveDocument(doc); // get last version (document before update) versions = session.getVersions(doc.getRef()); assertEquals(2, versions.size()); lastVersion = versions.get(1); assertFalse(lastVersion.isCheckedOut()); assertEquals("0.2", lastVersion.getVersionLabel()); assertTrue(doc.isCheckedOut()); assertEquals("0.2+", doc.getVersionLabel()); } @Test @LocalDeploy("org.nuxeo.ecm.core.test.tests:test-auto-versioning-before-minor-after-major.xml") public void testAutoVersioningBeforeAlwaysMinorAfterAlwaysMajor() { // No initial state defined by policy DocumentModel doc = session.createDocumentModel("/", "testfile1", "File"); // creation should create a version doc.setPropertyValue("dc:title", "A"); doc = session.createDocument(doc); assertFalse(doc.isCheckedOut()); assertEquals("1.0", doc.getVersionLabel()); // update document by disabling automatic versioning after update, furthermore automatic versioning before // update won't be performed cause document is already check in doc.setPropertyValue("dc:title", "B"); doc.putContextData(VersioningService.VERSIONING_OPTION, VersioningOption.NONE); doc = session.saveDocument(doc); assertTrue(doc.isCheckedOut()); assertEquals("1.0+", doc.getVersionLabel()); // check there's only one version List<DocumentModel> versions = session.getVersions(doc.getRef()); assertEquals(1, versions.size()); // an update should create a version before and after doc = session.saveDocument(doc); // get versions (document before update) versions = session.getVersions(doc.getRef()); versions.sort((v1, v2) -> v1.getVersionLabel().compareTo(v2.getVersionLabel())); assertEquals(3, versions.size()); DocumentModel versionAfterCreation = versions.get(0); DocumentModel versionBeforeUpdate = versions.get(1); DocumentModel versionAfterUpdate = versions.get(2); assertFalse(versionAfterCreation.isCheckedOut()); assertEquals("1.0", versionAfterCreation.getVersionLabel()); assertFalse(versionBeforeUpdate.isCheckedOut()); assertEquals("1.1", versionBeforeUpdate.getVersionLabel()); assertFalse(versionBeforeUpdate.isCheckedOut()); assertEquals("2.0", versionAfterUpdate.getVersionLabel()); assertFalse(doc.isCheckedOut()); assertEquals("2.0", doc.getVersionLabel()); // wait for mem repository - repository is fast, we assume that some workers update states with a previous state // of metadata, in this case version label for version 3.0 is not correct (ie: 2.0) txFeature.nextTransaction(); // an edition should create a version after update as document is already checked out doc.setPropertyValue("dc:title", "C"); doc = session.saveDocument(doc); // get versions versions = session.getVersions(doc.getRef()); versions.sort((v1, v2) -> v1.getVersionLabel().compareTo(v2.getVersionLabel())); // as document before update was already a version - service will just create one new version assertEquals(4, versions.size()); versionAfterUpdate = versions.get(3); assertFalse(versionAfterUpdate.isCheckedOut()); assertEquals("3.0", versionAfterUpdate.getVersionLabel()); assertFalse(doc.isCheckedOut()); assertEquals("3.0", doc.getVersionLabel()); } @Test @LocalDeploy("org.nuxeo.ecm.core.test.tests:test-auto-versioning-before-always-minor.xml") public void testManualVersioningCreateABeforeVersion() { // No initial state defined by policy DocumentModel doc = session.createDocumentModel("/", "testfile1", "File"); doc.setPropertyValue("dc:title", "A"); doc = session.createDocument(doc); assertTrue(doc.isCheckedOut()); assertEquals("0.0", doc.getVersionLabel()); // Ask for a version doc.setPropertyValue("dc:title", "B"); doc.putContextData(VersioningService.VERSIONING_OPTION, VersioningOption.MAJOR); doc = session.saveDocument(doc); assertFalse(doc.isCheckedOut()); assertEquals("1.0", doc.getVersionLabel()); // Check that before automatic versioning was trigger List<DocumentModel> versions = session.getVersions(doc.getRef()); versions.sort((v1, v2) -> v1.getVersionLabel().compareTo(v2.getVersionLabel())); assertEquals(2, versions.size()); assertEquals("0.1", versions.get(0).getVersionLabel()); assertEquals("1.0", versions.get(1).getVersionLabel()); } @Test @LocalDeploy("org.nuxeo.ecm.core.test.tests:test-auto-versioning-before-always-minor.xml") public void testManualVersioningOnlyDoesntCreateABeforeVersion() { // No initial state defined by policy DocumentModel doc = session.createDocumentModel("/", "testfile1", "File"); doc.setPropertyValue("dc:title", "A"); doc = session.createDocument(doc); assertTrue(doc.isCheckedOut()); assertEquals("0.0", doc.getVersionLabel()); // Ask for a version doc.putContextData(VersioningService.VERSIONING_OPTION, VersioningOption.MAJOR); doc = session.saveDocument(doc); assertFalse(doc.isCheckedOut()); assertEquals("1.0", doc.getVersionLabel()); // Check that before automatic versioning wasn't trigger List<DocumentModel> versions = session.getVersions(doc.getRef()); assertEquals(1, versions.size()); assertEquals("1.0", versions.get(0).getVersionLabel()); } @Test @LocalDeploy("org.nuxeo.ecm.core.test.tests:test-no-auto-versioning-system.xml") public void testAutoVersioningNoneOption() { DocumentModel doc = session.createDocumentModel("/", "note", "Note4"); doc = session.createDocument(doc); doc.setPropertyValue("dc:title", "newNote"); doc = session.saveDocument(doc); assertTrue(doc.isCheckedOut()); assertEquals("0.0", doc.getVersionLabel()); } /** A custom filter for tests. */ public static class CustomVersioningFilter implements VersioningPolicyFilter { @Override public boolean test(DocumentModel previousDocument, DocumentModel currentDocument) { // Handle creation case - do nothing if (previousDocument == null) { return false; } // Run versioning only if dc:title has changed Serializable previousTitle = previousDocument.getPropertyValue("dc:title"); Serializable currentTitle = currentDocument.getPropertyValue("dc:title"); return !Objects.equals(previousTitle, currentTitle); } } }