main 5041353

purge_test.go RawHistoryFolder

1package styles_test
2
3import (
4	"testing"
5	"time"
6
7	"github.com/bnema/dumber/internal/cli/styles"
8	"github.com/bnema/dumber/internal/domain/entity"
9	"github.com/bnema/dumber/internal/infrastructure/config"
10	"github.com/stretchr/testify/assert"
11	"github.com/stretchr/testify/require"
12)
13
14func testTheme() *styles.Theme {
15	return styles.NewTheme(config.DefaultConfig())
16}
17
18func TestPurgeModel_SessionsDisabledWhenDataSelected(t *testing.T) {
19	theme := testTheme()
20
21	targets := []entity.PurgeTarget{
22		{Type: entity.PurgeTargetConfig, Path: "/config", Exists: true, Size: 100},
23		{Type: entity.PurgeTargetData, Path: "/data", Exists: true, Size: 1000},
24	}
25
26	endedAt := time.Now().Add(-time.Hour)
27	sessions := []entity.SessionPurgeItem{
28		{
29			Info: entity.SessionInfo{
30				Session: &entity.Session{
31					ID:        "session1",
32					Type:      entity.SessionTypeBrowser,
33					StartedAt: time.Now().Add(-2 * time.Hour),
34					EndedAt:   &endedAt,
35				},
36				TabCount:  2,
37				PaneCount: 3,
38			},
39			Selected: true,
40		},
41	}
42
43	m := styles.NewPurgeWithSessions(theme, targets, sessions, 500)
44
45	// Initially Data is selected (default for existing items)
46	assert.False(t, m.SessionsEnabled(), "sessions should be disabled when Data is selected")
47
48	// Deselect Data
49	m.Items[1].Selected = false
50	assert.True(t, m.SessionsEnabled(), "sessions should be enabled when Data is not selected")
51}
52
53func TestPurgeModel_SelectedSessionIDs_ReturnsNilWhenDataSelected(t *testing.T) {
54	theme := testTheme()
55
56	targets := []entity.PurgeTarget{
57		{Type: entity.PurgeTargetData, Path: "/data", Exists: true, Size: 1000},
58	}
59
60	endedAt := time.Now().Add(-time.Hour)
61	sessions := []entity.SessionPurgeItem{
62		{
63			Info: entity.SessionInfo{
64				Session: &entity.Session{
65					ID:        "session1",
66					Type:      entity.SessionTypeBrowser,
67					StartedAt: time.Now().Add(-2 * time.Hour),
68					EndedAt:   &endedAt,
69				},
70			},
71		},
72	}
73
74	m := styles.NewPurgeWithSessions(theme, targets, sessions, 500)
75
76	// Data is selected, so sessions should return nil
77	ids := m.SelectedSessionIDs()
78	assert.Nil(t, ids, "should return nil when Data is selected")
79
80	// Deselect Data and select all sessions
81	m.Items[0].Selected = false
82	m.ToggleAllSessions() // Now allSessionsSelected = true
83	ids = m.SelectedSessionIDs()
84	require.Len(t, ids, 1)
85	assert.Equal(t, entity.SessionID("session1"), ids[0])
86}
87
88func TestPurgeModel_SelectedCount_IncludesSessions(t *testing.T) {
89	theme := testTheme()
90
91	targets := []entity.PurgeTarget{
92		{Type: entity.PurgeTargetConfig, Path: "/config", Exists: true, Size: 100},
93		{Type: entity.PurgeTargetCache, Path: "/cache", Exists: true, Size: 200},
94	}
95
96	endedAt := time.Now().Add(-time.Hour)
97	sessions := []entity.SessionPurgeItem{
98		{
99			Info: entity.SessionInfo{
100				Session: &entity.Session{
101					ID:        "session1",
102					Type:      entity.SessionTypeBrowser,
103					StartedAt: time.Now().Add(-2 * time.Hour),
104					EndedAt:   &endedAt,
105				},
106			},
107		},
108		{
109			Info: entity.SessionInfo{
110				Session: &entity.Session{
111					ID:        "session2",
112					Type:      entity.SessionTypeBrowser,
113					StartedAt: time.Now().Add(-3 * time.Hour),
114					EndedAt:   &endedAt,
115				},
116			},
117		},
118	}
119
120	m := styles.NewPurgeWithSessions(theme, targets, sessions, 500)
121
122	// 2 targets selected, sessions not selected = 2
123	assert.Equal(t, 2, m.SelectedCount())
124
125	// Select all sessions (as a single item)
126	m.ToggleAllSessions()
127	// 2 targets + 1 sessions item = 3
128	assert.Equal(t, 3, m.SelectedCount())
129}
130
131func TestPurgeModel_ToggleAllSessions(t *testing.T) {
132	theme := testTheme()
133
134	targets := []entity.PurgeTarget{
135		{Type: entity.PurgeTargetConfig, Path: "/config", Exists: true, Size: 100},
136	}
137
138	endedAt := time.Now().Add(-time.Hour)
139	sessions := []entity.SessionPurgeItem{
140		{
141			Info: entity.SessionInfo{
142				Session: &entity.Session{
143					ID:        "session1",
144					Type:      entity.SessionTypeBrowser,
145					StartedAt: time.Now().Add(-2 * time.Hour),
146					EndedAt:   &endedAt,
147				},
148			},
149		},
150		{
151			Info: entity.SessionInfo{
152				Session: &entity.Session{
153					ID:        "session2",
154					Type:      entity.SessionTypeBrowser,
155					StartedAt: time.Now().Add(-3 * time.Hour),
156					EndedAt:   &endedAt,
157				},
158			},
159		},
160	}
161
162	m := styles.NewPurgeWithSessions(theme, targets, sessions, 500)
163
164	// Initially sessions are not selected
165	ids := m.SelectedSessionIDs()
166	assert.Nil(t, ids, "sessions should not be selected initially")
167
168	// Toggle to select all
169	m.ToggleAllSessions()
170	ids = m.SelectedSessionIDs()
171	require.Len(t, ids, 2, "all sessions should be selected after toggle")
172
173	// Toggle again to deselect all
174	m.ToggleAllSessions()
175	ids = m.SelectedSessionIDs()
176	assert.Nil(t, ids, "sessions should be deselected after second toggle")
177}
178
179func TestPurgeModel_SelectedSize_IncludesAllSessionsWhenSelected(t *testing.T) {
180	theme := testTheme()
181
182	targets := []entity.PurgeTarget{
183		{Type: entity.PurgeTargetConfig, Path: "/config", Exists: true, Size: 100},
184	}
185
186	endedAt := time.Now().Add(-time.Hour)
187	sessions := []entity.SessionPurgeItem{
188		{
189			Info: entity.SessionInfo{
190				Session: &entity.Session{
191					ID:        "session1",
192					Type:      entity.SessionTypeBrowser,
193					StartedAt: time.Now().Add(-2 * time.Hour),
194					EndedAt:   &endedAt,
195				},
196			},
197		},
198		{
199			Info: entity.SessionInfo{
200				Session: &entity.Session{
201					ID:        "session2",
202					Type:      entity.SessionTypeBrowser,
203					StartedAt: time.Now().Add(-3 * time.Hour),
204					EndedAt:   &endedAt,
205				},
206			},
207		},
208	}
209
210	// Total sessions size is 1000
211	m := styles.NewPurgeWithSessions(theme, targets, sessions, 1000)
212
213	// Only config selected = 100
214	assert.Equal(t, int64(100), m.SelectedSize())
215
216	// Select all sessions
217	m.ToggleAllSessions()
218	// 100 (config) + 1000 (all sessions) = 1100
219	assert.Equal(t, int64(1100), m.SelectedSize())
220}
221
222func TestPurgeModel_SelectedSize_IncludesFullSessionsSizeWhenDataSelected(t *testing.T) {
223	theme := testTheme()
224
225	targets := []entity.PurgeTarget{
226		{Type: entity.PurgeTargetData, Path: "/data", Exists: true, Size: 100},
227	}
228
229	endedAt := time.Now().Add(-time.Hour)
230	sessions := []entity.SessionPurgeItem{
231		{
232			Info: entity.SessionInfo{
233				Session: &entity.Session{
234					ID:        "session1",
235					Type:      entity.SessionTypeBrowser,
236					StartedAt: time.Now().Add(-2 * time.Hour),
237					EndedAt:   &endedAt,
238				},
239			},
240		},
241	}
242
243	m := styles.NewPurgeWithSessions(theme, targets, sessions, 1000)
244
245	// 100 (data) + 1000 (all sessions because DB is being deleted) = 1100
246	assert.Equal(t, int64(1100), m.SelectedSize())
247}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close