diff options
Diffstat (limited to 'internal/tui/tui_test.go')
| -rw-r--r-- | internal/tui/tui_test.go | 123 |
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() |
