Files
pixa/internal/config/referer_blocklist_internal_test.go
T
clawbot e1737f497c Add failing tests for host entries that can never match
A `*.` entry, an entry with a port and one with two leading dots must
abort startup for referer_blocklist, and the first two for
allowlist_hosts; IPv4 and IPv6 address entries must still load.

Model: opus-5-5
2026-10-04 19:08:30 +00:00

148 lines
4.4 KiB
Go

package config
import (
"slices"
"testing"
)
// TestRefererBlocklistParsed loads a referer_blocklist with a host and a
// pattern starting with "." and checks both are kept in order.
func TestRefererBlocklistParsed(t *testing.T) {
t.Parallel()
c, err := configFromYAML(t, signingKeyLine+`referer_blocklist:
- leech.example
- .hotlinker.example
`)
if err != nil {
t.Fatalf("valid referer_blocklist should load, got error: %v", err)
}
want := []string{"leech.example", ".hotlinker.example"}
if !slices.Equal(c.RefererBlocklist, want) {
t.Errorf("RefererBlocklist = %v, want %v", c.RefererBlocklist, want)
}
}
// TestRefererBlocklistAcceptsIPAddresses checks that IPv4 and IPv6 addresses,
// the IPv6 one written without brackets, are accepted as entries.
func TestRefererBlocklistAcceptsIPAddresses(t *testing.T) {
t.Parallel()
c, err := configFromYAML(t, signingKeyLine+`referer_blocklist:
- 192.0.2.7
- "2001:db8::7"
`)
if err != nil {
t.Fatalf("IP address entries should load, got error: %v", err)
}
want := []string{"192.0.2.7", "2001:db8::7"}
if !slices.Equal(c.RefererBlocklist, want) {
t.Errorf("RefererBlocklist = %v, want %v", c.RefererBlocklist, want)
}
}
// TestRefererBlocklistOmittedIsEmpty checks that an omitted key blocks no
// referer.
func TestRefererBlocklistOmittedIsEmpty(t *testing.T) {
t.Parallel()
c, err := configFromYAML(t, signingKeyLine)
if err != nil {
t.Fatalf("minimal config should be valid, got error: %v", err)
}
if len(c.RefererBlocklist) != 0 {
t.Errorf("RefererBlocklist = %v, want empty", c.RefererBlocklist)
}
}
// TestRefererBlocklistInvalidAbortsStartup checks that an entry that is not a
// host, or a value that is not a list of them, aborts startup with an error
// naming the key and the entry.
func TestRefererBlocklistInvalidAbortsStartup(t *testing.T) {
t.Parallel()
runAbortCases(t, []abortCase{
{
name: "entry with a scheme",
yaml: signingKeyLine + "referer_blocklist:\n - https://leech.example\n",
wantErrSubstrings: []string{
keyRefererBlocklist, "https://leech.example",
},
},
{
name: "entry with a path",
yaml: signingKeyLine + "referer_blocklist:\n - leech.example/page\n",
wantErrSubstrings: []string{
keyRefererBlocklist, "leech.example/page",
},
},
{
name: "wildcard entry",
yaml: signingKeyLine + "referer_blocklist:\n - \"*.leech.example\"\n",
wantErrSubstrings: []string{
keyRefererBlocklist, "*.leech.example",
},
},
{
name: "entry with a port",
yaml: signingKeyLine + "referer_blocklist:\n - leech.example:8080\n",
wantErrSubstrings: []string{
keyRefererBlocklist, "leech.example:8080",
},
},
{
name: "two leading dots",
yaml: signingKeyLine + "referer_blocklist:\n - ..leech.example\n",
wantErrSubstrings: []string{
keyRefererBlocklist, "..leech.example",
},
},
{
name: "dot only",
yaml: signingKeyLine + "referer_blocklist:\n - \".\"\n",
wantErrSubstrings: []string{keyRefererBlocklist, `"."`},
},
{
name: "empty entry",
yaml: signingKeyLine + "referer_blocklist:\n - \"\"\n",
wantErrSubstrings: []string{keyRefererBlocklist},
},
{
name: "entry not a string",
yaml: signingKeyLine + "referer_blocklist:\n - 42\n",
wantErrSubstrings: []string{keyRefererBlocklist, "42"},
},
{
name: "null value",
yaml: signingKeyLine + "referer_blocklist:\n",
wantErrSubstrings: []string{keyRefererBlocklist, nullValueText},
},
})
}
// TestRefererBlocklistFromEnvironment checks that PIXA_REFERER_BLOCKLIST
// takes comma-separated entries, and that an entry in it that is not a host
// aborts startup naming the variable and the entry.
func TestRefererBlocklistFromEnvironment(t *testing.T) {
t.Setenv("PIXA_SIGNING_KEY", validTestSigningKey)
t.Setenv("PIXA_REFERER_BLOCKLIST", " leech.example , .hotlinker.example ")
c, err := newFromSmartConfig(nil)
if err != nil {
t.Fatalf("valid PIXA_REFERER_BLOCKLIST should load, got error: %v", err)
}
want := []string{"leech.example", ".hotlinker.example"}
if !slices.Equal(c.RefererBlocklist, want) {
t.Errorf("RefererBlocklist = %v, want %v", c.RefererBlocklist, want)
}
t.Setenv("PIXA_REFERER_BLOCKLIST", "leech.example,https://hotlinker.example")
_, err = newFromSmartConfig(nil)
wantStartupError(t, err, "PIXA_REFERER_BLOCKLIST", "https://hotlinker.example")
}