package samgov import ( "encoding/json" "testing" ) const galapagosNotice = `{ "noticeId": "abc123", "title": "Cyber Defense Engineering Support", "solicitationNumber": "FA8773-26-R-0001", "fullParentPathName": "DEPT OF DEFENSE.DEPT OF THE AIR FORCE.AIR FORCE MATERIEL COMMAND", "fullParentPathCode": "057.5700.FA8773", "postedDate": "2026-05-01", "type": "Solicitation", "baseType": "Combined Synopsis/Solicitation", "typeOfSetAside": "8A", "typeOfSetAsideDescription": "8(a) Set-Aside", "responseDeadLine": "2026-06-15T17:00:00-05:00", "naicsCode": "541512", "classificationCode": "D310", "active": "Yes", "description": "https://api.sam.gov/prod/opportunities/v1/noticedesc?noticeid=abc123", "uiLink": "https://sam.gov/opp/abc123/view", "resourceLinks": ["https://sam.gov/api/prod/opps/v3/opportunities/resources/files/x/download"], "pointOfContact": [{"type":"primary","fullName":"Jane Doe","email":"jane@us.af.mil"}], "placeOfPerformance": {"city":{"name":"Honolulu"},"state":{"code":"HI"},"zip":"96853"} }` func recordFrom(t *testing.T, s string) Record { t.Helper() raw := json.RawMessage(s) var op Opportunity if err := json.Unmarshal(raw, &op); err != nil { t.Fatalf("unmarshal: %v", err) } return Record{Op: op, Raw: raw} } func TestNormalizeMapsGalapagosNotice(t *testing.T) { n := Normalize(recordFrom(t, galapagosNotice)) if n.NoticeID != "abc123" || n.Title != "Cyber Defense Engineering Support" { t.Fatalf("id/title wrong: %+v", n) } if n.Department != "DEPT OF DEFENSE" { t.Fatalf("department should be first dotted segment, got %q", n.Department) } if n.SubAgency != "AIR FORCE" { t.Fatalf("sub-agency should normalize to AIR FORCE, got %q", n.SubAgency) } if n.NaicsCode != "541512" || n.PSCCode != "D310" { t.Fatalf("naics/psc wrong: %q / %q", n.NaicsCode, n.PSCCode) } if n.SetAsideCode != "8A" || n.SetAside != "8(a) Set-Aside" { t.Fatalf("set-aside wrong: %q / %q", n.SetAsideCode, n.SetAside) } if !n.Active { t.Fatal("active 'Yes' must map to true") } if n.POPState != "HI" || n.POPCity != "Honolulu" { t.Fatalf("place of performance wrong: %q %q", n.POPCity, n.POPState) } if n.PostedDate == nil || n.PostedDate.Format("2006-01-02") != "2026-05-01" { t.Fatalf("posted date not parsed: %v", n.PostedDate) } if n.ResponseDeadline == nil || n.ResponseDeadline.Year() != 2026 { t.Fatalf("response deadline not parsed: %v", n.ResponseDeadline) } if n.DescriptionURL == "" || n.UILink == "" { t.Fatalf("description/ui link missing: %+v", n) } if string(n.Raw) == "" || string(n.Raw) == "{}" { t.Fatal("raw must hold the full notice JSON") } // resource_links + poc must be valid non-null JSON arrays. var rl []string if err := json.Unmarshal(n.ResourceLinks, &rl); err != nil || len(rl) != 1 { t.Fatalf("resource links not a 1-element array: %v %s", err, n.ResourceLinks) } } func TestNormalizeSpaceForceAndInactive(t *testing.T) { n := Normalize(recordFrom(t, `{ "noticeId":"z9","fullParentPathName":"DEPT OF DEFENSE.DEPT OF THE AIR FORCE.UNITED STATES SPACE FORCE", "active":"No","naicsCode":"541513"}`)) if n.SubAgency != "SPACE FORCE" { t.Fatalf("space force must win over air force substring, got %q", n.SubAgency) } if n.Active { t.Fatal("active 'No' must map to false") } } func TestNormalizeEmptyArraysNeverNull(t *testing.T) { n := Normalize(recordFrom(t, `{"noticeId":"e1","active":"Yes"}`)) if string(n.ResourceLinks) != "[]" || string(n.POC) != "[]" { t.Fatalf("empty arrays must be '[]', got %s / %s", n.ResourceLinks, n.POC) } if string(n.Raw) == "" { t.Fatal("raw must never be empty") } }