刘光辉
4 小时以前 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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
package jnpf.dmsService;
 
import jnpf.base.UserInfo;
import jnpf.dmsEntity.permission.entity.DmsDocumentEntity;
import jnpf.dmsEntity.permission.entity.DmsFileVersionEntity;
import jnpf.dmsEntity.permission.enums.DmsPermissionAction;
import jnpf.dmsEntity.permission.enums.DmsResourceType;
import jnpf.dmsEntity.storage.form.DmsFileExtendValidityForm;
import jnpf.dmsEntity.storage.form.DmsFileExtendValidityForm.FileRequest;
import jnpf.dmsMapper.DmsDocumentMapper;
import jnpf.dmsMapper.DmsFileVersionMapper;
import jnpf.dmsMapper.DmsVersionStateMapper;
import jnpf.dmsPermission.DmsCurrentIdentity;
import jnpf.exception.DataException;
import jnpf.flowable.entity.TaskEntity;
import jnpf.flowable.enums.TaskStatusEnum;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InOrder;
 
import java.util.Arrays;
import java.util.Date;
import java.util.UUID;
 
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.*;
 
class DmsFileValidityServiceTest {
    private static final String TENANT = "tenant-1";
    private final DmsCurrentIdentity identity = mock(DmsCurrentIdentity.class);
    private final DmsPermissionDecisionService permissions = mock(DmsPermissionDecisionService.class);
    private final DmsWorkflowFileActivationService workflow = mock(DmsWorkflowFileActivationService.class);
    private final DmsFileVersionMapper versions = mock(DmsFileVersionMapper.class);
    private final DmsDocumentMapper documents = mock(DmsDocumentMapper.class);
    private final DmsVersionStateMapper states = mock(DmsVersionStateMapper.class);
    private final DmsFileValidityProjection projection = mock(DmsFileValidityProjection.class);
    private final DmsFileValidityService service = new DmsFileValidityService(
            identity, permissions, workflow, versions, documents, states, projection,new DmsBusinessLifecycleGuard(null,false));
    private final UUID firstId = UUID.fromString("018f0000-0000-7000-8000-000000000801");
    private final UUID secondId = UUID.fromString("018f0000-0000-7000-8000-000000000802");
    private final UUID firstDocumentId = UUID.fromString("018f0000-0000-7000-8000-000000000811");
    private final UUID secondDocumentId = UUID.fromString("018f0000-0000-7000-8000-000000000812");
    private final Date firstExpiry = new Date(1893456000000L);
    private final Date secondExpiry = new Date(1924992000000L);
    private DmsFileExtendValidityForm form;
    private TaskEntity task;
 
    @BeforeEach
    void setUp() {
        UserInfo user = new UserInfo();
        when(identity.requireUser()).thenReturn(user);
        when(identity.tenantId(user)).thenReturn(TENANT);
        form = form(file(firstId, firstExpiry), file(secondId, secondExpiry));
        form.setSourceId(" flow-1 ");
        form.setTaskId(" task-1 ");
        task = new TaskEntity();
        task.setStatus(TaskStatusEnum.PASSED.getCode());
        when(workflow.requireTask("flow-1", "task-1")).thenReturn(task);
        stubVersion(firstId, firstDocumentId);
        stubVersion(secondId, secondDocumentId);
        when(documents.selectByTenantAndIdForUpdate(TENANT, firstDocumentId))
                .thenReturn(new DmsDocumentEntity());
        when(documents.selectByTenantAndIdForUpdate(TENANT, secondDocumentId))
                .thenReturn(new DmsDocumentEntity());
        when(states.updateCurrentEffectiveTo(TENANT, firstId, firstExpiry)).thenReturn(1);
        when(states.updateCurrentEffectiveTo(TENANT, secondId, secondExpiry)).thenReturn(1);
    }
 
    @Test
    void workflowRequestChecksApprovalAndPermissionThenUpdatesEveryCurrentVersion() {
        service.extendValidity(form);
 
        verify(workflow).requireTask("flow-1", "task-1");
        verify(permissions).requireAllowed(DmsResourceType.FILE_VERSION, firstId, DmsPermissionAction.UPDATE);
        verify(permissions).requireAllowed(DmsResourceType.FILE_VERSION, secondId, DmsPermissionAction.UPDATE);
        InOrder updates = inOrder(states);
        updates.verify(states).updateCurrentEffectiveTo(TENANT, firstId, firstExpiry);
        updates.verify(states).updateCurrentEffectiveTo(TENANT, secondId, secondExpiry);
        verify(projection).apply(TENANT, firstId, firstExpiry, null);
    }
 
    @Test
    void requestWithoutWorkflowStillChecksPermissionAndCurrentValidity() {
        form.setSourceId(" ");
        form.setTaskId(null);
 
        service.extendValidity(form);
 
        verifyNoInteractions(workflow);
        verify(permissions).requireAllowed(DmsResourceType.FILE_VERSION, firstId, DmsPermissionAction.UPDATE);
        verify(states).updateCurrentEffectiveTo(TENANT, firstId, firstExpiry);
        verify(states).updateCurrentEffectiveTo(TENANT, secondId, secondExpiry);
    }
 
    @Test
    void rejectsWhenOnlyOneWorkflowIdentifierIsProvided() {
        form.setTaskId(null);
 
        assertThrows(DataException.class, () -> service.extendValidity(form));
 
        verifyNoInteractions(identity, workflow, permissions, versions, documents, states);
    }
 
    @Test
    void rejectsUnapprovedWorkflowBeforeReadingFiles() {
        task.setStatus(null);
 
        assertThrows(DataException.class, () -> service.extendValidity(form));
 
        verifyNoInteractions(permissions, versions, documents, states);
    }
 
    @Test
    void rejectsDuplicateFileVersionIds() {
        form.setFiles(Arrays.asList(file(firstId, firstExpiry), file(firstId, secondExpiry)));
 
        assertThrows(DataException.class, () -> service.extendValidity(form));
 
        verifyNoInteractions(identity, workflow, permissions, versions, documents, states);
    }
 
    @Test
    void stopsBeforeAnyUpdateWhenOneVersionDoesNotExist() {
        when(versions.selectByTenantAndId(TENANT, secondId)).thenReturn(null);
 
        assertThrows(DataException.class, () -> service.extendValidity(form));
 
        verifyNoInteractions(documents, states);
    }
 
    @Test
    void reportsFailureSoTransactionCanRollBackTheWholeBatch() {
        when(states.updateCurrentEffectiveTo(TENANT, secondId, secondExpiry)).thenReturn(0);
 
        assertThrows(DataException.class, () -> service.extendValidity(form));
 
        verify(states).updateCurrentEffectiveTo(TENANT, firstId, firstExpiry);
        verify(states).updateCurrentEffectiveTo(TENANT, secondId, secondExpiry);
    }
 
    private DmsFileExtendValidityForm form(FileRequest... files) {
        DmsFileExtendValidityForm value = new DmsFileExtendValidityForm();
        value.setFiles(Arrays.asList(files));
        return value;
    }
 
    private FileRequest file(UUID fileVersionId, Date effectiveTo) {
        FileRequest value = new FileRequest();
        value.setFileVersionId(fileVersionId);
        value.setEffectiveTo(effectiveTo);
        return value;
    }
 
    private void stubVersion(UUID fileVersionId, UUID documentId) {
        DmsFileVersionEntity version = new DmsFileVersionEntity();
        version.setDocumentId(documentId);
        when(versions.selectByTenantAndId(TENANT, fileVersionId)).thenReturn(version);
    }
}