Cybersecurity-Projects/PROJECTS/intermediate/security-news-scraper/internal/tui/format_test.go

174 lines
4.1 KiB
Go

// ©AngelaMos | 2026
// format_test.go
package tui
import (
"testing"
"time"
"github.com/CarterPerez-dev/nadezhda/internal/store"
)
func ptr(v float64) *float64 { return &v }
func TestCVSSBand(t *testing.T) {
cases := []struct {
in *float64
want band
}{
{nil, bandNone},
{ptr(0), bandNone},
{ptr(3.9), bandLow},
{ptr(4.0), bandMedium},
{ptr(6.9), bandMedium},
{ptr(7.0), bandHigh},
{ptr(8.9), bandHigh},
{ptr(9.0), bandCritical},
{ptr(10.0), bandCritical},
}
for _, c := range cases {
if got := cvssBand(c.in); got != c.want {
t.Errorf("cvssBand(%v) = %v, want %v", c.in, got, c.want)
}
}
}
func TestEPSSBand(t *testing.T) {
cases := []struct {
in *float64
want band
}{
{nil, bandNone},
{ptr(0), bandNone},
{ptr(0.05), bandMedium},
{ptr(0.1), bandHigh},
{ptr(0.49), bandHigh},
{ptr(0.5), bandCritical},
{ptr(0.97), bandCritical},
}
for _, c := range cases {
if got := epssBand(c.in); got != c.want {
t.Errorf("epssBand(%v) = %v, want %v", c.in, got, c.want)
}
}
}
func TestBandLabel(t *testing.T) {
cases := map[band]string{
bandCritical: "CRITICAL",
bandHigh: "HIGH",
bandMedium: "MEDIUM",
bandLow: "LOW",
bandNone: naMarker,
}
for b, want := range cases {
if got := bandLabel(b); got != want {
t.Errorf("bandLabel(%v) = %q, want %q", b, got, want)
}
}
}
func TestCVSSString(t *testing.T) {
if got := cvssString(nil); got != naMarker {
t.Errorf("cvssString(nil) = %q, want %q", got, naMarker)
}
if got := cvssString(ptr(9.8)); got != "9.8" {
t.Errorf("cvssString(9.8) = %q, want 9.8", got)
}
if got := cvssString(ptr(10)); got != "10.0" {
t.Errorf("cvssString(10) = %q, want 10.0", got)
}
}
func TestEPSSString(t *testing.T) {
if got := epssString(nil); got != naMarker {
t.Errorf("epssString(nil) = %q, want %q", got, naMarker)
}
if got := epssString(ptr(0.5)); got != "50.0%" {
t.Errorf("epssString(0.5) = %q, want 50.0%%", got)
}
if got := epssString(ptr(0.001)); got != "0.1%" {
t.Errorf("epssString(0.001) = %q, want 0.1%%", got)
}
}
func TestRelativeAge(t *testing.T) {
now := time.Unix(1_000_000, 0)
cases := []struct {
unix int64
want string
}{
{0, naMarker},
{now.Unix() + 100, "just now"},
{now.Unix() - 30, "just now"},
{now.Unix() - 120, "2m ago"},
{now.Unix() - 7200, "2h ago"},
{now.Unix() - 172800, "2d ago"},
}
for _, c := range cases {
if got := relativeAge(c.unix, now); got != c.want {
t.Errorf("relativeAge(%d) = %q, want %q", c.unix, got, c.want)
}
}
}
func TestTruncate(t *testing.T) {
cases := []struct {
in string
max int
want string
}{
{"hello world", 20, "hello world"},
{"hello world", 5, "hell" + ellipsis},
{" multi space ", 20, "multi space"},
{"abc", 1, ellipsis},
{"abc", 0, ""},
}
for _, c := range cases {
if got := truncate(c.in, c.max); got != c.want {
t.Errorf("truncate(%q, %d) = %q, want %q", c.in, c.max, got, c.want)
}
}
}
func TestClusterSignals(t *testing.T) {
c := store.DigestCluster{
CVEs: []store.DigestCVE{
{ID: "CVE-A", CVSSScore: ptr(7.5), EPSS: ptr(0.2)},
{ID: "CVE-B", CVSSScore: ptr(9.8), EPSS: ptr(0.9), IsKEV: true},
{ID: "CVE-C"},
},
}
if !clusterHasKEV(c) {
t.Error("clusterHasKEV = false, want true")
}
if got := clusterMaxCVSS(c); got == nil || *got != 9.8 {
t.Errorf("clusterMaxCVSS = %v, want 9.8", got)
}
if got := clusterMaxEPSS(c); got == nil || *got != 0.9 {
t.Errorf("clusterMaxEPSS = %v, want 0.9", got)
}
if got := clusterBand(c); got != bandCritical {
t.Errorf("clusterBand = %v, want bandCritical (KEV)", got)
}
noKev := store.DigestCluster{CVEs: []store.DigestCVE{{ID: "CVE-D", CVSSScore: ptr(7.5)}}}
if got := clusterBand(noKev); got != bandHigh {
t.Errorf("clusterBand(no kev, 7.5) = %v, want bandHigh", got)
}
empty := store.DigestCluster{}
if got := clusterBand(empty); got != bandNone {
t.Errorf("clusterBand(empty) = %v, want bandNone", got)
}
}
func TestOutletColor(t *testing.T) {
cases := map[int]string{1: colorDim, 2: colorBlue, 3: colorCyan, 4: colorViolet, 9: colorViolet}
for n, want := range cases {
if got := outletColor(n); got != want {
t.Errorf("outletColor(%d) = %q, want %q", n, got, want)
}
}
}