package jnpf.dmsMapper;
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
import jnpf.dmsDatabase.DmsUuidTypeHandler;
|
import jnpf.dmsEntity.permission.entity.DmsFileVersionEntity;
|
import jnpf.dmsService.DmsVersionPropertiesService;
|
import org.apache.ibatis.builder.xml.XMLMapperBuilder;
|
import org.apache.ibatis.datasource.unpooled.UnpooledDataSource;
|
import org.apache.ibatis.mapping.Environment;
|
import org.apache.ibatis.session.Configuration;
|
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
|
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
|
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
|
|
import java.io.StringReader;
|
import java.nio.charset.StandardCharsets;
|
import java.sql.SQLException;
|
import java.time.LocalDate;
|
import java.util.UUID;
|
|
import static org.junit.jupiter.api.Assertions.*;
|
|
/** Uses the target schema's real constraints/guard on a connection-local table; always rolls back. */
|
@EnabledIfEnvironmentVariable(named = "DMS_PROPERTIES_TEST_URL", matches = ".+")
|
class DmsVersionPropertiesPostgresTest {
|
@Test void insertsSnapshotAtomicallyWithoutRelaxingExistingVersionGuards() throws Exception {
|
var dataSource = new UnpooledDataSource("org.postgresql.Driver", System.getenv("DMS_PROPERTIES_TEST_URL"),
|
System.getenv("DMS_PROPERTIES_TEST_USER"), System.getenv("DMS_PROPERTIES_TEST_PASSWORD"));
|
var config = new Configuration(new Environment("properties-test", new JdbcTransactionFactory(), dataSource));
|
config.getTypeHandlerRegistry().register(DmsUuidTypeHandler.class);
|
config.setDefaultStatementTimeout(15);
|
String path = "mapper/DmsVersionPropertiesMapper.xml";
|
try (var input = getClass().getResourceAsStream("/" + path)) {
|
assertNotNull(input);
|
String xml = new String(input.readAllBytes(), StandardCharsets.UTF_8)
|
.replace("public.dms_file_versions", "pg_temp.dms_version_properties_test");
|
new XMLMapperBuilder(new StringReader(xml), config, path, config.getSqlFragments()).parse();
|
}
|
try (var session = new SqlSessionFactoryBuilder().build(config).openSession(false)) {
|
try {
|
var connection = session.getConnection();
|
try (var statement = connection.createStatement()) {
|
statement.execute("CREATE TEMP TABLE dms_version_properties_test "
|
+ "(LIKE public.dms_file_versions INCLUDING DEFAULTS INCLUDING CONSTRAINTS INCLUDING INDEXES) ON COMMIT DROP");
|
statement.execute("CREATE TRIGGER metadata_guard BEFORE UPDATE ON pg_temp.dms_version_properties_test "
|
+ "FOR EACH ROW EXECUTE FUNCTION public.dms_guard_file_version_metadata_completion()");
|
}
|
var mapper = session.getMapper(DmsVersionPropertiesMapper.class);
|
var service = new DmsVersionPropertiesService(mapper);
|
var json = new ObjectMapper();
|
var properties = json.readTree("{\"prepared_by_name\":\"管理员\",\"reviewers\":[{\"user_id\":\"859053987238827589\",\"name\":\"\"}]}");
|
var row = version("018f0000-0000-7000-8000-000000000701", 1);
|
service.insertVersion(row, properties);
|
assertEquals(properties, mapper.find("properties-test", row.getId()).getExtendedProperties());
|
service.verifyRetry("properties-test", row.getId(), properties);
|
assertNull(mapper.find("another-tenant", row.getId()));
|
|
var legacy = version("018f0000-0000-7000-8000-000000000702", 2);
|
service.insertVersion(legacy, null);
|
assertNull(mapper.find("properties-test", legacy.getId()).getExtendedProperties());
|
try (var statement = connection.createStatement();
|
var result = statement.executeQuery("SELECT count(*) FROM pg_temp.dms_version_properties_test WHERE created_at IS NOT NULL")) {
|
assertTrue(result.next());
|
assertEquals(2, result.getInt(1));
|
}
|
// Both the previously failing snapshot-only update and identity mutation stay forbidden.
|
for (String assignment : new String[]{"extended_properties = '{}'::jsonb", "file_name = 'changed.docx'"}) {
|
var savepoint = connection.setSavepoint();
|
try (var statement = connection.createStatement()) {
|
SQLException error = assertThrows(SQLException.class, () -> statement.executeUpdate(
|
"UPDATE pg_temp.dms_version_properties_test SET " + assignment + " WHERE version_no = 1"));
|
assertEquals("55000", error.getSQLState());
|
} finally {
|
connection.rollback(savepoint);
|
}
|
}
|
session.clearCache();
|
assertEquals(properties, mapper.find("properties-test", row.getId()).getExtendedProperties());
|
} finally {
|
session.rollback(true);
|
}
|
}
|
}
|
|
private DmsFileVersionEntity version(String id, long number) {
|
var row = new DmsFileVersionEntity();
|
row.setId(UUID.fromString(id));
|
row.setTenantId("properties-test");
|
row.setDocumentId(UUID.fromString("018f0000-0000-7000-8000-000000000700"));
|
row.setVersionNo(number);
|
row.setVersionLabel(number == 1 ? "D(00)" : "D(01)");
|
row.setFileName("test.docx");
|
row.setSizeBytes(10L);
|
row.setChecksumSha256("a".repeat(64));
|
row.setPreparedBy("test-user");
|
row.setPreparedOn(LocalDate.of(2026, 10, 9));
|
row.setShifouShoukong("yes");
|
row.setCreatedBy("test-user");
|
return row;
|
}
|
}
|