1package ui
2
3import (
4 "context"
5 "testing"
6
7 "github.com/stretchr/testify/mock"
8
9 "github.com/bnema/dumber/internal/application/dto"
10 "github.com/bnema/dumber/internal/application/port"
11 portmocks "github.com/bnema/dumber/internal/application/port/mocks"
12 "github.com/bnema/dumber/internal/domain/entity"
13 "github.com/bnema/dumber/internal/shared/syncdispatch"
14 "github.com/bnema/dumber/internal/ui/coordinator/content"
15)
16
17func TestDependenciesValidateAcceptsRuntimeConfigOnly(t *testing.T) {
18 runtimeConfig := portmocks.NewMockRuntimeConfigProvider(t)
19 engine := portmocks.NewMockEngine(t)
20 deps := &Dependencies{
21 Ctx: context.Background(),
22 RuntimeConfig: runtimeConfig,
23 Engine: engine,
24 HandlerDeps: port.HandlerDeps{
25 SaveConfig: func(context.Context, dto.WebUIConfig) error {
26 return nil
27 },
28 SaveOmniboxInitialBehavior: func(context.Context, entity.OmniboxInitialBehavior) error {
29 return nil
30 },
31 SaveModeLegendCollapsed: func(context.Context, bool) error {
32 return nil
33 },
34 },
35 }
36
37 if err := deps.Validate(); err != nil {
38 t.Fatalf("Validate() error = %v, want nil", err)
39 }
40}
41
42func TestAppRuntimeConfigReturnsProviderSnapshot(t *testing.T) {
43 provider := portmocks.NewMockRuntimeConfigProvider(t)
44 provider.EXPECT().
45 Current().
46 Return(entity.RuntimeConfigSnapshot{
47 UI: entity.RuntimeUIConfig{DefaultUIScale: 1.6},
48 }).
49 Once()
50 app := &App{deps: &Dependencies{RuntimeConfig: provider}}
51
52 got := app.runtimeConfigSnapshot()
53
54 if got.UI.DefaultUIScale != 1.6 {
55 t.Fatalf("DefaultUIScale=%v, want 1.6", got.UI.DefaultUIScale)
56 }
57}
58
59func TestAppRuntimeConfigStateStoresLatestSnapshot(t *testing.T) {
60 app := &App{}
61 setRuntimeConfigSnapshotForTest(app, entity.RuntimeConfigSnapshot{
62 UI: entity.RuntimeUIConfig{SidebarWidth: 340},
63 })
64
65 got := app.runtimeConfigSnapshot()
66 if got.UI.SidebarWidth != 340 {
67 t.Fatalf("SidebarWidth=%d, want 340", got.UI.SidebarWidth)
68 }
69}
70
71func TestConfigWatcherOnChangeUpdatesRuntimeConfigState(t *testing.T) {
72 ctx := context.Background()
73 provider := portmocks.NewMockRuntimeConfigProvider(t)
74 provider.EXPECT().Watch().Return(nil).Once()
75 var onChange func(entity.RuntimeConfigSnapshot)
76 provider.EXPECT().
77 OnChange(mock.Anything).
78 Run(func(fn func(entity.RuntimeConfigSnapshot)) {
79 onChange = fn
80 }).
81 Once()
82
83 initial := entity.RuntimeConfigSnapshot{
84 UI: entity.RuntimeUIConfig{
85 Workspace: entity.WorkspaceConfig{
86 BrowsingContexts: entity.BrowsingContextConfig{OpenInNewPane: true},
87 },
88 },
89 }
90 app := &App{
91 deps: &Dependencies{RuntimeConfig: provider},
92 runtimeConfig: runtimeConfigStateFromSnapshotForTest(initial),
93 contentCoord: &content.Coordinator{},
94 browserWindows: map[string]*browserWindow{},
95 dispatchOnMainThread: func(label string, fn func()) syncdispatch.SyncDispatchResult {
96 if label != "ui.runtime_config_reload" {
97 t.Fatalf("dispatch label=%q, want ui.runtime_config_reload", label)
98 }
99 fn()
100 return syncdispatch.SyncDispatchResult{Label: label, Status: syncdispatch.SyncDispatchCompleted}
101 },
102 }
103 app.contentCoord.SetPopupConfig(nil, &initial.UI.Workspace.BrowsingContexts, nil)
104
105 app.initConfigWatcher(ctx)
106 if onChange == nil {
107 t.Fatal("runtime config OnChange callback was not registered")
108 }
109
110 onChange(entity.RuntimeConfigSnapshot{
111 UI: entity.RuntimeUIConfig{
112 SidebarWidth: 360,
113 Workspace: entity.WorkspaceConfig{
114 BrowsingContexts: entity.BrowsingContextConfig{OpenInNewPane: false, OAuthAutoClose: true},
115 },
116 },
117 })
118
119 got := app.runtimeConfigSnapshot()
120 if got.UI.SidebarWidth != 360 {
121 t.Fatalf("SidebarWidth=%d, want 360", got.UI.SidebarWidth)
122 }
123 if got.UI.Workspace.BrowsingContexts.OpenInNewPane {
124 t.Fatal("runtime config state did not observe updated popup OpenInNewPane")
125 }
126 if !got.UI.Workspace.BrowsingContexts.OAuthAutoClose {
127 t.Fatal("runtime config state did not observe updated popup OAuthAutoClose")
128 }
129}