krz/skunky-art

Alternative privacy frontend for DeviantArt.

clone: git clone https://gitbay.org/krz/skunky-art.git

v1.4.0: app/util_test.go · raw

  1package app
  2
  3import (
  4	"strings"
  5	"testing"
  6)
  7
  8// TestNavBaseRendersFirstPageWithoutPageCount is the regression test for the
  9// navigation panel vanishing on some artworks. The comment list on a deviation
 10// cannot count its pages, so it passes Pages: 0; on page one, with no further
 11// page to offer, the panel used to render as nothing but a <br>.
 12func TestNavBaseRendersFirstPageWithoutPageCount(t *testing.T) {
 13	s := skunkyart{Page: 1, _pth: "/deviation/1"}
 14
 15	out := s.NavBase(DeviationList{Pages: 0, More: false})
 16
 17	if strings.TrimSpace(strings.TrimPrefix(out, "<br>")) == "" {
 18		t.Fatalf("navigation panel is empty, want the current page rendered: %q", out)
 19	}
 20	if !strings.Contains(out, "1") {
 21		t.Errorf("current page number missing from %q", out)
 22	}
 23}
 24
 25// TestNavBaseFirstPageOffersNextWhenMore covers the same Pages: 0 case when a
 26// further page does exist: the current page must still appear alongside Next,
 27// rather than Next standing on its own with nothing to anchor it.
 28func TestNavBaseFirstPageOffersNextWhenMore(t *testing.T) {
 29	s := skunkyart{Page: 1, _pth: "/deviation/1"}
 30
 31	out := s.NavBase(DeviationList{Pages: 0, More: true})
 32
 33	if !strings.Contains(out, "Next") {
 34		t.Errorf("Next link missing from %q", out)
 35	}
 36	if !strings.Contains(out, "1") {
 37		t.Errorf("current page number missing from %q", out)
 38	}
 39}
 40
 41// TestNavBaseKnownPageCountUnchanged pins the ordinary path: when the caller
 42// does know the page count, the window is still bounded by it.
 43func TestNavBaseKnownPageCountUnchanged(t *testing.T) {
 44	s := skunkyart{Page: 1, _pth: "/gallery"}
 45
 46	out := s.NavBase(DeviationList{Pages: 3, More: true})
 47
 48	for _, want := range []string{"1", "2", "3"} {
 49		if !strings.Contains(out, want) {
 50			t.Errorf("page %s missing from %q", want, out)
 51		}
 52	}
 53	if strings.Contains(out, "p=4") {
 54		t.Errorf("linked past the last page in %q", out)
 55	}
 56}
 57
 58// TestInstanceAboutCarriesHideAI covers the About page and /api/instance both
 59// reading hide-ai from config, so a visitor can tell whether an instance
 60// filters AI-generated works without inferring it from absent results.
 61func TestInstanceAboutCarriesHideAI(t *testing.T) {
 62	hide := CFG.HideAI
 63	defer func() { CFG.HideAI = hide }()
 64
 65	for _, on := range []bool{true, false} {
 66		CFG.HideAI = on
 67		if got := (instanceAbout{HideAI: CFG.HideAI}).HideAI; got != on {
 68			t.Errorf("instanceAbout.HideAI = %v, want %v", got, on)
 69		}
 70		if got := (settingsParams{HideAI: CFG.HideAI}).HideAI; got != on {
 71			t.Errorf("settingsParams.HideAI = %v, want %v", got, on)
 72		}
 73	}
 74}
 75
 76// TestForcedThemeCSSOnlyForAnExplicitChoice pins that "auto" adds nothing: the
 77// stylesheet already carries dark plus a prefers-color-scheme light block, and
 78// appending a palette would defeat the visitor's own system setting.
 79func TestForcedThemeCSSOnlyForAnExplicitChoice(t *testing.T) {
 80	theme := CFG.Theme
 81	defer func() { CFG.Theme = theme }()
 82
 83	CFG.Theme = "auto"
 84	if got := forcedThemeCSS(); got != "" {
 85		t.Errorf("auto appended %q, want nothing", got)
 86	}
 87
 88	for _, want := range []string{"dark", "light"} {
 89		CFG.Theme = want
 90		css := forcedThemeCSS()
 91		if !strings.Contains(css, ":root{") {
 92			t.Errorf("%s theme did not emit a :root block: %q", want, css)
 93		}
 94		if !strings.Contains(css, "--bg:") || !strings.Contains(css, "--status-note:") {
 95			t.Errorf("%s theme is missing palette variables: %q", want, css)
 96		}
 97	}
 98}
 99
100// TestForcedThemeCSSCoversEveryVariable is the guard against a half-applied
101// palette: a forced theme that omits a variable falls through to the default
102// one, which is how a light theme ends up with black panels.
103func TestForcedThemeCSSCoversEveryVariable(t *testing.T) {
104	theme := CFG.Theme
105	defer func() { CFG.Theme = theme }()
106
107	vars := []string{
108		"--bg", "--fg", "--fg-strong", "--link", "--link-hover", "--edge",
109		"--edge-strong", "--accent", "--surface", "--surface-sunken",
110		"--surface-alt", "--surface-deep", "--status-bad", "--status-good",
111		"--status-mild", "--status-note",
112	}
113	for _, mode := range []string{"dark", "light"} {
114		CFG.Theme = mode
115		css := forcedThemeCSS()
116		for _, v := range vars {
117			if !strings.Contains(css, v+":") {
118				t.Errorf("%s theme does not set %s", mode, v)
119			}
120		}
121	}
122}