package jnpf.dmsService;
|
|
import jnpf.dmsEntity.storage.*;
|
import jnpf.dmsMapper.DmsRevisionEditMapper;
|
import jnpf.exception.DataException;
|
import jnpf.util.JsonUtil;
|
import org.junit.jupiter.api.Test;
|
import java.util.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
import static org.mockito.Mockito.*;
|
|
public class DmsRevisionEditServiceTest {
|
@Test public void nonEditableSourcesReceiveFreshVerifiableReceiptsWithoutOldUploadTokens() {
|
for (String extension : List.of("txt", "pdf", "doc", "docx")) {
|
DmsRevisionEditMapper mapper = mock(DmsRevisionEditMapper.class);
|
DmsRevisionEditSource source = source();
|
source.setFiles(JsonUtil.getObjectToString(List.of(Map.of("fileId", "original", "name", "source." + extension,
|
"uploadReceipt", "expired-upload", "laiyuan_muban_id", "template"))));
|
when(mapper.sources("tenant", "owner", "source", "model")).thenReturn(List.of(source));
|
Map<String, String> tickets = new HashMap<>();
|
DmsRevisionEditService service = new DmsRevisionEditService(mapper, tickets::get,
|
(json, ttl) -> { tickets.put("receipt", json); return "receipt"; });
|
Map<?, ?> file = (Map<?, ?>)((List<?>)service.prepare(request(), "tenant", "owner").get(0).get("files")).get(0);
|
assertEquals("receipt", file.get("revisionEditReceipt"));
|
assertFalse(file.containsKey("uploadReceipt"));
|
Map<?, ?> verified = (Map<?, ?>) service.verify(request()).get("file");
|
assertEquals("source." + extension, verified.get("name"));
|
assertEquals("template", verified.get("laiyuan_muban_id"));
|
source.setFiles(JsonUtil.getObjectToString(List.of(Map.of("fileId", "original", "name", "source." + extension,
|
"uploadReceipt", "expired-upload"))));
|
Map<?, ?> ordinary = (Map<?, ?>)((List<?>)service.prepare(request(), "tenant", "owner").get(0).get("files")).get(0);
|
assertFalse(ordinary.containsKey("laiyuan_muban_id"));
|
assertFalse(((Map<?, ?>)service.verify(request()).get("file")).containsKey("laiyuan_muban_id"));
|
when(mapper.sources("tenant", "owner", "source", "model")).thenReturn(List.of());
|
assertThrows(DataException.class, () -> service.verify(request()));
|
}
|
}
|
@Test public void unchangedSourceReturnsCompleteTrustedJsonButEditedCopyDoesNot() throws Exception {
|
DmsRevisionEditMapper mapper = mock(DmsRevisionEditMapper.class);
|
DmsRevisionEditSource source = source();
|
String original = "{\"fileId\":\"original\",\"name\":\"source.txt\",\"uploadReceipt\":\"historical-owner-token\",\"fileVersionId\":null}";
|
source.setFiles("[" + original + "]");
|
when(mapper.sources("tenant", "owner", "source", "model")).thenReturn(List.of(source));
|
Map<String,Object> grant = proof();
|
grant.put("file", Map.of("fileId", "original", "name", "source.txt"));
|
grant.put("sourceFileJson", "forged");
|
DmsRevisionEditService service = new DmsRevisionEditService(mapper,
|
token -> JsonUtil.getObjectToString(grant), (json, ttl) -> "issued");
|
Map<String,Object> verified = service.verify(request());
|
com.fasterxml.jackson.databind.ObjectMapper json = new com.fasterxml.jackson.databind.ObjectMapper();
|
assertEquals(json.readTree(original), json.readTree((String)verified.get("sourceFileJson")));
|
assertFalse(((Map<?,?>)verified.get("file")).containsKey("laiyuan_muban_id"));
|
grant.put("file", Map.of("fileId", "copy", "name", "source.docx"));
|
assertFalse(service.verify(request()).containsKey("sourceFileJson"));
|
}
|
|
private static void assertThrows(Class<? extends Throwable> type, Runnable action) {
|
try { action.run(); } catch (Throwable error) { if (type.isInstance(error)) return; throw error; }
|
fail("Expected " + type.getSimpleName());
|
}
|
|
private DmsRevisionEditRequest request() {
|
DmsRevisionEditRequest r = new DmsRevisionEditRequest();
|
r.setTenantId("tenant"); r.setOwnerId("owner"); r.setModelId("model");
|
r.setSourceItemId("source"); r.setField("wenjian"); r.setParentField(""); r.setReceipt("receipt"); return r;
|
}
|
private DmsRevisionEditSource source() {
|
DmsRevisionEditSource s = new DmsRevisionEditSource();
|
s.setVersionId("version"); s.setField("wenjian"); s.setParentField("");
|
s.setFiles("[{\"fileId\":\"original\",\"name\":\"source.docx\"}]"); return s;
|
}
|
private Map<String,Object> proof() {
|
Map<String,Object> p = new HashMap<>();
|
p.put("purpose", "dms-revision-edit"); p.put("tenantId", "tenant"); p.put("ownerId", "owner");
|
p.put("modelId", "model"); p.put("sourceItemId", "source"); p.put("field", "wenjian"); p.put("parentField", "");
|
p.put("versionId", "version"); p.put("originFileId", "original"); p.put("expiresAt", System.currentTimeMillis()+60000);
|
p.put("file", Map.of("fileId", "copy", "name", "source.docx")); return p;
|
}
|
@Test public void receiptRevalidatesCanonicalSourceAndRejectsTampering() {
|
DmsRevisionEditMapper mapper = mock(DmsRevisionEditMapper.class);
|
when(mapper.sources("tenant","owner","source","model")).thenReturn(List.of(source()));
|
Map<String,Object> current = proof();
|
DmsRevisionEditService service = new DmsRevisionEditService(mapper,
|
token -> JsonUtil.getObjectToString(current), (json, ttl) -> "issued");
|
assertEquals("copy", ((Map<?,?>)service.verify(request()).get("file")).get("fileId"));
|
for (String field : List.of("purpose", "tenantId", "ownerId", "modelId", "field", "parentField", "versionId", "originFileId")) {
|
Object original = current.put(field, "foreign");
|
assertThrows(DataException.class, () -> service.verify(request())); current.put(field, original);
|
}
|
current.put("expiresAt", 1); assertThrows(DataException.class, () -> service.verify(request()));
|
}
|
@Test public void sourceRemovedAfterIssuanceIsRejected() {
|
DmsRevisionEditMapper mapper = mock(DmsRevisionEditMapper.class);
|
DmsRevisionEditService service = new DmsRevisionEditService(mapper,
|
token -> JsonUtil.getObjectToString(proof()), (json, ttl) -> "issued");
|
assertThrows(DataException.class, () -> service.verify(request()));
|
}
|
@Test public void prepareUsesOnlyServerFilesAndBindsChildVersion() {
|
DmsRevisionEditMapper mapper = mock(DmsRevisionEditMapper.class);
|
DmsRevisionEditSource child = source(); child.setParentField("jilu_mingxi"); child.setField("jilu_wenjian");
|
when(mapper.sources("tenant","owner","source","model")).thenReturn(List.of(child));
|
DmsRevisionEditService service = new DmsRevisionEditService(mapper, token -> null, (json, ttl) -> {
|
Map<?,?> proof = JsonUtil.getJsonToBean(json, Map.class);
|
assertEquals("jilu_mingxi", proof.get("parentField")); assertEquals("version", proof.get("versionId"));
|
assertEquals("original", proof.get("originFileId")); assertEquals(14400L, ttl.longValue()); return "issued";
|
});
|
List<Map<String,Object>> rows = service.prepare(request(), "tenant", "owner");
|
assertEquals("issued", ((Map<?,?>)((List<?>)rows.get(0).get("files")).get(0)).get("revisionEditReceipt"));
|
}
|
}
|