package engine import ( "context" "sort" "testing" ) // These expected sets MUST equal the SQL CHECK literals in db/migrations/0002_matching.sql. // If the schema changes a CHECK set, this test fails until the codes (and schema) agree again. var ( wantLevelCodes = []string{"unknown", "none", "confidential", "secret", "top_secret", "ts_sci"} wantPolyCodes = []string{"none", "ci", "full_scope"} wantStatusCodes = []string{"unknown", "active", "expired", "inactive"} wantBandCodes = []string{"green", "yellow", "red"} ) func sortedSet(m map[string]bool) []string { out := make([]string, 0, len(m)) for k := range m { out = append(out, k) } sort.Strings(out) return out } func setOf(items []string) map[string]bool { m := make(map[string]bool, len(items)) for _, it := range items { m[it] = true } return m } func assertSameSet(t *testing.T, name string, got, want map[string]bool) { t.Helper() g, w := sortedSet(got), sortedSet(want) if len(g) != len(w) { t.Fatalf("%s: code count %d != schema CHECK count %d (got %v, want %v)", name, len(g), len(w), g, w) } for _, v := range w { if !got[v] { t.Errorf("%s: schema CHECK value %q has no engine Code()", name, v) } } for _, v := range g { if !want[v] { t.Errorf("%s: engine Code() %q not in schema CHECK set", name, v) } } } func TestEnumCodesMatchSQLCheckSets(t *testing.T) { levels := map[string]bool{} for _, c := range []ClearanceLevel{ClearanceUnknown, ClearanceNone, ClearanceConfidential, ClearanceSecret, ClearanceTopSecret, ClearanceTSSCI} { levels[c.Code()] = true } assertSameSet(t, "clearance_level", levels, setOf(wantLevelCodes)) polys := map[string]bool{} for _, p := range []Polygraph{PolyNone, PolyCI, PolyFullScope} { polys[p.Code()] = true } assertSameSet(t, "clearance_poly", polys, setOf(wantPolyCodes)) statuses := map[string]bool{} for _, s := range []ClearanceStatus{StatusUnknown, StatusActive, StatusExpired, StatusInactive} { statuses[s.Code()] = true } assertSameSet(t, "clearance_status", statuses, setOf(wantStatusCodes)) bands := map[string]bool{} for _, b := range []Band{BandRed, BandYellow, BandGreen} { bands[b.Code()] = true } assertSameSet(t, "band", bands, setOf(wantBandCodes)) } func TestCodeParseRoundTrip(t *testing.T) { for _, c := range []ClearanceLevel{ClearanceUnknown, ClearanceNone, ClearanceConfidential, ClearanceSecret, ClearanceTopSecret, ClearanceTSSCI} { got, err := ParseClearanceLevel(c.Code()) if err != nil || got != c { t.Errorf("clearance level round-trip failed for %v: got %v err %v", c, got, err) } } for _, p := range []Polygraph{PolyNone, PolyCI, PolyFullScope} { got, err := ParsePolygraph(p.Code()) if err != nil || got != p { t.Errorf("poly round-trip failed for %v: got %v err %v", p, got, err) } } for _, s := range []ClearanceStatus{StatusUnknown, StatusActive, StatusExpired, StatusInactive} { got, err := ParseClearanceStatus(s.Code()) if err != nil || got != s { t.Errorf("status round-trip failed for %v: got %v err %v", s, got, err) } } for _, b := range []Band{BandRed, BandYellow, BandGreen} { got, err := ParseBand(b.Code()) if err != nil || got != b { t.Errorf("band round-trip failed for %v: got %v err %v", b, got, err) } } } func TestParseRejectsUnknownCodes(t *testing.T) { if _, err := ParseClearanceLevel("tssci"); err == nil { // wrong spelling (no underscore) t.Error("ParseClearanceLevel must reject 'tssci'") } if _, err := ParseBand("Green"); err == nil { // String() label, not a Code() t.Error("ParseBand must reject the human label 'Green'") } if _, err := ParsePolygraph("polygraph"); err == nil { t.Error("ParsePolygraph must reject garbage") } } // Locks SQLC-1's invariant: no component or total can exceed the numeric(7,4) CHECK range [0,100]. func TestAllScoresWithinZeroToHundred(t *testing.T) { reqs := []Requirement{ perfectRequirement(), {ID: "r-empty"}, // nothing required {ID: "r-ts", RequiredLevel: ClearanceTSSCI, RequiredPoly: PolyFullScope, RequiredYears: 20, RequiredSkills: []RequiredSkill{{SkillID: "x", Name: "X", Mandatory: true}}, RequiredCerts: []string{"CISSP"}, CustomerAgency: "NSA", WorkLocation: "Remote"}, } cands := []Candidate{perfectCandidate(), {ID: "c-empty"}} for _, r := range reqs { for _, c := range cands { res := ScoreCandidate(context.Background(), c, r, nil) for _, comp := range res.Trace { if comp.Raw.IsNegative() || comp.Raw.GreaterThan(hundred) { t.Fatalf("%s raw %s out of [0,100] (cand %s, req %s)", comp.Component, comp.Raw, c.ID, r.ID) } } if res.Total.IsNegative() || res.Total.GreaterThan(hundred) { t.Fatalf("total %s out of [0,100] (cand %s, req %s)", res.Total, c.ID, r.ID) } } } }