刘光辉
8 小时以前 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
88
89
90
91
92
93
94
95
package jnpf.onlinedev.service;
 
import jnpf.base.UserInfo;
import jnpf.base.entity.VisualdevEntity;
import jnpf.base.mapper.UploadEditDraftMapper;
import jnpf.base.model.flow.DataModel;
import jnpf.base.model.uploadedit.UploadEditDraft;
import jnpf.base.service.*;
import jnpf.base.util.*;
import jnpf.exception.DataException;
import jnpf.exception.WorkFlowException;
import jnpf.flowable.model.filepermission.FilePermissionView;
import jnpf.onlinedev.util.FlowFormCustomUtils;
import jnpf.util.UserProvider;
import org.junit.jupiter.api.*;
import org.mockito.MockedStatic;
import java.util.*;
import java.util.function.Consumer;
import static org.mockito.Mockito.*;
import static org.mockito.ArgumentMatchers.*;
import static org.junit.jupiter.api.Assertions.*;
 
public class WorkflowFileCheckpointServiceTest {
    private VisualdevService models;
    private FlowFormDataUtil data;
    private FlowFormCustomUtils nativeForms;
    private UploadEditDraftMapper drafts;
    private UploadFilePermissionQuery permissions;
    private WorkflowFileCheckpointService service;
    private UploadEditDraft draft;
    private MockedStatic<UserProvider> users;
    private Map<String,Object> persisted;
    @BeforeEach public void setup() {
        jnpf.util.context.SpringContext.setApplicationContext(mock(org.springframework.context.ApplicationContext.class));
        users = mockStatic(UserProvider.class); UserInfo user = new UserInfo(); user.setTenantId("0"); user.setUserId("reviewer");
        users.when(UserProvider::getUser).thenReturn(user);
        models = mock(VisualdevService.class); data = mock(FlowFormDataUtil.class); nativeForms = mock(FlowFormCustomUtils.class);
        drafts = mock(UploadEditDraftMapper.class); permissions = mock(UploadFilePermissionQuery.class);
        service = new WorkflowFileCheckpointService(models,data,nativeForms,drafts,permissions);
        FilePermissionView view = FilePermissionView.legacy("task", "form"); view.setEnabled(true);
        when(permissions.current("task", "form")).thenReturn(view);
        when(models.getReleaseInfo("form")).thenReturn(new VisualdevEntity());
        persisted = new HashMap<>(Map.of("id", "record", "flowTaskId", "task", "files", List.of(Map.of("fileId", "A")), "title", "persisted"));
        when(data.getFilePermissionDataInfo(any(), eq("task"), any())).thenReturn(persisted);
        draft = new UploadEditDraft(); draft.setTenantId("0"); draft.setModelId("form"); draft.setRecordId("record"); draft.setTaskId("task");
        draft.setField("files"); draft.setBaselineJson("[{\"fileId\":\"A\"}]"); draft.setCurrentJson("[{\"fileId\":\"B\"}]");
        draft.setId(UploadEditWorkingCopy.id("0", UploadEditDraftService.context(draft)));
        when(drafts.lockRecord("0", "form", "record")).thenReturn(List.of(draft));
    }
    @AfterEach public void close() { users.close(); }
    @Test public void checkpointsOnlyUsingPersistedDataAndContinuesAfterNativeSave() throws Exception {
        when(nativeForms.checkpointWorkflowFiles(any(), any())).thenAnswer(call -> {
            jnpf.base.model.flow.FlowFormDataModel model = call.getArgument(1);
            assertEquals("persisted", model.getMap().get("title")); assertEquals("record",model.getId());
            assertTrue(model.getSkipRequiredValidation());
            model.getMap().put("files", List.of(Map.of("fileId", "B")));
            DataModel saved = new DataModel(); saved.getWorkflowWorkingFields().add("files"); return saved;
        });
        List<Map<String,Object>> output = new ArrayList<>();
        service.save("task", "form", Map.of("title", "unsaved opinion"), output::add);
        assertEquals(1,output.size()); assertEquals("unsaved opinion",output.get(0).get("title"));
        assertEquals(List.of(Map.of("fileId", "B")),output.get(0).get("files"));
    }
    @Test public void nativeFailurePreventsNodeContinuation() throws Exception {
        when(nativeForms.checkpointWorkflowFiles(any(),any())).thenThrow(new WorkFlowException("native failed"));
        Consumer<Map<String,Object>> continuation = mock(Consumer.class);
        try { service.save("task","form",Map.of(),continuation); fail("must reject"); } catch (DataException expected) { }
        verifyNoInteractions(continuation);
    }
    @Test public void openLeasePreventsNativeSaveAndContinuation() {
        draft.setLeaseId("active"); draft.setUpdatedAt(new Date());
        Consumer<Map<String,Object>> continuation = mock(Consumer.class);
        try { service.save("task","form",Map.of(),continuation); fail("must reject"); } catch (DataException expected) { }
        verifyNoInteractions(nativeForms, continuation);
    }
    @Test public void unchangedWorkingFileDoesNotWriteNativeForm() {
        draft.setCurrentJson(draft.getBaselineJson()); List<Map<String,Object>> output = new ArrayList<>();
        service.save("task","form",Map.of("opinion","keep"),output::add);
        assertEquals("keep",output.get(0).get("opinion")); verifyNoInteractions(nativeForms);
    }
    @Test public void mismatchedInstanceCannotCheckpoint() {
        persisted.put("flowTaskId", "other"); Consumer<Map<String,Object>> continuation = mock(Consumer.class);
        try { service.save("task","form",Map.of(),continuation); fail("instance"); } catch (DataException expected) { }
        verifyNoInteractions(nativeForms, continuation, drafts);
    }
    @Test public void checkpointPassesHandlingReferenceToNativeSave() throws Exception {
        when(nativeForms.checkpointWorkflowFiles(any(), any())).thenAnswer(call -> {
            jnpf.base.model.flow.FlowFormDataModel model = call.getArgument(1);
            assertEquals("operator-round-2", model.getWorkflowOperatorId());
            return new DataModel();
        });
        service.save("task", "form", "operator-round-2", Map.of(), saved -> { });
        verify(nativeForms, times(1)).checkpointWorkflowFiles(any(), any());
    }
}