package server import ( "html/template" "testing" "testing/fstest" ) // TestComposeUITemplates covers the UIMount seam added for task 1.6 // (design.md Decision 8): an integration's Templates FS is parsed into the // shared template set only when every "*.html" file it contributes carries // the integration's slug prefix; a violation panics at startup rather than // silently registering an unnamespaced template. func TestComposeUITemplates(t *testing.T) { newBase := func() *template.Template { return template.Must(template.New("root").Parse(`{{define "root.html"}}root{{end}}`)) } t.Run("no mounts is a no-op", func(t *testing.T) { base := newBase() got := composeUITemplates(base, nil) if got.Lookup("root.html") == nil { t.Fatalf("expected core template to survive an empty mount list") } }) t.Run("mount with nil Templates is skipped", func(t *testing.T) { base := newBase() got := composeUITemplates(base, []UIMount{{Slug: "example", Templates: nil}}) if got.Lookup("root.html") == nil { t.Fatalf("expected core template to survive a mount with nil Templates") } }) t.Run("correctly slug-prefixed template is parsed in", func(t *testing.T) { base := newBase() mount := UIMount{ Slug: "example", Templates: fstest.MapFS{ "example_widget.html": &fstest.MapFile{Data: []byte("example widget")}, }, } got := composeUITemplates(base, []UIMount{mount}) if got.Lookup("example_widget.html") == nil { t.Fatalf("expected example_widget.html to be registered") } if got.Lookup("root.html") == nil { t.Fatalf("expected core template to still be present after composing in a mount") } }) t.Run("template name without slug prefix panics", func(t *testing.T) { base := newBase() mount := UIMount{ Slug: "example", Templates: fstest.MapFS{ "widget.html": &fstest.MapFile{Data: []byte("unnamespaced widget")}, }, } defer func() { if r := recover(); r == nil { t.Fatalf("expected composeUITemplates to panic on an unnamespaced template name") } }() composeUITemplates(base, []UIMount{mount}) }) }