// Copyright (c) 2026 Petr BalvĂ­n (https://petrbalvin.org) // SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0 package templates import ( "errors" "os" "path/filepath" "testing" ) // addTemplate fails the test when a template cannot be created, which is // not what is under test in the cases that use it. func addTemplate(t *testing.T, s *Store, tpl PostTemplate) *PostTemplate { t.Helper() created, err := s.Add(tpl) if err != nil { t.Fatalf("Add(%q): %v", tpl.Name, err) } return created } func TestAddAndList(t *testing.T) { path := filepath.Join(t.TempDir(), "templates.toml") s := New(path) tpl, err := s.Add(PostTemplate{ Name: "Review", Tags: []string{"review"}, Body: "## Summary\n", Title: "Review: ", Slug: "review", }) if err != nil { t.Fatalf("Add: %v", err) } if tpl.Name != "Review" { t.Fatalf("tpl = %+v", tpl) } all := s.All() if len(all) != 1 || all[0].Name != "Review" || len(all[0].Tags) != 1 { t.Fatalf("templates = %v", all) } if all[0].Body != "## Summary\n" || all[0].Title != "Review: " || all[0].Slug != "review" { t.Fatalf("template fields = %+v", all[0]) } if _, err := s.Add(PostTemplate{Name: "Review"}); !errors.Is(err, ErrNameTaken) { t.Fatalf("duplicate accepted: %v", err) } if _, err := s.Add(PostTemplate{}); !errors.Is(err, ErrEmptyName) { t.Fatalf("empty name accepted: %v", err) } info, err := os.Stat(path) if err != nil { t.Fatalf("stat: %v", err) } if info.Mode().Perm() != 0o600 { t.Fatalf("mode = %v", info.Mode().Perm()) } reopened := New(path) if len(reopened.All()) != 1 { t.Fatalf("reopened = %v", reopened.All()) } } // The extra fields survive the round trip through the file, which is // what lets a scientific template pre-fill a DOI, a series or an ORCID. func TestFieldsRoundTrip(t *testing.T) { path := filepath.Join(t.TempDir(), "templates.toml") s := New(path) addTemplate(t, s, PostTemplate{ Name: "Paper", Fields: map[string]string{ "doi": "10.5555/", "orcid": "0000-0002-1825-0097", "series": "tds", "series_order": "2", }, }) reopened := New(path) all := reopened.All() if len(all) != 1 { t.Fatalf("templates = %v", all) } fields := all[0].Fields if fields["doi"] != "10.5555/" || fields["orcid"] != "0000-0002-1825-0097" || fields["series"] != "tds" || fields["series_order"] != "2" { t.Fatalf("fields = %v", fields) } // A template without extra fields reads back with none. addTemplate(t, s, PostTemplate{Name: "Bare"}) for _, tpl := range New(path).All() { if tpl.Name == "Bare" && tpl.Fields != nil { t.Fatalf("bare template has fields: %v", tpl.Fields) } } } func TestDelete(t *testing.T) { s := New(filepath.Join(t.TempDir(), "templates.toml")) addTemplate(t, s, PostTemplate{Name: "A"}) if err := s.Delete("A"); err != nil { t.Fatalf("Delete: %v", err) } if err := s.Delete("A"); !errors.Is(err, ErrNoSuchTemplate) { t.Fatalf("second Delete = %v, want ErrNoSuchTemplate", err) } } func TestMissingAndBrokenFiles(t *testing.T) { if got := New(filepath.Join(t.TempDir(), "nope.toml")).All(); got != nil { t.Fatalf("templates = %v, want none", got) } path := filepath.Join(t.TempDir(), "templates.toml") if err := os.WriteFile(path, []byte("broken = = ="), 0o600); err != nil { t.Fatalf("write: %v", err) } if got := New(path).All(); got != nil { t.Fatalf("templates = %v, want none", got) } } func TestEntriesWithoutNameSkipped(t *testing.T) { path := filepath.Join(t.TempDir(), "templates.toml") body := "[[templates]]\nbody = \"no name\"\n\n[[templates]]\nname = \"ok\"\n" if err := os.WriteFile(path, []byte(body), 0o600); err != nil { t.Fatalf("write: %v", err) } all := New(path).All() if len(all) != 1 || all[0].Name != "ok" { t.Fatalf("templates = %v", all) } } // A hand-written fields table with a scalar of any TOML type arrives as // its text, so a series order written bare as a number still fills the // form. func TestFieldsHandWrittenTable(t *testing.T) { path := filepath.Join(t.TempDir(), "templates.toml") body := "[[templates]]\nname = \"paper\"\n[templates.fields]\nseries_order = 3\ndoi = \"10.1/x\"\n" if err := os.WriteFile(path, []byte(body), 0o600); err != nil { t.Fatalf("write: %v", err) } all := New(path).All() if len(all) != 1 || all[0].Fields["series_order"] != "3" || all[0].Fields["doi"] != "10.1/x" { t.Fatalf("templates = %+v", all) } }