Files
mesh-catalog/modules/mesh-issues/cmd/mesh-issues/moves_test.go
T
jschoubben dfe490d9e2
mesh/delivery merged: source.main moved to novox/mesh-catalog@9cdac09ad962
mesh/check being carried to dfe490d9e245 on 9cdac09ad962 | from 25f615456423
issue-tracker.changes reads each issue's moves over a window from the tracker's own log, so progress since says from what each issue moved, not only where it is
2026-10-28 12:33:01 +01:00

77 lines
2.8 KiB
Go

package main
import (
"encoding/json"
"strings"
"testing"
"time"
)
// changes reads the tracker's own log over a window (the lead, 2026-10-28, for knowledge-base.progress since): each
// move from what to what, by whom and when, and each open, as the tracker's verbs wrote them into its log here.
func TestChangesSaysEachMoveFromWhatToWhatOverAWindow(t *testing.T) {
h := newHarness(t)
clock := time.Date(2026, 10, 28, 9, 0, 0, 0, time.UTC)
h.Tracker.Now = func() time.Time { return clock }
at := func(hh, mm int) { clock = time.Date(2026, 10, 28, hh, mm, 0, 0, time.UTC); h.log.clock = clock }
at(9, 0)
a := h.open(t, "an issue fixed in the window", "hq")
at(9, 10)
b := h.open(t, "an issue given up in the window")
at(10, 0)
if _, err := h.Move(MoveAsk{Number: a, Status: StatusDiagnosing, By: "a@g14"}); err != nil {
t.Fatal(err)
}
at(10, 30)
if _, err := h.Move(MoveAsk{Number: a, Status: StatusFixing, By: "a@g14"}); err != nil {
t.Fatal(err)
}
at(10, 40)
if _, err := h.Note(a, "a note moves nothing"); err != nil {
t.Fatal(err)
}
at(11, 0)
if _, err := h.Move(MoveAsk{Number: a, Status: StatusResolved, FixedBy: []string{"hq#1"}}); err != nil {
t.Fatal(err)
}
at(11, 5)
if _, err := h.Move(MoveAsk{Number: b, Status: StatusWontfix, Reason: "the module is retired"}); err != nil {
t.Fatal(err)
}
at(11, 30)
say := func(r *ChangesRead) string {
var lines []string
for _, c := range r.Changes {
lines = append(lines, strings.Join([]string{c.At.Format("15:04"), c.Kind, itoa(int(c.Number)), c.From + ">" + c.To, c.By + "/" + c.Worker}, " "))
}
return strings.Join(lines, "\n")
}
got, err := h.call(t, "changes", map[string]any{"since": "60m"})
if err != nil {
t.Fatal(err)
}
r := got.(*ChangesRead)
if want := "10:30 moved 365 diagnosing>fixing " + Unproven + "/a@g14\n11:00 resolved 365 fixing>resolved " + Unproven + "/\n11:05 wontfix 366 open>wontfix " + Unproven + "/"; say(r) != want {
t.Errorf("the last hour:\n%s\nwant\n%s", say(r), want)
}
if !r.Since.Equal(time.Date(2026, 10, 28, 10, 30, 0, 0, time.UTC)) || r.Changes[0].Title != "an issue fixed in the window" || !strings.Contains(r.Said, "3 changes") {
t.Errorf("since %v, title %q, said %q", r.Since, r.Changes[0].Title, r.Said)
}
got, err = h.call(t, "changes", map[string]any{"since": "3h", "number": b})
if err != nil {
t.Fatal(err)
}
if want := "09:10 opened 366 >open " + Unproven + "/\n11:05 wontfix 366 open>wontfix " + Unproven + "/"; say(got.(*ChangesRead)) != want {
t.Errorf("one issue:\n%s", say(got.(*ChangesRead)))
}
raw, _ := json.Marshal(got)
if !strings.Contains(string(raw), `"from":"open","to":"wontfix"`) {
t.Errorf("as JSON: %s", raw)
}
for _, bad := range []map[string]any{{"since": "25h"}, {"since": "0m"}, {}, {"since": "60m", "number": 9999}} {
if _, err := h.call(t, "changes", bad); err == nil {
t.Errorf("%v was answered", bad)
}
}
}