84 lines
4.5 KiB
Java
84 lines
4.5 KiB
Java
package com.baiyue.lastleg.financefee;
|
|
|
|
import com.baomidou.mybatisplus.core.MybatisConfiguration;
|
|
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
|
|
import com.baiyue.lastleg.financefee.entity.OverseasFeeCommand;
|
|
import com.baiyue.lastleg.financefee.mapper.OverseasFeeCommandMapper;
|
|
import org.junit.jupiter.api.Test;
|
|
import org.mybatis.spring.SqlSessionTemplate;
|
|
import org.springframework.jdbc.core.JdbcTemplate;
|
|
import org.springframework.jdbc.datasource.DriverManagerDataSource;
|
|
|
|
import java.nio.file.Files;
|
|
import java.nio.file.Path;
|
|
import java.time.LocalDateTime;
|
|
import java.util.List;
|
|
import java.util.UUID;
|
|
import java.util.regex.Pattern;
|
|
|
|
import static org.assertj.core.api.Assertions.*;
|
|
|
|
class OverseasFeeCommandSchemaContractTest {
|
|
private static final String MIGRATION = "../deploy/sql/migrations/overseas/baiyue_lastleg/V35__widen_finance_fee_command_action.sql";
|
|
|
|
/** 两份初始化入口均须容纳完整重试动作,避免新环境再次截断幂等命令。 */
|
|
@Test void initializationEntriesSupportFundingRetryAction() throws Exception {
|
|
for (String path : List.of("src/main/resources/db/lastleg.sql", "../deploy/sql/海外区域统一增量-MySQL8.sql")) {
|
|
String ddl = commandTable(Files.readString(Path.of(path)));
|
|
var action = Pattern.compile("\\baction\\s+varchar\\((\\d+)\\)", Pattern.CASE_INSENSITIVE).matcher(ddl);
|
|
assertThat(action.find()).as(path).isTrue();
|
|
assertThat(Integer.parseInt(action.group(1))).as(path).isGreaterThanOrEqualTo(32);
|
|
assertThat(ddl).contains("uk_ll_finance_fee_command");
|
|
}
|
|
}
|
|
|
|
/** 真实 Mapper 复现旧列截断,迁移后重试动作可落库回读且幂等唯一约束仍生效。 */
|
|
@Test void migrationAllowsFundingRetryAndPreservesIdempotency() throws Exception {
|
|
var dataSource = new DriverManagerDataSource("jdbc:h2:mem:" + UUID.randomUUID() + ";MODE=MySQL;DB_CLOSE_DELAY=-1", "sa", "");
|
|
var jdbc = new JdbcTemplate(dataSource);
|
|
jdbc.execute("CREATE SCHEMA baiyue_lastleg");
|
|
jdbc.execute("SET SCHEMA baiyue_lastleg");
|
|
// 每次 Mapper 连接都使用相同服务库,不依赖单个连接的当前 schema。
|
|
dataSource.setUrl(dataSource.getUrl() + ";SCHEMA=baiyue_lastleg");
|
|
String ddl = commandTable(Files.readString(Path.of("src/main/resources/db/lastleg.sql")));
|
|
jdbc.execute(ddl.replace("VARCHAR(32)", "VARCHAR(16)"));
|
|
var configuration = new MybatisConfiguration();
|
|
configuration.setMapUnderscoreToCamelCase(true);
|
|
configuration.addMapper(OverseasFeeCommandMapper.class);
|
|
var factory = new MybatisSqlSessionFactoryBean();
|
|
factory.setDataSource(dataSource);
|
|
factory.setConfiguration(configuration);
|
|
factory.afterPropertiesSet();
|
|
var mapper = new SqlSessionTemplate(factory.getObject()).getMapper(OverseasFeeCommandMapper.class);
|
|
var command = new OverseasFeeCommand();
|
|
command.setId(1L);
|
|
command.setOperatorId("operator");
|
|
command.setAction("MANUAL_FUNDING_RETRY");
|
|
command.setIdempotencyKey("retry-1");
|
|
command.setRequestHash("a".repeat(64));
|
|
command.setSourceFeeId(701L);
|
|
command.setSourceVersion(1);
|
|
command.setCreatedAt(LocalDateTime.now());
|
|
assertThatThrownBy(() -> mapper.insert(command)).hasStackTraceContaining("Value too long");
|
|
|
|
String migration = Files.readString(Path.of(MIGRATION));
|
|
assertThat(migration).contains("ALTER TABLE baiyue_lastleg.ll_finance_fee_command", "MODIFY COLUMN action VARCHAR(32) NOT NULL COMMENT");
|
|
jdbc.execute(migration);
|
|
jdbc.execute(migration);
|
|
assertThat(mapper.insert(command)).isEqualTo(1);
|
|
var stored = mapper.find("operator", "MANUAL_FUNDING_RETRY", "retry-1");
|
|
assertThat(stored.getAction()).isEqualTo("MANUAL_FUNDING_RETRY");
|
|
assertThat(stored.getSourceFeeId()).isEqualTo(701L);
|
|
command.setId(2L);
|
|
assertThatThrownBy(() -> mapper.insert(command)).hasStackTraceContaining("UK_LL_FINANCE_FEE_COMMAND");
|
|
assertThat(jdbc.queryForObject("SELECT COUNT(*) FROM ll_finance_fee_command", Integer.class)).isEqualTo(1);
|
|
}
|
|
|
|
/** 仅提取费用命令实际建表定义,避免手写测试结构与正式基线脱节。 */
|
|
private static String commandTable(String sql) {
|
|
var table = Pattern.compile("CREATE TABLE(?: IF NOT EXISTS)? ll_finance_fee_command \\([\\s\\S]*?\\) ENGINE=InnoDB[^\\r\\n]*;").matcher(sql);
|
|
assertThat(table.find()).isTrue();
|
|
return table.group();
|
|
}
|
|
}
|