package jnpf.dmsMapper;
|
|
import jnpf.dmsDatabase.DmsUuidTypeHandler;
|
import org.apache.ibatis.mapping.BoundSql;
|
import org.apache.ibatis.mapping.MappedStatement;
|
import org.apache.ibatis.session.Configuration;
|
import org.junit.jupiter.api.Test;
|
|
import java.util.HashMap;
|
import java.util.Map;
|
import java.util.UUID;
|
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
class DmsVersionStateMapperSqlTest {
|
|
@Test
|
void expiryPreservesValidityFactsAndRequiresDueDeadlineForOneTenantVersion() {
|
Map<String, Object> parameters = revisionParameters();
|
parameters.put("effectiveFrom", new java.util.Date(1726329600000L));
|
parameters.put("effectiveTo", new java.util.Date(1757865600000L));
|
parameters.put("statusReason", "到期检查确认");
|
parameters.put("changedBy", "jnpf-file");
|
|
String sql = sql("expire", parameters);
|
|
assertTrue(sql.contains("lifecycle_status = 'EXPIRED'"));
|
assertFalse(sql.contains("effective_from ="));
|
assertFalse(sql.contains("effective_to ="));
|
assertTrue(sql.contains("effective_to <= statement_timestamp()"));
|
assertTrue(sql.contains("tenant_id = ?"));
|
assertTrue(sql.contains("file_version_id = ?"));
|
assertTrue(sql.contains("lifecycle_status = 'EFFECTIVE'"));
|
assertTrue(sql.contains("revision = revision + 1"));
|
}
|
|
@Test
|
void directUploadCreatesImmediatelyEffectiveLifecycleState() {
|
Configuration configuration = new Configuration();
|
configuration.getTypeHandlerRegistry().register(UUID.class, DmsUuidTypeHandler.class);
|
loadXml(configuration);
|
MappedStatement statement = configuration.getMappedStatement(
|
DmsVersionStateMapper.class.getName() + ".insertDirectEffective");
|
|
Map<String, Object> parameters = new HashMap<>();
|
parameters.put("tenantId", "tenant-1");
|
parameters.put("documentId", UUID.fromString("018f0000-0000-7000-8000-000000000301"));
|
parameters.put("fileVersionId", UUID.fromString("018f0000-0000-7000-8000-000000000302"));
|
parameters.put("userId", "user-1");
|
BoundSql boundSql = statement.getBoundSql(parameters);
|
String sql = boundSql.getSql().replaceAll("\\s+", " ").trim();
|
|
assertTrue(sql.startsWith("INSERT INTO public.dms_version_states"));
|
assertTrue(sql.contains("'EFFECTIVE'"));
|
assertTrue(sql.contains("'DIRECT'"));
|
assertTrue(sql.contains("CURRENT_TIMESTAMP"));
|
assertTrue(sql.contains("CAST(? AS TEXT)"));
|
assertFalse(sql.contains("SELECT *"));
|
}
|
|
@Test
|
void revisionSupersedesOnlyTheExpectedCurrentVersion() {
|
String sql = sql("supersedeCurrent", revisionParameters());
|
|
assertTrue(sql.startsWith("UPDATE public.dms_version_states"));
|
assertTrue(sql.contains("lifecycle_status = 'SUPERSEDED'"));
|
assertTrue(sql.contains("file_version_id = ?"));
|
assertTrue(sql.contains("lifecycle_status = 'EFFECTIVE'"));
|
assertTrue(sql.contains("effective_to = CURRENT_TIMESTAMP"));
|
assertTrue(sql.contains("revision = revision + 1"));
|
}
|
|
@Test
|
void revisionCreatesNewEffectiveStateWithIdempotencySource() {
|
String sql = sql("insertRevisionEffective", revisionParameters());
|
|
assertTrue(sql.startsWith("INSERT INTO public.dms_version_states"));
|
assertTrue(sql.contains("'EFFECTIVE'"));
|
assertTrue(sql.contains("CONCAT('revision:', CAST(? AS TEXT), ':', ?)"));
|
assertTrue(sql.contains("CURRENT_TIMESTAMP"));
|
assertFalse(sql.contains("SELECT *"));
|
}
|
|
@Test
|
void workflowUploadCreatesPendingApprovalState() {
|
Map<String, Object> parameters = revisionParameters();
|
parameters.put("approvalSourceId", "workflow:key");
|
parameters.put("flowId", "flow-1");
|
parameters.put("taskId", "task-1");
|
parameters.put("fileType", "CREATE");
|
String sql = sql("insertWorkflowPending", parameters);
|
|
assertTrue(sql.contains("'PENDING_APPROVAL'"));
|
assertTrue(sql.contains("'WORKFLOW'"));
|
assertTrue(sql.contains("workflow_flow_id"));
|
assertFalse(sql.contains("SELECT *"));
|
}
|
|
@Test
|
void activationOnlyUpdatesPendingApprovalState() {
|
String sql = sql("activateWorkflowPending", revisionParameters());
|
|
assertTrue(sql.contains("lifecycle_status = 'EFFECTIVE'"));
|
assertTrue(sql.contains("lifecycle_status = 'PENDING_APPROVAL'"));
|
assertTrue(sql.contains("workflow_flow_id = ?"));
|
assertTrue(sql.contains("workflow_task_id = ?"));
|
assertTrue(sql.contains("workflow_file_type = ?"));
|
assertTrue(sql.contains("revision = revision + 1"));
|
assertTrue(sql.contains("archived_at = CURRENT_TIMESTAMP"));
|
}
|
|
@Test
|
void readableVersionExcludesPendingAndNeverApprovedInvalidatedStates() {
|
Configuration configuration = new Configuration();
|
configuration.getTypeHandlerRegistry().register(UUID.class, DmsUuidTypeHandler.class);
|
configuration.addMapper(DmsFileVersionMapper.class);
|
MappedStatement statement = configuration.getMappedStatement(
|
DmsFileVersionMapper.class.getName() + ".selectReadableByTenantAndId");
|
Map<String, Object> parameters = revisionParameters();
|
parameters.put("id", parameters.get("fileVersionId"));
|
String sql = statement.getBoundSql(parameters).getSql().replaceAll("\\s+", " ").trim();
|
|
assertFalse(sql.contains("PENDING_APPROVAL"));
|
assertFalse(sql.contains("PENDING_EFFECTIVE"));
|
assertTrue(sql.contains("s.lifecycle_status = 'INVALIDATED' AND s.approved_at IS NOT NULL"));
|
}
|
|
private void loadXml(Configuration configuration) {
|
String resource = "mapper/DmsVersionStateMapper.xml";
|
try (java.io.InputStream input = org.apache.ibatis.io.Resources.getResourceAsStream(resource)) {
|
new org.apache.ibatis.builder.xml.XMLMapperBuilder(input, configuration, resource, configuration.getSqlFragments()).parse();
|
} catch (java.io.IOException e) { throw new IllegalStateException(e); }
|
}
|
|
private String sql(String method, Map<String, Object> parameters) {
|
Configuration configuration = new Configuration();
|
configuration.getTypeHandlerRegistry().register(UUID.class, DmsUuidTypeHandler.class);
|
loadXml(configuration);
|
MappedStatement statement = configuration.getMappedStatement(
|
DmsVersionStateMapper.class.getName() + "." + method);
|
return statement.getBoundSql(parameters).getSql().replaceAll("\\s+", " ").trim();
|
}
|
|
private Map<String, Object> revisionParameters() {
|
Map<String, Object> parameters = new HashMap<>();
|
parameters.put("tenantId", "tenant-1");
|
parameters.put("documentId", UUID.fromString("018f0000-0000-7000-8000-000000000301"));
|
parameters.put("baseFileVersionId", UUID.fromString("018f0000-0000-7000-8000-000000000302"));
|
parameters.put("fileVersionId", UUID.fromString("018f0000-0000-7000-8000-000000000303"));
|
parameters.put("sourceId", "revision-1");
|
parameters.put("revisionReason", "更新质量职责");
|
parameters.put("newVersionLabel", "D(01)");
|
parameters.put("userId", "user-1");
|
return parameters;
|
}
|
}
|