repos / pico

pico services - prose.sh, pastes.sh, imgs.sh, feeds.sh, pgs.sh
git clone https://github.com/picosh/pico.git

pico / pgs
Eric Bower · 13 Oct 24

calc_route_test.go

  1package pgs
  2
  3import (
  4	"testing"
  5
  6	"github.com/google/go-cmp/cmp"
  7)
  8
  9type RouteFixture struct {
 10	Name     string
 11	Actual   []*HttpReply
 12	Expected []*HttpReply
 13}
 14
 15func TestCalcRoutes(t *testing.T) {
 16	fixtures := []RouteFixture{
 17		{
 18			Name:   "basic-index",
 19			Actual: calcRoutes("test", "/index.html", []*RedirectRule{}),
 20			Expected: []*HttpReply{
 21				{Filepath: "test/index.html", Status: 200},
 22				{Filepath: "/index.html/", Status: 301},
 23				{Filepath: "test/404.html", Status: 404},
 24			},
 25		},
 26		{
 27			Name:   "basic-txt",
 28			Actual: calcRoutes("test", "/index.txt", []*RedirectRule{}),
 29			Expected: []*HttpReply{
 30				{Filepath: "test/index.txt", Status: 200},
 31				{Filepath: "/index.txt/", Status: 301},
 32				{Filepath: "test/404.html", Status: 404},
 33			},
 34		},
 35		{
 36			Name:   "basic-named",
 37			Actual: calcRoutes("test", "/wow.html", []*RedirectRule{}),
 38			Expected: []*HttpReply{
 39				{Filepath: "test/wow.html", Status: 200},
 40				{Filepath: "/wow.html/", Status: 301},
 41				{Filepath: "test/404.html", Status: 404},
 42			},
 43		},
 44		{
 45			Name:   "subdirectory-index",
 46			Actual: calcRoutes("test", "/nice/index.html", []*RedirectRule{}),
 47			Expected: []*HttpReply{
 48				{Filepath: "test/nice/index.html", Status: 200},
 49				{Filepath: "/nice/index.html/", Status: 301},
 50				{Filepath: "test/404.html", Status: 404},
 51			},
 52		},
 53		{
 54			Name:   "subdirectory-named",
 55			Actual: calcRoutes("test", "/nice/wow.html", []*RedirectRule{}),
 56			Expected: []*HttpReply{
 57				{Filepath: "test/nice/wow.html", Status: 200},
 58				{Filepath: "/nice/wow.html/", Status: 301},
 59				{Filepath: "test/404.html", Status: 404},
 60			},
 61		},
 62		{
 63			Name:   "subdirectory-bare",
 64			Actual: calcRoutes("test", "/nice/", []*RedirectRule{}),
 65			Expected: []*HttpReply{
 66				{Filepath: "test/nice/index.html", Status: 200},
 67				{Filepath: "test/404.html", Status: 404},
 68			},
 69		},
 70		{
 71			Name:   "trailing-slash",
 72			Actual: calcRoutes("test", "/folder", []*RedirectRule{}),
 73			Expected: []*HttpReply{
 74				{Filepath: "test/folder", Status: 200},
 75				{Filepath: "test/folder.html", Status: 200},
 76				{Filepath: "/folder/", Status: 301},
 77				{Filepath: "test/404.html", Status: 404},
 78			},
 79		},
 80		{
 81			Name: "spa",
 82			Actual: calcRoutes("test", "/nice.html", []*RedirectRule{
 83				{
 84					From:   "/*",
 85					To:     "/index.html",
 86					Status: 200,
 87				},
 88			}),
 89			Expected: []*HttpReply{
 90				{Filepath: "test/nice.html", Status: 200},
 91				{Filepath: "test/index.html", Status: 200},
 92				{Filepath: "/index.html/", Status: 301},
 93				{Filepath: "test/404.html", Status: 404},
 94			},
 95		},
 96		{
 97			Name:   "xml",
 98			Actual: calcRoutes("test", "/index.xml", []*RedirectRule{}),
 99			Expected: []*HttpReply{
100				{Filepath: "test/index.xml", Status: 200},
101				{Filepath: "/index.xml/", Status: 301},
102				{Filepath: "test/404.html", Status: 404},
103			},
104		},
105		{
106			Name: "redirect-rule",
107			Actual: calcRoutes(
108				"test",
109				"/wow",
110				[]*RedirectRule{
111					{
112						From:   "/wow",
113						To:     "/index.html",
114						Status: 301,
115					},
116				},
117			),
118			Expected: []*HttpReply{
119				{Filepath: "test/wow", Status: 200},
120				{Filepath: "test/wow.html", Status: 200},
121				{Filepath: "/index.html", Status: 301},
122				{Filepath: "/wow/", Status: 301},
123				{Filepath: "test/404.html", Status: 404},
124			},
125		},
126		{
127			Name: "redirect-to-pico",
128			Actual: calcRoutes(
129				"test",
130				"/tester1",
131				[]*RedirectRule{
132					{
133						From:   "/tester1",
134						To:     "https://pico.sh",
135						Status: 301,
136					},
137				},
138			),
139			Expected: []*HttpReply{
140				{Filepath: "test/tester1", Status: 200},
141				{Filepath: "test/tester1.html", Status: 200},
142				{Filepath: "https://pico.sh", Status: 301},
143			},
144		},
145		{
146			Name: "root",
147			Actual: calcRoutes(
148				"test",
149				"",
150				[]*RedirectRule{},
151			),
152			Expected: []*HttpReply{
153				{Filepath: "test/index.html", Status: 200},
154				{Filepath: "test/404.html", Status: 404},
155			},
156		},
157		{
158			Name: "redirect-to-root",
159			Actual: calcRoutes(
160				"test",
161				"/wow/",
162				[]*RedirectRule{
163					{
164						From:   "/wow/",
165						To:     "/",
166						Status: 301,
167					},
168				},
169			),
170			Expected: []*HttpReply{
171				{Filepath: "test/wow/index.html", Status: 200},
172				{Filepath: "/", Status: 301},
173				{Filepath: "test/404.html", Status: 404},
174			},
175		},
176		{
177			Name: "force",
178			Actual: calcRoutes(
179				"test",
180				"/wow",
181				[]*RedirectRule{
182					{
183						From:   "/wow",
184						To:     "/",
185						Status: 301,
186						Force:  true,
187					},
188				},
189			),
190			Expected: []*HttpReply{
191				{Filepath: "/", Status: 301},
192				{Filepath: "/wow/", Status: 301},
193				{Filepath: "test/404.html", Status: 404},
194			},
195		},
196		{
197			Name: "redirect-full-url",
198			Actual: calcRoutes(
199				"test",
200				"/wow.html",
201				[]*RedirectRule{
202					{
203						From:   "/wow",
204						To:     "https://pico.sh",
205						Status: 301,
206					},
207				},
208			),
209			Expected: []*HttpReply{
210				{Filepath: "test/wow.html", Status: 200},
211				{Filepath: "/wow.html/", Status: 301},
212				{Filepath: "test/404.html", Status: 404},
213			},
214		},
215		{
216			Name: "redirect-full-url-directory",
217			Actual: calcRoutes(
218				"test",
219				"/wow",
220				[]*RedirectRule{
221					{
222						From:   "/wow",
223						To:     "https://pico.sh",
224						Status: 301,
225					},
226				},
227			),
228			Expected: []*HttpReply{
229				{Filepath: "test/wow", Status: 200},
230				{Filepath: "test/wow.html", Status: 200},
231				{Filepath: "https://pico.sh", Status: 301},
232			},
233		},
234		{
235			Name: "redirect-directory",
236			Actual: calcRoutes(
237				"public",
238				"/xyz",
239				[]*RedirectRule{
240					{
241						From:   "/xyz",
242						To:     "/wrk-xyz",
243						Status: 301,
244					},
245				},
246			),
247			Expected: []*HttpReply{
248				{Filepath: "public/xyz", Status: 200},
249				{Filepath: "public/xyz.html", Status: 200},
250				{Filepath: "/wrk-xyz", Status: 301},
251				{Filepath: "/xyz/", Status: 301},
252				{Filepath: "public/404.html", Status: 404},
253			},
254		},
255		{
256			Name: "redirect-sub-directory",
257			Actual: calcRoutes(
258				"public",
259				"/folder2",
260				[]*RedirectRule{
261					{
262						From:   "/folder2",
263						To:     "/folder",
264						Status: 200,
265					},
266				},
267			),
268			Expected: []*HttpReply{
269				{Filepath: "public/folder2", Status: 200},
270				{Filepath: "public/folder2.html", Status: 200},
271				{Filepath: "public/folder", Status: 200},
272				{Filepath: "public/folder.html", Status: 200},
273				{Filepath: "/folder/", Status: 301},
274				{Filepath: "public/404.html", Status: 404},
275			},
276		},
277		{
278			Name: "redirect-from-and-to-same",
279			Actual: calcRoutes(
280				"public",
281				"/folder2",
282				[]*RedirectRule{
283					{
284						From:   "/folder2",
285						To:     "/folder2",
286						Status: 200,
287					},
288				},
289			),
290			Expected: []*HttpReply{
291				{Filepath: "public/folder2", Status: 200},
292				{Filepath: "public/folder2.html", Status: 200},
293				{Filepath: "/folder2/", Status: 301},
294				{Filepath: "public/404.html", Status: 404},
295			},
296		},
297		{
298			Name: "redirect-no-trailing-slash",
299			Actual: calcRoutes(
300				"public",
301				"/space/",
302				[]*RedirectRule{
303					{
304						From:   "/space",
305						To:     "/frontier/",
306						Status: 301,
307					},
308				},
309			),
310			Expected: []*HttpReply{
311				{Filepath: "public/space/index.html", Status: 200},
312				{Filepath: "/frontier/", Status: 301},
313				{Filepath: "public/404.html", Status: 404},
314			},
315		},
316		{
317			Name: "redirect-with-trailing-slash",
318			Actual: calcRoutes(
319				"public",
320				"/space",
321				[]*RedirectRule{
322					{
323						From:   "/space/",
324						To:     "/frontier/",
325						Status: 301,
326					},
327				},
328			),
329			Expected: []*HttpReply{
330				{Filepath: "public/space", Status: 200},
331				{Filepath: "public/space.html", Status: 200},
332				{Filepath: "/frontier/", Status: 301},
333				{Filepath: "/space/", Status: 301},
334				{Filepath: "public/404.html", Status: 404},
335			},
336		},
337		{
338			Name: "directory-with-extension",
339			Actual: calcRoutes(
340				"public",
341				"/space.nvim",
342				[]*RedirectRule{},
343			),
344			Expected: []*HttpReply{
345				{Filepath: "public/space.nvim", Status: 200},
346				{Filepath: "public/space.nvim.html", Status: 200},
347				{Filepath: "/space.nvim/", Status: 301},
348				{Filepath: "public/404.html", Status: 404},
349			},
350		},
351		{
352			Name: "rewrite-to-site",
353			Actual: calcRoutes(
354				"public",
355				"/",
356				[]*RedirectRule{
357					{
358						From:   "/*",
359						To:     "https://my-other-site.pgs.sh/:splat",
360						Status: 200,
361					},
362				},
363			),
364			Expected: []*HttpReply{
365				{Filepath: "public/index.html", Status: 200},
366				{Filepath: "https://my-other-site.pgs.sh/", Status: 200},
367			},
368		},
369		{
370			Name: "rewrite-to-site-subdir",
371			Actual: calcRoutes(
372				"public",
373				"/plugin/nice/",
374				[]*RedirectRule{
375					{
376						From:   "/*",
377						To:     "https://my-other-site.pgs.sh/:splat",
378						Status: 200,
379					},
380				},
381			),
382			Expected: []*HttpReply{
383				{Filepath: "public/plugin/nice/index.html", Status: 200},
384				{Filepath: "https://my-other-site.pgs.sh/plugin/nice/", Status: 200},
385			},
386		},
387		{
388			Name: "rewrite-to-another-pgs-site",
389			Actual: calcRoutes(
390				"public",
391				"/my-site/index.html",
392				[]*RedirectRule{
393					{
394						From:   "/my-site/*",
395						To:     "https://my-other-site.pgs.sh/:splat",
396						Status: 200,
397					},
398				},
399			),
400			Expected: []*HttpReply{
401				{Filepath: "public/my-site/index.html", Status: 200},
402				{Filepath: "https://my-other-site.pgs.sh/index.html", Status: 200},
403			},
404		},
405		{
406			Name: "rewrite-placeholders",
407			Actual: calcRoutes(
408				"public",
409				"/news/02/12/2004/my-story",
410				[]*RedirectRule{
411					{
412						From:   "/news/:month/:date/:year/*",
413						To:     "/blog/:year/:month/:date/:splat",
414						Status: 200,
415					},
416				},
417			),
418			Expected: []*HttpReply{
419				{Filepath: "public/news/02/12/2004/my-story", Status: 200},
420				{Filepath: "public/news/02/12/2004/my-story.html", Status: 200},
421				{Filepath: "public/blog/2004/02/12/my-story", Status: 200},
422				{Filepath: "public/blog/2004/02/12/my-story.html", Status: 200},
423				{Filepath: "/blog/2004/02/12/my-story/", Status: 301},
424				{Filepath: "public/404.html", Status: 404},
425			},
426		},
427		{
428			Name: "302-redirect",
429			Actual: calcRoutes(
430				"public",
431				"/pages/chem351.html",
432				[]*RedirectRule{
433					{
434						From:   "/pages/chem351.html",
435						To:     "/pages/chem351",
436						Status: 302,
437						Force:  true,
438					},
439				},
440			),
441			Expected: []*HttpReply{
442				{Filepath: "/pages/chem351", Status: 302},
443				{Filepath: "/pages/chem351.html/", Status: 301},
444				{Filepath: "public/404.html", Status: 404},
445			},
446		},
447		{
448			Name: "302-redirect-non-match",
449			Actual: calcRoutes(
450				"public",
451				"/pages/chem351",
452				[]*RedirectRule{
453					{
454						From:   "/pages/chem351.html",
455						To:     "/pages/chem351",
456						Status: 302,
457						Force:  true,
458					},
459				},
460			),
461			Expected: []*HttpReply{
462				{Filepath: "public/pages/chem351", Status: 200},
463				{Filepath: "public/pages/chem351.html", Status: 200},
464				{Filepath: "/pages/chem351/", Status: 301},
465				{Filepath: "public/404.html", Status: 404},
466			},
467		},
468		{
469			Name: "wildcard-with-word",
470			Actual: calcRoutes(
471				"public",
472				"/pictures/soup",
473				[]*RedirectRule{
474					{
475						From:   "/pictures*",
476						To:     "https://super.fly.sh/:splat",
477						Status: 200,
478					},
479					{
480						From:   "/*",
481						To:     "https://super.fly.sh/:splat",
482						Status: 302,
483					},
484				},
485			),
486			Expected: []*HttpReply{
487				{Filepath: "public/pictures/soup", Status: 200},
488				{Filepath: "public/pictures/soup.html", Status: 200},
489				{Filepath: "https://super.fly.sh/soup", Status: 200},
490			},
491		},
492		{
493			Name: "wildcard-multiple",
494			Actual: calcRoutes(
495				"public",
496				"/super/ficial.html",
497				[]*RedirectRule{
498					{
499						From:   "/pictures*",
500						To:     "https://super.fly.sh/:splat",
501						Status: 200,
502					},
503					{
504						From:   "/*",
505						To:     "https://super.fly.sh/:splat",
506						Status: 302,
507					},
508				},
509			),
510			Expected: []*HttpReply{
511				{Filepath: "public/super/ficial.html", Status: 200},
512				{Filepath: "https://super.fly.sh/super/ficial.html", Status: 302},
513			},
514		},
515	}
516
517	for _, fixture := range fixtures {
518		t.Run(fixture.Name, func(t *testing.T) {
519			if cmp.Equal(fixture.Actual, fixture.Expected) == false {
520				//nolint
521				t.Fatalf(cmp.Diff(fixture.Expected, fixture.Actual))
522			}
523		})
524	}
525}