reject non-3xx status codes; close the CSV file; add tests
CI / go-tests (pull_request) Successful in 2m4s

A row with a status code outside 3xx (e.g. "0" from a typo) was accepted
at load and then panicked net/http's WriteHeader on the first matching
request. ReadCsvRedirects now rejects anything that isn't 300-399, with a
line number in the message, and reports a non-numeric code clearly.

Also defer reader.Close() (the file was left open for the process
lifetime) and drop the unreachable "row == nil" check.

Adds internal/{csv,redirect,http}_test.go covering CSV parsing (valid,
reordered headings, header-only, missing heading, non-numeric and non-3xx
status, ragged row, missing file), Redirects.Find / Redirect.Match, and
ServeHTTP (redirect, 404, query string dropped).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-07 14:19:44 +01:00
co-authored by Claude Sonnet 5
parent 1dfa60a237
commit 68546badb3
4 changed files with 198 additions and 9 deletions
+31
View File
@@ -0,0 +1,31 @@
package internal
import "testing"
func TestRedirectsFind(t *testing.T) {
rs := Redirects{
{From: "/a", To: "https://example.com/a", StatusCode: 301},
{From: "/b", To: "https://example.com/b", StatusCode: 302},
}
if got := rs.Find("/b"); got == nil || got.To != "https://example.com/b" {
t.Errorf("Find(/b) = %+v", got)
}
if got := rs.Find("/missing"); got != nil {
t.Errorf("Find(/missing) = %+v, want nil", got)
}
if got := rs.Find("/A"); got != nil {
t.Errorf("Find is case-sensitive; Find(/A) = %+v, want nil", got)
}
}
func TestRedirectMatch(t *testing.T) {
r := &Redirect{From: "/x"}
if !r.Match("/x") {
t.Error("Match(/x) = false, want true")
}
if r.Match("/x/") {
t.Error("Match(/x/) = true, want false (exact match only)")
}
}