Skip to content
quarry Artifact [b31ce024a2]
Login

Artifact [b31ce024a2]

Artifact b31ce024a2338ef8d41a6bee20f17ca0646b91188f0c89ec66f1941642ae023c:


package markup

import (
	"html/template"
	"regexp"
	"strings"
	"testing"
)

func cardOf(t *testing.T, d EmailDoc) string {
	t.Helper()
	if d.Body == "" {
		d.Body = "<p>hi</p>"
	}
	got, ok := EmailDocument(d)
	if !ok {
		t.Fatal("EmailDocument fell back")
	}
	return got
}

var cardDoc = EmailDoc{
	Title: "t", Name: "alpha", Mark: IdenticonMark("alpha"), Surface: "chat",
	Context: "<strong>jva</strong> mentioned you", Meta: "now",
	Open: "Open the message", OpenURL: "https://forge.example/r/alpha/chat/7",
	Why: "because", SettingsURL: "https://forge.example/me#notifications",
	HomeURL: "https://forge.example", HomeName: "forge.example",
}

func TestEmailDocumentIsOneTableCard(t *testing.T) {
	got := cardOf(t, cardDoc)
	if n := strings.Count(got, `class="q-card"`); n != 1 {
		t.Errorf("%d cards", n)
	}
	for _, want := range []string{`max-width:600px`, `role="presentation"`, `class="q-page"`, `class="q-btn"`, `<!doctype html>`} {
		if !strings.Contains(got, want) {
			t.Errorf("missing %s", want)
		}
	}
	for _, banned := range []string{"<div style=\"display:flex", "display:grid", "<img", "<script", "<svg"} {
		if strings.Contains(got, banned) {
			t.Errorf("carries %s", banned)
		}
	}
}

func TestEmailDocumentLoadsOnlyTheFontSheet(t *testing.T) {
	got := cardOf(t, cardDoc)
	for _, m := range regexp.MustCompile(`(?:src|href)="([^"]*)"`).FindAllStringSubmatch(got, -1) {
		u := m[1]
		if !strings.HasPrefix(u, "https://") {
			t.Errorf("non-absolute %q", u)
		}
	}
	links := regexp.MustCompile(`<link [^>]*>`).FindAllString(got, -1)
	if len(links) != 1 || !strings.Contains(links[0], `href="https://fonts.googleapis.com/`) {
		t.Errorf("links: %v", links)
	}
	if strings.Contains(got, "@import") || strings.Contains(got, "url(") {
		t.Error("remote resource in the stylesheet")
	}
}

func TestEmailDocumentReplyHintOnlyWhenAsked(t *testing.T) {
	if got := cardOf(t, cardDoc); strings.Contains(got, "reply to this email") {
		t.Error("reply hint without ReplyIn")
	}
	d := cardDoc
	d.ReplyIn = "answer in chat"
	if got := cardOf(t, d); !strings.Contains(got, "reply to this email") {
		t.Error("no reply hint with ReplyIn")
	}
}

func TestEmailDocumentHasDarkBlockAndPlexFirst(t *testing.T) {
	got := cardOf(t, cardDoc)
	if !strings.Contains(got, "@media (prefers-color-scheme: dark)") {
		t.Error("no dark block")
	}
	if !strings.Contains(got, "font-family:'IBM Plex Sans',") {
		t.Error("Plex Sans is not first")
	}
}

func TestEmailDocumentEscapesAndCaps(t *testing.T) {
	d := cardDoc
	d.Name = "<b>x</b>"
	if got := cardOf(t, d); strings.Contains(got, "<b>x</b>") {
		t.Error("repo not escaped")
	}
	d.Body = template.HTML("<p>" + strings.Repeat("word ", EmailHTMLMax/4) + "</p>")
	if _, ok := EmailDocument(d); ok {
		t.Error("oversized document kept")
	}
}