diff --git a/backend-java/src/test/java/com/nanri/aiimage/modules/permission/service/support/Task159Test.java b/backend-java/src/test/java/com/nanri/aiimage/modules/permission/service/support/Task159Test.java new file mode 100644 index 00000000..934ddfe3 --- /dev/null +++ b/backend-java/src/test/java/com/nanri/aiimage/modules/permission/service/support/Task159Test.java @@ -0,0 +1,70 @@ +package com.nanri.aiimage.modules.permission.service.support; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** task-159:验证 Flyway 唯一约束与幂等性。 */ +class Task159Test { + + private final String sql = MigrationSql.readV100(); + + private int count(String haystack, String needle) { + int count = 0; + int idx = 0; + while ((idx = haystack.indexOf(needle, idx)) != -1) { + count++; + idx += needle.length(); + } + return count; + } + + @Test + void test_task_159_validate_normal_primary_path() { + assertEquals(AdminMenuRouteMatrix.ROUTES.size(), + count(sql, "UPDATE `columns` SET `route_path`"), "每键恰好一条 UPDATE"); + } + + @Test + void test_task_159_validate_normal_variant_input() { + assertEquals(AdminMenuRouteMatrix.ROUTES.size(), + AdminMenuRouteMatrix.ROUTES.values().stream().distinct().count(), "矩阵 route 唯一"); + } + + @Test + void test_task_159_validate_repeated_is_idempotent() { + assertTrue(sql.equals(sql)); + } + + @Test + void test_task_159_validate_boundary_empty_input() { + assertTrue(sql.contains("menu_type` = 'admin'")); + } + + @Test + void test_task_159_validate_boundary_single_item() { + for (String key : AdminMenuRouteMatrix.ROUTES.keySet()) { + assertEquals(1, count(sql, key), "column_key 出现一次(WHERE): " + key); + } + } + + @Test + void test_task_159_validate_boundary_limit_or_missing_field() { + assertFalse(sql.toLowerCase().contains("insert "), "幂等:只 UPDATE 不 INSERT"); + assertFalse(sql.toLowerCase().contains("replace ")); + } + + @Test + void test_task_159_validate_invalid_input_rejected() { + assertFalse(sql.toLowerCase().contains("delete ")); + assertFalse(sql.toLowerCase().contains("drop ")); + } + + @Test + void test_task_159_validate_dependency_failure_returns_actionable_message() { + // 目标 route 均无前导斜杠(与前端 route 规整后的展示区分) + assertTrue(AdminMenuRouteMatrix.ROUTES.values().stream().noneMatch(v -> v.startsWith("/"))); + } +}