test: add missing GUI coverage
This commit is contained in:
parent
e11a03afbc
commit
4e690f1794
5 changed files with 372 additions and 0 deletions
|
|
@ -109,3 +109,65 @@ func TestBackground_RegisterBackgroundActions_Ugly(t *testing.T) {
|
|||
assert.Equal(t, "card-01", payload["key"])
|
||||
assert.Equal(t, map[string]any{"network": "visa", "last4": "4242"}, payload["details"])
|
||||
}
|
||||
|
||||
func TestBackground_AddSync_Good(t *testing.T) {
|
||||
r := NewBackgroundRegistry()
|
||||
source := map[string]any{"tag": "refresh", "kind": "sync"}
|
||||
record := r.AddSync(source)
|
||||
|
||||
require.NotNil(t, record)
|
||||
assert.Equal(t, "refresh", record["tag"])
|
||||
assert.Equal(t, "sync", record["kind"])
|
||||
source["tag"] = "mutated"
|
||||
assert.Equal(t, "refresh", record["tag"])
|
||||
}
|
||||
|
||||
func TestBackground_AddSync_Bad(t *testing.T) {
|
||||
r := NewBackgroundRegistry()
|
||||
record := r.AddSync(nil)
|
||||
|
||||
require.NotNil(t, record)
|
||||
assert.Empty(t, record)
|
||||
}
|
||||
|
||||
func TestBackground_AddSync_Ugly(t *testing.T) {
|
||||
r := NewBackgroundRegistry()
|
||||
first := r.AddSync(map[string]any{"tag": "sync-1"})
|
||||
second := r.AddSync(map[string]any{"tag": "sync-2"})
|
||||
|
||||
require.NotNil(t, first)
|
||||
require.NotNil(t, second)
|
||||
assert.Len(t, r.syncRegistrations, 2)
|
||||
}
|
||||
|
||||
func TestBackground_AddPush_Good(t *testing.T) {
|
||||
r := NewBackgroundRegistry()
|
||||
source := map[string]any{"endpoint": "/push/abc", "auth": "core-local"}
|
||||
record := r.AddPush(source)
|
||||
|
||||
require.NotNil(t, record)
|
||||
assert.Equal(t, "/push/abc", record["endpoint"])
|
||||
assert.Equal(t, "core-local", record["auth"])
|
||||
source["endpoint"] = "/push/mutated"
|
||||
assert.Equal(t, "/push/abc", record["endpoint"])
|
||||
}
|
||||
|
||||
func TestBackground_AddPush_Bad(t *testing.T) {
|
||||
r := NewBackgroundRegistry()
|
||||
record := r.AddPush(nil)
|
||||
|
||||
require.NotNil(t, record)
|
||||
assert.Empty(t, record)
|
||||
}
|
||||
|
||||
func TestBackground_AddPush_Ugly(t *testing.T) {
|
||||
r := NewBackgroundRegistry()
|
||||
first := r.AddPush(map[string]any{"endpoint": "/push/abc"})
|
||||
second := r.AddPush(map[string]any{"endpoint": "/push/def"})
|
||||
|
||||
require.NotNil(t, first)
|
||||
require.NotNil(t, second)
|
||||
assert.Len(t, r.pushSubscriptions, 2)
|
||||
assert.Equal(t, "/push/abc", first["endpoint"])
|
||||
assert.Equal(t, "/push/def", second["endpoint"])
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package display
|
|||
import (
|
||||
"context"
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
|
|
@ -392,6 +393,119 @@ func TestHandleWSMessage_SetWindowOpacity_Good(t *testing.T) {
|
|||
assert.InDelta(t, 0.35, info.Opacity, 0.0001)
|
||||
}
|
||||
|
||||
func TestDisplay_requireStringField_Good(t *testing.T) {
|
||||
value, err := requireStringField(map[string]any{"window": "main"}, "window")
|
||||
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "main", value)
|
||||
}
|
||||
|
||||
func TestDisplay_requireStringField_Bad(t *testing.T) {
|
||||
value, err := requireStringField(map[string]any{"window": ""}, "window")
|
||||
|
||||
require.Error(t, err)
|
||||
assert.Empty(t, value)
|
||||
}
|
||||
|
||||
func TestDisplay_requireStringField_Ugly(t *testing.T) {
|
||||
value, err := requireStringField(map[string]any{"window": 42}, "window")
|
||||
|
||||
require.Error(t, err)
|
||||
assert.Empty(t, value)
|
||||
}
|
||||
|
||||
func TestDisplay_optionsFromMap_Good(t *testing.T) {
|
||||
opts := optionsFromMap(map[string]any{"alpha": "one", "beta": 2})
|
||||
|
||||
require.Equal(t, 2, opts.Len())
|
||||
got := map[string]any{}
|
||||
for _, opt := range opts.Items() {
|
||||
got[opt.Key] = opt.Value
|
||||
}
|
||||
assert.True(t, reflect.DeepEqual(map[string]any{"alpha": "one", "beta": 2}, got))
|
||||
}
|
||||
|
||||
func TestDisplay_optionsFromMap_Bad(t *testing.T) {
|
||||
opts := optionsFromMap(nil)
|
||||
|
||||
require.NotNil(t, opts)
|
||||
assert.Equal(t, 0, opts.Len())
|
||||
}
|
||||
|
||||
func TestDisplay_optionsFromMap_Ugly(t *testing.T) {
|
||||
opts := wsOptions(map[string]any{"nested": map[string]any{"value": "x"}})
|
||||
|
||||
require.Equal(t, 1, opts.Len())
|
||||
item := opts.Items()[0]
|
||||
assert.Equal(t, "nested", item.Key)
|
||||
assert.Equal(t, map[string]any{"value": "x"}, item.Value)
|
||||
}
|
||||
|
||||
func TestDisplay_handleWSMessage_Good(t *testing.T) {
|
||||
c := newTestConclave(t)
|
||||
svc := core.MustServiceFor[*Service](c, "display")
|
||||
_ = svc.OpenWindow(window.WithName("opacity-win"))
|
||||
|
||||
result := svc.handleWSMessage(WSMessage{
|
||||
Action: "window:set-opacity",
|
||||
Data: map[string]any{
|
||||
"name": "opacity-win",
|
||||
"opacity": 0.55,
|
||||
},
|
||||
})
|
||||
require.True(t, result.OK)
|
||||
|
||||
info, err := svc.GetWindowInfo("opacity-win")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, info)
|
||||
assert.InDelta(t, 0.55, info.Opacity, 0.0001)
|
||||
}
|
||||
|
||||
func TestDisplay_handleWSMessage_Bad(t *testing.T) {
|
||||
svc, _ := newTestDisplayService(t)
|
||||
result := svc.handleWSMessage(WSMessage{Action: "unknown:action"})
|
||||
|
||||
require.False(t, result.OK)
|
||||
assert.Contains(t, result.Value.(error).Error(), "unknown websocket action")
|
||||
}
|
||||
|
||||
func TestDisplay_handleWSMessage_Ugly(t *testing.T) {
|
||||
svc, _ := newTestDisplayService(t)
|
||||
result := svc.handleWSMessage(WSMessage{
|
||||
Action: "window:set-opacity",
|
||||
Data: map[string]any{
|
||||
"name": "main",
|
||||
},
|
||||
})
|
||||
|
||||
require.False(t, result.OK)
|
||||
assert.Contains(t, result.Value.(error).Error(), "missing required field \"opacity\"")
|
||||
}
|
||||
|
||||
func TestDisplay_handleTrayAction_Good(t *testing.T) {
|
||||
platform := window.NewMockPlatform()
|
||||
c := core.New(
|
||||
core.WithService(Register(nil)),
|
||||
core.WithService(window.Register(platform)),
|
||||
core.WithService(systray.Register(systray.NewMockPlatform())),
|
||||
core.WithService(menu.Register(menu.NewMockPlatform())),
|
||||
core.WithServiceLock(),
|
||||
)
|
||||
require.True(t, c.ServiceStartup(context.Background(), nil).OK)
|
||||
svc := core.MustServiceFor[*Service](c, "display")
|
||||
_ = svc.OpenWindow(window.WithName("one"))
|
||||
_ = svc.OpenWindow(window.WithName("two"))
|
||||
|
||||
svc.handleTrayAction("open-desktop")
|
||||
require.Len(t, platform.Windows, 2)
|
||||
assert.True(t, platform.Windows[0].IsFocused())
|
||||
assert.True(t, platform.Windows[1].IsFocused())
|
||||
|
||||
svc.handleTrayAction("close-desktop")
|
||||
assert.False(t, platform.Windows[0].IsVisible())
|
||||
assert.False(t, platform.Windows[1].IsVisible())
|
||||
}
|
||||
|
||||
func TestGetFocusedWindow_Good(t *testing.T) {
|
||||
c := newTestConclave(t)
|
||||
svc := core.MustServiceFor[*Service](c, "display")
|
||||
|
|
|
|||
|
|
@ -166,6 +166,131 @@ func TestWSEventManager_HandleWebSocket_RejectsLoopbackSpoofedOrigin(t *testing.
|
|||
assert.Equal(t, http.StatusForbidden, recorder.Code)
|
||||
}
|
||||
|
||||
func TestEvents_trustedWebSocketOrigin_Good(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
req *http.Request
|
||||
want bool
|
||||
}{
|
||||
{
|
||||
name: "localhost without origin",
|
||||
req: func() *http.Request {
|
||||
r := httptest.NewRequest(http.MethodGet, "http://127.0.0.1/events", nil)
|
||||
r.RemoteAddr = "127.0.0.1:12345"
|
||||
return r
|
||||
}(),
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "local origin",
|
||||
req: func() *http.Request {
|
||||
r := httptest.NewRequest(http.MethodGet, "http://127.0.0.1/events", nil)
|
||||
r.RemoteAddr = "127.0.0.1:12345"
|
||||
r.Header.Set("Origin", "http://localhost:8080")
|
||||
return r
|
||||
}(),
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "file origin",
|
||||
req: func() *http.Request {
|
||||
r := httptest.NewRequest(http.MethodGet, "http://127.0.0.1/events", nil)
|
||||
r.RemoteAddr = "[::1]:12345"
|
||||
r.Header.Set("Origin", "file://local")
|
||||
return r
|
||||
}(),
|
||||
want: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
assert.Equal(t, tc.want, trustedWebSocketOrigin(tc.req))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestEvents_trustedWebSocketOrigin_Bad(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
req *http.Request
|
||||
}{
|
||||
{
|
||||
name: "nil request",
|
||||
},
|
||||
{
|
||||
name: "wrong path",
|
||||
req: func() *http.Request {
|
||||
r := httptest.NewRequest(http.MethodGet, "http://127.0.0.1/other", nil)
|
||||
r.RemoteAddr = "127.0.0.1:12345"
|
||||
return r
|
||||
}(),
|
||||
},
|
||||
{
|
||||
name: "remote client",
|
||||
req: func() *http.Request {
|
||||
r := httptest.NewRequest(http.MethodGet, "http://127.0.0.1/events", nil)
|
||||
r.RemoteAddr = "203.0.113.10:2222"
|
||||
return r
|
||||
}(),
|
||||
},
|
||||
{
|
||||
name: "remote origin",
|
||||
req: func() *http.Request {
|
||||
r := httptest.NewRequest(http.MethodGet, "http://127.0.0.1/events", nil)
|
||||
r.RemoteAddr = "127.0.0.1:12345"
|
||||
r.Header.Set("Origin", "https://evil.example")
|
||||
return r
|
||||
}(),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
assert.False(t, trustedWebSocketOrigin(tc.req))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestEvents_trustedWebSocketOrigin_Ugly(t *testing.T) {
|
||||
req := httptest.NewRequest(http.MethodGet, "http://127.0.0.1/events", nil)
|
||||
req.RemoteAddr = "127.0.0.1:12345"
|
||||
req.Header.Set("Origin", "://bad")
|
||||
|
||||
assert.False(t, trustedWebSocketOrigin(req))
|
||||
assert.False(t, trustedWebSocketOrigin(&http.Request{}))
|
||||
}
|
||||
|
||||
func TestEvents_trustedWebSocketHost_Good(t *testing.T) {
|
||||
assert.True(t, trustedWebSocketHost("localhost"))
|
||||
assert.True(t, trustedWebSocketHost("127.0.0.1:443"))
|
||||
assert.True(t, trustedWebSocketHost("[::1]:80"))
|
||||
}
|
||||
|
||||
func TestEvents_trustedWebSocketHost_Bad(t *testing.T) {
|
||||
assert.False(t, trustedWebSocketHost(""))
|
||||
assert.False(t, trustedWebSocketHost("example.com"))
|
||||
}
|
||||
|
||||
func TestEvents_trustedWebSocketHost_Ugly(t *testing.T) {
|
||||
assert.False(t, trustedWebSocketHost("not a host"))
|
||||
}
|
||||
|
||||
func TestEvents_isLoopbackHost_Good(t *testing.T) {
|
||||
assert.True(t, isLoopbackHost("localhost"))
|
||||
assert.True(t, isLoopbackHost("127.0.0.1"))
|
||||
assert.True(t, isLoopbackHost("::1"))
|
||||
}
|
||||
|
||||
func TestEvents_isLoopbackHost_Bad(t *testing.T) {
|
||||
assert.False(t, isLoopbackHost(""))
|
||||
assert.False(t, isLoopbackHost("example.com"))
|
||||
}
|
||||
|
||||
func TestEvents_isLoopbackHost_Ugly(t *testing.T) {
|
||||
assert.False(t, isLoopbackHost("203.0.113.10"))
|
||||
}
|
||||
|
||||
func TestWSEventManager_HandleWebSocket_ClosesOnMalformedMessage(t *testing.T) {
|
||||
em := NewWSEventManager()
|
||||
conn, cleanup := dialWSEventManager(t, em)
|
||||
|
|
|
|||
|
|
@ -170,3 +170,45 @@ func TestManifest_LoadManifestForOrigin_RejectsOversizedFile(t *testing.T) {
|
|||
require.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "exceeds")
|
||||
}
|
||||
|
||||
func TestManifest_ManifestBaseDir_Good(t *testing.T) {
|
||||
assert.Equal(t, "/tmp/app", manifestBaseDir("/tmp/app/.core/view.yaml"))
|
||||
assert.Equal(t, "/tmp/app/assets", manifestBaseDir("/tmp/app/assets/view.yaml"))
|
||||
}
|
||||
|
||||
func TestManifest_ManifestBaseDir_Bad(t *testing.T) {
|
||||
assert.Equal(t, ".", manifestBaseDir(".core/view.yaml"))
|
||||
}
|
||||
|
||||
func TestManifest_ManifestBaseDir_Ugly(t *testing.T) {
|
||||
assert.Equal(t, "/", manifestBaseDir("/.core/view.yaml"))
|
||||
}
|
||||
|
||||
func TestManifest_SafeManifestRelativePath_Good(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
target := filepath.Join(root, "preload.js")
|
||||
require.NoError(t, os.WriteFile(target, []byte("globalThis.ready = true;"), 0o644))
|
||||
expected, err := filepath.EvalSymlinks(target)
|
||||
require.NoError(t, err)
|
||||
|
||||
got, err := safeManifestRelativePath(root, "preload.js", "preload path")
|
||||
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, expected, got)
|
||||
}
|
||||
|
||||
func TestManifest_SafeManifestRelativePath_Bad(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
|
||||
_, err := safeManifestRelativePath(root, "", "preload path")
|
||||
require.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "empty")
|
||||
}
|
||||
|
||||
func TestManifest_SafeManifestRelativePath_Ugly(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
|
||||
_, err := safeManifestRelativePath(root, "../escape.js", "preload path")
|
||||
require.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "escapes")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
package window
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
|
@ -161,6 +162,34 @@ func TestManager_Remove_Good(t *testing.T) {
|
|||
assert.False(t, ok)
|
||||
}
|
||||
|
||||
func TestManager_NewManagerWithDir_Good(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
p := newMockPlatform()
|
||||
|
||||
m := NewManagerWithDir(p, dir)
|
||||
|
||||
require.NotNil(t, m)
|
||||
assert.Same(t, p, m.Platform())
|
||||
assert.Equal(t, dir, m.State().dataDir())
|
||||
assert.Equal(t, filepath.Join(dir, "layouts.json"), m.Layout().filePath())
|
||||
}
|
||||
|
||||
func TestManager_NewManagerWithDir_Bad(t *testing.T) {
|
||||
m := NewManagerWithDir(nil, "")
|
||||
|
||||
require.NotNil(t, m)
|
||||
assert.Nil(t, m.Platform())
|
||||
assert.Empty(t, m.State().dataDir())
|
||||
}
|
||||
|
||||
func TestManager_NewManagerWithDir_Ugly(t *testing.T) {
|
||||
dir := filepath.Join(t.TempDir(), "..", "workspace")
|
||||
m := NewManagerWithDir(nil, dir)
|
||||
|
||||
require.NotNil(t, m)
|
||||
assert.Equal(t, dir, m.State().dataDir())
|
||||
}
|
||||
|
||||
// --- Tiling Tests ---
|
||||
|
||||
func TestTileMode_String_Good(t *testing.T) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue