Migration
This is my new public git source viewer. Source coming soon. Please contact with concerns/bugs.
Contact me
internal/modules/notices_test.go
8d1bb5bfdd2cba82488775b46308efed740132a8
· 2.3 KB · 88 lines
raw
| 1 | package modules |
| 2 | |
| 3 | import ( |
| 4 | "html/template" |
| 5 | "os" |
| 6 | "path/filepath" |
| 7 | "strings" |
| 8 | "testing" |
| 9 | |
| 10 | "gsg/internal/core" |
| 11 | "gsg/internal/notices" |
| 12 | ) |
| 13 | |
| 14 | // Global notices come before the repository's own; a site-scoped Ctx (nil |
| 15 | // Repo, empty Slug) gets the global list only and must not panic. |
| 16 | func TestNoticesModMergesGlobalThenRepo(t *testing.T) { |
| 17 | path := filepath.Join(t.TempDir(), "notices.yaml") |
| 18 | st, err := notices.Open(path) |
| 19 | if err != nil { |
| 20 | t.Fatal(err) |
| 21 | } |
| 22 | t.Cleanup(st.Close) |
| 23 | err = st.Set(notices.Document{ |
| 24 | Global: []notices.Notice{{Type: notices.TypeCritical, Title: "global"}}, |
| 25 | Repos: map[string][]notices.Notice{"demo": {{Type: notices.TypeInfo, Title: "repo"}}}, |
| 26 | }) |
| 27 | if err != nil { |
| 28 | t.Fatal(err) |
| 29 | } |
| 30 | notices.SetDefault(st) |
| 31 | t.Cleanup(func() { notices.SetDefault(nil) }) |
| 32 | |
| 33 | v, err := noticesMod(&core.Ctx{Info: core.RepoInfo{Slug: "demo"}}) |
| 34 | if err != nil { |
| 35 | t.Fatal(err) |
| 36 | } |
| 37 | got, ok := v.([]notices.Notice) |
| 38 | if !ok { |
| 39 | t.Fatalf("notices returned %T", v) |
| 40 | } |
| 41 | if len(got) != 2 || got[0].Title != "global" || got[1].Title != "repo" { |
| 42 | t.Fatalf("got %+v", got) |
| 43 | } |
| 44 | |
| 45 | v, err = noticesMod(&core.Ctx{}) |
| 46 | if err != nil { |
| 47 | t.Fatal(err) |
| 48 | } |
| 49 | if got := v.([]notices.Notice); len(got) != 1 || got[0].Title != "global" { |
| 50 | t.Fatalf("site-scoped got %+v", got) |
| 51 | } |
| 52 | } |
| 53 | |
| 54 | // The notices partial must render nothing on a page that will be cached |
| 55 | // immutably, and must not even call the module there -- the guard wraps the |
| 56 | // modOr call, not just its output. |
| 57 | func TestNoticesPartialSuppressesImmutable(t *testing.T) { |
| 58 | src, err := os.ReadFile("../../templates/layouts/notices.html") |
| 59 | if err != nil { |
| 60 | t.Fatal(err) |
| 61 | } |
| 62 | calls := 0 |
| 63 | tmpl, err := template.New("notices.html").Funcs(template.FuncMap{ |
| 64 | "modOr": func(string, ...string) any { |
| 65 | calls++ |
| 66 | return []notices.Notice{{Type: notices.TypeInfo, Title: "banner"}} |
| 67 | }, |
| 68 | }).Parse(string(src)) |
| 69 | if err != nil { |
| 70 | t.Fatal(err) |
| 71 | } |
| 72 | render := func(immutable bool) string { |
| 73 | var sb strings.Builder |
| 74 | if err := tmpl.ExecuteTemplate(&sb, "notices", struct{ Immutable bool }{immutable}); err != nil { |
| 75 | t.Fatal(err) |
| 76 | } |
| 77 | return sb.String() |
| 78 | } |
| 79 | |
| 80 | got := render(true) |
| 81 | if strings.Contains(got, "banner") || calls != 0 { |
| 82 | t.Fatalf("immutable page rendered notices (calls=%d): %q", calls, got) |
| 83 | } |
| 84 | got = render(false) |
| 85 | if !strings.Contains(got, "banner") || calls != 1 { |
| 86 | t.Fatalf("non-immutable page did not render (calls=%d): %q", calls, got) |
| 87 | } |
| 88 | } |