/* * 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 org.xwiki.refactoring.internal.job; import java.util.Arrays; import java.util.Collections; import java.util.Map; import org.junit.Rule; import org.junit.Test; import org.xwiki.job.GroupedJob; import org.xwiki.job.Job; import org.xwiki.model.EntityType; import org.xwiki.model.reference.DocumentReference; import org.xwiki.model.reference.SpaceReference; import org.xwiki.model.reference.WikiReference; import org.xwiki.refactoring.internal.LinkRefactoring; import org.xwiki.refactoring.job.MoveRequest; import org.xwiki.refactoring.job.RefactoringJobs; import org.xwiki.security.authorization.Right; import org.xwiki.test.mockito.MockitoComponentMockingRule; import org.xwiki.wiki.descriptor.WikiDescriptorManager; import static org.junit.Assert.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; /** * Unit tests for {@link MoveJob}. * * @version $Id: 92c9088c886046bf97faf5e87954a8721fe96fbe $ */ public class MoveJobTest extends AbstractMoveJobTest { @Rule public MockitoComponentMockingRule<Job> mocker = new MockitoComponentMockingRule<Job>(MoveJob.class); @Override protected MockitoComponentMockingRule<Job> getMocker() { return this.mocker; } @Test public void moveInsideItsOwnHierarchy() throws Exception { SpaceReference spaceReference = new SpaceReference("Entity", new SpaceReference("Model", new WikiReference("code"))); run(createRequest(spaceReference.getParent(), spaceReference)); verify(this.mocker.getMockedLogger()).error("Cannot make [{}] a descendant of itself.", spaceReference.getParent()); verifyNoMove(); } @Test public void moveUnsupportedEntity() throws Exception { run(createRequest(new WikiReference("from"), new WikiReference("to"))); verify(this.mocker.getMockedLogger()).error("Unsupported source entity type [{}].", EntityType.WIKI); verifyNoMove(); } @Test public void moveToUnsupportedDestination() throws Exception { run(createRequest(new DocumentReference("wiki", "Space", "Page"), new WikiReference("test"))); verify(this.mocker.getMockedLogger()).error("Unsupported destination entity type [{}] for a document.", EntityType.WIKI); run(createRequest(new DocumentReference("wiki", "Space", "Page"), new DocumentReference("test", "A", "B"))); verify(this.mocker.getMockedLogger()).error("Unsupported destination entity type [{}] for a document.", EntityType.DOCUMENT); run(createRequest(new SpaceReference("Space", new WikiReference("wiki")), new DocumentReference("test", "A", "B"))); verify(this.mocker.getMockedLogger()).error("Unsupported destination entity type [{}] for a space.", EntityType.DOCUMENT); verifyNoMove(); } @Test public void moveMissingDocument() throws Exception { DocumentReference sourceReference = new DocumentReference("foo", "A", "Page"); run(createRequest(sourceReference, new SpaceReference("B", new WikiReference("bar")))); verify(this.mocker.getMockedLogger()).warn("Skipping [{}] because it doesn't exist.", sourceReference); verifyNoMove(); } @Test public void moveDocumentWithoutDeleteRight() throws Exception { DocumentReference documentReference = new DocumentReference("wiki", "Space", "Page"); when(this.modelBridge.exists(documentReference)).thenReturn(true); DocumentReference userReference = new DocumentReference("wiki", "Users", "Alice"); when(this.authorization.hasAccess(Right.DELETE, userReference, documentReference)).thenReturn(false); MoveRequest request = createRequest(documentReference, new SpaceReference("Foo", new WikiReference("bar"))); request.setCheckRights(true); request.setUserReference(userReference); run(request); verify(this.mocker.getMockedLogger()).error("You are not allowed to delete [{}].", documentReference); verifyNoMove(); } @Test public void moveDocumentToRestrictedDestination() throws Exception { DocumentReference oldReference = new DocumentReference("wiki", "One", "Page"); DocumentReference newReference = new DocumentReference("wiki", "Two", "Page"); when(this.modelBridge.exists(oldReference)).thenReturn(true); DocumentReference userReference = new DocumentReference("wiki", "Users", "Alice"); when(this.authorization.hasAccess(Right.DELETE, userReference, oldReference)).thenReturn(true); when(this.authorization.hasAccess(Right.VIEW, userReference, newReference)).thenReturn(false); MoveRequest request = createRequest(oldReference, newReference.getParent()); request.setCheckRights(true); request.setUserReference(userReference); run(request); verify(this.mocker.getMockedLogger()).error( "You don't have sufficient permissions over the destination document [{}].", newReference); verifyNoMove(); } @Test public void moveDocumentToSpace() throws Exception { DocumentReference oldReference = new DocumentReference("wiki", "One", "Page"); when(this.modelBridge.exists(oldReference)).thenReturn(true); DocumentReference backLinkReference = new DocumentReference("wiki", "Three", "BackLink"); when(this.modelBridge.getBackLinkedReferences(oldReference, "wiki")) .thenReturn(Arrays.asList(backLinkReference)); DocumentReference newReference = new DocumentReference("wiki", "Two", "Page"); when(this.modelBridge.exists(newReference)).thenReturn(true); DocumentReference userReference = new DocumentReference("wiki", "Users", "Alice"); when(this.modelBridge.delete(newReference)).thenReturn(true); when(this.modelBridge.copy(oldReference, newReference)).thenReturn(true); MoveRequest request = createRequest(oldReference, newReference.getParent()); request.setCheckRights(false); request.setInteractive(false); request.setUserReference(userReference); run(request); LinkRefactoring linkRefactoring = getMocker().getInstance(LinkRefactoring.class); verify(linkRefactoring).renameLinks(backLinkReference, oldReference, newReference); verify(linkRefactoring).updateRelativeLinks(oldReference, newReference); verify(this.modelBridge).setContextUserReference(userReference); verify(this.modelBridge).delete(oldReference); verify(this.modelBridge).createRedirect(oldReference, newReference); } @Test public void updateLinksOnFarm() throws Exception { DocumentReference oldReference = new DocumentReference("foo", "One", "Page"); when(this.modelBridge.exists(oldReference)).thenReturn(true); DocumentReference newReference = new DocumentReference("foo", "Two", "Page"); when(this.modelBridge.exists(newReference)).thenReturn(false); when(this.modelBridge.copy(oldReference, newReference)).thenReturn(true); WikiDescriptorManager wikiDescriptorManager = this.mocker.getInstance(WikiDescriptorManager.class); when(wikiDescriptorManager.getAllIds()).thenReturn(Arrays.asList("foo", "bar")); DocumentReference aliceReference = new DocumentReference("foo", "Alice", "BackLink"); when(this.modelBridge.getBackLinkedReferences(oldReference, "foo")).thenReturn(Arrays.asList(aliceReference)); DocumentReference bobReference = new DocumentReference("bar", "Bob", "BackLink"); when(this.modelBridge.getBackLinkedReferences(oldReference, "bar")).thenReturn(Arrays.asList(bobReference)); MoveRequest request = createRequest(oldReference, newReference.getParent()); request.setCheckRights(false); request.setInteractive(false); request.setUpdateLinksOnFarm(true); GroupedJob job = (GroupedJob) run(request); assertEquals(RefactoringJobs.GROUP, job.getGroupPath().toString()); LinkRefactoring linkRefactoring = getMocker().getInstance(LinkRefactoring.class); verify(linkRefactoring).renameLinks(aliceReference, oldReference, newReference); verify(linkRefactoring).renameLinks(bobReference, oldReference, newReference); } @Test public void moveDocumentToSpaceHome() throws Exception { DocumentReference source = new DocumentReference("wiki", "A", "B"); when(this.modelBridge.exists(source)).thenReturn(true); DocumentReference destination = new DocumentReference("wiki", "C", "WebHome"); MoveRequest request = createRequest(source, destination); request.setCheckRights(false); run(request); verify(this.modelBridge).copy(source, new DocumentReference("wiki", "C", "B")); } @Test public void moveSpaceHomeDeep() throws Exception { DocumentReference spaceHome = new DocumentReference("chess", Arrays.asList("A", "B", "C"), "WebHome"); DocumentReference docFromSpace = new DocumentReference("X", spaceHome.getLastSpaceReference()); when(this.modelBridge.getDocumentReferences(spaceHome.getLastSpaceReference())).thenReturn( Arrays.asList(docFromSpace)); when(this.modelBridge.exists(docFromSpace)).thenReturn(true); WikiReference newWiki = new WikiReference("tennis"); MoveRequest request = createRequest(spaceHome, newWiki); request.setCheckRights(false); request.setDeep(true); run(request); verify(this.modelBridge).copy(docFromSpace, new DocumentReference("tennis", "C", "X")); } @Test public void moveSpaceToSpaceHome() throws Exception { SpaceReference sourceSpace = new SpaceReference("wiki", "A", "B"); DocumentReference sourceDoc = new DocumentReference("X", sourceSpace); when(this.modelBridge.getDocumentReferences(sourceSpace)).thenReturn(Arrays.asList(sourceDoc)); when(this.modelBridge.exists(sourceDoc)).thenReturn(true); DocumentReference destination = new DocumentReference("wiki", "C", "WebHome"); MoveRequest request = createRequest(sourceSpace, destination); request.setCheckRights(false); run(request); verify(this.modelBridge).copy(sourceDoc, new DocumentReference("wiki", Arrays.asList("C", "B"), "X")); } @Test public void copyDocument() throws Exception { DocumentReference sourceReference = new DocumentReference("wiki", "Space", "Page"); when(this.modelBridge.exists(sourceReference)).thenReturn(true); DocumentReference copyReference = new DocumentReference("wiki", "Copy", "Page"); when(this.modelBridge.copy(sourceReference, copyReference)).thenReturn(true); MoveRequest request = createRequest(sourceReference, copyReference.getParent()); request.setCheckRights(false); request.setInteractive(false); request.setDeleteSource(false); Map<String, String> parameters = Collections.singletonMap("foo", "bar"); request.setEntityParameters(sourceReference, parameters); run(request); verify(this.modelBridge).update(copyReference, parameters); LinkRefactoring linkRefactoring = getMocker().getInstance(LinkRefactoring.class); verify(linkRefactoring, never()).renameLinks(any(DocumentReference.class), any(DocumentReference.class), any(DocumentReference.class)); verify(linkRefactoring).updateRelativeLinks(sourceReference, copyReference); verify(this.modelBridge, never()).delete(any(DocumentReference.class)); verify(this.modelBridge, never()).createRedirect(any(DocumentReference.class), any(DocumentReference.class)); } }