package adapters import ( "testing" "github.com/missionworkforce/missionmatch/internal/modules/ontology" ) // niceFixture is a minimal NICE components JSON shaped exactly like the real v2-2-0 file. // It contains one work_role element and one task element plus structural types that the parser // must ignore (sort, category, competency_area, opm_code). const niceFixture = `{ "documents": [ { "doc_identifier": "SP_800_181_2_2_0", "name": "Workforce Framework for Cybersecurity (NICE Framework) (NIST SP 800-181 Rev 1)", "version": "2.2.0", "website": "https://csrc.nist.gov/pubs/sp/800/181/r1/final" } ], "relationship_types": [ { "relationship_identifier": "projection", "description": "Represents a relationship between two elements." } ], "elements": [ { "element_type": "sort", "element_identifier": "S-OG", "title": "00001", "text": "", "doc_identifier": "SP_800_181_2_2_0" }, { "element_type": "category", "element_identifier": "OG", "title": "OVERSIGHT and GOVERNANCE", "text": "Provides leadership, management, direction, or development and advocacy so the organization may effectively conduct cybersecurity work.", "doc_identifier": "SP_800_181_2_2_0" }, { "element_type": "work_role", "element_identifier": "OG-WRL-017", "title": "Cybersecurity Supply Chain Risk Management", "text": "Responsible for developing cybersecurity supply chain risk management policies and procedures.", "doc_identifier": "SP_800_181_2_2_0" }, { "element_type": "competency_area", "element_identifier": "NF-COM-001", "title": "AI Security", "text": "Applies knowledge of AI concepts to secure systems.", "doc_identifier": "SP_800_181_2_2_0" }, { "element_type": "task", "element_identifier": "T0006", "title": "", "text": "Advocate organization's official position in legal and legislative proceedings", "doc_identifier": "SP_800_181_2_2_0" }, { "element_type": "knowledge", "element_identifier": "K0018", "title": "", "text": "Knowledge of encryption algorithms", "doc_identifier": "SP_800_181_2_2_0" }, { "element_type": "skill", "element_identifier": "S0011", "title": "", "text": "Skill in conducting information searches", "doc_identifier": "SP_800_181_2_2_0" }, { "element_type": "opm_code", "element_identifier": "2210", "title": "Information Technology Management", "text": "", "doc_identifier": "SP_800_181_2_2_0" } ] }` func TestParseNICE(t *testing.T) { recs, err := parseNICE([]byte(niceFixture)) if err != nil { t.Fatalf("parseNICE returned an error: %v", err) } // Expect 4 records: one work_role + three TKS (task, knowledge, skill). // sort, category, competency_area, and opm_code must be skipped. if len(recs) != 4 { t.Fatalf("want 4 records (1 work_role + 3 TKS), got %d: %+v", len(recs), recs) } // Index by SourceRecordID for order-independent assertions. byID := make(map[string]ontology.VocabRecord, len(recs)) for _, r := range recs { byID[r.SourceRecordID] = r } // Work role assertions. wr, ok := byID["OG-WRL-017"] if !ok { t.Fatal("expected a record with SourceRecordID OG-WRL-017") } if wr.Kind != ontology.KindWorkRole { t.Errorf("work_role: want Kind %q, got %q", ontology.KindWorkRole, wr.Kind) } if wr.Term != "Cybersecurity Supply Chain Risk Management" { t.Errorf("work_role: wrong Term %q", wr.Term) } if wr.Code != "OG-WRL-017" { t.Errorf("work_role: wrong Code %q", wr.Code) } if wr.SourceName != "NICE Framework" { t.Errorf("work_role: wrong SourceName %q", wr.SourceName) } if wr.Category != "work_role" { t.Errorf("work_role: wrong Category %q", wr.Category) } // Task assertions. tk, ok := byID["T0006"] if !ok { t.Fatal("expected a record with SourceRecordID T0006") } if tk.Kind != ontology.KindKSA { t.Errorf("task: want Kind %q, got %q", ontology.KindKSA, tk.Kind) } if tk.Term != "Advocate organization's official position in legal and legislative proceedings" { t.Errorf("task: wrong Term %q", tk.Term) } if tk.Category != "task" { t.Errorf("task: wrong Category %q", tk.Category) } // Knowledge assertions. kn, ok := byID["K0018"] if !ok { t.Fatal("expected a record with SourceRecordID K0018") } if kn.Kind != ontology.KindKSA { t.Errorf("knowledge: want Kind %q, got %q", ontology.KindKSA, kn.Kind) } if kn.Term != "Knowledge of encryption algorithms" { t.Errorf("knowledge: wrong Term %q", kn.Term) } if kn.Category != "knowledge" { t.Errorf("knowledge: wrong Category %q", kn.Category) } // Skill assertions. sk, ok := byID["S0011"] if !ok { t.Fatal("expected a record with SourceRecordID S0011") } if sk.Kind != ontology.KindKSA { t.Errorf("skill: want Kind %q, got %q", ontology.KindKSA, sk.Kind) } if sk.Term != "Skill in conducting information searches" { t.Errorf("skill: wrong Term %q", sk.Term) } if sk.Category != "skill" { t.Errorf("skill: wrong Category %q", sk.Category) } }