package dav import ( "encoding/json" "strings" "testing" "time" sdk "git.happydns.org/checker-sdk-go/checker" ) func relatedFrom(t *testing.T, payload any) sdk.RelatedObservation { t.Helper() b, err := json.Marshal(payload) if err != nil { t.Fatalf("marshal: %v", err) } return sdk.RelatedObservation{Key: TLSRelatedKey, Data: b} } func TestFoldTLSRelated_expiringCertProducesCallout(t *testing.T) { exp := time.Now().Add(5 * 24 * time.Hour) related := []sdk.RelatedObservation{relatedFrom(t, map[string]any{ "host": "dav.example.com", "port": 443, "not_after": exp, })} sums, callouts := foldTLSRelated(related) if len(sums) != 1 || sums[0].Address != "dav.example.com:443" || sums[0].Status != "warn" { t.Fatalf("summary: %+v", sums) } if len(callouts) != 1 || callouts[0].Severity != "warn" { t.Fatalf("expected a warn callout, got %+v", callouts) } if !strings.Contains(callouts[0].Title, "expires in") { t.Errorf("callout title: %q", callouts[0].Title) } } func TestFoldTLSRelated_expiredCertCrit(t *testing.T) { exp := time.Now().Add(-2 * 24 * time.Hour) _, callouts := foldTLSRelated([]sdk.RelatedObservation{relatedFrom(t, map[string]any{ "host": "dav.example.com", "port": 443, "not_after": exp, })}) if len(callouts) != 1 || callouts[0].Severity != "crit" { t.Fatalf("expected crit for expired cert, got %+v", callouts) } } func TestFoldTLSRelated_chainInvalid(t *testing.T) { _, callouts := foldTLSRelated([]sdk.RelatedObservation{relatedFrom(t, map[string]any{ "host": "dav.example.com", "port": 443, "chain_valid": false, })}) if len(callouts) != 1 || callouts[0].Severity != "crit" { t.Fatalf("expected crit for broken chain, got %+v", callouts) } } func TestFoldTLSRelated_explicitIssueWinsOverFlags(t *testing.T) { _, callouts := foldTLSRelated([]sdk.RelatedObservation{relatedFrom(t, map[string]any{ "host": "dav.example.com", "port": 443, "chain_valid": false, // would normally synthesize a callout "issues": []map[string]any{ {"code": "weak_cipher", "severity": "warn", "message": "TLS 1.0 offered", "fix": "disable TLS <1.2"}, }, })}) // When explicit issues exist, we do not also emit synthesized callouts; // the TLS checker is the source of truth for severity and wording. if len(callouts) != 1 || callouts[0].Severity != "warn" { t.Fatalf("want single warn callout, got %+v", callouts) } if !strings.Contains(callouts[0].Body, "disable TLS") { t.Errorf("fix text lost: %q", callouts[0].Body) } } func TestFoldTLSRelated_empty(t *testing.T) { if sums, callouts := foldTLSRelated(nil); sums != nil || callouts != nil { t.Errorf("expected nil,nil on nil input, got %+v %+v", sums, callouts) } }