package main import ( "io/fs" "net/http" "os" "path" "strings" "testing" "amadan.net/rastrillo/abono" ) // exampleKeys is every "example.*" key the example's own templates and Go // name. The generated pages (abono_pages.go, templates/abono/) are abono's // and use abono.* keys, which its own gate holds to its catalog; main.go // is configuration, where "example.db" is a file name, not a key. func exampleKeys(t *testing.T) map[string]bool { t.Helper() used := map[string]bool{} root := os.DirFS(".") err := fs.WalkDir(root, ".", func(p string, d fs.DirEntry, err error) error { if err != nil { return err } if d.IsDir() { if p == "templates/abono" || p == "migrations" { return fs.SkipDir } return nil } if ext := path.Ext(p); (ext != ".html" && ext != ".go") || strings.HasSuffix(p, "_test.go") || p == "abono_pages.go" || p == "main.go" { return nil } src, err := fs.ReadFile(root, p) if err != nil { return err } for _, m := range keyLiteral.FindAllSubmatch(src, -1) { if k := string(m[1]); strings.HasPrefix(k, "example.") { used[k] = true } } return nil }) if err != nil { t.Fatal(err) } return used } // The example's "example.*" keys and locales/en.toml agree: every key its // templates use is defined there, every key there is used, and the file // holds nothing but example.* keys (abono's belong to abono's catalog). func TestExampleCatalogCoversTheKeysTheExampleUses(t *testing.T) { own, err := ownCatalog() if err != nil { t.Fatal(err) } used := exampleKeys(t) if !used["example.signout"] { t.Error("exampleKeys misses example.signout, which the layout uses") } for k := range used { if _, ok := own[k]; !ok { t.Errorf("%s is used but not in locales/en.toml", k) } } for k := range own { if !used[k] { t.Errorf("%s is in locales/en.toml but nothing uses it", k) } if !strings.HasPrefix(k, "example.") { t.Errorf("%s is in the example's catalog but is not an example.* key", k) } } for k := range abono.Catalog() { if strings.HasPrefix(k, "example.") { t.Errorf("abono's catalog has %s, which is the example's", k) } } merged := Catalog() for k, v := range abono.Catalog() { if merged[k] != v { t.Errorf("Catalog() changed abono's %s", k) } } for k, v := range own { if merged[k] != v { t.Errorf("Catalog() lacks the example's %s", k) } } } // With no catalog given, the example runs on its own: a signed-in page // says "Sign out", not the key. func TestExampleSaysSignOutInItsOwnCatalog(t *testing.T) { app := newApp(t, func(c *Config) { c.Catalog = nil }) reader := newClient(t, app) reader.signin("reader@example.com") status, body := reader.get("/subscribe") if status != http.StatusOK { t.Fatalf("GET /subscribe: %d", status) } if !strings.Contains(body, ">Sign out<") || strings.Contains(body, "example.signout") { t.Errorf("the nav does not say Sign out:\n%s", body) } }