aboutsummaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-07-24 15:04:12 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-07-24 15:04:12 +0200
commite6665bd3f9ae011f65788004e4eab4472a461e8f (patch)
tree604141f068b03276d590d2e2418673960236e994 /internal
parent2453b598def94649cc7ce9af7155bfaad40cce12 (diff)
downloadlectio-e6665bd3f9ae011f65788004e4eab4472a461e8f.tar.gz
lectio-e6665bd3f9ae011f65788004e4eab4472a461e8f.zip
web: don't clobber books.toml when the settings books field is empty
Diffstat (limited to 'internal')
-rw-r--r--internal/web/server.go9
-rw-r--r--internal/web/server_test.go30
2 files changed, 37 insertions, 2 deletions
diff --git a/internal/web/server.go b/internal/web/server.go
index 34371b7..d7f0ebc 100644
--- a/internal/web/server.go
+++ b/internal/web/server.go
@@ -651,8 +651,13 @@ func settingsPost(s *server) http.HandlerFunc {
renderSettingsError(w, cfg, booksText, "saving config: "+err.Error())
return
}
- if p, err := config.BooksPath(); err == nil {
- _ = os.WriteFile(p, []byte(booksText), 0o644)
+ // Only write books.toml when the editor actually carried content, so a
+ // submit with an empty/absent books field never clobbers an existing
+ // override (the form always pre-fills the textarea).
+ if strings.TrimSpace(booksText) != "" {
+ if p, err := config.BooksPath(); err == nil {
+ _ = os.WriteFile(p, []byte(booksText), 0o644)
+ }
}
s.apply(cfg, newTbl)
diff --git a/internal/web/server_test.go b/internal/web/server_test.go
index ee36318..61546b8 100644
--- a/internal/web/server_test.go
+++ b/internal/web/server_test.go
@@ -567,3 +567,33 @@ func TestSettingsPostInvalidBooks(t *testing.T) {
}
func bibleDefaultBooks() []byte { return bible.DefaultBooksTOML() }
+
+// TestSettingsPostEmptyBooksPreservesFile guards that a submit without a books
+// field never clobbers an existing books.toml override.
+func TestSettingsPostEmptyBooksPreservesFile(t *testing.T) {
+ dir := t.TempDir()
+ t.Setenv("LECTIO_CONFIG", filepath.Join(dir, "config.toml"))
+ booksPath := filepath.Join(dir, "books.toml")
+ original := []byte("[en]\nJohn = [\"Jn\", \"John\"]\n")
+ if err := os.WriteFile(booksPath, original, 0o644); err != nil {
+ t.Fatal(err)
+ }
+ srv := NewServer(config.Default())
+ form := url.Values{}
+ form.Set("lectionary", "new")
+ form.Set("ui_language", "en")
+ form.Set("web_display", "vertical")
+ form.Set("web_theme", "transfiguration")
+ form.Set("default_version", "bt")
+ form["versions"] = []string{"bt"} // no "books" field
+ post := httptest.NewRequest("POST", "/settings", strings.NewReader(form.Encode()))
+ post.Header.Set("Content-Type", "application/x-www-form-urlencoded")
+ rec := httptest.NewRecorder()
+ srv.ServeHTTP(rec, post)
+ if rec.Code != http.StatusSeeOther {
+ t.Fatalf("status %d", rec.Code)
+ }
+ if got, _ := os.ReadFile(booksPath); string(got) != string(original) {
+ t.Errorf("empty books submit clobbered books.toml: got %q", got)
+ }
+}