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}