aboutsummaryrefslogtreecommitdiff
path: root/mobile/mobile_test.go
blob: 57e835a44179856ffa273d55580de916e35424eb (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package mobile

import (
	"encoding/json"
	"strings"
	"testing"
)

func decodeDay(t *testing.T, s string) map[string]any {
	t.Helper()
	var m map[string]any
	if err := json.Unmarshal([]byte(s), &m); err != nil {
		t.Fatalf("Day returned invalid JSON: %v\n%s", err, s)
	}
	return m
}

func TestDayCarriesLocalisedRank(t *testing.T) {
	pl := decodeDay(t, Day("2026-08-01", "of", "vul", "pl"))
	if pl["rank"] != "memorial" {
		t.Errorf("pl rank = %v, want memorial", pl["rank"])
	}
	if pl["rank_label"] != "wspomnienie obowiązkowe" {
		t.Errorf("pl rank_label = %v", pl["rank_label"])
	}
	en := decodeDay(t, Day("2026-08-01", "of", "vul", "en"))
	if en["rank_label"] != "memorial" {
		t.Errorf("en rank_label = %v", en["rank_label"])
	}
}

// The app shows the colour as a swatch and never as a word, so the raw key must
// be present and no localised label may be. This test exists so the app cannot
// quietly start depending on a colour word.
func TestDayHasColourKeyButNoColourLabel(t *testing.T) {
	m := decodeDay(t, Day("2026-08-01", "of", "vul", "pl"))
	if m["colour"] != "white" {
		t.Errorf("colour = %v, want white", m["colour"])
	}
	if _, present := m["colour_label"]; present {
		t.Error("colour_label must not be returned: the app draws a swatch")
	}
}

func decodeDays(t *testing.T, s string) []map[string]any {
	t.Helper()
	var a []map[string]any
	if err := json.Unmarshal([]byte(s), &a); err != nil {
		t.Fatalf("Days returned invalid JSON: %v\n%s", err, s)
	}
	return a
}

func TestDaysReturnsConsecutiveDates(t *testing.T) {
	a := decodeDays(t, Days("2026-07-27", 7, "of", "pl"))
	if len(a) != 7 {
		t.Fatalf("got %d elements, want 7", len(a))
	}
	want := []string{"2026-07-27", "2026-07-28", "2026-07-29", "2026-07-30",
		"2026-07-31", "2026-08-01", "2026-08-02"}
	for i, w := range want {
		if a[i]["date"] != w {
			t.Errorf("element %d date = %v, want %v", i, a[i]["date"], w)
		}
	}
}

// Days must agree with Day about the same date -- it is a cheaper projection of
// the same computation, not a second implementation.
func TestDaysAgreesWithDay(t *testing.T) {
	one := decodeDay(t, Day("2026-08-01", "of", "vul", "pl"))
	week := decodeDays(t, Days("2026-08-01", 1, "of", "pl"))
	if len(week) != 1 {
		t.Fatalf("got %d elements, want 1", len(week))
	}
	row := week[0]
	for _, k := range []string{"name", "colour", "rank", "rank_label"} {
		if row[k] != one[k] {
			t.Errorf("%s: Days = %v, Day = %v", k, row[k], one[k])
		}
	}
	parts := row["parts"].([]any)
	readings := one["readings"].([]any)
	if len(parts) != len(readings) {
		t.Fatalf("parts = %d, readings = %d", len(parts), len(readings))
	}
	for i := range parts {
		p := parts[i].(map[string]any)
		r := readings[i].(map[string]any)
		if p["part"] != r["part"] || p["citation"] != r["citation"] {
			t.Errorf("element %d: Days %v/%v vs Day %v/%v",
				i, p["part"], p["citation"], r["part"], r["citation"])
		}
	}
}

// No reading text may cross the boundary: that is the whole point of Days.
func TestDaysCarriesNoReadingText(t *testing.T) {
	s := Days("2026-08-01", 7, "of", "pl")
	if strings.Contains(s, `"text"`) {
		t.Error("Days must not return reading text")
	}
	if strings.Contains(s, "colour_label") {
		t.Error("Days must not return a colour label")
	}
}

func TestDaysRejectsBadInput(t *testing.T) {
	for _, c := range []struct {
		start string
		count int
	}{
		{"not-a-date", 7}, {"2026-08-01", 0}, {"2026-08-01", -1}, {"2026-08-01", 400},
	} {
		if got := Days(c.start, c.count, "of", "pl"); got != "[]" {
			t.Errorf("Days(%q, %d) = %s, want []", c.start, c.count, got)
		}
	}
}

func BenchmarkDaysWeek(b *testing.B) {
	for i := 0; i < b.N; i++ {
		Days("2026-07-27", 7, "of", "pl")
	}
}