diff --git a/backend-java/src/test/java/com/nanri/aiimage/config/FlywayMigrationTemplateDocTest.java b/backend-java/src/test/java/com/nanri/aiimage/config/FlywayMigrationTemplateDocTest.java new file mode 100644 index 00000000..8f8a8baa --- /dev/null +++ b/backend-java/src/test/java/com/nanri/aiimage/config/FlywayMigrationTemplateDocTest.java @@ -0,0 +1,76 @@ +package com.nanri.aiimage.config; + +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * task-192:迁移规范模板契约。 + * docs/flyway-migration-template.md 存在且六项必填(目的/影响表与数据量/锁表风险/验证 SQL/ + * 回滚步骤/上线窗口)齐全,含示例 SQL,可被新迁移文件头注释引用。 + */ +class FlywayMigrationTemplateDocTest { + + private static final String DOC = "docs/flyway-migration-template.md"; + + private String doc() throws IOException { + return Files.readString(Path.of(System.getProperty("user.dir"), DOC)); + } + + @Test + void templateExists() throws IOException { + assertTrue(Files.exists(Path.of(System.getProperty("user.dir"), DOC)), "模板文件应存在"); + } + + @Test + void sixMandatoryFieldsPresent() throws IOException { + String text = doc(); + for (int i = 1; i <= 6; i++) { + assertTrue(text.contains(i + ". "), "头注释应含第 " + i + " 项必填"); + } + } + + @Test + void fieldNamesListed() throws IOException { + String text = doc(); + assertTrue(text.contains("变更目的")); + assertTrue(text.contains("影响表与数据量")); + assertTrue(text.contains("锁表风险")); + assertTrue(text.contains("验证 SQL")); + assertTrue(text.contains("回滚步骤")); + assertTrue(text.contains("上线窗口")); + } + + @Test + void hasCopyableHeaderComment() throws IOException { + assertTrue(doc().contains("复制以下头注释"), "模板应提供可复制头注释"); + assertTrue(doc().contains("V{N+1}__"), "头注释示例应含占位版本号"); + } + + @Test + void hasValidationSqlExample() throws IOException { + assertTrue(doc().contains("SELECT COUNT(*)"), "应含验证 SQL 示例"); + } + + @Test + void hasRollbackField() throws IOException { + assertTrue(doc().contains("回滚步骤"), "应含回滚步骤说明"); + } + + @Test + void hasUpgradeWindowField() throws IOException { + assertTrue(doc().contains("上线窗口"), "应含上线窗口说明"); + } + + @Test + void templateUsableByNewMigrations() throws IOException { + String text = doc(); + assertTrue(text.contains("src/main/resources/db/"), "应说明迁移文件目录"); + assertTrue(text.contains("只追加"), "应强调只追加不改历史"); + assertTrue(text.contains("V109") || text.contains("最大现有版本"), "应说明版本号取最大现有版本+1"); + } +}