package feed import ( "encoding/json" "fmt" "strconv" "testing" ) func TestParseCveIdYear(t *testing.T) { if got, err := parseCveIdYear("asdf"); err == nil { t.Errorf("got %d, exp error", got) return } goodTests := []struct { val string exp uint16 } { { "2000", 2000 }, { "2001", 2001 }, { "2100", 2100 }, } for _, test := range(goodTests) { t.Run(test.val, func(t *testing.T) { got, err := parseCveIdYear(test.val) if err != nil { t.Error(err) return } if got != test.exp { t.Errorf("got %d, exp %d", got, test.exp) return } }) } badTests := []struct { val string exp string } { { "0000", "year out of bounds: 0000" }, { "0001", "year out of bounds: 0001" }, { "1998", "year out of bounds: 1998" }, { "2128", "year out of bounds: 2128" }, { "9999", "year out of bounds: 9999" }, } for _, test := range(badTests) { t.Run(test.val, func(t *testing.T) { if got, err := parseCveIdYear(test.val); err == nil { t.Errorf("got %d, exp error", got) return } else if err.Error() != test.exp { t.Errorf("got \"%s\", exp \"%s\"", err.Error(), test.exp) } }) } } func TestParseCveIdNum(t *testing.T) { if got, err := parseCveIdNum("asdf"); err == nil { t.Errorf("got %d, exp error", got) return } goodTests := []struct { val string exp uint32 } { { "0", 0 }, { "0001", 1 }, { "2100", 2100 }, { "999999", 999999 }, { "33554431", 33554431 }, } for _, test := range(goodTests) { t.Run(test.val, func(t *testing.T) { got, err := parseCveIdNum(test.val) if err != nil { t.Error(err) return } if got != test.exp { t.Errorf("got %d, exp %d", got, test.exp) return } }) } badTests := []struct { val string exp string } { { "33554432", "number out of bounds: 33554432" }, { "99999999", "number out of bounds: 99999999" }, } for _, test := range(badTests) { t.Run(test.val, func(t *testing.T) { if got, err := parseCveIdNum(test.val); err == nil { t.Errorf("got %d, exp error", got) } else if err.Error() != test.exp { t.Errorf("got \"%s\", exp \"%s\"", err.Error(), test.exp) } }) } } func TestNewCveId(t *testing.T) { badMatchTests := []string { "", "\nCVE-2002-1234", "CVE-2002-1234\n", "CVE20021234\n", "asdf", } for _, test := range(badMatchTests) { t.Run(test, func(t *testing.T) { exp := fmt.Sprintf("invalid CVE ID: %s", test) if got, err := NewCveId(test); err == nil { t.Errorf("got %s, exp error", got) } else if err.Error() != exp { t.Errorf("got \"%s\", exp \"%s\"", err.Error(), exp) } }) } badYearTests := []struct { val string exp string } { { "CVE-0000-1234", "year out of bounds: 0000" }, { "CVE-1998-1234", "year out of bounds: 1998" }, { "CVE-2128-1234", "year out of bounds: 2128" }, { "CVE-9999-1234", "year out of bounds: 9999" }, } for _, test := range(badYearTests) { t.Run(test.val, func(t *testing.T) { if got, err := NewCveId(test.val); err == nil { t.Errorf("got %s, exp error", got) } else if err.Error() != test.exp { t.Errorf("got \"%s\", exp \"%s\"", err.Error(), test.exp) } }) } badNumTests := []struct { val string exp string } { { "CVE-2000-33554432", "number out of bounds: 33554432" }, { "CVE-2000-99999999", "number out of bounds: 99999999" }, } for _, test := range(badNumTests) { t.Run(test.val, func(t *testing.T) { if got, err := NewCveId(test.val); err == nil { t.Errorf("got %s, exp error", got) } else if err.Error() != test.exp { t.Errorf("got \"%s\", exp \"%s\"", err.Error(), test.exp) } }) } goodTests := []string { "CVE-1999-0", "CVE-2126-0", "CVE-1999-33554431", "CVE-2126-33554431", } for _, val := range(goodTests) { t.Run(val, func(t *testing.T) { if _, err := NewCveId(val); err != nil { t.Error(err) } }) } } func TestCveIdYear(t *testing.T) { for year := 1999; year < 2126; year++ { t.Run(strconv.FormatInt(int64(year), 10), func(t *testing.T) { // expected value exp := uint16(year) // build cve id, check for error id, err := NewCveId(fmt.Sprintf("CVE-%04d-0000", year)) if err != nil { t.Error(err) return } // check year got := id.Year() if got != exp { t.Errorf("got %d, exp %d", got, exp) } }) } } func TestCveIdNumber(t *testing.T) { for num := 0; num < 99999; num++ { t.Run(strconv.FormatInt(int64(num), 10), func(t *testing.T) { // expected value exp := uint32(num) // build cve id, check for error id, err := NewCveId(fmt.Sprintf("CVE-2000-%04d", num)) if err != nil { t.Error(err) return } // check number got := id.Number() if got != exp { t.Errorf("got %d, exp %d", got, exp) } }) } } func TestCveIdUnmarshalInvalidData(t *testing.T) { test := []byte(`{}`) var val CveId if err := json.Unmarshal(test, &val); err == nil { t.Errorf("got \"%s\", exp error", val) } } func TestCveIdUnmarshalUnknown(t *testing.T) { test := []byte(`"foo"`) exp := "invalid CVE ID: foo" var val CveId err := json.Unmarshal(test, &val) if err == nil { t.Errorf("got \"%s\", exp error", val) return } if err.Error() != exp { t.Errorf("got \"%s\", exp \"%s\"", err.Error(), exp) } } func TestCveIdUnmarshalValid(t *testing.T) { tests := []struct { val string expYear uint16 expNum uint32 exp string } { { "\"CVE-1999-0\"", 1999, 0, "CVE-1999-0000" }, { "\"CVE-1999-1234\"", 1999, 1234, "CVE-1999-1234" }, { "\"CVE-1999-33554431\"", 1999, 33554431, "CVE-1999-33554431" }, { "\"CVE-2126-0\"", 2126, 0, "CVE-2126-0000" }, { "\"CVE-2126-1234\"", 2126, 1234, "CVE-2126-1234" }, { "\"CVE-2126-33554431\"", 2126, 33554431, "CVE-2126-33554431" }, } for _, test := range(tests) { t.Run(test.val, func(t *testing.T) { var got CveId if err := json.Unmarshal([]byte(test.val), &got); err != nil { t.Error(err) return } // check year if got.Year() != test.expYear { t.Errorf("got \"%d\", exp \"%d\"", got.Year(), test.expYear) } // check year if got.Number() != test.expNum { t.Errorf("got \"%d\", exp \"%d\"", got.Number(), test.expNum) } // check string if got.String() != test.exp { t.Errorf("got \"%s\", exp \"%s\"", got.String(), test.exp) } }) } }