/*
* 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.extension.script;
import java.util.Arrays;
import java.util.List;
import javax.inject.Provider;
import org.apache.commons.collections4.Predicate;
import org.apache.commons.lang.StringUtils;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.xwiki.bridge.DocumentAccessBridge;
import org.xwiki.context.Execution;
import org.xwiki.context.ExecutionContext;
import org.xwiki.extension.job.InstallRequest;
import org.xwiki.extension.job.UninstallRequest;
import org.xwiki.extension.job.history.ExtensionJobHistory;
import org.xwiki.extension.job.history.ExtensionJobHistoryRecord;
import org.xwiki.extension.job.history.ReplayRequest;
import org.xwiki.extension.job.history.internal.ReplayJob;
import org.xwiki.job.Job;
import org.xwiki.job.JobExecutor;
import org.xwiki.model.reference.DocumentReference;
import org.xwiki.model.reference.WikiReference;
import org.xwiki.script.service.ScriptService;
import org.xwiki.security.authorization.ContextualAuthorizationManager;
import org.xwiki.security.authorization.Right;
import org.xwiki.test.mockito.MockitoComponentMockingRule;
import com.xpn.xwiki.XWikiContext;
import static org.junit.Assert.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
/**
* Unit tests for {@link ExtensionHistoryScriptService}.
*
* @version $Id: d38258de2c95b024ace2e413b0d0653ad5e1ae35 $
* @since 7.1RC1
*/
public class ExtensionHistoryScriptServiceTest
{
@Rule
public MockitoComponentMockingRule<ExtensionHistoryScriptService> mocker =
new MockitoComponentMockingRule<ExtensionHistoryScriptService>(ExtensionHistoryScriptService.class,
ScriptService.class);
private XWikiContext xcontext = mock(XWikiContext.class);
private ExecutionContext executionContext = new ExecutionContext();
private JobExecutor jobExecutor;
private ContextualAuthorizationManager authorization;
private DocumentAccessBridge documentAccessBridge;
@Before
public void configure() throws Exception
{
Provider<XWikiContext> xcontextProvider = this.mocker.getInstance(XWikiContext.TYPE_PROVIDER);
when(xcontextProvider.get()).thenReturn(this.xcontext);
Execution execution = this.mocker.getInstance(Execution.class);
when(execution.getContext()).thenReturn(this.executionContext);
this.jobExecutor = this.mocker.getInstance(JobExecutor.class);
this.authorization = this.mocker.getInstance(ContextualAuthorizationManager.class);
this.documentAccessBridge = this.mocker.getInstance(DocumentAccessBridge.class);
}
@Test
public void getRecords() throws Exception
{
InstallRequest devInstallReq = new InstallRequest();
devInstallReq.addNamespace("wiki:dev");
ExtensionJobHistoryRecord devInstall =
new ExtensionJobHistoryRecord("install", devInstallReq, null, null, null);
UninstallRequest devUninstallReq = new UninstallRequest();
devUninstallReq.addNamespace("wiki:dev");
ExtensionJobHistoryRecord devUninstall =
new ExtensionJobHistoryRecord("uninstall", devUninstallReq, null, null, null);
ExtensionJobHistoryRecord globalInstall =
new ExtensionJobHistoryRecord("install", new InstallRequest(), null, null, null);
ExtensionJobHistoryRecord globalUninstall =
new ExtensionJobHistoryRecord("uninstall", new UninstallRequest(), null, null, null);
InstallRequest draftsInstallReq = new InstallRequest();
draftsInstallReq.addNamespace("wiki:drafts");
ExtensionJobHistoryRecord draftsInstall =
new ExtensionJobHistoryRecord("install", draftsInstallReq, null, null, null);
List<ExtensionJobHistoryRecord> records = Arrays.asList(devInstall, globalInstall);
ExtensionJobHistory history = this.mocker.getInstance(ExtensionJobHistory.class);
ArgumentCaptor<Predicate<ExtensionJobHistoryRecord>> predicateCaptor =
ArgumentCaptor.forClass((Class) Predicate.class);
when(history.getRecords(predicateCaptor.capture(), eq("offsetRecordId"), eq(5))).thenReturn(records);
when(this.xcontext.getWikiId()).thenReturn("dev");
assertEquals(
records,
this.mocker.getComponentUnderTest().getRecords().fromThisWiki().ofType(Arrays.asList("install"))
.list("offsetRecordId", 5));
Predicate<ExtensionJobHistoryRecord> predicate = predicateCaptor.getValue();
assertTrue(predicate.evaluate(devInstall));
assertTrue(predicate.evaluate(globalInstall));
assertFalse(predicate.evaluate(devUninstall));
assertFalse(predicate.evaluate(globalUninstall));
assertFalse(predicate.evaluate(draftsInstall));
}
@Test
public void replayWithoutAdmin() throws Exception
{
InstallRequest installRequest = new InstallRequest();
installRequest.addNamespace("wiki:dev");
ExtensionJobHistoryRecord install = new ExtensionJobHistoryRecord("install", installRequest, null, null, null);
List<ExtensionJobHistoryRecord> records = Arrays.asList(install);
when(this.xcontext.getWikiId()).thenReturn("dev");
when(this.authorization.hasAccess(Right.ADMIN, new WikiReference("dev"))).thenReturn(false);
Job replayJob = mock(Job.class);
ArgumentCaptor<ReplayRequest> requestCaptor = ArgumentCaptor.forClass(ReplayRequest.class);
when(jobExecutor.execute(eq(ReplayJob.JOB_TYPE), requestCaptor.capture())).thenReturn(replayJob);
assertSame(replayJob, this.mocker.getComponentUnderTest().replay(records));
ReplayRequest request = requestCaptor.getValue();
assertTrue(request.getRecords().isEmpty());
}
@Test
public void replayWithAdminButNoPR() throws Exception
{
InstallRequest installRequest = new InstallRequest();
installRequest.addNamespace("wiki:drafts");
installRequest.setProperty("user.reference", new DocumentReference("drafts", "Users", "Alice"));
ExtensionJobHistoryRecord install = new ExtensionJobHistoryRecord("install", installRequest, null, null, null);
List<ExtensionJobHistoryRecord> records = Arrays.asList(install);
when(this.xcontext.getWikiId()).thenReturn("dev");
when(this.documentAccessBridge.getCurrentUserReference()).thenReturn(
new DocumentReference("dev", "Users", "Bob"));
when(this.authorization.hasAccess(Right.ADMIN, new WikiReference("dev"))).thenReturn(true);
when(this.authorization.hasAccess(Right.PROGRAM)).thenReturn(false);
Job replayJob = mock(Job.class);
ArgumentCaptor<ReplayRequest> requestCaptor = ArgumentCaptor.forClass(ReplayRequest.class);
when(jobExecutor.execute(eq(ReplayJob.JOB_TYPE), requestCaptor.capture())).thenReturn(replayJob);
assertSame(replayJob, this.mocker.getComponentUnderTest().replay(records));
ReplayRequest request = requestCaptor.getValue();
assertEquals(Arrays.asList(install), request.getRecords());
assertEquals(Arrays.asList("wiki:dev"), install.getRequest().getNamespaces());
assertEquals(this.documentAccessBridge.getCurrentUserReference(),
install.getRequest().getProperty("user.reference"));
}
@Test
public void replayWithPR() throws Exception
{
InstallRequest installRequest = new InstallRequest();
installRequest.addNamespace("wiki:drafts");
installRequest.setProperty("user.reference", new DocumentReference("drafts", "Users", "Alice"));
ExtensionJobHistoryRecord install = new ExtensionJobHistoryRecord("install", installRequest, null, null, null);
List<ExtensionJobHistoryRecord> records = Arrays.asList(install);
when(this.xcontext.getWikiId()).thenReturn("dev");
when(this.xcontext.getAction()).thenReturn("foo");
when(this.documentAccessBridge.getCurrentUserReference()).thenReturn(
new DocumentReference("dev", "Users", "Bob"));
when(this.authorization.hasAccess(Right.ADMIN, new WikiReference("dev"))).thenReturn(true);
when(this.authorization.hasAccess(Right.PROGRAM)).thenReturn(true);
Job replayJob = mock(Job.class);
ArgumentCaptor<ReplayRequest> requestCaptor = ArgumentCaptor.forClass(ReplayRequest.class);
when(jobExecutor.execute(eq(ReplayJob.JOB_TYPE), requestCaptor.capture())).thenReturn(replayJob);
assertSame(replayJob, this.mocker.getComponentUnderTest().replay(records));
ReplayRequest request = requestCaptor.getValue();
assertTrue(StringUtils.join(request.getId(), '/').startsWith("extension/history/"));
assertTrue(request.isInteractive());
assertEquals(Arrays.asList(install), request.getRecords());
assertEquals(this.xcontext.getWikiId(), request.getProperty("context.wiki"));
assertEquals(this.xcontext.getAction(), request.getProperty("context.action"));
assertEquals(this.documentAccessBridge.getCurrentUserReference(), request.getProperty("user.reference"));
assertEquals(Arrays.asList("wiki:drafts"), install.getRequest().getNamespaces());
assertEquals(new DocumentReference("drafts", "Users", "Alice"),
install.getRequest().getProperty("user.reference"));
}
}