/* * See the NOTICE file distributed with this work for additional * information regarding copyright ownership. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package com.xpn.xwiki.doc; import java.util.Arrays; import java.util.List; import java.util.Locale; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.xwiki.diff.internal.DefaultDiffManager; import org.xwiki.logging.LogLevel; import org.xwiki.logging.event.LogEvent; import org.xwiki.model.internal.DefaultModelConfiguration; import org.xwiki.model.internal.reference.DefaultEntityReferenceProvider; import org.xwiki.model.internal.reference.DefaultStringDocumentReferenceResolver; import org.xwiki.model.internal.reference.DefaultStringEntityReferenceResolver; import org.xwiki.model.internal.reference.DefaultStringEntityReferenceSerializer; import org.xwiki.model.internal.reference.DefaultSymbolScheme; import org.xwiki.model.internal.reference.LocalStringEntityReferenceSerializer; import org.xwiki.model.internal.reference.LocalUidStringEntityReferenceSerializer; import org.xwiki.model.reference.DocumentReference; import org.xwiki.test.annotation.ComponentList; import com.xpn.xwiki.doc.merge.MergeConfiguration; import com.xpn.xwiki.doc.merge.MergeException; import com.xpn.xwiki.doc.merge.MergeResult; import com.xpn.xwiki.internal.model.reference.CurrentEntityReferenceProvider; import com.xpn.xwiki.internal.model.reference.CurrentReferenceDocumentReferenceResolver; import com.xpn.xwiki.internal.model.reference.CurrentReferenceEntityReferenceResolver; import com.xpn.xwiki.internal.model.reference.CurrentStringDocumentReferenceResolver; import com.xpn.xwiki.internal.model.reference.CurrentStringEntityReferenceResolver; import com.xpn.xwiki.objects.BaseObject; import com.xpn.xwiki.objects.classes.BaseClass; import com.xpn.xwiki.objects.classes.TextAreaClass; import com.xpn.xwiki.test.MockitoOldcoreRule; import com.xpn.xwiki.test.reference.ReferenceComponentList; /** * Validate {@link XWikiDocument#merge(XWikiDocument, XWikiDocument, MergeConfiguration, com.xpn.xwiki.XWikiContext)}. * * @version $Id: 536592816f2ea14c5a0e1f89a5a1b5e8ad2fb22f $ */ @ComponentList(value = { DefaultDiffManager.class }) @ReferenceComponentList public class XWikiDocumentMergeTest { @Rule public MockitoOldcoreRule oldcore = new MockitoOldcoreRule(); private XWikiDocument currentDocument; private XWikiDocument previousDocument; private XWikiDocument nextDocument; private BaseObject xobject; private BaseClass xclass; private MergeConfiguration configuration; @Before public void before() throws Exception { this.oldcore.registerMockEnvironment(); this.currentDocument = new XWikiDocument(new DocumentReference("wiki", "space", "page")); this.previousDocument = this.currentDocument.clone(); this.nextDocument = this.currentDocument.clone(); this.xclass = new BaseClass(); this.xclass.setDocumentReference(new DocumentReference("wiki", "classspace", "class")); this.xclass.addTextField("string", "String", 30); this.xclass.addTextAreaField("area", "Area", 10, 10); this.xclass.addTextAreaField("puretextarea", "Pure text area", 10, 10); // set the text areas an non interpreted content ((TextAreaClass) this.xclass.getField("puretextarea")).setContentType("puretext"); this.xclass.addPasswordField("passwd", "Password", 30); this.xclass.addBooleanField("boolean", "Boolean", "yesno"); this.xclass.addNumberField("int", "Int", 10, "integer"); this.xclass.addStaticListField("stringlist", "StringList", "value1, value2"); this.xobject = new BaseObject(); this.xobject.setXClassReference(this.xclass.getDocumentReference()); this.xobject.setStringValue("string", "string"); this.xobject.setLargeStringValue("area", "area"); this.xobject.setStringValue("passwd", "passwd"); this.xobject.setIntValue("boolean", 1); this.xobject.setIntValue("int", 42); this.xobject.setStringListValue("stringlist", Arrays.asList("VALUE1", "VALUE2")); this.configuration = new MergeConfiguration(); } private MergeResult merge() throws Exception { MergeResult result = this.currentDocument.merge(this.previousDocument, this.nextDocument, this.configuration, this.oldcore.getXWikiContext()); List<LogEvent> exception = result.getLog().getLogs(LogLevel.ERROR); if (!exception.isEmpty()) { throw new MergeException(exception.get(0).getFormattedMessage(), exception.get(0).getThrowable()); } return result; } // Tests // #merge @Test public void testMergeContent() throws Exception { this.previousDocument.setContent("some content"); this.nextDocument.setContent("some new content"); this.currentDocument.setContent("some content"); merge(); Assert.assertEquals("some new content", this.currentDocument.getContent()); } @Test public void testMergeDefaultLocale() throws Exception { this.previousDocument.setDefaultLocale(Locale.ENGLISH); this.nextDocument.setDefaultLocale(Locale.FRENCH); this.currentDocument.setDefaultLocale(Locale.ENGLISH); merge(); Assert.assertEquals(Locale.FRENCH, this.currentDocument.getDefaultLocale()); } @Test public void testMergeContentModified() throws Exception { this.previousDocument.setContent("some content"); this.nextDocument.setContent("some content\nafter"); this.currentDocument.setContent("before\nsome content"); merge(); Assert.assertEquals("before\nsome content\nafter", this.currentDocument.getContent()); this.previousDocument.setContent("some content"); this.nextDocument.setContent("some content\nafter"); this.currentDocument.setContent("some content"); merge(); Assert.assertEquals("some content\nafter", this.currentDocument.getContent()); } @Test public void testMergeNewObjectAdded() throws Exception { this.nextDocument.addXObject(this.xobject); merge(); Assert.assertSame(this.xobject, this.currentDocument.getXObject(this.xclass.getReference(), 0)); } @Test public void testMergeNewObjectRemoved() throws Exception { this.previousDocument.addXObject(this.xobject); this.currentDocument.addXObject(this.xobject.clone()); merge(); Assert.assertNull(this.currentDocument.getXObject(this.xclass.getReference(), 0)); } @Test public void testMergeObjectModified() throws Exception { BaseObject previousobj = this.xobject; previousobj.setStringValue("test", "test1"); this.previousDocument.addXObject(previousobj); BaseObject obj = this.xobject.clone(); obj.setStringValue("test", "test1"); this.currentDocument.addXObject(obj); BaseObject newobj = this.xobject.clone(); newobj.setStringValue("test", "test2"); this.nextDocument.addXObject(newobj); merge(); BaseObject mergedobj = this.currentDocument.getXObject(this.xclass.getReference(), 0); Assert.assertNotNull(mergedobj); Assert.assertEquals("test2", mergedobj.getStringValue("test")); } @Test public void testMergeCurrentObjectRemoved() throws Exception { this.xobject.setStringValue("test", ""); this.xobject.setStringValue("previoustest", "previoustest"); this.previousDocument.addXObject(this.xobject); BaseObject newobj = this.xobject.clone(); newobj.setStringValue("test", "test2"); newobj.setStringValue("newtest", "newtest"); this.nextDocument.addXObject(newobj); merge(); BaseObject mergedobj = this.currentDocument.getXObject(this.xclass.getReference(), 0); Assert.assertNull(mergedobj); } @Test public void testMergeAttachmentEquals() throws Exception { XWikiAttachment attachment = new XWikiAttachment(); attachment.setContent(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); attachment.setLongSize(10); attachment.setFilename("file"); this.previousDocument.addAttachment(attachment); this.nextDocument.addAttachment((XWikiAttachment) attachment.clone()); this.currentDocument.addAttachment((XWikiAttachment) attachment.clone()); MergeResult result = merge(); Assert.assertFalse(result.isModified()); } @Test public void testMergeAttachmentEqualsDeletedCurrent() throws Exception { XWikiAttachment attachment = new XWikiAttachment(); attachment.setContent(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); attachment.setLongSize(10); attachment.setFilename("file"); this.previousDocument.addAttachment(attachment); this.nextDocument.addAttachment((XWikiAttachment) attachment.clone()); MergeResult result = merge(); Assert.assertFalse(result.isModified()); } @Test public void testMergeAttachmentEqualsAddedCurrent() throws Exception { XWikiAttachment attachment = new XWikiAttachment(); attachment.setContent(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); attachment.setLongSize(10); attachment.setFilename("file"); this.currentDocument.addAttachment(attachment); MergeResult result = merge(); Assert.assertFalse(result.isModified()); } @Test public void testMergeAttachmentEqualsModifiedCurrent() throws Exception { XWikiAttachment attachment = new XWikiAttachment(); attachment.setContent(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); attachment.setLongSize(10); attachment.setFilename("file"); this.previousDocument.addAttachment(attachment); this.nextDocument.addAttachment((XWikiAttachment) attachment.clone()); attachment = (XWikiAttachment) attachment.clone(); attachment.setContent(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8 }); attachment.setLongSize(9); this.currentDocument.addAttachment(attachment); MergeResult result = merge(); Assert.assertFalse(result.isModified()); } @Test public void testMergeAttachmentNew() throws Exception { XWikiAttachment attachment = new XWikiAttachment(); attachment.setContent(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); attachment.setLongSize(10); attachment.setFilename("file"); this.nextDocument.addAttachment(attachment); MergeResult result = merge(); Assert.assertTrue(result.isModified()); XWikiAttachment newAttachment = this.currentDocument.getAttachment("file"); Assert.assertNotNull(newAttachment); Assert.assertEquals(10, newAttachment.getLongSize()); Assert.assertArrayEquals(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, newAttachment.getContent(null)); } @Test public void testMergeAttachmentDeleted() throws Exception { XWikiAttachment attachment = new XWikiAttachment(); attachment.setContent(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); attachment.setLongSize(10); attachment.setFilename("file"); this.currentDocument.addAttachment(attachment); this.previousDocument.addAttachment((XWikiAttachment) attachment.clone()); MergeResult result = merge(); Assert.assertTrue(result.isModified()); XWikiAttachment newAttachment = this.currentDocument.getAttachment("file"); Assert.assertNull(newAttachment); } @Test public void testMergeAttachmentModified() throws Exception { XWikiAttachment attachment = new XWikiAttachment(); attachment.setContent(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); attachment.setLongSize(10); attachment.setFilename("file"); this.currentDocument.addAttachment(attachment); this.previousDocument.addAttachment((XWikiAttachment) attachment.clone()); attachment = (XWikiAttachment) attachment.clone(); attachment.setContent(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8 }); attachment.setLongSize(9); this.nextDocument.addAttachment(attachment); MergeResult result = merge(); Assert.assertTrue(result.isModified()); XWikiAttachment newAttachment = this.currentDocument.getAttachment("file"); Assert.assertNotNull(newAttachment); Assert.assertEquals(9, newAttachment.getLongSize()); Assert.assertArrayEquals(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8 }, newAttachment.getContent(null)); } // #apply @Test public void testApplyWithUnmodifiedObject() { this.previousDocument.addXObject(this.xobject); this.currentDocument.addXObject(this.xobject.clone()); Assert.assertFalse(this.previousDocument.apply(this.currentDocument, true)); } @Test public void testApplyWithModifiedObjectAndClean() { this.previousDocument.addXObject(this.xobject); BaseObject modifiedObject = this.xobject.clone(); modifiedObject.setStringValue("string", "string2"); this.currentDocument.addXObject(modifiedObject); Assert.assertTrue(this.previousDocument.apply(this.currentDocument, true)); Assert.assertEquals("string2", this.xobject.getStringValue("string")); } }