summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-08-03 23:59:50 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-08-03 23:59:50 +0200
commit1106568c52265ea3076b9d3f1943c052c83a2a89 (patch)
treee969fca7657b7eeb5d612fc6f966c7f03051aa2e
parent27ceffcb90c0716179342109163c559d492a8abc (diff)
downloadlectio-1106568c52265ea3076b9d3f1943c052c83a2a89.tar.gz
lectio-1106568c52265ea3076b9d3f1943c052c83a2a89.zip
mobile: add PartLabels so the app stops hardcoding part IDs
-rw-r--r--mobile/mobile.go31
-rw-r--r--mobile/mobile_test.go45
2 files changed, 76 insertions, 0 deletions
diff --git a/mobile/mobile.go b/mobile/mobile.go
index e79e748..d863463 100644
--- a/mobile/mobile.go
+++ b/mobile/mobile.go
@@ -184,6 +184,37 @@ func Days(start string, count int, form, lang string) string {
return string(b)
}
+// partLabel is one section's machine ID and its human label.
+type partLabel struct {
+ Part string `json:"part"`
+ Label string `json:"label"`
+}
+
+// PartLabels returns the form's section IDs and their labels in lang, in display
+// order, as a JSON array. The app builds its reading filters from this instead
+// of hardcoding part IDs -- which is how it came to ship seven 1962 checkboxes
+// the engine never emits.
+//
+// An array, not an object: JSON object key order is not guaranteed and the app
+// renders these in order.
+func PartLabels(form, lang string) string {
+ ids := readings.PartIDs(lectByForm(form))
+ ui := i18n.Get(lang)
+ out := make([]partLabel, 0, len(ids))
+ for _, id := range ids {
+ label := ui.PartLabel[id]
+ if label == "" {
+ label = id
+ }
+ out = append(out, partLabel{Part: id, Label: label})
+ }
+ b, err := json.Marshal(out)
+ if err != nil {
+ return "[]"
+ }
+ return string(b)
+}
+
// Ping is a trivial JNI smoke test: it returns "pong" so the app can confirm the
// native engine loaded before issuing a real query.
func Ping() string { return "pong" }
diff --git a/mobile/mobile_test.go b/mobile/mobile_test.go
index 57e835a..1a115f3 100644
--- a/mobile/mobile_test.go
+++ b/mobile/mobile_test.go
@@ -123,3 +123,48 @@ func BenchmarkDaysWeek(b *testing.B) {
Days("2026-07-27", 7, "of", "pl")
}
}
+
+// This is the assertion that would have caught the app's dead 1962 checkboxes:
+// it listed nine part IDs where the engine emits two.
+func TestPartLabelsMatchesWhatTheEngineEmits(t *testing.T) {
+ var ef []map[string]any
+ if err := json.Unmarshal([]byte(PartLabels("ef", "pl")), &ef); err != nil {
+ t.Fatalf("invalid JSON: %v", err)
+ }
+ if len(ef) != 2 {
+ t.Fatalf("ef: got %d labels, want 2: %v", len(ef), ef)
+ }
+ if ef[0]["part"] != "epistola" || ef[0]["label"] != "Lekcja" {
+ t.Errorf("ef[0] = %v, want epistola/Lekcja", ef[0])
+ }
+ if ef[1]["part"] != "evangelium" || ef[1]["label"] != "Ewangelia" {
+ t.Errorf("ef[1] = %v, want evangelium/Ewangelia", ef[1])
+ }
+
+ var of []map[string]any
+ if err := json.Unmarshal([]byte(PartLabels("of", "pl")), &of); err != nil {
+ t.Fatalf("invalid JSON: %v", err)
+ }
+ if len(of) != 5 {
+ t.Fatalf("of: got %d labels, want 5: %v", len(of), of)
+ }
+ // aklamacja was missing from the app's hardcoded list.
+ var seen []string
+ for _, e := range of {
+ seen = append(seen, e["part"].(string))
+ }
+ want := []string{"pierwsze_czytanie", "psalm", "drugie_czytanie", "aklamacja", "ewangelia"}
+ for i := range want {
+ if seen[i] != want[i] {
+ t.Errorf("of order = %v, want %v", seen, want)
+ break
+ }
+ }
+}
+
+func TestPartLabelsUnknownForm(t *testing.T) {
+ // An unknown form is treated as the modern one, matching lectByForm.
+ if got := PartLabels("nonsense", "en"); got == "[]" {
+ t.Error("unknown form should fall back to the modern lectionary, not empty")
+ }
+}