刘光辉
118 分钟以前 06f314545ac3514d7ce28939920866ae8188d31c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package jnpf.flowable.service;
 
import jnpf.flowable.mapper.DmsLifecycleNativeFormMapper;
import org.junit.Test;
import java.util.*;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
 
public class DmsRevisionAttachmentSubmissionTest {
    private final DmsLifecycleNativeFormMapper mapper=mock(DmsLifecycleNativeFormMapper.class);
    private final DmsLifecycleSubmissionGuard guard=new DmsLifecycleSubmissionGuard(mapper,null,null,false);
    private jnpf.file.FileContentApi api;
    @org.junit.Before public void configureContentApi() throws Exception {
        api = mock(jnpf.file.FileContentApi.class);
        var response = new jnpf.base.ActionResult<Boolean>(); response.setCode(200); response.setData(false);
        when(api.sameContent(anyString(), any())).thenReturn(response);
        var field = DmsLifecycleSubmissionGuard.class.getDeclaredField("fileContentApi"); field.setAccessible(true); field.set(guard, api);
    }
    private static final String ORIGINAL="[{\"fileId\":\"a\",\"url\":\"/a\"}]";
    private static <T extends Throwable> T assertThrows(Class<T> type,Runnable action) {
        try { action.run(); } catch(Throwable failure) {
            if(type.isInstance(failure)) return type.cast(failure);
            throw new AssertionError(failure);
        }
        throw new AssertionError("Expected "+type.getName());
    }
    private Map<String,Object> row(Object attachment) {
        Map<String,Object> row=new HashMap<>();
        row.put("biangeng_fangshi","wubianhua");row.put("jilu_wenjian_id","record");
        row.put("yuan_wenjian_banben_id","version");row.put("jilu_wenjian",attachment);
        row.put("shifou_shoukong","yes");row.put("fujian_mingcheng","new name");
        return row;
    }
    @Test public void metadataChangesAndJsonPropertyOrderAreAllowed() {
        when(mapper.revisionAttachment("tenant","record","version")).thenReturn(ORIGINAL);
        guard.validateRevisionAttachments("tenant",Map.of(),List.of(
                row("[{\"url\":\"/a\",\"fileId\":\"a\"}]")));
        guard.validateRevisionAttachments("tenant",Map.of(),List.of(
                row(List.of(Map.of("fileId","a","url","/a")))));
    }
    @Test public void changedRemovedMissingOrMalformedAttachmentsAreRejected() {
        when(mapper.revisionAttachment("tenant","record","version")).thenReturn(ORIGINAL);
        for(Object attachment:Arrays.asList("[{\"fileId\":\"b\",\"url\":\"/b\"}]","[]","",null,"broken",Map.of())) {
            var failure=assertThrows(IllegalArgumentException.class,
                    ()->guard.validateRevisionAttachments("tenant",Map.of(),List.of(row(attachment))));
            assertTrue(failure.getMessage().contains("第1行记录"));
            assertTrue(failure.getMessage().contains("升级"));
        }
    }
    @Test public void missingAuthoritativeVersionCannotBeAccepted() {
        assertThrows(IllegalArgumentException.class,()->guard.validateRevisionAttachments("other",Map.of(),List.of(row(ORIGINAL))));
    }
    @Test public void upgradedAttachmentIsNotSubjectToReuseValidation() {
        var row=row("[{\"fileId\":\"b\"}]");row.put("biangeng_fangshi","shengji");
        guard.validateRevisionAttachments("tenant",Map.of("biangeng_fangshi","shengji"),List.of(row));
        verifyNoInteractions(mapper);
    }
    @Test public void mainSharedAttachmentMustMatchFixedOriginalVersion() {
        assertThrows(IllegalArgumentException.class, () -> guard.validateRevisionAttachments("tenant",Map.of("biangeng_fangshi","wubianhua",
                "xiuding_shenqing_zixiang_id","detail","wenjian","[]"),List.of()));
        verify(mapper).revisionMainAttachment("tenant", "detail");
    }
    @Test public void repeatedImmutableEditComparisonReusesResultButRechecksOriginalAndTenant() {
        when(mapper.revisionAttachment("tenant", "record", "version")).thenReturn(ORIGINAL);
        var equal = new jnpf.base.ActionResult<Boolean>(); equal.setCode(200); equal.setData(true);
        when(api.sameContent(anyString(), any())).thenReturn(equal);
        String id = "onlyoffice-edit-temp," + "a".repeat(32) + "," + "b".repeat(32) + ",saved.docx";
        var row = row(List.of(Map.of("fileId", id, "url", "/saved")));
        guard.validateRevisionAttachments("tenant", Map.of(), List.of(row));
        guard.validateRevisionAttachments("tenant", Map.of(), List.of(row));
        verify(api, times(1)).sameContent(anyString(), any());
        verify(mapper, times(2)).revisionAttachment("tenant", "record", "version");
        when(mapper.revisionAttachment("tenant", "record", "version")).thenReturn("[{\"fileId\":\"new-original\",\"url\":\"/new\"}]");
        guard.validateRevisionAttachments("tenant", Map.of(), List.of(row));
        verify(api, times(2)).sameContent(anyString(), any());
        assertThrows(IllegalArgumentException.class, () -> guard.validateRevisionAttachments("other", Map.of(), List.of(row)));
    }
    @Test public void ordinaryMutableFilesDoNotReuseComparisonResults() {
        when(mapper.revisionAttachment("tenant", "record", "version")).thenReturn(ORIGINAL);
        var equal = new jnpf.base.ActionResult<Boolean>(); equal.setCode(200); equal.setData(true);
        when(api.sameContent(anyString(), any())).thenReturn(equal);
        var row = row(List.of(Map.of("fileId", "ordinary", "url", "/ordinary")));
        guard.validateRevisionAttachments("tenant", Map.of(), List.of(row));
        guard.validateRevisionAttachments("tenant", Map.of(), List.of(row));
        verify(api, times(2)).sameContent(anyString(), any());
    }
}