checker-http/checker/rules_test.go

128 lines
3.5 KiB
Go

// This file is part of the happyDomain (R) project.
// Copyright (c) 2020-2026 happyDomain
// Authors: Pierre-Olivier Mercier, et al.
package checker
import (
"context"
"net/http"
"testing"
sdk "git.happydns.org/checker-sdk-go/checker"
)
func TestRulesShape(t *testing.T) {
rs := Rules()
if len(rs) == 0 {
t.Fatal("Rules() returned no rules")
}
seen := map[string]bool{}
for _, r := range rs {
name := r.Name()
if name == "" {
t.Errorf("rule with empty name: %T", r)
}
if r.Description() == "" {
t.Errorf("rule %q has empty description", name)
}
if seen[name] {
t.Errorf("duplicate rule name: %q", name)
}
seen[name] = true
}
// The two reachability rules must exist with distinct codes per scheme.
for _, want := range []string{"http.tcp_reachable", "https.tcp_reachable", "http.https_redirect", "http.hsts", "http.csp", "http.x_frame_options", "http.x_content_type_options", "http.x_xss_protection", "http.cookie_flags", "http.sri"} {
if !seen[want] {
t.Errorf("missing rule %q in Rules()", want)
}
}
}
func TestLoadHTTPDataFailure(t *testing.T) {
obs := &fakeObs{failGet: true}
data, errSt := loadHTTPData(context.Background(), obs)
if data != nil {
t.Fatal("expected nil data on failure")
}
if errSt == nil || errSt.Status != sdk.StatusError {
t.Fatalf("expected StatusError, got %+v", errSt)
}
if errSt.Code != "http.observation_error" {
t.Errorf("unexpected code: %q", errSt.Code)
}
}
func TestLoadHTTPDataSuccess(t *testing.T) {
want := &HTTPData{Domain: "example.test", Probes: []HTTPProbe{httpsProbe("203.0.113.1:443")}}
data, errSt := loadHTTPData(context.Background(), &fakeObs{data: want})
if errSt != nil {
t.Fatalf("unexpected error state: %+v", errSt)
}
if data == nil || data.Domain != "example.test" || len(data.Probes) != 1 {
t.Fatalf("unexpected data: %+v", data)
}
}
func TestProbesByScheme(t *testing.T) {
probes := []HTTPProbe{
httpProbe("a:80"),
httpsProbe("a:443"),
httpProbe("b:80"),
}
if got := probesByScheme(probes, "http"); len(got) != 2 {
t.Errorf("http: got %d, want 2", len(got))
}
if got := probesByScheme(probes, "https"); len(got) != 1 {
t.Errorf("https: got %d, want 1", len(got))
}
if got := probesByScheme(probes, "gopher"); got != nil {
t.Errorf("unknown scheme should return nil, got %+v", got)
}
}
func TestSuccessfulHTTPSProbes(t *testing.T) {
failed := httpsProbe("a:443")
failed.StatusCode = 0
failed.TCPConnected = false
probes := []HTTPProbe{
httpProbe("a:80"),
httpsProbe("a:443"),
failed,
}
got := successfulHTTPSProbes(probes)
if len(got) != 1 {
t.Fatalf("got %d successful HTTPS probes, want 1", len(got))
}
if got[0].Address != "a:443" || got[0].StatusCode != 200 {
t.Errorf("unexpected probe: %+v", got[0])
}
}
func TestPassAndUnknownStateBuilders(t *testing.T) {
if s := passState("c", "m"); s.Status != sdk.StatusOK || s.Code != "c" || s.Message != "m" {
t.Errorf("passState wrong: %+v", s)
}
if s := unknownState("c", "m"); s.Status != sdk.StatusUnknown || s.Code != "c" || s.Message != "m" {
t.Errorf("unknownState wrong: %+v", s)
}
}
func TestSameSiteString(t *testing.T) {
cases := []struct {
in http.SameSite
want string
}{
{http.SameSiteLaxMode, "Lax"},
{http.SameSiteStrictMode, "Strict"},
{http.SameSiteNoneMode, "None"},
{http.SameSiteDefaultMode, ""},
{http.SameSite(99), ""},
}
for _, c := range cases {
if got := sameSiteString(c.in); got != c.want {
t.Errorf("sameSiteString(%v) = %q, want %q", c.in, got, c.want)
}
}
}