aboutsummaryrefslogtreecommitdiff
path: root/internal/web
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-07-24 14:38:12 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-07-24 14:38:12 +0200
commit35f98e0a8a0573d51a4412ec7f60c7de068acfe6 (patch)
tree52bafbc1b3f8dc4c20dd5db536849a4f66daeda5 /internal/web
parentc769f80475e99b1f810fbb6c29eade3cc43a3786 (diff)
downloadlectio-35f98e0a8a0573d51a4412ec7f60c7de068acfe6.tar.gz
lectio-35f98e0a8a0573d51a4412ec7f60c7de068acfe6.zip
web: drop phantom hidden bt for traditional on explicit submit, so 'no version -> nothing' works in trad too; v0.13.1
Diffstat (limited to 'internal/web')
-rw-r--r--internal/web/server.go20
-rw-r--r--internal/web/server_test.go29
2 files changed, 49 insertions, 0 deletions
diff --git a/internal/web/server.go b/internal/web/server.go
index 6393076..7c90e9e 100644
--- a/internal/web/server.go
+++ b/internal/web/server.go
@@ -107,6 +107,17 @@ func requestVersions(cfg config.Config, r *http.Request) []string {
return []string{cfg.DefaultVersion}
}
+// withoutVersion returns versions with every occurrence of drop removed.
+func withoutVersion(versions []string, drop string) []string {
+ kept := make([]string, 0, len(versions))
+ for _, v := range versions {
+ if v != drop {
+ kept = append(kept, v)
+ }
+ }
+ return kept
+}
+
// queryBool reads a truthy/falsy query param ("1"/"true"/"on"/"yes" vs.
// "0"/"false"/"off"/"no"), falling back to def when the param is absent or
// unrecognized.
@@ -156,6 +167,15 @@ func resolveQuery(cfg config.Config, r *http.Request) (date, lectionary string,
lectionary = requestLectionary(cfg, r)
all = queryBool(r, "all", cfg.All)
versions = requestVersions(cfg, r)
+ // "bt" (the niedziela modern scrape) is invalid for the traditional
+ // lectionary and is hidden in the form -- but a box hidden by CSS stays
+ // checked, so switching modern->traditional carries a phantom v=bt that
+ // EffectiveVersions would substitute to wuj, defeating "no version selected
+ // -> nothing". On an explicit form submit (vset) drop that phantom bt; a
+ // fresh visit (no vset) keeps bt so its bt->wuj default still shows.
+ if lectionary == "traditional" && r.URL.Query().Has("vset") {
+ versions = withoutVersion(versions, "bt")
+ }
display = requestDisplay(cfg, r)
return date, lectionary, all, versions, display
}
diff --git a/internal/web/server_test.go b/internal/web/server_test.go
index 925ea18..5f15796 100644
--- a/internal/web/server_test.go
+++ b/internal/web/server_test.go
@@ -437,6 +437,35 @@ func TestVsetEmptyShowsNothing(t *testing.T) {
}
}
+// TestTraditionalDropsPhantomBT guards the traditional case of "no version ->
+// nothing": a phantom checked-but-hidden bt (carried over from modern) must not
+// substitute to wuj on an explicit form submit, but a fresh visit keeps the
+// bt->wuj default.
+func TestTraditionalDropsPhantomBT(t *testing.T) {
+ srv := NewServer(config.Default())
+
+ // Explicit submit, only the phantom bt "checked": empty pane.
+ phantom := httptest.NewRecorder()
+ srv.ServeHTTP(phantom, httptest.NewRequest("GET", "/readings?vset=1&lectionary=traditional&v=bt", nil))
+ if b := strings.TrimSpace(phantom.Body.String()); b != "" {
+ t.Errorf("traditional vset+v=bt should be empty, got %d bytes", len(b))
+ }
+
+ // Explicit submit, bt phantom + a real corpus version: still renders it.
+ withWuj := httptest.NewRecorder()
+ srv.ServeHTTP(withWuj, httptest.NewRequest("GET", "/readings?vset=1&lectionary=traditional&v=bt&v=wuj", nil))
+ if !strings.Contains(withWuj.Body.String(), "block") {
+ t.Errorf("traditional vset+v=bt+v=wuj should still render wuj")
+ }
+
+ // Fresh visit (no vset): the bt->wuj default is kept and wuj is checked.
+ fresh := httptest.NewRecorder()
+ srv.ServeHTTP(fresh, httptest.NewRequest("GET", "/?lectionary=traditional", nil))
+ if !strings.Contains(fresh.Body.String(), `value="wuj" checked`) {
+ t.Errorf("fresh traditional visit should default to wuj (checked)")
+ }
+}
+
// TestReaderPaneOutsideForm guards the mono fix: #pane must render AFTER the
// controls </form> so its reading text inherits body's --font-reading (which
// the mono toggle flips) instead of the form's --font-ui.