oficina / meet Public

Clone
git clone https://amadan.net/oficina/meet

Plain git — no account needed to clone.

Download

Download this file

1package calls
2
3import (
4 "strings"
5 "testing"
6 "time"
7)
8
9// TestCallTitle is the review follow-up for "Start a call":
10// callstest's black-box test only ever checked the title for a
11// "Call, " prefix, so this pins the exact format over a fixed time
12// and a few zones, including one that rolls the date over.
13func TestCallTitle(t *testing.T) {
14 dublin, err := time.LoadLocation("Europe/Dublin")
15 if err != nil {
16 t.Fatal(err)
17 }
18 tokyo, err := time.LoadLocation("Asia/Tokyo")
19 if err != nil {
20 t.Fatal(err)
21 }
22 cases := []struct {
23 name string
24 now time.Time
25 zone *time.Location
26 want string
27 wantZone string
28 }{
29 {
30 // Not "Call, 30 Sep 20:47 UTC" (f86d4da until 2026-10-02):
31 // the zone is data, not words.
32 name: "no browser zone: the instance zone, kept but not in the title",
33 now: time.Date(2026, 9, 30, 20, 47, 0, 0, time.UTC),
34 zone: nil,
35 want: "Call, 30 Sep 20:47",
36 wantZone: "UTC",
37 },
38 {
39 name: "UTC",
40 now: time.Date(2026, 9, 10, 9, 5, 0, 0, time.UTC),
41 zone: time.UTC,
42 want: "Call, 10 Sep 09:05",
43 },
44 {
45 name: "single-digit day is not zero-padded",
46 now: time.Date(2026, 9, 3, 9, 5, 0, 0, time.UTC),
47 zone: time.UTC,
48 want: "Call, 3 Sep 09:05",
49 },
50 {
51 name: "a zone ahead of UTC, same day",
52 now: time.Date(2026, 9, 10, 9, 15, 0, 0, time.UTC),
53 zone: dublin, // Irish summer time is UTC+1 in September
54 want: "Call, 10 Sep 10:15",
55 wantZone: "Europe/Dublin",
56 },
57 {
58 name: "a zone far enough ahead to roll the date over",
59 now: time.Date(2026, 9, 10, 23, 30, 0, 0, time.UTC),
60 zone: tokyo, // UTC+9, no DST
61 want: "Call, 11 Sep 08:30",
62 },
63 }
64 for _, c := range cases {
65 t.Run(c.name, func(t *testing.T) {
66 got := callTitle(c.now, c.zone, time.UTC)
67 if got.Text != c.want {
68 t.Errorf("callTitle(%s, %s) = %q, want %q", c.now, c.zone, got.Text, c.want)
69 }
70 if c.wantZone != "" && got.Zone != c.wantZone {
71 t.Errorf("callTitle(%s, %s) zone = %q, want %q", c.now, c.zone, got.Zone, c.wantZone)
72 }
73 })
74 }
75}
76
77// TestCallZone: the browser's zone is used only when it is a real IANA
78// zone; anything else falls back to the instance zone (and its name).
79func TestCallZone(t *testing.T) {
80 if callZone("Europe/Dublin") == nil {
81 t.Error("a real zone was refused")
82 }
83 for _, bad := range []string{"", "Local", "Mars/Olympus", "../../etc/passwd", "Europe/Dublin\n"} {
84 if callZone(bad) != nil {
85 t.Errorf("callZone(%q) accepted", bad)
86 }
87 }
88}
89
90// TestCallTitleNeverNamesItsZone: whatever zone the title is written in,
91// the title is the day and time and nothing after them — the reported
92// "Call, 2 Oct 15:40 Europe/Dublin" — and the zone is returned beside it.
93func TestCallTitleNeverNamesItsZone(t *testing.T) {
94 dublin, _ := time.LoadLocation("Europe/Dublin")
95 now := time.Date(2026, 10, 2, 14, 40, 0, 0, time.UTC)
96 for _, local := range []*time.Location{nil, dublin, time.UTC} {
97 got := callTitle(now, local, dublin)
98 if got.Text != "Call, 2 Oct 15:40" && local != time.UTC {
99 t.Errorf("callTitle in %v = %q", local, got.Text)
100 }
101 if strings.Contains(got.Text, "/") || strings.HasSuffix(got.Text, "UTC") {
102 t.Errorf("callTitle in %v names its zone: %q", local, got.Text)
103 }
104 if got.Zone == "" {
105 t.Errorf("callTitle in %v kept no zone", local)
106 }
107 }
108}
109
110// TestAutoTitleIsAFlagNotAReading: a meeting started with no title is
111// marked when it is made, and a meeting someone titled is not — even
112// one whose title reads exactly like an automatic one, which is why
113// this is a flag and not a pattern match on the words.
114func TestAutoTitleIsAFlagNotAReading(t *testing.T) {
115 s, _ := testStore(t)
116 ctx := t.Context()
117 auto, _, err := s.createCall(ctx, autoTitle{Text: "Call, 2 Oct 15:40", Zone: "Europe/Dublin"}, "person:1")
118 if err != nil {
119 t.Fatal(err)
120 }
121 named, _, err := s.createMeeting(ctx, "Call, 2 Oct 15:40", nil, "person:1")
122 if err != nil {
123 t.Fatal(err)
124 }
125 for _, c := range []struct {
126 m Meeting
127 auto bool
128 zone string
129 }{{auto, true, "Europe/Dublin"}, {named, false, ""}} {
130 got, ok, err := s.meetingBySqid(ctx, c.m.Sqid)
131 if err != nil || !ok {
132 t.Fatalf("read back %s: %v %v", c.m.Sqid, ok, err)
133 }
134 if got.AutoTitle != c.auto || got.TitleZone != c.zone {
135 t.Errorf("meeting %s: auto %v zone %q, want %v %q", c.m.Sqid, got.AutoTitle, got.TitleZone, c.auto, c.zone)
136 }
137 if s.title(got) != "Call, 2 Oct 15:40" {
138 t.Errorf("title read back as %q", s.title(got))
139 }
140 }
141}
142