package markup
import (
"regexp"
"strings"
"testing"
"craftdesign.group/quarry/internal/idn"
)
// The identicon is idn's face, cell for cell, drawn as a table: five
// rows of five, a cell coloured exactly where the grid is on and in the
// shade the grid says.
func TestIdenticonMarkMatchesTheGrid(t *testing.T) {
const name = "dantest-sandbox"
got := string(IdenticonMark(name))
for _, banned := range []string{"<svg", "<img", "display:grid", "display:flex", "url("} {
if strings.Contains(got, banned) {
t.Errorf("mark carries %s", banned)
}
}
inner := got[strings.Index(got, `align="center"`):]
rows := strings.Split(inner, "<tr>")[1:]
if len(rows) != 5 {
t.Fatalf("%d rows", len(rows))
}
lit, deep := idn.Hex(name, markLit), idn.Hex(name, markDeep)
for r, row := range rows {
cells := regexp.MustCompile(`<td [^>]*>`).FindAllString(row, -1)
if len(cells) != 5 {
t.Fatalf("row %d: %d cells", r, len(cells))
}
for c, cell := range cells {
want := ""
switch idn.Grid(name)[r][c] {
case 1:
want = `bgcolor="` + lit + `"`
case 2:
want = `bgcolor="` + deep + `"`
}
if has := strings.Contains(cell, "bgcolor="); has != (want != "") || (want != "" && !strings.Contains(cell, want)) {
t.Errorf("cell %d,%d = %s, want %q", r, c, cell, want)
}
}
}
}
func TestAvatarMarkIsOneSizedImage(t *testing.T) {
got := string(AvatarMark("https://forge.example/r/alpha/avatar", "alpha"))
for _, want := range []string{`src="https://forge.example/r/alpha/avatar"`, `width="28"`, `height="28"`, `border-radius:6px`, `alt="alpha"`} {
if !strings.Contains(got, want) {
t.Errorf("missing %s", want)
}
}
}
// With nothing else to name, a card is the application's: no lowercase
// repository name, and the lockup tile where the name would be, then
// again in the footer in its small rendition.
func TestAccountCardIsTheApplicationsNotARepositorys(t *testing.T) {
got, ok := EmailDocument(EmailDoc{Title: "t", Surface: "account", Body: "<p>x</p>", Why: "w"})
if !ok || strings.Contains(got, ">quarry<") || !strings.Contains(got, ">QUARRY<") {
t.Errorf("fallback header: %v", ok)
}
const big, small = "https://forge.example/lockup.png", "https://forge.example/lockup-sm.png"
got, _ = EmailDocument(EmailDoc{Title: "t", Surface: "account", Body: "<p>x</p>", Why: "w",
LockupURL: big, LockupSmallURL: small, HomeURL: "https://forge.example", HomeName: "forge.example"})
if !strings.Contains(got, `<img src="`+big+`" alt="QUARRY" width="92" height="28"`) {
t.Error("header lockup")
}
if !strings.Contains(got, `<img src="`+small+`" alt="QUARRY" width="59" height="18"`) {
t.Error("footer lockup")
}
if strings.Contains(got, "Sent by") || strings.Contains(got, ">quarry<") || strings.Contains(got, "◆") {
t.Error("lowercase quarry, the diamond or the old footer words")
}
}
// A repository's header keeps its own mark and name; only the footer
// carries the lockup. And no orange wordmark is left anywhere in mail.
func TestRepoCardKeepsItsMarkAndFooterHasTheLockup(t *testing.T) {
const small = "https://forge.example/lockup-sm.png"
got, _ := EmailDocument(EmailDoc{Title: "t", Name: "alpha", Mark: IdenticonMark("alpha"), Body: "<p>x</p>", LockupURL: "https://forge.example/lockup.png", LockupSmallURL: small})
if strings.Count(got, "<img") != 1 || !strings.Contains(got, `<img src="`+small+`"`) || strings.Contains(got, "lockup.png") {
t.Errorf("repo card images: %d", strings.Count(got, "<img"))
}
if strings.Contains(strings.ToLower(got), "b9541a") || strings.Contains(got, "wordmark") {
t.Error("the orange wordmark is still in mail")
}
}