Files
KenanZhu fec3ace600
Release / Validate Templates (push) Canceled after 0s
Release / Package & Release (push) Canceled after 0s
Release / Update Latest Release Documentation (push) Canceled after 0s
chore: migrate mail themes to shared framework and locked upstream inputs
2026-10-09 18:34:36 +08:00

107 lines
3.2 KiB
Go

package builder
import (
"bytes"
"gitea-mail-templates/tools/upstream"
"os"
"path/filepath"
"testing"
)
func TestGenerationPreservesSnapshot(t *testing.T) {
s, err := upstream.Load(filepath.Join("..", "..", "build", "upstream"))
if err != nil {
t.Fatal(err)
}
packages, err := BuildAll(filepath.Join("..", "..", "themes"), s, nil)
if err != nil {
t.Fatal(err)
}
for name, p := range packages {
if len(p.Files) != len(s.Templates)+3 {
t.Fatalf("%s missing generated files", name)
}
for filename, generated := range p.Files {
if _, ok := p.Theme.Controls[filename]; ok {
continue
}
original, err := StripInjections(generated)
if err != nil {
t.Fatal(err)
}
baseline := s.Templates[filename]
if !bytes.HasPrefix([]byte(filename), []byte("mail/base/")) {
baseline, err = AdaptOfficial(s, filename)
if err != nil {
t.Fatal(err)
}
}
if !bytes.Equal(original, baseline) {
t.Fatal("official source altered")
}
}
again, err := Build(s, p.Theme)
if err != nil {
t.Fatal(err)
}
for filename, b := range again.Files {
if !bytes.Equal(b, p.Files[filename]) {
t.Fatal("nondeterministic build")
}
}
}
shared, err := Build(s, &Theme{Name: "test", Mode: "shared", CSS: "a {color:#000}"})
if err != nil {
t.Fatal(err)
}
if len(shared.Files) != 2 {
t.Fatal("shared theme overrides正文")
}
output := filepath.Join(t.TempDir(), "build", "themes")
if err := Write(output, s, map[string]*Package{"test": packages["mono"]}); err != nil {
t.Fatal(err)
}
if err := Write(output, s, map[string]*Package{"test": shared}); err != nil {
t.Fatal(err)
}
if _, err := os.Stat(filepath.Join(output, "test", "mail", "repo", "release.tmpl")); !os.IsNotExist(err) {
t.Fatal("stale framed override retained")
}
}
func TestRejectUnsafeDecorationAndAnchors(t *testing.T) {
for _, markup := range []string{"<div>Extra text</div>", "<a href='https://example.com'></a>", "<div onclick='bad()'></div>", "<div>{{.Subject}}</div>", "<table><tr></table>"} {
if ValidateDecoration(markup) == nil {
t.Fatalf("accepted %s", markup)
}
}
for _, css := range []string{"a {background:url(https://example.com)}", "p {display:none}", "div:before {content:'Extra'}", "</style>"} {
if ValidateCSS(css) == nil {
t.Fatalf("accepted %s", css)
}
}
if err := ValidateCSS("p {font-size:0.9em}"); err != nil {
t.Fatal(err)
}
if ValidateCSS("p {font-size:0!important}") == nil {
t.Fatal("accepted hidden text")
}
for _, source := range []string{"<html></html>", "<body><body>{{template \"mail/base/footer\"}}</body>", "<body></body>", "<body>{{template \"mail/base/footer\"}}</body></body>"} {
if _, err := Frame([]byte(source), "<div>", "</div>"); err == nil {
t.Fatalf("accepted changed anchor %s", source)
}
}
good := []byte("<!-- <body> -->{{ $x := \"<body> }}\" }}<body>{{template \"mail/base/footer\"}}</body>")
result, err := Frame(good, "<div>", "</div>")
if err != nil {
t.Fatal(err)
}
stripped, err := StripInjections(result)
if err != nil || !bytes.Equal(stripped, good) {
t.Fatal("action/comment anchors altered")
}
if _, err := MaskActions([]byte("{{ /* unclosed")); err == nil {
t.Fatal("accepted invalid action")
}
}