//go:build integration package integration import ( "context" "testing" "github.com/missionworkforce/missionmatch/internal/modules/matching/engine" ) // TestClearanceReferenceHierarchyConsistency reads clearance_levels and polygraph_types from the // live DB and asserts that for every seeded code, the rank stored in the reference table equals // the integer value of the corresponding engine enum constant. This pins the documented hierarchy // to the scored one so they can never silently diverge: if the migration seed or the engine enum // iota changes independently, the build or the validation run catches it. // // The test uses the migrator pool (BYPASSRLS) because the reference tables are global and outside // RLS, with SELECT granted to missionmatch_app, but the simplest consistent read path at test time // is through migrator. No tenant setup or org context is needed. func TestClearanceReferenceHierarchyConsistency(t *testing.T) { ctx := context.Background() // Clearance levels: expected map of code => engine int value (the iota ordinal). wantLevels := map[string]int{ "unknown": int(engine.ClearanceUnknown), "none": int(engine.ClearanceNone), "confidential": int(engine.ClearanceConfidential), "secret": int(engine.ClearanceSecret), "top_secret": int(engine.ClearanceTopSecret), "ts_sci": int(engine.ClearanceTSSCI), } rows, err := migrator.Query(ctx, "SELECT code, rank FROM clearance_levels ORDER BY rank") if err != nil { t.Fatalf("query clearance_levels: %v", err) } defer rows.Close() seen := 0 for rows.Next() { var code string var rank int32 if err := rows.Scan(&code, &rank); err != nil { t.Fatalf("scan clearance_levels row: %v", err) } wantRank, ok := wantLevels[code] if !ok { t.Errorf("clearance_levels has unexpected code %q not in engine enum", code) continue } if int(rank) != wantRank { t.Errorf("clearance_levels code %q: DB rank %d != engine enum value %d", code, rank, wantRank) } parsed, err := engine.ParseClearanceLevel(code) if err != nil { t.Errorf("engine.ParseClearanceLevel(%q) failed: %v", code, err) continue } if int(parsed) != wantRank { t.Errorf("ParseClearanceLevel(%q) returned %d, want %d", code, int(parsed), wantRank) } seen++ } if err := rows.Err(); err != nil { t.Fatalf("clearance_levels rows error: %v", err) } if seen != len(wantLevels) { t.Errorf("clearance_levels: read %d rows, want %d (missing seed rows?)", seen, len(wantLevels)) } // Polygraph types: expected map of code => engine int value. wantPolys := map[string]int{ "none": int(engine.PolyNone), "ci": int(engine.PolyCI), "full_scope": int(engine.PolyFullScope), } polyRows, err := migrator.Query(ctx, "SELECT code, rank FROM polygraph_types ORDER BY rank") if err != nil { t.Fatalf("query polygraph_types: %v", err) } defer polyRows.Close() seenPoly := 0 for polyRows.Next() { var code string var rank int32 if err := polyRows.Scan(&code, &rank); err != nil { t.Fatalf("scan polygraph_types row: %v", err) } wantRank, ok := wantPolys[code] if !ok { t.Errorf("polygraph_types has unexpected code %q not in engine enum", code) continue } if int(rank) != wantRank { t.Errorf("polygraph_types code %q: DB rank %d != engine enum value %d", code, rank, wantRank) } parsed, err := engine.ParsePolygraph(code) if err != nil { t.Errorf("engine.ParsePolygraph(%q) failed: %v", code, err) continue } if int(parsed) != wantRank { t.Errorf("ParsePolygraph(%q) returned %d, want %d", code, int(parsed), wantRank) } seenPoly++ } if err := polyRows.Err(); err != nil { t.Fatalf("polygraph_types rows error: %v", err) } if seenPoly != len(wantPolys) { t.Errorf("polygraph_types: read %d rows, want %d (missing seed rows?)", seenPoly, len(wantPolys)) } }