repos / pico

pico services mono repo
git clone https://github.com/picosh/pico.git

pico / pkg / apps / pgs
Eric Bower  ·  2026-04-04

redirect_test.go

  1package pgs
  2
  3import (
  4	"testing"
  5
  6	"github.com/google/go-cmp/cmp"
  7)
  8
  9type RedirectFixture struct {
 10	name        string
 11	input       string
 12	expect      []*RedirectRule
 13	shouldError bool
 14}
 15
 16func TestParseRedirectText(t *testing.T) {
 17	empty := map[string]string{}
 18	spa := RedirectFixture{
 19		name:  "spa",
 20		input: "/*   /index.html   200",
 21		expect: []*RedirectRule{
 22			{
 23				From:       "/*",
 24				To:         "/index.html",
 25				Status:     200,
 26				Query:      empty,
 27				Conditions: empty,
 28			},
 29		},
 30	}
 31
 32	rss := RedirectFixture{
 33		name:  "rss",
 34		input: "/rss /rss.atom 200",
 35		expect: []*RedirectRule{
 36			{
 37				From:       "/rss",
 38				To:         "/rss.atom",
 39				Status:     200,
 40				Query:      empty,
 41				Conditions: empty,
 42			},
 43		},
 44	}
 45
 46	withStatus := RedirectFixture{
 47		name:  "with-status",
 48		input: "/wow     /index.html     301",
 49		expect: []*RedirectRule{
 50			{
 51				From:       "/wow",
 52				To:         "/index.html",
 53				Status:     301,
 54				Query:      empty,
 55				Conditions: empty,
 56			},
 57		},
 58	}
 59
 60	noStatus := RedirectFixture{
 61		name:  "no-status",
 62		input: "/wow     /index.html",
 63		expect: []*RedirectRule{
 64			{
 65				From:       "/wow",
 66				To:         "/index.html",
 67				Status:     301,
 68				Query:      empty,
 69				Conditions: empty,
 70			},
 71		},
 72	}
 73
 74	absoluteUriNoProto := RedirectFixture{
 75		name:        "absolute-uri-no-proto",
 76		input:       "/*  www.example.com  301",
 77		expect:      []*RedirectRule{},
 78		shouldError: true,
 79	}
 80
 81	absoluteUriWithProto := RedirectFixture{
 82		name:  "absolute-uri-no-proto",
 83		input: "/*  https://www.example.com  301",
 84		expect: []*RedirectRule{
 85			{
 86				From:       "/*",
 87				To:         "https://www.example.com",
 88				Status:     301,
 89				Query:      empty,
 90				Conditions: empty,
 91			},
 92		},
 93	}
 94
 95	selfReferentialExact := RedirectFixture{
 96		name:        "self-referential-exact",
 97		input:       "/page /page 301",
 98		expect:      []*RedirectRule{},
 99		shouldError: true,
100	}
101
102	selfReferentialWildcard := RedirectFixture{
103		name:        "self-referential-wildcard",
104		input:       "/* /* 301",
105		expect:      []*RedirectRule{},
106		shouldError: true,
107	}
108
109	selfReferentialWithVariables := RedirectFixture{
110		name:        "self-referential-with-variables",
111		input:       "/:path /:path 301",
112		expect:      []*RedirectRule{},
113		shouldError: true,
114	}
115
116	externalUrlNotSelfRef := RedirectFixture{
117		name:  "external-url-not-self-referential",
118		input: "/* https://example.com 301",
119		expect: []*RedirectRule{
120			{
121				From:       "/*",
122				To:         "https://example.com",
123				Status:     301,
124				Query:      empty,
125				Conditions: empty,
126			},
127		},
128	}
129
130	validPathRedirect := RedirectFixture{
131		name:  "valid-path-redirect",
132		input: "/old-path /new-path 301",
133		expect: []*RedirectRule{
134			{
135				From:       "/old-path",
136				To:         "/new-path",
137				Status:     301,
138				Query:      empty,
139				Conditions: empty,
140			},
141		},
142	}
143
144	rootRedirect := RedirectFixture{
145		name:  "root-redirect",
146		input: "/ /dax/cool/wow/ 302!",
147		expect: []*RedirectRule{
148			{
149				From:       "/",
150				To:         "/dax/cool/wow/",
151				Status:     302,
152				Query:      empty,
153				Conditions: empty,
154				Force:      true,
155			},
156		},
157	}
158
159	fixtures := []RedirectFixture{
160		spa,
161		rss,
162		withStatus,
163		noStatus,
164		absoluteUriNoProto,
165		absoluteUriWithProto,
166		selfReferentialExact,
167		selfReferentialWildcard,
168		selfReferentialWithVariables,
169		externalUrlNotSelfRef,
170		validPathRedirect,
171		rootRedirect,
172	}
173
174	for _, fixture := range fixtures {
175		t.Run(fixture.name, func(t *testing.T) {
176			results, err := parseRedirectText(fixture.input)
177			if err != nil && !fixture.shouldError {
178				t.Error(err)
179			}
180			if cmp.Equal(results, fixture.expect) == false {
181				//nolint
182				t.Fatal(cmp.Diff(fixture.expect, results))
183			}
184		})
185	}
186}