126 lines
3.7 KiB
Go
126 lines
3.7 KiB
Go
package badge
|
|
|
|
import (
|
|
"bytes"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestRenderEscapesText(t *testing.T) {
|
|
data, etag := Render(Options{Label: `<script>`, Message: `A&B`, Extent: "assisted"})
|
|
if bytes.Contains(data, []byte(`<script>`)) {
|
|
t.Fatal("unescaped label")
|
|
}
|
|
if !bytes.Contains(data, []byte(`A&B`)) {
|
|
t.Fatal("message not escaped")
|
|
}
|
|
if etag == "" {
|
|
t.Fatal("missing etag")
|
|
}
|
|
}
|
|
|
|
func TestRenderEmojiIsSquareAndPresetSpecific(t *testing.T) {
|
|
data, etag := Render(Options{
|
|
Label: "KI-Nutzung",
|
|
Message: "Vollständige Inhaltserstellung",
|
|
Extent: "full",
|
|
Preset: "full",
|
|
Theme: "emoji",
|
|
})
|
|
body := string(data)
|
|
for _, expected := range []string{
|
|
`width="64" height="64"`,
|
|
`viewBox="0 0 64 64"`,
|
|
`data-theme="emoji"`,
|
|
`data-icon="bolt"`,
|
|
`fill="#c53030"`,
|
|
`<title>KI-Nutzung: Vollständige Inhaltserstellung</title>`,
|
|
} {
|
|
if !bytes.Contains(data, []byte(expected)) {
|
|
t.Fatalf("emoji SVG missing %q: %s", expected, body)
|
|
}
|
|
}
|
|
if etag == "" {
|
|
t.Fatal("missing etag")
|
|
}
|
|
}
|
|
|
|
func TestRenderEmojiUsesCustomColoursAndEscapesAccessibleText(t *testing.T) {
|
|
data, _ := Render(Options{
|
|
Label: `<AI>`,
|
|
Message: `Research & review`,
|
|
Extent: "assisted",
|
|
Preset: "research",
|
|
Theme: "emoji",
|
|
LeftColor: "#112233",
|
|
RightColor: "#abcdef",
|
|
})
|
|
body := string(data)
|
|
for _, expected := range []string{
|
|
`data-icon="research"`,
|
|
`fill="#abcdef"`,
|
|
`stroke="#112233"`,
|
|
`<AI>: Research & review`,
|
|
} {
|
|
if !strings.Contains(body, expected) {
|
|
t.Fatalf("emoji SVG missing %q: %s", expected, body)
|
|
}
|
|
}
|
|
if strings.Contains(body, `<AI>`) {
|
|
t.Fatal("accessible text was not escaped")
|
|
}
|
|
}
|
|
|
|
func TestEmojiIconMapping(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
options Options
|
|
icon string
|
|
}{
|
|
{name: "no AI", options: Options{Extent: "none", Preset: "no-ai", Theme: "emoji"}, icon: "human"},
|
|
{name: "research", options: Options{Extent: "assisted", Preset: "research", Theme: "emoji"}, icon: "research"},
|
|
{name: "summary", options: Options{Extent: "assisted", Preset: "summary", Theme: "emoji"}, icon: "summary"},
|
|
{name: "full", options: Options{Extent: "full", Preset: "full", Theme: "emoji"}, icon: "bolt"},
|
|
{name: "article", options: Options{Extent: "mostly", Article: true, Theme: "emoji"}, icon: "article"},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
data, _ := Render(tt.options)
|
|
if !bytes.Contains(data, []byte(`data-icon="`+tt.icon+`"`)) {
|
|
t.Fatalf("expected icon %q: %s", tt.icon, data)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestFlatBadgeAutomaticallyChoosesContrastingText(t *testing.T) {
|
|
data, _ := Render(Options{Label: "KI-Nutzung", Message: "Teilweise", Extent: "partial", Theme: "color"})
|
|
body := string(data)
|
|
if !strings.Contains(body, `fill="#b7791f"`) {
|
|
t.Fatalf("expected partial background: %s", body)
|
|
}
|
|
if !strings.Contains(body, `fill="#000000">Teilweise</text>`) {
|
|
t.Fatalf("expected automatic black text on gold background: %s", body)
|
|
}
|
|
if ratio := contrastRatio("#000000", "#b7791f"); ratio < 4.5 {
|
|
t.Fatalf("contrast ratio %.2f is below 4.5", ratio)
|
|
}
|
|
}
|
|
|
|
func TestEmojiBadgeAdjustsInsufficientCustomForegroundContrast(t *testing.T) {
|
|
data, _ := Render(Options{
|
|
Label: "KI-Nutzung", Message: "Hinweis", Extent: "assisted", Theme: "emoji",
|
|
LeftColor: "#ffffff", RightColor: "#abcdef",
|
|
})
|
|
body := string(data)
|
|
if strings.Contains(body, `stroke="#ffffff"`) {
|
|
t.Fatalf("low-contrast custom foreground was not adjusted: %s", body)
|
|
}
|
|
if !strings.Contains(body, `stroke="#000000"`) {
|
|
t.Fatalf("expected automatic black icon foreground: %s", body)
|
|
}
|
|
if ratio := contrastRatio("#000000", "#abcdef"); ratio < 3 {
|
|
t.Fatalf("adjusted contrast ratio %.2f is below 3", ratio)
|
|
}
|
|
}
|