package jnpf.bizcommon.onlyoffice.service.impl;
|
|
import jnpf.base.ActionResult;
|
import jnpf.base.UserInfo;
|
import jnpf.bizcommon.onlyoffice.entity.OnlyOfficeConfigParam;
|
import jnpf.bizcommon.onlyoffice.entity.OnlyOfficeProperties;
|
import jnpf.bizcommon.onlyoffice.entity.OnlyOfficeSessionEntity;
|
import jnpf.eln.RecordFillApi;
|
import jnpf.exception.DataException;
|
import org.junit.Test;
|
|
import java.util.Arrays;
|
import java.util.LinkedHashMap;
|
import java.util.Map;
|
|
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertSame;
|
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.fail;
|
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.when;
|
|
public class OnlyOfficeSceneConfigRegistryTest {
|
|
@Test
|
public void dispatchesKnownScenesOnceAndFallsBackToTheDefaultBuilder() {
|
OnlyOfficeSceneConfigBuilder annotate = mock(OnlyOfficeSceneConfigBuilder.class);
|
when(annotate.scene()).thenReturn("eln.template.annotate");
|
when(annotate.bizModule()).thenReturn("eln.template");
|
OnlyOfficeSceneConfigBuilder recordFill = mock(OnlyOfficeSceneConfigBuilder.class);
|
when(recordFill.scene()).thenReturn("eln.record.fill");
|
when(recordFill.bizModule()).thenReturn("eln.record");
|
DefaultSceneConfigBuilder defaultBuilder = mock(DefaultSceneConfigBuilder.class);
|
OnlyOfficeSceneConfigRegistry registry = new OnlyOfficeSceneConfigRegistry(
|
Arrays.asList(annotate, recordFill), defaultBuilder);
|
|
assertSame(recordFill, registry.resolve(param("eln.record.fill", "eln.record")));
|
assertSame(annotate, registry.resolve(param("eln.template.annotate", "eln.template")));
|
assertSame(defaultBuilder, registry.resolve(param("ordinary.view", "lims.document")));
|
|
try {
|
registry.resolve(param("eln.record.fill", "eln.template"));
|
fail("scene and module mismatch must be rejected");
|
} catch (DataException expected) {
|
assertEquals("OnlyOffice 插件场景与业务模块不匹配", expected.getMessage());
|
}
|
}
|
|
@Test
|
public void recordFillBuilderOwnsAdmissionLockAndPluginContext() {
|
RecordFillApi recordFillApi = mock(RecordFillApi.class);
|
ActionResult<Boolean> allowed = mock(ActionResult.class);
|
when(allowed.getCode()).thenReturn(200);
|
when(allowed.getData()).thenReturn(true);
|
when(recordFillApi.canFill(any(), any(), any(), any())).thenReturn(allowed);
|
ElnRecordFillTicketIssuer ticketIssuer = mock(ElnRecordFillTicketIssuer.class);
|
when(ticketIssuer.issue(any(), any(), any())).thenReturn("record-ticket");
|
ElnRecordFillConfigBuilder builder = new ElnRecordFillConfigBuilder(recordFillApi, ticketIssuer);
|
OnlyOfficeConfigParam param = param("eln.record.fill", "eln.record");
|
param.setFileId("file-1");
|
param.setFileType("annex");
|
param.setBizDataId("record-1");
|
UserInfo user = new UserInfo();
|
user.setUserId("user-1");
|
OnlyOfficeSessionEntity session = new OnlyOfficeSessionEntity();
|
session.setTenantId("tenant-1");
|
session.setFileId("file-1");
|
session.setFileType("annex");
|
session.setBizModule("eln.record");
|
session.setBizDataId("record-1");
|
|
OnlyOfficeSceneBuildPlan plan = builder.build(
|
new OnlyOfficeSceneBuildContext(param, session, user, "tenant-1"));
|
Map<String, Object> pluginContext = new LinkedHashMap<>();
|
plan.customizePluginContext("eln-record-filler", "guid-1", pluginContext, true);
|
|
assertTrue(plan.canEdit());
|
assertTrue(plan.allowSameUserLockReopen());
|
assertTrue(plan.hideCommentsWhenWritable());
|
assertEquals(true, pluginContext.get("canFill"));
|
assertEquals("onlyoffice:eln-record-fill", pluginContext.get("scope"));
|
assertEquals("record-ticket", pluginContext.get("ticket"));
|
|
Map<String, Object> unrelated = new LinkedHashMap<>();
|
plan.customizePluginContext("document-helper", "guid-2", unrelated, true);
|
assertFalse(unrelated.containsKey("ticket"));
|
}
|
|
@Test
|
public void qianpiyeModeCanEditWithoutAPluginScene() {
|
UserInfo administrator = mock(UserInfo.class);
|
when(administrator.getIsAdministrator()).thenReturn(true);
|
OnlyOfficeConfigParam param = new OnlyOfficeConfigParam();
|
param.setMode("qianpiye");
|
|
OnlyOfficeSceneBuildPlan plan = new DefaultSceneConfigBuilder(
|
new OnlyOfficeEditPermissionEvaluator(new OnlyOfficeProperties())).build(
|
new OnlyOfficeSceneBuildContext(param, new OnlyOfficeSessionEntity(), administrator, "tenant-1"));
|
|
assertTrue(plan.canEdit());
|
}
|
|
@Test
|
public void qianpiyeBuilderIssuesTicketOnlyForItsOwnWritablePlugin() {
|
UserInfo administrator = mock(UserInfo.class);
|
when(administrator.getIsAdministrator()).thenReturn(true);
|
DmsQianpiyeTicketIssuer ticketIssuer = mock(DmsQianpiyeTicketIssuer.class);
|
when(ticketIssuer.issue(any(), any(), any())).thenReturn("qianpiye-ticket");
|
OnlyOfficeConfigParam param = param("dms.qianpiye", "dms");
|
param.setFileId("file-1");
|
DmsQianpiyeConfigBuilder builder = new DmsQianpiyeConfigBuilder(
|
new OnlyOfficeEditPermissionEvaluator(new OnlyOfficeProperties()), ticketIssuer);
|
OnlyOfficeSceneBuildPlan plan = builder.build(new OnlyOfficeSceneBuildContext(
|
param, new OnlyOfficeSessionEntity(), administrator, "tenant-1"));
|
|
Map<String, Object> context = new LinkedHashMap<>();
|
plan.customizePluginContext("dms-qianpiye-annotator",
|
"asc.{C764F7D6-055D-4C7D-97FD-83D2C4440585}", context, true);
|
|
assertTrue(plan.canEdit());
|
assertTrue(plan.allowSameUserLockReopen());
|
assertTrue(plan.hideCommentsWhenWritable());
|
assertEquals(true, context.get("canAnnotate"));
|
assertEquals("onlyoffice:dms-qianpiye", context.get("scope"));
|
assertEquals("qianpiye-ticket", context.get("ticket"));
|
assertFalse(plan.keepPluginInReadOnly("dms-qianpiye-annotator", false));
|
}
|
|
@Test
|
public void qianpiyeBuilderOnlyAdoptsAnIdleUnboundSessionForTheSameFile() {
|
DmsQianpiyeConfigBuilder builder = new DmsQianpiyeConfigBuilder(
|
new OnlyOfficeEditPermissionEvaluator(new OnlyOfficeProperties()), mock(DmsQianpiyeTicketIssuer.class));
|
OnlyOfficeConfigParam param = param("dms.qianpiye", "dms");
|
param.setFileId("file-1");
|
param.setFileType("annex");
|
param.setBizDataId("qianpiye-1");
|
OnlyOfficeSessionEntity session = new OnlyOfficeSessionEntity();
|
session.setTenantId("tenant-1");
|
session.setFileId("file-1");
|
session.setFileType("annex");
|
session.setSessionStatus(OnlyOfficeSessionEntity.SessionStatus.IDLE);
|
|
assertTrue(builder.canAdoptUnboundSession(session, param, "tenant-1"));
|
|
// 旧版普通编辑会话可能记录了页面模块,但尚未绑定具体业务记录,允许签批页迁移。
|
session.setBizModule("签批页管理");
|
assertTrue(builder.canAdoptUnboundSession(session, param, "tenant-1"));
|
|
session.setBizDataId("another-business");
|
assertFalse(builder.canAdoptUnboundSession(session, param, "tenant-1"));
|
session.setBizDataId(null);
|
session.setSessionStatus(OnlyOfficeSessionEntity.SessionStatus.EDITING);
|
assertFalse(builder.canAdoptUnboundSession(session, param, "tenant-1"));
|
}
|
|
@Test
|
public void qianpiyeSessionCanBeReusedWithoutBizDataId() {
|
DmsQianpiyeConfigBuilder builder = new DmsQianpiyeConfigBuilder(
|
new OnlyOfficeEditPermissionEvaluator(new OnlyOfficeProperties()), mock(DmsQianpiyeTicketIssuer.class));
|
OnlyOfficeSessionEntity session = new OnlyOfficeSessionEntity();
|
session.setTenantId("tenant-1");
|
session.setFileId("file-1");
|
session.setFileType("annex");
|
session.setBizModule("dms");
|
session.setBizDataId("qianpiye-1");
|
|
OnlyOfficeConfigParam genericPreview = new OnlyOfficeConfigParam();
|
genericPreview.setFileId("file-1");
|
genericPreview.setFileType("annex");
|
genericPreview.setMode("view");
|
assertTrue(builder.matchesSession(session, genericPreview, "tenant-1"));
|
|
OnlyOfficeConfigParam annotation = param("dms.qianpiye", "dms");
|
annotation.setFileId("file-1");
|
annotation.setFileType("annex");
|
annotation.setMode("qianpiye");
|
assertTrue(builder.matchesSession(session, annotation, "tenant-1"));
|
|
OnlyOfficeConfigParam otherBusiness = param("eln.record.fill", "eln.record");
|
otherBusiness.setFileId("file-1");
|
otherBusiness.setFileType("annex");
|
otherBusiness.setMode("view");
|
assertFalse(builder.matchesSession(session, otherBusiness, "tenant-1"));
|
|
annotation.setBizDataId("another-business");
|
assertFalse(builder.matchesSession(session, annotation, "tenant-1"));
|
}
|
|
@Test(expected = IllegalStateException.class)
|
public void rejectsDuplicateSceneBuilders() {
|
OnlyOfficeSceneConfigBuilder first = builder("eln.record.fill", "eln.record");
|
OnlyOfficeSceneConfigBuilder duplicate = builder("eln.record.fill", "eln.other-record");
|
|
new OnlyOfficeSceneConfigRegistry(Arrays.asList(first, duplicate),
|
mock(DefaultSceneConfigBuilder.class));
|
}
|
|
@Test(expected = IllegalStateException.class)
|
public void rejectsDuplicateBusinessModuleGuards() {
|
OnlyOfficeSceneConfigBuilder first = builder("eln.record.fill", "eln.record");
|
OnlyOfficeSceneConfigBuilder duplicate = builder("eln.record.review", "eln.record");
|
|
new OnlyOfficeSceneConfigRegistry(Arrays.asList(first, duplicate),
|
mock(DefaultSceneConfigBuilder.class));
|
}
|
|
private OnlyOfficeSceneConfigBuilder builder(String scene, String module) {
|
OnlyOfficeSceneConfigBuilder builder = mock(OnlyOfficeSceneConfigBuilder.class);
|
when(builder.scene()).thenReturn(scene);
|
when(builder.bizModule()).thenReturn(module);
|
when(builder.guardsBusinessContext()).thenReturn(true);
|
return builder;
|
}
|
|
private OnlyOfficeConfigParam param(String scene, String module) {
|
OnlyOfficeConfigParam param = new OnlyOfficeConfigParam();
|
param.setBizScene(scene);
|
param.setBizModule(module);
|
return param;
|
}
|
}
|