From 5352b6155f7baa772ee676b505cc429976f7d854 Mon Sep 17 00:00:00 2001
From: Paul Duncan <pabs@pablotron.org>
Date: Tue, 1 Feb 2022 13:57:27 -0500
Subject: internal/feed: add v2accessvector, v2accessvector tests

---
 internal/feed/feed.go                  | 33 --------------
 internal/feed/v2accessvector.go        | 42 ++++++++++++++++++
 internal/feed/v2accessvector_string.go | 25 +++++++++++
 internal/feed/v2accessvector_test.go   | 79 ++++++++++++++++++++++++++++++++++
 4 files changed, 146 insertions(+), 33 deletions(-)
 create mode 100644 internal/feed/v2accessvector.go
 create mode 100644 internal/feed/v2accessvector_string.go
 create mode 100644 internal/feed/v2accessvector_test.go

(limited to 'internal')

diff --git a/internal/feed/feed.go b/internal/feed/feed.go
index 40e385d..aa5fd08 100644
--- a/internal/feed/feed.go
+++ b/internal/feed/feed.go
@@ -21,39 +21,6 @@ const (
 
 // TODO: parse cpe
 
-type V2AccessVector byte
-
-const (
-  V2AVAdjacentNetwork V2AccessVector = iota
-  V2AVLocal
-  V2AVNetwork
-)
-
-// Unmarshal CVSS V2 access vector from JSON.
-func (me *V2AccessVector) UnmarshalJSON(b []byte) error {
-  // decode string, check for error
-  var s string
-  if err := json.Unmarshal(b, &s); err != nil {
-    return err
-  }
-
-  // check value
-  switch s {
-  case "ADJACENT_NETWORK":
-    *me = V2AVAdjacentNetwork
-  case "LOCAL":
-    *me = V2AVLocal
-  case "NETWORK":
-    *me = V2AVNetwork
-  default:
-    // return error
-    return fmt.Errorf("unknown CVSS v2 access vector: %s", s)
-  }
-
-  // return success
-  return nil
-}
-
 // CVSS V2 attack complexity
 type AccessComplexity int
 
diff --git a/internal/feed/v2accessvector.go b/internal/feed/v2accessvector.go
new file mode 100644
index 0000000..80490c2
--- /dev/null
+++ b/internal/feed/v2accessvector.go
@@ -0,0 +1,42 @@
+package feed
+
+//go:generate stringer -linecomment -type=V2AccessVector
+
+import (
+  "encoding/json"
+  "fmt"
+)
+
+type V2AccessVector byte
+
+const (
+  V2AVAdjacentNetwork V2AccessVector = iota // ADJACENT_NETWORK
+  V2AVLocal // LOCAL
+  V2AVNetwork // NETWORK
+)
+
+// Unmarshal CVSS V2 access vector from JSON.
+func (me *V2AccessVector) UnmarshalJSON(b []byte) error {
+  // decode string, check for error
+  var s string
+  if err := json.Unmarshal(b, &s); err != nil {
+    return err
+  }
+
+  // check value
+  switch s {
+  case "ADJACENT_NETWORK":
+    *me = V2AVAdjacentNetwork
+  case "LOCAL":
+    *me = V2AVLocal
+  case "NETWORK":
+    *me = V2AVNetwork
+  default:
+    // return error
+    return fmt.Errorf("unknown CVSS v2 access vector: %s", s)
+  }
+
+  // return success
+  return nil
+}
+
diff --git a/internal/feed/v2accessvector_string.go b/internal/feed/v2accessvector_string.go
new file mode 100644
index 0000000..bf354fc
--- /dev/null
+++ b/internal/feed/v2accessvector_string.go
@@ -0,0 +1,25 @@
+// Code generated by "stringer -linecomment -type=V2AccessVector"; DO NOT EDIT.
+
+package feed
+
+import "strconv"
+
+func _() {
+	// An "invalid array index" compiler error signifies that the constant values have changed.
+	// Re-run the stringer command to generate them again.
+	var x [1]struct{}
+	_ = x[V2AVAdjacentNetwork-0]
+	_ = x[V2AVLocal-1]
+	_ = x[V2AVNetwork-2]
+}
+
+const _V2AccessVector_name = "ADJACENT_NETWORKLOCALNETWORK"
+
+var _V2AccessVector_index = [...]uint8{0, 16, 21, 28}
+
+func (i V2AccessVector) String() string {
+	if i >= V2AccessVector(len(_V2AccessVector_index)-1) {
+		return "V2AccessVector(" + strconv.FormatInt(int64(i), 10) + ")"
+	}
+	return _V2AccessVector_name[_V2AccessVector_index[i]:_V2AccessVector_index[i+1]]
+}
diff --git a/internal/feed/v2accessvector_test.go b/internal/feed/v2accessvector_test.go
new file mode 100644
index 0000000..6e0df24
--- /dev/null
+++ b/internal/feed/v2accessvector_test.go
@@ -0,0 +1,79 @@
+package feed
+
+import (
+  "encoding/json"
+  "testing"
+)
+
+func TestV2AccessVectorUnmarshalInvalidData(t *testing.T) {
+  test := []byte(`{}`)
+  var val V2AccessVector
+
+  if err := json.Unmarshal(test, &val); err == nil {
+    t.Errorf("got \"%s\", exp error", val)
+  }
+}
+
+func TestV2AccessVectorUnmarshalUnknown(t *testing.T) {
+  test := []byte(`"foo"`)
+  exp := "unknown CVSS v2 access vector: foo"
+  var val V2AccessVector
+
+  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 TestV2AccessVectorUnmarshalValid(t *testing.T) {
+  tests := []struct {
+    val string
+    exp V2AccessVector
+  } {
+    { "\"ADJACENT_NETWORK\"", V2AVAdjacentNetwork },
+    { "\"LOCAL\"", V2AVLocal },
+    { "\"NETWORK\"", V2AVNetwork },
+  }
+
+  for _, test := range(tests) {
+    t.Run(test.val, func(t *testing.T) {
+      var got V2AccessVector
+      if err := json.Unmarshal([]byte(test.val), &got); err != nil {
+        t.Error(err)
+        return
+      }
+
+      if got != test.exp {
+        t.Errorf("got \"%s\", exp \"%s\"", got, test.exp)
+      }
+    })
+  }
+}
+
+func TestV2AccessVectorString(t *testing.T) {
+  tests := []struct {
+    val V2AccessVector
+    exp string
+  } {
+    { V2AVAdjacentNetwork, "ADJACENT_NETWORK" },
+    { V2AVLocal, "LOCAL" },
+    { V2AVNetwork, "NETWORK" },
+
+    { V2AccessVector(255), "V2AccessVector(255)" },
+  }
+
+  for _, test := range(tests) {
+    t.Run(test.exp, func(t *testing.T) {
+      got := test.val.String()
+
+      if got != test.exp {
+        t.Errorf("got \"%s\", exp \"%s\"", got, test.exp)
+      }
+    })
+  }
+}
-- 
cgit v1.2.3