summaryrefslogtreecommitdiff
path: root/internal/tui/tui_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/tui/tui_test.go')
-rw-r--r--internal/tui/tui_test.go123
1 files changed, 122 insertions, 1 deletions
diff --git a/internal/tui/tui_test.go b/internal/tui/tui_test.go
index 26fe216..eb64f14 100644
--- a/internal/tui/tui_test.go
+++ b/internal/tui/tui_test.go
@@ -3,8 +3,10 @@ package tui
import (
"strings"
"testing"
+ "time"
- "codeberg.org/snonux/timr/internal/config"
+ "codeberg.org/snonux/timesamurai/internal/config"
+ "codeberg.org/snonux/timesamurai/internal/worktime"
tea "github.com/charmbracelet/bubbletea"
)
@@ -46,6 +48,18 @@ func TestHelpToggle(t *testing.T) {
if model.showHelp {
t.Fatal("showHelp = true, want false after second ?")
}
+
+ modelAny, _ = model.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'H'}})
+ model = modelAny.(*Model)
+ if !model.showHelp {
+ t.Fatal("showHelp = false, want true after H")
+ }
+
+ modelAny, _ = model.Update(tea.KeyMsg{Type: tea.KeyEsc})
+ model = modelAny.(*Model)
+ if model.showHelp {
+ t.Fatal("showHelp = true, want false after Esc")
+ }
}
func TestQuitKeys(t *testing.T) {
@@ -72,6 +86,70 @@ func TestQuitKeys(t *testing.T) {
}
}
+func TestQuitWithUnsavedChangesPromptsConfirmation(t *testing.T) {
+ model := newRootModelForTest(t)
+
+ modelAny, _ := model.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'o'}})
+ model = modelAny.(*Model)
+ if !model.entries.hasUnsavedChanges() {
+ t.Fatal("entries.hasUnsavedChanges() = false, want true after insertion")
+ }
+
+ modelAny, cmd := model.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'q'}})
+ model = modelAny.(*Model)
+ if cmd != nil {
+ t.Fatal("quit command should be deferred until quit confirmation")
+ }
+ if !model.confirmQuit {
+ t.Fatal("confirmQuit = false, want true after q with unsaved changes")
+ }
+
+ modelAny, cmd = model.Update(tea.KeyMsg{Type: tea.KeyEsc})
+ model = modelAny.(*Model)
+ if cmd != nil {
+ t.Fatal("Esc in quit confirmation should not quit")
+ }
+ if model.confirmQuit {
+ t.Fatal("confirmQuit = true, want false after Esc")
+ }
+}
+
+func TestQuitConfirmationSaveAndQuitPersistsEntries(t *testing.T) {
+ model := newRootModelForTest(t)
+
+ modelAny, _ := model.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'o'}})
+ model = modelAny.(*Model)
+ if !model.entries.hasUnsavedChanges() {
+ t.Fatal("entries.hasUnsavedChanges() = false, want true after insertion")
+ }
+
+ modelAny, _ = model.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'q'}})
+ model = modelAny.(*Model)
+ if !model.confirmQuit {
+ t.Fatal("confirmQuit = false, want true after q with unsaved changes")
+ }
+
+ modelAny, cmd := model.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'s'}})
+ model = modelAny.(*Model)
+ if cmd == nil {
+ t.Fatal("quit cmd is nil for save-and-quit")
+ }
+ if _, ok := cmd().(tea.QuitMsg); !ok {
+ t.Fatal("save-and-quit did not return tea.Quit command")
+ }
+ if model.entries.hasUnsavedChanges() {
+ t.Fatal("entries.hasUnsavedChanges() = true, want false after save-and-quit")
+ }
+
+ db, err := worktime.LoadHost(model.entries.dbDir, model.entries.dbHost)
+ if err != nil {
+ t.Fatalf("LoadHost() error = %v", err)
+ }
+ if got := len(db.Entries[model.entries.dbHost]); got != 1 {
+ t.Fatalf("saved entries len = %d, want 1", got)
+ }
+}
+
func TestViewContainsTabLabels(t *testing.T) {
model := newRootModelForTest(t)
view := model.View()
@@ -88,6 +166,49 @@ func TestEntriesTabUsesEntriesModelView(t *testing.T) {
}
}
+func TestDiscoToggleAndThemeResetKeys(t *testing.T) {
+ model := newRootModelForTest(t)
+
+ modelAny, _ := model.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'x'}})
+ model = modelAny.(*Model)
+ if !model.disco {
+ t.Fatal("disco = false, want true after x")
+ }
+
+ modelAny, _ = model.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'C'}})
+ model = modelAny.(*Model)
+ if model.theme != DefaultTheme() {
+ t.Fatalf("theme after C = %+v, want default theme", model.theme)
+ }
+}
+
+func TestModelSetsReportWarningForOpenSession(t *testing.T) {
+ tempDir := t.TempDir()
+ t.Setenv("XDG_CONFIG_HOME", tempDir)
+ t.Setenv("HOME", tempDir)
+
+ cfg := config.Default()
+ cfg.WorktimeDBDir = tempDir
+ cfg.Hostname = "host-a"
+
+ if _, err := worktime.Login(cfg.WorktimeDBDir, cfg.Hostname, "work", localTime(2026, 3, 4, 10, 0), ""); err != nil {
+ t.Fatalf("Login() error = %v", err)
+ }
+
+ model, err := NewModelWithConfig(cfg)
+ if err != nil {
+ t.Fatalf("NewModelWithConfig() error = %v", err)
+ }
+
+ if !strings.Contains(model.report.warn, "currently logged in") {
+ t.Fatalf("report warning = %q, want currently logged in warning", model.report.warn)
+ }
+}
+
+func localTime(year int, month time.Month, day, hour, minute int) time.Time {
+ return time.Date(year, month, day, hour, minute, 0, 0, time.Local)
+}
+
func newRootModelForTest(t *testing.T) *Model {
t.Helper()