chore(M4): regenerate mocks and add engine seam tests
Add all missing port interfaces to .mockery.yaml (AccentKeyHandler, AutoCopyConfig, Clipboard, DesktopIntegration, DownloadEventHandler, DownloadPreparer, FaviconService, FileSystem, FilterManager, Focusable, FindController, GTKEntryInputTarget, HomepageFavorites, HomepageHistory, AllKeybindingsResetter, KeybindingResetter, KeybindingSetter, KeybindingsGetter, MediaDiagnostics, NativeWidgetProvider, Notification, RenderingEnvManager, RuntimeVersionProbe, ScriptRefresher, SnapshotService, TextInputTargetProvider, Texture, ToolkitAvailabilityNotifier, UpdateApplier, UpdateChecker, UpdateDownloader, WebUIConfigSaver, XDGPaths) and regenerate mocks. Add nil-safety/wrong-type tests for engine seam in webkit and bootstrap packages. Fix pre-existing download_handler_test.go field name mismatch.
- commit
- 115d8d080bb356cb7024f3baec809dfa6ae3b3e0
- author
- brice · · 2026-03-17 10:32 UTC
- parent
- 10854a9
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
5 files · +9986 -2539
M .mockery.yaml +33 -0
| @@ -44,6 +44,39 @@ packages: | |||
| 44 | 44 | OAuthCallbackCapable: {} | |
| 45 | 45 | DevToolsOpener: {} | |
| 46 | 46 | Printer: {} | |
| 47 | + | AccentKeyHandler: {} | |
| 48 | + | AutoCopyConfig: {} | |
| 49 | + | Clipboard: {} | |
| 50 | + | DesktopIntegration: {} | |
| 51 | + | DownloadEventHandler: {} | |
| 52 | + | DownloadPreparer: {} | |
| 53 | + | FaviconService: {} | |
| 54 | + | FileSystem: {} | |
| 55 | + | FilterManager: {} | |
| 56 | + | Focusable: {} | |
| 57 | + | FindController: {} | |
| 58 | + | GTKEntryInputTarget: {} | |
| 59 | + | HomepageFavorites: {} | |
| 60 | + | HomepageHistory: {} | |
| 61 | + | AllKeybindingsResetter: {} | |
| 62 | + | KeybindingResetter: {} | |
| 63 | + | KeybindingSetter: {} | |
| 64 | + | KeybindingsGetter: {} | |
| 65 | + | MediaDiagnostics: {} | |
| 66 | + | NativeWidgetProvider: {} | |
| 67 | + | Notification: {} | |
| 68 | + | RenderingEnvManager: {} | |
| 69 | + | RuntimeVersionProbe: {} | |
| 70 | + | ScriptRefresher: {} | |
| 71 | + | SnapshotService: {} | |
| 72 | + | TextInputTargetProvider: {} | |
| 73 | + | Texture: {} | |
| 74 | + | ToolkitAvailabilityNotifier: {} | |
| 75 | + | UpdateApplier: {} | |
| 76 | + | UpdateChecker: {} | |
| 77 | + | UpdateDownloader: {} | |
| 78 | + | WebUIConfigSaver: {} | |
| 79 | + | XDGPaths: {} | |
| 47 | 80 | github.com/bnema/dumber/internal/domain/repository: | |
| 48 | 81 | config: | |
| 49 | 82 | dir: '{{.InterfaceDir}}/mocks' | |
| @@ -44,6 +44,39 @@ packages: | |||||
| 44 | OAuthCallbackCapable: {} | 44 | OAuthCallbackCapable: {} | ||
| 45 | DevToolsOpener: {} | 45 | DevToolsOpener: {} | ||
| 46 | Printer: {} | 46 | Printer: {} | ||
| 47 | + | AccentKeyHandler: {} | |||
| 48 | + | AutoCopyConfig: {} | |||
| 49 | + | Clipboard: {} | |||
| 50 | + | DesktopIntegration: {} | |||
| 51 | + | DownloadEventHandler: {} | |||
| 52 | + | DownloadPreparer: {} | |||
| 53 | + | FaviconService: {} | |||
| 54 | + | FileSystem: {} | |||
| 55 | + | FilterManager: {} | |||
| 56 | + | Focusable: {} | |||
| 57 | + | FindController: {} | |||
| 58 | + | GTKEntryInputTarget: {} | |||
| 59 | + | HomepageFavorites: {} | |||
| 60 | + | HomepageHistory: {} | |||
| 61 | + | AllKeybindingsResetter: {} | |||
| 62 | + | KeybindingResetter: {} | |||
| 63 | + | KeybindingSetter: {} | |||
| 64 | + | KeybindingsGetter: {} | |||
| 65 | + | MediaDiagnostics: {} | |||
| 66 | + | NativeWidgetProvider: {} | |||
| 67 | + | Notification: {} | |||
| 68 | + | RenderingEnvManager: {} | |||
| 69 | + | RuntimeVersionProbe: {} | |||
| 70 | + | ScriptRefresher: {} | |||
| 71 | + | SnapshotService: {} | |||
| 72 | + | TextInputTargetProvider: {} | |||
| 73 | + | Texture: {} | |||
| 74 | + | ToolkitAvailabilityNotifier: {} | |||
| 75 | + | UpdateApplier: {} | |||
| 76 | + | UpdateChecker: {} | |||
| 77 | + | UpdateDownloader: {} | |||
| 78 | + | WebUIConfigSaver: {} | |||
| 79 | + | XDGPaths: {} | |||
| 47 | github.com/bnema/dumber/internal/domain/repository: | 80 | github.com/bnema/dumber/internal/domain/repository: | ||
| 48 | config: | 81 | config: | ||
| 49 | dir: '{{.InterfaceDir}}/mocks' | 82 | dir: '{{.InterfaceDir}}/mocks' | ||
M internal/application/port/mocks/mocks.go +9874 -2538 large diff (12412 lines changed): collapsed
A internal/bootstrap/engine_test.go +25 -0
| @@ -0,0 +1,25 @@ | |||
| 1 | + | package bootstrap | |
| 2 | + | ||
| 3 | + | import ( | |
| 4 | + | "context" | |
| 5 | + | "testing" | |
| 6 | + | ||
| 7 | + | "github.com/bnema/dumber/internal/infrastructure/config" | |
| 8 | + | "github.com/stretchr/testify/require" | |
| 9 | + | ) | |
| 10 | + | ||
| 11 | + | func TestBuildEngine_UnknownType(t *testing.T) { | |
| 12 | + | cfg := config.DefaultConfig() | |
| 13 | + | cfg.Engine.Type = "unknown" | |
| 14 | + | _, err := BuildEngine(EngineInput{Config: cfg, Ctx: context.Background()}) | |
| 15 | + | require.Error(t, err) | |
| 16 | + | require.Contains(t, err.Error(), "unknown engine type") | |
| 17 | + | } | |
| 18 | + | ||
| 19 | + | func TestBuildEngine_CEF_NotImplemented(t *testing.T) { | |
| 20 | + | cfg := config.DefaultConfig() | |
| 21 | + | cfg.Engine.Type = "cef" | |
| 22 | + | _, err := BuildEngine(EngineInput{Config: cfg, Ctx: context.Background()}) | |
| 23 | + | require.Error(t, err) | |
| 24 | + | require.Contains(t, err.Error(), "not yet implemented") | |
| 25 | + | } | |
| @@ -0,0 +1,25 @@ | |||||
| 1 | + | package bootstrap | |||
| 2 | + | ||||
| 3 | + | import ( | |||
| 4 | + | "context" | |||
| 5 | + | "testing" | |||
| 6 | + | ||||
| 7 | + | "github.com/bnema/dumber/internal/infrastructure/config" | |||
| 8 | + | "github.com/stretchr/testify/require" | |||
| 9 | + | ) | |||
| 10 | + | ||||
| 11 | + | func TestBuildEngine_UnknownType(t *testing.T) { | |||
| 12 | + | cfg := config.DefaultConfig() | |||
| 13 | + | cfg.Engine.Type = "unknown" | |||
| 14 | + | _, err := BuildEngine(EngineInput{Config: cfg, Ctx: context.Background()}) | |||
| 15 | + | require.Error(t, err) | |||
| 16 | + | require.Contains(t, err.Error(), "unknown engine type") | |||
| 17 | + | } | |||
| 18 | + | ||||
| 19 | + | func TestBuildEngine_CEF_NotImplemented(t *testing.T) { | |||
| 20 | + | cfg := config.DefaultConfig() | |||
| 21 | + | cfg.Engine.Type = "cef" | |||
| 22 | + | _, err := BuildEngine(EngineInput{Config: cfg, Ctx: context.Background()}) | |||
| 23 | + | require.Error(t, err) | |||
| 24 | + | require.Contains(t, err.Error(), "not yet implemented") | |||
| 25 | + | } | |||
M internal/infrastructure/webkit/download_handler_test.go +1 -1
| @@ -16,7 +16,7 @@ func TestNewDownloadHandler(t *testing.T) { | |||
| 16 | 16 | assert.NotNil(t, handler) | |
| 17 | 17 | assert.Equal(t, "/tmp/downloads", handler.downloadPath) | |
| 18 | 18 | assert.Nil(t, handler.eventHandler) | |
| 19 | - | assert.NotNil(t, handler.prepareDownloadUC) | |
| 19 | + | assert.NotNil(t, handler.preparer) | |
| 20 | 20 | }) | |
| 21 | 21 | ||
| 22 | 22 | t.Run("creates handler with custom path", func(t *testing.T) { | |
| @@ -16,7 +16,7 @@ func TestNewDownloadHandler(t *testing.T) { | |||||
| 16 | assert.NotNil(t, handler) | 16 | assert.NotNil(t, handler) | ||
| 17 | assert.Equal(t, "/tmp/downloads", handler.downloadPath) | 17 | assert.Equal(t, "/tmp/downloads", handler.downloadPath) | ||
| 18 | assert.Nil(t, handler.eventHandler) | 18 | assert.Nil(t, handler.eventHandler) | ||
| 19 | - | assert.NotNil(t, handler.prepareDownloadUC) | 19 | + | assert.NotNil(t, handler.preparer) |
| 20 | }) | 20 | }) | ||
| 21 | 21 | ||||
| 22 | t.Run("creates handler with custom path", func(t *testing.T) { | 22 | t.Run("creates handler with custom path", func(t *testing.T) { | ||
A internal/infrastructure/webkit/engine_runtime_test.go +53 -0
| @@ -0,0 +1,53 @@ | |||
| 1 | + | package webkit | |
| 2 | + | ||
| 3 | + | import ( | |
| 4 | + | "context" | |
| 5 | + | "testing" | |
| 6 | + | ||
| 7 | + | "github.com/bnema/dumber/internal/application/port" | |
| 8 | + | "github.com/bnema/dumber/internal/infrastructure/config" | |
| 9 | + | "github.com/stretchr/testify/require" | |
| 10 | + | ) | |
| 11 | + | ||
| 12 | + | func TestEngine_UpdateSettings_WrongType(t *testing.T) { | |
| 13 | + | e := &Engine{} | |
| 14 | + | err := e.UpdateSettings(context.Background(), port.EngineSettingsUpdate{Raw: "wrong"}) | |
| 15 | + | require.Error(t, err) | |
| 16 | + | require.Contains(t, err.Error(), "expected *config.Config") | |
| 17 | + | } | |
| 18 | + | ||
| 19 | + | func TestEngine_UpdateSettings_NilSettings(t *testing.T) { | |
| 20 | + | // settings is nil — should not panic, just be a no-op. | |
| 21 | + | e := &Engine{} | |
| 22 | + | // Use a nil *config.Config to pass the type assertion. | |
| 23 | + | var cfg *config.Config | |
| 24 | + | err := e.UpdateSettings(context.Background(), port.EngineSettingsUpdate{Raw: cfg}) | |
| 25 | + | require.NoError(t, err) | |
| 26 | + | } | |
| 27 | + | ||
| 28 | + | func TestEngine_RegisterHandlers_NilRouter(t *testing.T) { | |
| 29 | + | e := &Engine{} | |
| 30 | + | err := e.RegisterHandlers(context.Background(), port.HandlerDependencies{}) | |
| 31 | + | require.Error(t, err) | |
| 32 | + | require.Contains(t, err.Error(), "message router not initialized") | |
| 33 | + | } | |
| 34 | + | ||
| 35 | + | func TestEngine_RegisterAccentHandlers_NilRouter(t *testing.T) { | |
| 36 | + | e := &Engine{} | |
| 37 | + | err := e.RegisterAccentHandlers(context.Background(), nil) | |
| 38 | + | require.Error(t, err) | |
| 39 | + | require.Contains(t, err.Error(), "message router not initialized") | |
| 40 | + | } | |
| 41 | + | ||
| 42 | + | func TestEngine_ConfigureDownloads_NilContext(t *testing.T) { | |
| 43 | + | e := &Engine{} | |
| 44 | + | err := e.ConfigureDownloads(context.Background(), "/tmp", nil, nil) | |
| 45 | + | require.Error(t, err) | |
| 46 | + | require.Contains(t, err.Error(), "webkit context not initialized") | |
| 47 | + | } | |
| 48 | + | ||
| 49 | + | func TestEngine_Close_NilPool(t *testing.T) { | |
| 50 | + | e := &Engine{} | |
| 51 | + | err := e.Close() | |
| 52 | + | require.NoError(t, err) | |
| 53 | + | } | |
| @@ -0,0 +1,53 @@ | |||||
| 1 | + | package webkit | |||
| 2 | + | ||||
| 3 | + | import ( | |||
| 4 | + | "context" | |||
| 5 | + | "testing" | |||
| 6 | + | ||||
| 7 | + | "github.com/bnema/dumber/internal/application/port" | |||
| 8 | + | "github.com/bnema/dumber/internal/infrastructure/config" | |||
| 9 | + | "github.com/stretchr/testify/require" | |||
| 10 | + | ) | |||
| 11 | + | ||||
| 12 | + | func TestEngine_UpdateSettings_WrongType(t *testing.T) { | |||
| 13 | + | e := &Engine{} | |||
| 14 | + | err := e.UpdateSettings(context.Background(), port.EngineSettingsUpdate{Raw: "wrong"}) | |||
| 15 | + | require.Error(t, err) | |||
| 16 | + | require.Contains(t, err.Error(), "expected *config.Config") | |||
| 17 | + | } | |||
| 18 | + | ||||
| 19 | + | func TestEngine_UpdateSettings_NilSettings(t *testing.T) { | |||
| 20 | + | // settings is nil — should not panic, just be a no-op. | |||
| 21 | + | e := &Engine{} | |||
| 22 | + | // Use a nil *config.Config to pass the type assertion. | |||
| 23 | + | var cfg *config.Config | |||
| 24 | + | err := e.UpdateSettings(context.Background(), port.EngineSettingsUpdate{Raw: cfg}) | |||
| 25 | + | require.NoError(t, err) | |||
| 26 | + | } | |||
| 27 | + | ||||
| 28 | + | func TestEngine_RegisterHandlers_NilRouter(t *testing.T) { | |||
| 29 | + | e := &Engine{} | |||
| 30 | + | err := e.RegisterHandlers(context.Background(), port.HandlerDependencies{}) | |||
| 31 | + | require.Error(t, err) | |||
| 32 | + | require.Contains(t, err.Error(), "message router not initialized") | |||
| 33 | + | } | |||
| 34 | + | ||||
| 35 | + | func TestEngine_RegisterAccentHandlers_NilRouter(t *testing.T) { | |||
| 36 | + | e := &Engine{} | |||
| 37 | + | err := e.RegisterAccentHandlers(context.Background(), nil) | |||
| 38 | + | require.Error(t, err) | |||
| 39 | + | require.Contains(t, err.Error(), "message router not initialized") | |||
| 40 | + | } | |||
| 41 | + | ||||
| 42 | + | func TestEngine_ConfigureDownloads_NilContext(t *testing.T) { | |||
| 43 | + | e := &Engine{} | |||
| 44 | + | err := e.ConfigureDownloads(context.Background(), "/tmp", nil, nil) | |||
| 45 | + | require.Error(t, err) | |||
| 46 | + | require.Contains(t, err.Error(), "webkit context not initialized") | |||
| 47 | + | } | |||
| 48 | + | ||||
| 49 | + | func TestEngine_Close_NilPool(t *testing.T) { | |||
| 50 | + | e := &Engine{} | |||
| 51 | + | err := e.Close() | |||
| 52 | + | require.NoError(t, err) | |||
| 53 | + | } | |||