//go:build integration // 集成测试:公开只读视图(public_brand_runways / public_street_snaps)不得暴露审核/溯源列 // (job_id / reviewer / reject_reason)。设计规格 I2:视图列集已显式枚举,刻意排除这些列, // 使基表加列时敏感列不会无意泄露到公开读路径。 // // 运行:go test -tags integration ./internal/repository/ -run TestPublicViewsExcludeSensitiveColumns -v package repository import ( "testing" ) // TestPublicViewsExcludeSensitiveColumns 断言两个主表公开视图不含敏感列。 func TestPublicViewsExcludeSensitiveColumns(t *testing.T) { db := testDB(t) applyMigration(t, db, "2026-09-22-01-single-table-publish.sql") type v struct { view, col string } cases := []v{} for _, view := range []string{"public_brand_runways", "public_street_snaps"} { for _, col := range []string{"job_id", "reviewer", "reject_reason"} { cases = append(cases, v{view, col}) } } for _, c := range cases { var cnt int64 if err := db.Raw( `SELECT count(*) FROM information_schema.columns WHERE table_name = ? AND column_name = ?`, c.view, c.col, ).Scan(&cnt).Error; err != nil { t.Fatalf("查 information_schema 失败: %v", err) } if cnt != 0 { t.Errorf("公开视图 %s 不应暴露敏感列 %s", c.view, c.col) } } } // TestPublicViewsKeepNeededColumns 断言公开视图仍含对外必需的列(回归保护,避免收窄时误删)。 func TestPublicViewsKeepNeededColumns(t *testing.T) { db := testDB(t) applyMigration(t, db, "2026-09-22-01-single-table-publish.sql") keep := map[string][]string{ "public_brand_runways": {"id", "brand_id", "title_en", "cover", "image_count", "year", "season_code", "status"}, "public_street_snaps": {"id", "title", "title_cn", "city", "cover", "image_count", "year", "status"}, } for view, cols := range keep { for _, col := range cols { var cnt int64 if err := db.Raw( `SELECT count(*) FROM information_schema.columns WHERE table_name = ? AND column_name = ?`, view, col, ).Scan(&cnt).Error; err != nil { t.Fatalf("查 information_schema 失败: %v", err) } if cnt != 1 { t.Errorf("公开视图 %s 必须含列 %s(收窄时误删)", view, col) } } } }