▍ humdrum codex / ticktock v0.0.2

feat(grid): edit (SafeReplace) and confirm-delete (Remove) logged sessions

6cab7d55cc2cd7154f188a01d4878ca31d58b1c6
Kevin Kortum <kevinkortum@me.com> · 2026-07-07 21:45

parent 4e6ea8b2

1 files changed

internal/tui/grid/editdelete_test.go +80 −0
@@ -0,0 +1,80 @@
+package grid
+
+import (
+	"testing"
+
+	tea "github.com/charmbracelet/bubbletea"
+
+	"ticktock/internal/store"
+)
+
+func loggedFixture() *fakeStore {
+	return &fakeStore{entries: []store.Entry{{
+		Key: "2026-07-07-01", Start: at(8, 0), End: at(8, 30),
+		Project: "ARCHER", Description: "standup", Duration: 30 * 60 * 1e9,
+	}}}
+}
+
+// place cursor on the labeled row for the fixture (08:00 with default window).
+func onLoggedRow(m Model) Model {
+	row := m.grid.RowOf(8 * 60)
+	m.cursor = row
+	m.col = ColLogged
+	return m
+}
+
+func TestEnterOnLoggedOpensEditThenSafeReplace(t *testing.T) {
+	f := loggedFixture()
+	m := onLoggedRow(loaded(f))
+	nm, _ := m.Update(special(tea.KeyEnter))
+	mm := nm.(Model)
+	if !mm.editing || mm.adding || mm.form == nil {
+		t.Fatalf("enter on logged should open edit (not add) form")
+	}
+	if mm.editKey != "2026-07-07-01" || mm.fv.Desc != "standup" {
+		t.Errorf("edit form not prefilled from session: key=%q desc=%q", mm.editKey, mm.fv.Desc)
+	}
+	mm.fv.Desc = "standup (edited)"
+	nm, _ = mm.Update(special(tea.KeyCtrlS))
+	if len(f.repl) != 1 || f.repl[0].Description != "standup (edited)" {
+		t.Fatalf("SafeReplace not called with edit: %+v", f.repl)
+	}
+}
+
+func TestEnterOnEmptyLoggedRowDoesNothing(t *testing.T) {
+	f := loggedFixture()
+	m := loaded(f)
+	m.cursor = 0 // 07:00, empty
+	m.col = ColLogged
+	nm, _ := m.Update(special(tea.KeyEnter))
+	if nm.(Model).editing {
+		t.Errorf("enter on empty logged row should not open a form")
+	}
+}
+
+func TestDeleteConfirmThenRemove(t *testing.T) {
+	f := loggedFixture()
+	m := onLoggedRow(loaded(f))
+	nm, _ := m.Update(key("d"))
+	mm := nm.(Model)
+	if !mm.confirmDelete || mm.confirmKey != "2026-07-07-01" {
+		t.Fatalf("d should arm delete confirm for the session")
+	}
+	nm, _ = mm.Update(key("y"))
+	if len(f.removed) != 1 || f.removed[0] != "2026-07-07-01" {
+		t.Fatalf("y should confirm remove: %v", f.removed)
+	}
+}
+
+func TestDeleteConfirmCancel(t *testing.T) {
+	f := loggedFixture()
+	m := onLoggedRow(loaded(f))
+	nm, _ := m.Update(key("d"))
+	nm, _ = nm.(Model).Update(key("n"))
+	if nm.(Model).confirmDelete {
+		t.Errorf("n should cancel the delete confirm")
+	}
+	if len(f.removed) != 0 {
+		t.Errorf("cancel should not remove")
+	}
+}