detached b375737

test(usecase): add tests for session deletion and update mocks

commit
b37573729ed8161104e70eda3b9d665441abb7b5
author
brice · · 2025-12-25 09:42 UTC
parent
c654fc4
signature
unsigned
2 files · +312 -0
A internal/application/usecase/delete_session_test.go +255 -0
@@ -0,0 +1,255 @@
1+package usecase_test
2+
3+import (
4+ "errors"
5+ "os"
6+ "path/filepath"
7+ "testing"
8+ "time"
9+
10+ "github.com/bnema/dumber/internal/application/usecase"
11+ "github.com/bnema/dumber/internal/domain/entity"
12+ repomocks "github.com/bnema/dumber/internal/domain/repository/mocks"
13+ "github.com/stretchr/testify/assert"
14+ "github.com/stretchr/testify/require"
15+)
16+
17+func TestDeleteSessionUseCase_Execute_Success(t *testing.T) {
18+ ctx := testContext()
19+
20+ stateRepo := repomocks.NewMockSessionStateRepository(t)
21+ sessionRepo := repomocks.NewMockSessionRepository(t)
22+
23+ sessionID := entity.SessionID("20251224_120000_delete")
24+
25+ endedAt := time.Now().Add(-time.Hour)
26+ session := &entity.Session{
27+ ID: sessionID,
28+ Type: entity.SessionTypeBrowser,
29+ StartedAt: time.Now().Add(-2 * time.Hour),
30+ EndedAt: &endedAt,
31+ }
32+
33+ sessionRepo.EXPECT().FindByID(ctx, sessionID).Return(session, nil)
34+ stateRepo.EXPECT().DeleteSnapshot(ctx, sessionID).Return(nil)
35+ sessionRepo.EXPECT().Delete(ctx, sessionID).Return(nil)
36+
37+ uc := usecase.NewDeleteSessionUseCase(stateRepo, sessionRepo, "")
38+
39+ err := uc.Execute(ctx, usecase.DeleteSessionInput{
40+ SessionID: sessionID,
41+ CurrentSessionID: "other-session",
42+ })
43+ require.NoError(t, err)
44+}
45+
46+func TestDeleteSessionUseCase_Execute_CannotDeleteCurrentSession(t *testing.T) {
47+ ctx := testContext()
48+
49+ stateRepo := repomocks.NewMockSessionStateRepository(t)
50+ sessionRepo := repomocks.NewMockSessionRepository(t)
51+
52+ sessionID := entity.SessionID("20251224_120000_current")
53+
54+ uc := usecase.NewDeleteSessionUseCase(stateRepo, sessionRepo, "")
55+
56+ err := uc.Execute(ctx, usecase.DeleteSessionInput{
57+ SessionID: sessionID,
58+ CurrentSessionID: sessionID, // Same as current
59+ })
60+ require.Error(t, err)
61+ assert.ErrorIs(t, err, usecase.ErrCannotDeleteCurrentSession)
62+}
63+
64+func TestDeleteSessionUseCase_Execute_SessionNotFound(t *testing.T) {
65+ ctx := testContext()
66+
67+ stateRepo := repomocks.NewMockSessionStateRepository(t)
68+ sessionRepo := repomocks.NewMockSessionRepository(t)
69+
70+ sessionID := entity.SessionID("20251224_120000_notfound")
71+
72+ sessionRepo.EXPECT().FindByID(ctx, sessionID).Return(nil, nil)
73+
74+ uc := usecase.NewDeleteSessionUseCase(stateRepo, sessionRepo, "")
75+
76+ err := uc.Execute(ctx, usecase.DeleteSessionInput{
77+ SessionID: sessionID,
78+ CurrentSessionID: "other-session",
79+ })
80+ require.Error(t, err)
81+ assert.ErrorIs(t, err, usecase.ErrSessionNotFound)
82+}
83+
84+func TestDeleteSessionUseCase_Execute_CannotDeleteActiveSession(t *testing.T) {
85+ ctx := testContext()
86+
87+ stateRepo := repomocks.NewMockSessionStateRepository(t)
88+ sessionRepo := repomocks.NewMockSessionRepository(t)
89+
90+ sessionID := entity.SessionID("20251224_120000_active")
91+
92+ // Session with nil EndedAt (still active)
93+ session := &entity.Session{
94+ ID: sessionID,
95+ Type: entity.SessionTypeBrowser,
96+ StartedAt: time.Now().Add(-time.Hour),
97+ EndedAt: nil, // Active
98+ }
99+
100+ sessionRepo.EXPECT().FindByID(ctx, sessionID).Return(session, nil)
101+
102+ uc := usecase.NewDeleteSessionUseCase(stateRepo, sessionRepo, "")
103+
104+ err := uc.Execute(ctx, usecase.DeleteSessionInput{
105+ SessionID: sessionID,
106+ CurrentSessionID: "other-session",
107+ })
108+ require.Error(t, err)
109+ assert.ErrorIs(t, err, usecase.ErrCannotDeleteActiveSession)
110+}
111+
112+func TestDeleteSessionUseCase_Execute_CannotDeleteLockedSession(t *testing.T) {
113+ ctx := testContext()
114+
115+ stateRepo := repomocks.NewMockSessionStateRepository(t)
116+ sessionRepo := repomocks.NewMockSessionRepository(t)
117+
118+ // Create a temporary lock directory and lock file
119+ lockDir := t.TempDir()
120+ sessionID := entity.SessionID("20251224_120000_locked")
121+ lockPath := filepath.Join(lockDir, "session_"+string(sessionID)+".lock")
122+ f, err := os.Create(lockPath)
123+ require.NoError(t, err)
124+ f.Close()
125+
126+ endedAt := time.Now().Add(-time.Hour)
127+ session := &entity.Session{
128+ ID: sessionID,
129+ Type: entity.SessionTypeBrowser,
130+ StartedAt: time.Now().Add(-2 * time.Hour),
131+ EndedAt: &endedAt, // Ended, but has lock file
132+ }
133+
134+ sessionRepo.EXPECT().FindByID(ctx, sessionID).Return(session, nil)
135+
136+ uc := usecase.NewDeleteSessionUseCase(stateRepo, sessionRepo, lockDir)
137+
138+ err = uc.Execute(ctx, usecase.DeleteSessionInput{
139+ SessionID: sessionID,
140+ CurrentSessionID: "other-session",
141+ })
142+ require.Error(t, err)
143+ assert.ErrorIs(t, err, usecase.ErrCannotDeleteActiveSession)
144+}
145+
146+func TestDeleteSessionUseCase_Execute_FindByIDError(t *testing.T) {
147+ ctx := testContext()
148+
149+ stateRepo := repomocks.NewMockSessionStateRepository(t)
150+ sessionRepo := repomocks.NewMockSessionRepository(t)
151+
152+ sessionID := entity.SessionID("20251224_120000_dberror")
153+
154+ sessionRepo.EXPECT().FindByID(ctx, sessionID).Return(nil, errors.New("db error"))
155+
156+ uc := usecase.NewDeleteSessionUseCase(stateRepo, sessionRepo, "")
157+
158+ err := uc.Execute(ctx, usecase.DeleteSessionInput{
159+ SessionID: sessionID,
160+ CurrentSessionID: "other-session",
161+ })
162+ require.Error(t, err)
163+ assert.Contains(t, err.Error(), "db error")
164+}
165+
166+func TestDeleteSessionUseCase_Execute_DeleteSnapshotErrorIgnored(t *testing.T) {
167+ ctx := testContext()
168+
169+ stateRepo := repomocks.NewMockSessionStateRepository(t)
170+ sessionRepo := repomocks.NewMockSessionRepository(t)
171+
172+ sessionID := entity.SessionID("20251224_120000_nosnapshot")
173+
174+ endedAt := time.Now().Add(-time.Hour)
175+ session := &entity.Session{
176+ ID: sessionID,
177+ Type: entity.SessionTypeBrowser,
178+ StartedAt: time.Now().Add(-2 * time.Hour),
179+ EndedAt: &endedAt,
180+ }
181+
182+ sessionRepo.EXPECT().FindByID(ctx, sessionID).Return(session, nil)
183+ // Snapshot deletion fails (e.g., no snapshot exists) - should be ignored
184+ stateRepo.EXPECT().DeleteSnapshot(ctx, sessionID).Return(errors.New("no rows"))
185+ sessionRepo.EXPECT().Delete(ctx, sessionID).Return(nil)
186+
187+ uc := usecase.NewDeleteSessionUseCase(stateRepo, sessionRepo, "")
188+
189+ err := uc.Execute(ctx, usecase.DeleteSessionInput{
190+ SessionID: sessionID,
191+ CurrentSessionID: "other-session",
192+ })
193+ // Should succeed even though DeleteSnapshot failed
194+ require.NoError(t, err)
195+}
196+
197+func TestDeleteSessionUseCase_Execute_DeleteSessionError(t *testing.T) {
198+ ctx := testContext()
199+
200+ stateRepo := repomocks.NewMockSessionStateRepository(t)
201+ sessionRepo := repomocks.NewMockSessionRepository(t)
202+
203+ sessionID := entity.SessionID("20251224_120000_deleteerror")
204+
205+ endedAt := time.Now().Add(-time.Hour)
206+ session := &entity.Session{
207+ ID: sessionID,
208+ Type: entity.SessionTypeBrowser,
209+ StartedAt: time.Now().Add(-2 * time.Hour),
210+ EndedAt: &endedAt,
211+ }
212+
213+ sessionRepo.EXPECT().FindByID(ctx, sessionID).Return(session, nil)
214+ stateRepo.EXPECT().DeleteSnapshot(ctx, sessionID).Return(nil)
215+ sessionRepo.EXPECT().Delete(ctx, sessionID).Return(errors.New("delete failed"))
216+
217+ uc := usecase.NewDeleteSessionUseCase(stateRepo, sessionRepo, "")
218+
219+ err := uc.Execute(ctx, usecase.DeleteSessionInput{
220+ SessionID: sessionID,
221+ CurrentSessionID: "other-session",
222+ })
223+ require.Error(t, err)
224+ assert.Contains(t, err.Error(), "delete failed")
225+}
226+
227+func TestDeleteSessionUseCase_Execute_EmptyCurrentSessionAllowed(t *testing.T) {
228+ ctx := testContext()
229+
230+ stateRepo := repomocks.NewMockSessionStateRepository(t)
231+ sessionRepo := repomocks.NewMockSessionRepository(t)
232+
233+ sessionID := entity.SessionID("20251224_120000_nocurrent")
234+
235+ endedAt := time.Now().Add(-time.Hour)
236+ session := &entity.Session{
237+ ID: sessionID,
238+ Type: entity.SessionTypeBrowser,
239+ StartedAt: time.Now().Add(-2 * time.Hour),
240+ EndedAt: &endedAt,
241+ }
242+
243+ sessionRepo.EXPECT().FindByID(ctx, sessionID).Return(session, nil)
244+ stateRepo.EXPECT().DeleteSnapshot(ctx, sessionID).Return(nil)
245+ sessionRepo.EXPECT().Delete(ctx, sessionID).Return(nil)
246+
247+ uc := usecase.NewDeleteSessionUseCase(stateRepo, sessionRepo, "")
248+
249+ // CurrentSessionID is empty (e.g., CLI context)
250+ err := uc.Execute(ctx, usecase.DeleteSessionInput{
251+ SessionID: sessionID,
252+ CurrentSessionID: "",
253+ })
254+ require.NoError(t, err)
255+}
@@ -0,0 +1,255 @@
1+package usecase_test
2+
3+import (
4+ "errors"
5+ "os"
6+ "path/filepath"
7+ "testing"
8+ "time"
9+
10+ "github.com/bnema/dumber/internal/application/usecase"
11+ "github.com/bnema/dumber/internal/domain/entity"
12+ repomocks "github.com/bnema/dumber/internal/domain/repository/mocks"
13+ "github.com/stretchr/testify/assert"
14+ "github.com/stretchr/testify/require"
15+)
16+
17+func TestDeleteSessionUseCase_Execute_Success(t *testing.T) {
18+ ctx := testContext()
19+
20+ stateRepo := repomocks.NewMockSessionStateRepository(t)
21+ sessionRepo := repomocks.NewMockSessionRepository(t)
22+
23+ sessionID := entity.SessionID("20251224_120000_delete")
24+
25+ endedAt := time.Now().Add(-time.Hour)
26+ session := &entity.Session{
27+ ID: sessionID,
28+ Type: entity.SessionTypeBrowser,
29+ StartedAt: time.Now().Add(-2 * time.Hour),
30+ EndedAt: &endedAt,
31+ }
32+
33+ sessionRepo.EXPECT().FindByID(ctx, sessionID).Return(session, nil)
34+ stateRepo.EXPECT().DeleteSnapshot(ctx, sessionID).Return(nil)
35+ sessionRepo.EXPECT().Delete(ctx, sessionID).Return(nil)
36+
37+ uc := usecase.NewDeleteSessionUseCase(stateRepo, sessionRepo, "")
38+
39+ err := uc.Execute(ctx, usecase.DeleteSessionInput{
40+ SessionID: sessionID,
41+ CurrentSessionID: "other-session",
42+ })
43+ require.NoError(t, err)
44+}
45+
46+func TestDeleteSessionUseCase_Execute_CannotDeleteCurrentSession(t *testing.T) {
47+ ctx := testContext()
48+
49+ stateRepo := repomocks.NewMockSessionStateRepository(t)
50+ sessionRepo := repomocks.NewMockSessionRepository(t)
51+
52+ sessionID := entity.SessionID("20251224_120000_current")
53+
54+ uc := usecase.NewDeleteSessionUseCase(stateRepo, sessionRepo, "")
55+
56+ err := uc.Execute(ctx, usecase.DeleteSessionInput{
57+ SessionID: sessionID,
58+ CurrentSessionID: sessionID, // Same as current
59+ })
60+ require.Error(t, err)
61+ assert.ErrorIs(t, err, usecase.ErrCannotDeleteCurrentSession)
62+}
63+
64+func TestDeleteSessionUseCase_Execute_SessionNotFound(t *testing.T) {
65+ ctx := testContext()
66+
67+ stateRepo := repomocks.NewMockSessionStateRepository(t)
68+ sessionRepo := repomocks.NewMockSessionRepository(t)
69+
70+ sessionID := entity.SessionID("20251224_120000_notfound")
71+
72+ sessionRepo.EXPECT().FindByID(ctx, sessionID).Return(nil, nil)
73+
74+ uc := usecase.NewDeleteSessionUseCase(stateRepo, sessionRepo, "")
75+
76+ err := uc.Execute(ctx, usecase.DeleteSessionInput{
77+ SessionID: sessionID,
78+ CurrentSessionID: "other-session",
79+ })
80+ require.Error(t, err)
81+ assert.ErrorIs(t, err, usecase.ErrSessionNotFound)
82+}
83+
84+func TestDeleteSessionUseCase_Execute_CannotDeleteActiveSession(t *testing.T) {
85+ ctx := testContext()
86+
87+ stateRepo := repomocks.NewMockSessionStateRepository(t)
88+ sessionRepo := repomocks.NewMockSessionRepository(t)
89+
90+ sessionID := entity.SessionID("20251224_120000_active")
91+
92+ // Session with nil EndedAt (still active)
93+ session := &entity.Session{
94+ ID: sessionID,
95+ Type: entity.SessionTypeBrowser,
96+ StartedAt: time.Now().Add(-time.Hour),
97+ EndedAt: nil, // Active
98+ }
99+
100+ sessionRepo.EXPECT().FindByID(ctx, sessionID).Return(session, nil)
101+
102+ uc := usecase.NewDeleteSessionUseCase(stateRepo, sessionRepo, "")
103+
104+ err := uc.Execute(ctx, usecase.DeleteSessionInput{
105+ SessionID: sessionID,
106+ CurrentSessionID: "other-session",
107+ })
108+ require.Error(t, err)
109+ assert.ErrorIs(t, err, usecase.ErrCannotDeleteActiveSession)
110+}
111+
112+func TestDeleteSessionUseCase_Execute_CannotDeleteLockedSession(t *testing.T) {
113+ ctx := testContext()
114+
115+ stateRepo := repomocks.NewMockSessionStateRepository(t)
116+ sessionRepo := repomocks.NewMockSessionRepository(t)
117+
118+ // Create a temporary lock directory and lock file
119+ lockDir := t.TempDir()
120+ sessionID := entity.SessionID("20251224_120000_locked")
121+ lockPath := filepath.Join(lockDir, "session_"+string(sessionID)+".lock")
122+ f, err := os.Create(lockPath)
123+ require.NoError(t, err)
124+ f.Close()
125+
126+ endedAt := time.Now().Add(-time.Hour)
127+ session := &entity.Session{
128+ ID: sessionID,
129+ Type: entity.SessionTypeBrowser,
130+ StartedAt: time.Now().Add(-2 * time.Hour),
131+ EndedAt: &endedAt, // Ended, but has lock file
132+ }
133+
134+ sessionRepo.EXPECT().FindByID(ctx, sessionID).Return(session, nil)
135+
136+ uc := usecase.NewDeleteSessionUseCase(stateRepo, sessionRepo, lockDir)
137+
138+ err = uc.Execute(ctx, usecase.DeleteSessionInput{
139+ SessionID: sessionID,
140+ CurrentSessionID: "other-session",
141+ })
142+ require.Error(t, err)
143+ assert.ErrorIs(t, err, usecase.ErrCannotDeleteActiveSession)
144+}
145+
146+func TestDeleteSessionUseCase_Execute_FindByIDError(t *testing.T) {
147+ ctx := testContext()
148+
149+ stateRepo := repomocks.NewMockSessionStateRepository(t)
150+ sessionRepo := repomocks.NewMockSessionRepository(t)
151+
152+ sessionID := entity.SessionID("20251224_120000_dberror")
153+
154+ sessionRepo.EXPECT().FindByID(ctx, sessionID).Return(nil, errors.New("db error"))
155+
156+ uc := usecase.NewDeleteSessionUseCase(stateRepo, sessionRepo, "")
157+
158+ err := uc.Execute(ctx, usecase.DeleteSessionInput{
159+ SessionID: sessionID,
160+ CurrentSessionID: "other-session",
161+ })
162+ require.Error(t, err)
163+ assert.Contains(t, err.Error(), "db error")
164+}
165+
166+func TestDeleteSessionUseCase_Execute_DeleteSnapshotErrorIgnored(t *testing.T) {
167+ ctx := testContext()
168+
169+ stateRepo := repomocks.NewMockSessionStateRepository(t)
170+ sessionRepo := repomocks.NewMockSessionRepository(t)
171+
172+ sessionID := entity.SessionID("20251224_120000_nosnapshot")
173+
174+ endedAt := time.Now().Add(-time.Hour)
175+ session := &entity.Session{
176+ ID: sessionID,
177+ Type: entity.SessionTypeBrowser,
178+ StartedAt: time.Now().Add(-2 * time.Hour),
179+ EndedAt: &endedAt,
180+ }
181+
182+ sessionRepo.EXPECT().FindByID(ctx, sessionID).Return(session, nil)
183+ // Snapshot deletion fails (e.g., no snapshot exists) - should be ignored
184+ stateRepo.EXPECT().DeleteSnapshot(ctx, sessionID).Return(errors.New("no rows"))
185+ sessionRepo.EXPECT().Delete(ctx, sessionID).Return(nil)
186+
187+ uc := usecase.NewDeleteSessionUseCase(stateRepo, sessionRepo, "")
188+
189+ err := uc.Execute(ctx, usecase.DeleteSessionInput{
190+ SessionID: sessionID,
191+ CurrentSessionID: "other-session",
192+ })
193+ // Should succeed even though DeleteSnapshot failed
194+ require.NoError(t, err)
195+}
196+
197+func TestDeleteSessionUseCase_Execute_DeleteSessionError(t *testing.T) {
198+ ctx := testContext()
199+
200+ stateRepo := repomocks.NewMockSessionStateRepository(t)
201+ sessionRepo := repomocks.NewMockSessionRepository(t)
202+
203+ sessionID := entity.SessionID("20251224_120000_deleteerror")
204+
205+ endedAt := time.Now().Add(-time.Hour)
206+ session := &entity.Session{
207+ ID: sessionID,
208+ Type: entity.SessionTypeBrowser,
209+ StartedAt: time.Now().Add(-2 * time.Hour),
210+ EndedAt: &endedAt,
211+ }
212+
213+ sessionRepo.EXPECT().FindByID(ctx, sessionID).Return(session, nil)
214+ stateRepo.EXPECT().DeleteSnapshot(ctx, sessionID).Return(nil)
215+ sessionRepo.EXPECT().Delete(ctx, sessionID).Return(errors.New("delete failed"))
216+
217+ uc := usecase.NewDeleteSessionUseCase(stateRepo, sessionRepo, "")
218+
219+ err := uc.Execute(ctx, usecase.DeleteSessionInput{
220+ SessionID: sessionID,
221+ CurrentSessionID: "other-session",
222+ })
223+ require.Error(t, err)
224+ assert.Contains(t, err.Error(), "delete failed")
225+}
226+
227+func TestDeleteSessionUseCase_Execute_EmptyCurrentSessionAllowed(t *testing.T) {
228+ ctx := testContext()
229+
230+ stateRepo := repomocks.NewMockSessionStateRepository(t)
231+ sessionRepo := repomocks.NewMockSessionRepository(t)
232+
233+ sessionID := entity.SessionID("20251224_120000_nocurrent")
234+
235+ endedAt := time.Now().Add(-time.Hour)
236+ session := &entity.Session{
237+ ID: sessionID,
238+ Type: entity.SessionTypeBrowser,
239+ StartedAt: time.Now().Add(-2 * time.Hour),
240+ EndedAt: &endedAt,
241+ }
242+
243+ sessionRepo.EXPECT().FindByID(ctx, sessionID).Return(session, nil)
244+ stateRepo.EXPECT().DeleteSnapshot(ctx, sessionID).Return(nil)
245+ sessionRepo.EXPECT().Delete(ctx, sessionID).Return(nil)
246+
247+ uc := usecase.NewDeleteSessionUseCase(stateRepo, sessionRepo, "")
248+
249+ // CurrentSessionID is empty (e.g., CLI context)
250+ err := uc.Execute(ctx, usecase.DeleteSessionInput{
251+ SessionID: sessionID,
252+ CurrentSessionID: "",
253+ })
254+ require.NoError(t, err)
255+}
M internal/domain/repository/mocks/mocks.go +57 -0
@@ -2746,6 +2746,63 @@ func (_m *MockSessionRepository) EXPECT() *MockSessionRepository_Expecter {
27462746 return &MockSessionRepository_Expecter{mock: &_m.Mock}
27472747 }
27482748
2749+// Delete provides a mock function for the type MockSessionRepository
2750+func (_mock *MockSessionRepository) Delete(ctx context.Context, id entity.SessionID) error {
2751+ ret := _mock.Called(ctx, id)
2752+
2753+ if len(ret) == 0 {
2754+ panic("no return value specified for Delete")
2755+ }
2756+
2757+ var r0 error
2758+ if returnFunc, ok := ret.Get(0).(func(context.Context, entity.SessionID) error); ok {
2759+ r0 = returnFunc(ctx, id)
2760+ } else {
2761+ r0 = ret.Error(0)
2762+ }
2763+ return r0
2764+}
2765+
2766+// MockSessionRepository_Delete_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Delete'
2767+type MockSessionRepository_Delete_Call struct {
2768+ *mock.Call
2769+}
2770+
2771+// Delete is a helper method to define mock.On call
2772+// - ctx context.Context
2773+// - id entity.SessionID
2774+func (_e *MockSessionRepository_Expecter) Delete(ctx interface{}, id interface{}) *MockSessionRepository_Delete_Call {
2775+ return &MockSessionRepository_Delete_Call{Call: _e.mock.On("Delete", ctx, id)}
2776+}
2777+
2778+func (_c *MockSessionRepository_Delete_Call) Run(run func(ctx context.Context, id entity.SessionID)) *MockSessionRepository_Delete_Call {
2779+ _c.Call.Run(func(args mock.Arguments) {
2780+ var arg0 context.Context
2781+ if args[0] != nil {
2782+ arg0 = args[0].(context.Context)
2783+ }
2784+ var arg1 entity.SessionID
2785+ if args[1] != nil {
2786+ arg1 = args[1].(entity.SessionID)
2787+ }
2788+ run(
2789+ arg0,
2790+ arg1,
2791+ )
2792+ })
2793+ return _c
2794+}
2795+
2796+func (_c *MockSessionRepository_Delete_Call) Return(err error) *MockSessionRepository_Delete_Call {
2797+ _c.Call.Return(err)
2798+ return _c
2799+}
2800+
2801+func (_c *MockSessionRepository_Delete_Call) RunAndReturn(run func(ctx context.Context, id entity.SessionID) error) *MockSessionRepository_Delete_Call {
2802+ _c.Call.Return(run)
2803+ return _c
2804+}
2805+
27492806 // FindByID provides a mock function for the type MockSessionRepository
27502807 func (_mock *MockSessionRepository) FindByID(ctx context.Context, id entity.SessionID) (*entity.Session, error) {
27512808 ret := _mock.Called(ctx, id)
@@ -2746,6 +2746,63 @@ func (_m *MockSessionRepository) EXPECT() *MockSessionRepository_Expecter {
2746 return &MockSessionRepository_Expecter{mock: &_m.Mock}2746 return &MockSessionRepository_Expecter{mock: &_m.Mock}
2747 }2747 }
2748 2748
2749+// Delete provides a mock function for the type MockSessionRepository
2750+func (_mock *MockSessionRepository) Delete(ctx context.Context, id entity.SessionID) error {
2751+ ret := _mock.Called(ctx, id)
2752+
2753+ if len(ret) == 0 {
2754+ panic("no return value specified for Delete")
2755+ }
2756+
2757+ var r0 error
2758+ if returnFunc, ok := ret.Get(0).(func(context.Context, entity.SessionID) error); ok {
2759+ r0 = returnFunc(ctx, id)
2760+ } else {
2761+ r0 = ret.Error(0)
2762+ }
2763+ return r0
2764+}
2765+
2766+// MockSessionRepository_Delete_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Delete'
2767+type MockSessionRepository_Delete_Call struct {
2768+ *mock.Call
2769+}
2770+
2771+// Delete is a helper method to define mock.On call
2772+// - ctx context.Context
2773+// - id entity.SessionID
2774+func (_e *MockSessionRepository_Expecter) Delete(ctx interface{}, id interface{}) *MockSessionRepository_Delete_Call {
2775+ return &MockSessionRepository_Delete_Call{Call: _e.mock.On("Delete", ctx, id)}
2776+}
2777+
2778+func (_c *MockSessionRepository_Delete_Call) Run(run func(ctx context.Context, id entity.SessionID)) *MockSessionRepository_Delete_Call {
2779+ _c.Call.Run(func(args mock.Arguments) {
2780+ var arg0 context.Context
2781+ if args[0] != nil {
2782+ arg0 = args[0].(context.Context)
2783+ }
2784+ var arg1 entity.SessionID
2785+ if args[1] != nil {
2786+ arg1 = args[1].(entity.SessionID)
2787+ }
2788+ run(
2789+ arg0,
2790+ arg1,
2791+ )
2792+ })
2793+ return _c
2794+}
2795+
2796+func (_c *MockSessionRepository_Delete_Call) Return(err error) *MockSessionRepository_Delete_Call {
2797+ _c.Call.Return(err)
2798+ return _c
2799+}
2800+
2801+func (_c *MockSessionRepository_Delete_Call) RunAndReturn(run func(ctx context.Context, id entity.SessionID) error) *MockSessionRepository_Delete_Call {
2802+ _c.Call.Return(run)
2803+ return _c
2804+}
2805+
2749 // FindByID provides a mock function for the type MockSessionRepository2806 // FindByID provides a mock function for the type MockSessionRepository
2750 func (_mock *MockSessionRepository) FindByID(ctx context.Context, id entity.SessionID) (*entity.Session, error) {2807 func (_mock *MockSessionRepository) FindByID(ctx context.Context, id entity.SessionID) (*entity.Session, error) {
2751 ret := _mock.Called(ctx, id)2808 ret := _mock.Called(ctx, id)

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