package bls import ( "context" "strings" "testing" ) // TestParseDetailedOccupationsKeepsOnlyDisplayLevel3 pins the oe.occupation parser: given a tab delimited // flat file with a header row, aggregate roll up rows (display level 0, 1, 2), and detailed SOC rows // (display level 3), it keeps ONLY the detailed occupations and captures the six digit SOC and the OEWS // title. A malformed short row and a blank row are skipped rather than failing the parse. func TestParseDetailedOccupationsKeepsOnlyDisplayLevel3(t *testing.T) { // Columns: occupation_code, occupation_name, occupation_description, display_level, selectable, sort_sequence. flat := strings.Join([]string{ "occupation_code\toccupation_name\toccupation_description\tdisplay_level\tselectable\tsort_sequence", "000000\tAll Occupations\tAll occupations rollup\t0\tT\t1", "110000\tManagement Occupations\tManagement rollup\t1\tT\t2", "113021\tComputer and Information Systems Managers\tManage computer systems\t3\tT\t10", "150000\tComputer and Mathematical Occupations\tComputer rollup\t2\tT\t20", "151212\tInformation Security Analysts\tPlan security measures\t3\tT\t30", "151252\tSoftware Developers\tDevelop software\t3\tT\t40", "", // a blank row must be skipped "999999\tShort Row", // a malformed short row must be skipped, not crash }, "\n") occs, err := ParseDetailedOccupations(strings.NewReader(flat)) if err != nil { t.Fatalf("parse occupation list: %v", err) } if len(occs) != 3 { t.Fatalf("only the three display level 3 rows are detailed SOCs, got %d: %+v", len(occs), occs) } want := map[string]string{ "113021": "Computer and Information Systems Managers", "151212": "Information Security Analysts", "151252": "Software Developers", } for _, o := range occs { title, ok := want[o.SOC] if !ok { t.Errorf("unexpected SOC kept: %q", o.SOC) continue } if o.Title != title { t.Errorf("SOC %q title = %q, want %q", o.SOC, o.Title, title) } } // The header row, the rollups, the blank, and the short row must never appear. for _, o := range occs { if o.SOC == "occupation_code" || o.SOC == "000000" || o.SOC == "110000" || o.SOC == "150000" || o.SOC == "999999" { t.Errorf("a non detailed row leaked into the result: %q", o.SOC) } } } // TestFetchDetailedOccupationsRequiresUserAgent proves the download refuses an empty User Agent before any // request is made, since BLS returns 403 to a default or empty User Agent. No network is touched. func TestFetchDetailedOccupationsRequiresUserAgent(t *testing.T) { if _, err := FetchDetailedOccupations(context.Background(), nil, "http://example.invalid", ""); err == nil { t.Fatal("an empty User Agent must be rejected before the BLS request") } }