summaryrefslogtreecommitdiff
path: root/internal/web/server_test.go
Commit message (Collapse)AuthorAgeFilesLines
* test(bible): skip corpus-dependent tests when optional corpora aren't embeddedLukasz Kasprzak2026-07-291-12/+46
| | | | | | | | | | | | | | | | | | | | | | | | Since 51c0f4e split the corpora (only vul embedded by default; wuj/drb/grb behind -tags fullbible), `go test ./...` on the default build was red across six packages -- every failure was a test assuming an optional corpus is present. Guard those assertions with a skip keyed on bible.Meta(code), so they run under -tags fullbible and skip -- not fail -- on the default vul-only build. Mixed tests are split into subtests so the always-embedded vul assertions and pure logic (pl->vul fallback, explicit passthrough, bt-rejection, i18n labels) keep running on both builds. Test-only change; no product code or corpora touched. - internal/bible: TestVerses, TestLookup, TestCorpusBooks, TestChapters, TestGrbNoApparatusMarkers, TestCrossChapterRange* (requireCorpus helper). - internal/cli, config, render, tui, web: the same pattern for their corpus-dependent tests. - Fixes an index-out-of-range panic in internal/tui's reader tests that was aborting the package binary and masking 3 further corpus-absence failures (TestReaderBookmarkFlow, TestReaderChapterJump, TestReaderRemembersPlace). Verified: `go test ./...` and `go test -tags fullbible ./...` both green (0 FAIL); guards active only on the default build (29 skips vs 1 unrelated pre-existing); gofmt and go vet clean.
* licence: relicense MIT -> AGPL-3.0-or-laterLukasz Kasprzak2026-07-281-0/+49
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | lectio was MIT, which let anyone take it closed. The concern is not people selling it -- no licence stops that, and the AGPL does not try to -- but someone building a proprietary product on it and giving nothing back. Plain GPL would leave the obvious hole open: lectio-web is a network service, and hosting is not distribution, so a modified lectio-web could be run as a paid subscription API without ever publishing a line. AGPL section 13 closes exactly that. LICENSE is the verbatim FSF text. README carries the standard notice. Section 13 requires a modified network-reachable version to PROMINENTLY offer its source to the users interacting with it, so the offer ships with the code rather than living only in a file nobody fetches: - GET /source plain text, no template or config dependency, so it answers even when something else is broken - page footers every full page (fragments render inside one) - JSON envelope "source" / "license" - iCal header X-LECTIO-SOURCE / X-LECTIO-LICENSE The feed fields are not redundant: an /api/calendar.json consumer or an .ics subscriber never loads a page, so the footer alone would miss them. config.SourceURL is the single source of truth, and says in its comment that a fork running as a service must repoint it -- an offer that leads to someone else's code is not an offer. Tests pin all of it. This is a licence obligation, not a feature, so it should fail loudly if a later change drops it.
* refactor: remove the niedziela/missalemeum scrapers, bt, traditional_langLukasz Kasprzak2026-07-281-102/+69
| | | | | | | | | | | | | | | | | | | | | | The daily view now computes entirely offline (previous commit), so retire the network path and everything that served it: - Delete internal/tradlit (missalemeum) and the niedziela scraper from internal/liturgy (fetch/store/parse + fixtures); keep Section, DayInfo and ExtractCitation. - Remove the "bt" version everywhere (render gatherBT + branches, config, i18n, web form, TUI) and bible.ToEnglishRef (Polish citation converter). A legacy config carrying "bt" migrates to "wuj" on load (config.migrateBT). - Remove the traditional_lang config field and the -g/--lang flag from all three binaries. - Drop the now-dead flags -R/--refresh, -o/--offline, -u/--update, -C/--clean and the harvest/clean commands. - New defaults: versions = wuj,vul,grb,drb; default_version = vul. Update the README (offline-by-design, no harvest/update), help text, and stale niedziela/bt doc comments. Tests updated for the offline reality; go test ./... and go vet ./... are clean, all three binaries build and run offline (OF + EF, compare, web).
* feat: books.toml -> books.ini, multi-language (add Latin dialect), ↵Lukasz Kasprzak2026-07-271-5/+5
| | | | | | | | | | config-scoped citation display books.ini with [en]/[pl]/[la]; parseBooks reads INI (bible drops go-toml). Latin dialect resolves EF citations (Eccli->Sirach, Apoc->Revelation, Luc...); sigla_style gains 'latin'. Reading citations now DISPLAY in the configured sigla (FormatRef(SiglaLang)), not raw English. One-shot books.toml->books.ini user migration (go-toml now config-only). Web settings editor -> books.ini.
* export: month calendar PDF (A4 landscape, Monday-first grid, feast name + ↵Lukasz Kasprzak2026-07-241-0/+18
| | | | gospel ref + liturgical colour per day); cli --calendar YYYY-MM; web /calendar + link; readings.GospelCitation; v0.23.0
* export: internal/export (Markdown/Text/ReadingsPDF via pure-Go go-pdf/fpdf + ↵Lukasz Kasprzak2026-07-241-0/+12
| | | | embedded DejaVu Sans, covers pl/la/gr); cli --md/--pdf/--out; web /export + download links; v0.22.0
* bookmarks: per-verse (optional Verse field); web reader verse input + list ↵Lukasz Kasprzak2026-07-241-2/+4
| | | | shows Book Ch:V; v0.17.0
* bookmarks: web reader bookmarks with notes + tags ↵Lukasz Kasprzak2026-07-241-0/+34
| | | | (add/list/filter/jump/delete); v0.15.0
* web: don't clobber books.toml when the settings books field is emptyLukasz Kasprzak2026-07-241-0/+30
|
* web: /settings page to edit config + books.toml, persisted and applied live; ↵Lukasz Kasprzak2026-07-241-0/+68
| | | | v0.14.0
* web: drop phantom hidden bt for traditional on explicit submit, so 'no ↵Lukasz Kasprzak2026-07-241-0/+29
| | | | version -> nothing' works in trad too; v0.13.1
* web: empty pane when no version selected (hidden vset marker); config ↵Lukasz Kasprzak2026-07-241-0/+30
| | | | default checked on fresh load; v0.13.0
* web reader: fix chapter arrows (drive chap select) + mono (move #pane out of ↵Lukasz Kasprzak2026-07-241-0/+34
| | | | controls form)
* qol: tui jump-to-date (d) + lectio --citation/--week + hide bt for ↵Lukasz Kasprzak2026-07-241-0/+20
| | | | traditional web; v0.10.0
* web reader: /reader book picker + chapter nav + version compare, reusing ↵Lukasz Kasprzak2026-07-241-0/+51
| | | | pane templates; v0.9.0
* dayinfo: show feast/day name + colour (modern niedziela + traditional ↵Lukasz Kasprzak2026-07-241-2/+7
| | | | missalemeum) in cli/tui/web; v0.5.0
* rename the pl scripture version to bt (Biblia Tysiąclecia); v0.4.0Lukasz Kasprzak2026-07-241-5/+5
| | | | | | | | | | The niedziela.pl scraped Polish paragraph text is the Biblia Tysiąclecia translation; rename its version code from "pl" to "bt" and its i18n label to "Biblia Tysiąclecia (niedziela.pl)" everywhere the scripture VERSION is meant, across config, i18n, render, web, tui, cli and both binaries' help text. Language-role "pl" (ui_language, traditional_lang, i18n.Get lang, --lang validation) is untouched. Behavior is identical -- bt is still dropped for offline/traditional and substituted with wuj.
* i18n: fix consistency-review gaps in ui_language (en/pl chrome)Lukasz Kasprzak2026-07-231-0/+47
| | | | | | | | | | | | | | | | | | | | | | | | | Closes six findings from review of the ui_language feature so English mode carries no leftover Polish UI text: - Web: interlinear "no verses" note and the empty-day error fragment now route through i18n instead of being unconditionally Polish. - render.GatherVersion/GatherVerses/resolveRef's four lookup/citation- failure blocks are now lang-aware (resolveRef gained a lang param). - i18n.ErrorPrefix/NoReadingsFor lost a stray extra trailing space, restoring the pre-i18n single-space TUI concatenation. - render.LocalizeHeading now matches a heading's actual leading label text against all known modern pl labels, rather than trusting the label keyed by sec.PartID -- fixes split-feast days where PartID is "drugie_czytanie" but the heading still reads "1. czytanie ...". - cli bannerFor is lang-specific again (pl "na", en "for"), restoring pl's exact pre-i18n wording instead of "--" for both languages. - index.html's <html lang> now follows cfg.UILanguage instead of being hardcoded "pl". gofmt/vet clean, go test ./... green, all three binaries build, no new go.mod deps. Consistency grep across cli/tui/web/render's live source turns up only two non-displayed identifiers (a PartID slug list and a pre-existing incipit-stripping constant on the pl scripture text itself).
* i18n: ui_language config (default en) for UI chrome across cli/tui/web; ↵Lukasz Kasprzak2026-07-231-3/+8
| | | | version labels localised
* web: theme control boxes, one default version, drop search bar; traditional ↵Lukasz Kasprzak2026-07-231-27/+0
| | | | drops pl + all=readings-only
* web,liturgy: validate date against path traversal; bind lectio-web to localhostLukasz Kasprzak2026-07-231-1/+52
| | | | | | | | | | | | | | | | | An unvalidated ?date= query param flowed straight into liturgy.Load's filepath.Join(dir, date+".json"/".html") before any network call, letting a crafted date (e.g. "../../../../etc/hostname") read an arbitrary file whose JSON, if present, unmarshals into []liturgy.Section and renders back to the client. Fix both layers: resolveQuery now falls back to today() on empty or non-YYYY-MM-DD date (mirroring requestDisplay's normalize-don't-trust pattern), and liturgy.Load itself rejects a non-matching date before building any cache path, protecting every caller even if a future one forgets to validate. Also bind lectio-web's listener to 127.0.0.1 instead of all interfaces: it is a personal tool whose Run already prints http://localhost:<port>, so it should not be reachable from the LAN.
* web: default lectio-web to port 1099 with free-port fallbackLukasz Kasprzak2026-07-231-0/+58
| | | | | | | | | | | | | chooseListener(port) factors the listen logic out of Run: port==0 now tries defaultWebPort (1099) first and only falls back to an OS-picked free port if 1099 is taken; a non-zero port is still bound exactly, surfacing its bind error as before. config.Default() keeps WebPort: 0 unchanged (0 still means "auto"). Adds TestChooseListener, robust to sandboxes that can't bind 1099 or :0 (t.Skip instead of failing). Also folds the ?ref= whitespace trim into renderLookup itself so GET / and GET /lookup treat a whitespace-only ref identically (previously only lookupHandler trimmed it).
* web: horizontal/vertical/interlinear display modes + web_display configLukasz Kasprzak2026-07-231-0/+91
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Adds a display-layout option to lectio-web alongside the existing colour themes: - config: WebDisplay field (toml web_display), default "horizontal", normalized on load via the new exported config.NormalizeDisplay (unknown -> "horizontal", same lenient style as the other web_* fields). - render: extracts the citation/ToEnglishRef resolution shared by GatherVersion into an unexported resolveRef helper (GatherVersion's signature/behavior unchanged) and adds GatherVerses(version, sec, lectionary) returning raw bible.Verse structs plus a versified flag, for column/interlinear alignment. - web/render: RenderReadings gains a display parameter. "horizontal" is the original stacked layout, byte-for-byte the same code path as before. "vertical" reuses the same per-version column data in a .display-vertical/.vcol grid (the CLI compare view, browser-side). "interlinear" maps versions through render.OfflineVersions' pl->wuj substitution (pl has no verse numbers), gathers GatherVerses per version, and interleaves them by chapter:verse into .ilverse/.illine blocks (ordered union of keys, first versified version's order first). - server: adds a display <select> to the top bar wired into the existing #controls HTMX form; a resolveQuery(cfg, r) helper replaces the duplicated date/lectionary/all/versions(+now display) resolution in indexHandler and readingsHandler. - fold-in from the B2 review: indexHandler now populates indexData.Lookup via a shared renderLookup(ref, versions) helper (also used by lookupHandler), so a bookmarked "/?ref=...&v=..." link shows its lookup result instead of an empty pane. - base.css: layout-only rules for the two new modes (no colours; themes stay colour-only). go test ./..., go vet ./..., gofmt clean; go build ./cmd/lectio-web ok.
* web: HTMX server + lectio-web binaryLukasz Kasprzak2026-07-231-0/+107
NewServer wires B1's RenderReadings/Themes/themeCSS/embedded static+ templates FS into an http.ServeMux: GET / (full page), GET /readings (HTMX reading-pane fragment), GET /lookup (bible.Lookup passage search fragment), GET /theme.css (theme stylesheet, falling back through cfg.WebTheme to the built-in default on an unknown name), GET /static/. Run listens on cfg.WebPort (0 = OS-picked free port), prints the URL, best-effort opens a browser, then serves. cmd/lectio-web is the binary entry point (config.Load -> web.Run). Fold-in from the B1 review: hardened themeCSS's name guard to an explicit ^[A-Za-z0-9_-]+$ allowlist (the old filepath.Base/ContainsAny check let ".." through), plus guard-rejection and HTML-escaping regression tests -- B2 is what makes /theme.css?name=<raw> reachable from the network, so it owns closing this out.