okami.mom/albedo

git clone https://git.nkp.pet/okami.mom/albedo

nekomimi.pettui: rename and delete sessions straight from the list, and keep an archive from being undone by an older listing5e287ce

main
2.4 KiB73 linesraw
1package tui
2
3import (
4	"albedo/cli/internal/daemon"
5	"albedo/cli/internal/testwire"
6	"encoding/json"
7	"net/http"
8	"slices"
9	"testing"
10
11	tea "charm.land/bubbletea/v2"
12)
13
14// settleApp runs cmd and feeds every message it produces back into app, as the
15// program would, leaving out the preview timers.
16func settleApp(app *AppModel, cmd tea.Cmd) {
17	queue := []tea.Cmd{cmd}
18	for len(queue) > 0 {
19		next := queue[0]
20		queue = queue[1:]
21		if next == nil {
22			continue
23		}
24		switch msg := next().(type) {
25		case tea.BatchMsg:
26			queue = append(queue, msg...)
27		case nil, sessionPreviewTickMsg, sessionsLoadedMsg:
28		default:
29			updated, more := app.Update(msg)
30			*app = *updated.(*AppModel)
31			queue = append(queue, more)
32		}
33	}
34}
35
36// A session list requested before an archive answers after it; the picker
37// must not bring the archived row back from that older listing.
38func TestArchiveOutlivesAnOlderSessionListing(t *testing.T) {
39	conn := commandTestConnection(t, func(w http.ResponseWriter, r *http.Request) {
40		session := testwire.Session("s1", testwire.GenerationA, 0)
41		resource := session["configuration_resource"].(map[string]any)
42		switch r.Method {
43		case "GET":
44			w.Header().Set("ETag", resource["etag"].(string))
45			_ = json.NewEncoder(w).Encode(resource["value"])
46		case "PATCH":
47			session["preferences"].(map[string]any)["archived"] = true
48			resource["value"].(map[string]any)["preferences"].(map[string]any)["archived"] = true
49			_ = json.NewEncoder(w).Encode(map[string]any{"resource": resource, "session": session, "move": nil})
50		}
51	})
52	app := NewAppModel(conn, Bootstrap{}, nil, "", false, nil)
53	app.State = AppStateSessionPicker
54	listed := []daemon.Session{{ID: "s1", Title: "one", Workspace: "/work"}}
55	updated, _ := app.Update(sessionsLoadedMsg{Gen: app.SessionGen, Sessions: listed})
56	app = updated.(*AppModel)
57	// Reopening the list asks for a listing that answers after the archive.
58	app.openSessions()
59	older := sessionsLoadedMsg{Gen: app.SessionGen, Sessions: slices.Clone(listed)}
60
61	updated, cmd := app.Update(tea.KeyPressMsg{Code: 'a', Mod: tea.ModCtrl})
62	app = updated.(*AppModel)
63	settleApp(app, cmd)
64	if !app.SessionPicker.archivedIDs["s1"] {
65		t.Fatalf("ctrl+a did not archive the row: %q", app.SessionPicker.notice)
66	}
67	updated, cmd = app.Update(older)
68	app = updated.(*AppModel)
69	settleApp(app, cmd)
70	if !app.SessionPicker.archivedIDs["s1"] {
71		t.Fatal("an older listing brought the archived session back")
72	}
73}