v0.23.2 bfd5eb4

cleanup_sessions_test.go RawHistoryFolder

1package usecase_test
2
3import (
4	"errors"
5	"testing"
6	"time"
7
8	"github.com/bnema/dumber/internal/application/usecase"
9	repomocks "github.com/bnema/dumber/internal/domain/repository/mocks"
10	"github.com/stretchr/testify/assert"
11	"github.com/stretchr/testify/mock"
12	"github.com/stretchr/testify/require"
13)
14
15func TestCleanupSessionsUseCase_Execute_AgeAndCountCleanup(t *testing.T) {
16	ctx := testContext()
17
18	sessionRepo := repomocks.NewMockSessionRepository(t)
19
20	// Expect age-based deletion
21	sessionRepo.EXPECT().
22		DeleteExitedBefore(ctx, mock.MatchedBy(func(cutoff time.Time) bool {
23			// Should be approximately 7 days ago
24			expected := time.Now().AddDate(0, 0, -7)
25			diff := expected.Sub(cutoff)
26			return diff > -time.Minute && diff < time.Minute
27		})).
28		Return(int64(3), nil)
29
30	// Expect count-based deletion
31	sessionRepo.EXPECT().
32		DeleteOldestExited(ctx, 50).
33		Return(int64(2), nil)
34
35	uc := usecase.NewCleanupSessionsUseCase(sessionRepo)
36
37	output, err := uc.Execute(ctx, usecase.CleanupSessionsInput{
38		MaxExitedSessions:       50,
39		MaxExitedSessionAgeDays: 7,
40	})
41
42	require.NoError(t, err)
43	assert.Equal(t, int64(3), output.DeletedByAge)
44	assert.Equal(t, int64(2), output.DeletedByCount)
45	assert.Equal(t, int64(5), output.TotalDeleted)
46}
47
48func TestCleanupSessionsUseCase_Execute_AgeOnlyCleanup(t *testing.T) {
49	ctx := testContext()
50
51	sessionRepo := repomocks.NewMockSessionRepository(t)
52
53	// Expect age-based deletion
54	sessionRepo.EXPECT().
55		DeleteExitedBefore(ctx, mock.Anything).
56		Return(int64(5), nil)
57
58	// Count-based with -1 should be skipped (disabled)
59	// MaxExitedSessions >= 0 triggers count cleanup, so use -1 to disable
60	uc := usecase.NewCleanupSessionsUseCase(sessionRepo)
61
62	output, err := uc.Execute(ctx, usecase.CleanupSessionsInput{
63		MaxExitedSessions:       -1, // Disabled
64		MaxExitedSessionAgeDays: 30,
65	})
66
67	require.NoError(t, err)
68	assert.Equal(t, int64(5), output.DeletedByAge)
69	assert.Equal(t, int64(0), output.DeletedByCount)
70	assert.Equal(t, int64(5), output.TotalDeleted)
71}
72
73func TestCleanupSessionsUseCase_Execute_CountOnlyCleanup(t *testing.T) {
74	ctx := testContext()
75
76	sessionRepo := repomocks.NewMockSessionRepository(t)
77
78	// Count-based deletion only (age disabled with 0)
79	sessionRepo.EXPECT().
80		DeleteOldestExited(ctx, 10).
81		Return(int64(4), nil)
82
83	uc := usecase.NewCleanupSessionsUseCase(sessionRepo)
84
85	output, err := uc.Execute(ctx, usecase.CleanupSessionsInput{
86		MaxExitedSessions:       10,
87		MaxExitedSessionAgeDays: 0, // Disabled
88	})
89
90	require.NoError(t, err)
91	assert.Equal(t, int64(0), output.DeletedByAge)
92	assert.Equal(t, int64(4), output.DeletedByCount)
93	assert.Equal(t, int64(4), output.TotalDeleted)
94}
95
96func TestCleanupSessionsUseCase_Execute_NoCleanupNeeded(t *testing.T) {
97	ctx := testContext()
98
99	sessionRepo := repomocks.NewMockSessionRepository(t)
100
101	// Nothing to delete
102	sessionRepo.EXPECT().
103		DeleteExitedBefore(ctx, mock.Anything).
104		Return(int64(0), nil)
105
106	sessionRepo.EXPECT().
107		DeleteOldestExited(ctx, 50).
108		Return(int64(0), nil)
109
110	uc := usecase.NewCleanupSessionsUseCase(sessionRepo)
111
112	output, err := uc.Execute(ctx, usecase.CleanupSessionsInput{
113		MaxExitedSessions:       50,
114		MaxExitedSessionAgeDays: 7,
115	})
116
117	require.NoError(t, err)
118	assert.Equal(t, int64(0), output.DeletedByAge)
119	assert.Equal(t, int64(0), output.DeletedByCount)
120	assert.Equal(t, int64(0), output.TotalDeleted)
121}
122
123func TestCleanupSessionsUseCase_Execute_AgeDeleteError_ContinuesToCount(t *testing.T) {
124	ctx := testContext()
125
126	sessionRepo := repomocks.NewMockSessionRepository(t)
127
128	// Age-based deletion fails
129	sessionRepo.EXPECT().
130		DeleteExitedBefore(ctx, mock.Anything).
131		Return(int64(0), errors.New("db error"))
132
133	// Should still attempt count-based deletion
134	sessionRepo.EXPECT().
135		DeleteOldestExited(ctx, 50).
136		Return(int64(3), nil)
137
138	uc := usecase.NewCleanupSessionsUseCase(sessionRepo)
139
140	output, err := uc.Execute(ctx, usecase.CleanupSessionsInput{
141		MaxExitedSessions:       50,
142		MaxExitedSessionAgeDays: 7,
143	})
144
145	// Should not return error, just log warning
146	require.NoError(t, err)
147	assert.Equal(t, int64(0), output.DeletedByAge)
148	assert.Equal(t, int64(3), output.DeletedByCount)
149	assert.Equal(t, int64(3), output.TotalDeleted)
150}
151
152func TestCleanupSessionsUseCase_Execute_CountDeleteError(t *testing.T) {
153	ctx := testContext()
154
155	sessionRepo := repomocks.NewMockSessionRepository(t)
156
157	// Age-based deletion succeeds
158	sessionRepo.EXPECT().
159		DeleteExitedBefore(ctx, mock.Anything).
160		Return(int64(2), nil)
161
162	// Count-based deletion fails
163	sessionRepo.EXPECT().
164		DeleteOldestExited(ctx, 50).
165		Return(int64(0), errors.New("db error"))
166
167	uc := usecase.NewCleanupSessionsUseCase(sessionRepo)
168
169	output, err := uc.Execute(ctx, usecase.CleanupSessionsInput{
170		MaxExitedSessions:       50,
171		MaxExitedSessionAgeDays: 7,
172	})
173
174	// Should not return error, just log warning
175	require.NoError(t, err)
176	assert.Equal(t, int64(2), output.DeletedByAge)
177	assert.Equal(t, int64(0), output.DeletedByCount)
178	assert.Equal(t, int64(2), output.TotalDeleted)
179}
180
181func TestCleanupSessionsUseCase_Execute_BothDisabled(t *testing.T) {
182	ctx := testContext()
183
184	sessionRepo := repomocks.NewMockSessionRepository(t)
185
186	// No expectations - nothing should be called
187	// Actually, count with 0 means "keep 0" which will trigger cleanup
188	// So we need -1 for count and 0 for age to fully disable
189
190	uc := usecase.NewCleanupSessionsUseCase(sessionRepo)
191
192	output, err := uc.Execute(ctx, usecase.CleanupSessionsInput{
193		MaxExitedSessions:       -1, // Disabled
194		MaxExitedSessionAgeDays: 0,  // Disabled
195	})
196
197	require.NoError(t, err)
198	assert.Equal(t, int64(0), output.DeletedByAge)
199	assert.Equal(t, int64(0), output.DeletedByCount)
200	assert.Equal(t, int64(0), output.TotalDeleted)
201}
202
203func TestCleanupSessionsUseCase_Execute_ZeroMaxSessions(t *testing.T) {
204	ctx := testContext()
205
206	sessionRepo := repomocks.NewMockSessionRepository(t)
207
208	// MaxExitedSessions = 0 means keep 0 sessions (delete all)
209	sessionRepo.EXPECT().
210		DeleteOldestExited(ctx, 0).
211		Return(int64(10), nil)
212
213	uc := usecase.NewCleanupSessionsUseCase(sessionRepo)
214
215	output, err := uc.Execute(ctx, usecase.CleanupSessionsInput{
216		MaxExitedSessions:       0, // Keep 0 = delete all
217		MaxExitedSessionAgeDays: 0, // Disabled
218	})
219
220	require.NoError(t, err)
221	assert.Equal(t, int64(0), output.DeletedByAge)
222	assert.Equal(t, int64(10), output.DeletedByCount)
223	assert.Equal(t, int64(10), output.TotalDeleted)
224}

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