gui/pkg/display/scheme_test.go

246 lines
7.9 KiB
Go
Raw Normal View History

2026-04-15 17:27:40 +01:00
package display
import (
"context"
"net/url"
"testing"
core "dappco.re/go/core"
"forge.lthn.ai/core/gui/pkg/chat"
2026-04-15 19:16:45 +01:00
"forge.lthn.ai/core/gui/pkg/p2p"
2026-04-15 17:27:40 +01:00
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/wailsapp/wails/v3/pkg/application"
2026-04-15 17:27:40 +01:00
)
type testApplicationResponseWriter struct {
header map[string][]string
body []byte
status int
}
func newTestApplicationResponseWriter() *testApplicationResponseWriter {
return &testApplicationResponseWriter{header: map[string][]string{}}
}
func (w *testApplicationResponseWriter) Header() map[string][]string {
if w.header == nil {
w.header = map[string][]string{}
}
return w.header
}
func (w *testApplicationResponseWriter) Write(data []byte) (int, error) {
w.body = append(w.body, data...)
return len(data), nil
}
func (w *testApplicationResponseWriter) WriteHeader(statusCode int) {
w.status = statusCode
}
type testApplicationHandler struct {
called bool
}
func (h *testApplicationHandler) ServeHTTP(_ application.ResponseWriter, _ *application.Request) {
h.called = true
}
2026-04-15 19:16:45 +01:00
type mockPeerRouter struct {
peers []p2p.Peer
}
func (m mockPeerRouter) Peers() []p2p.Peer {
return m.peers
}
2026-04-15 17:27:40 +01:00
func TestScheme_ResolveScheme_Good(t *testing.T) {
svc, c := newTestDisplayService(t)
svc.registerDefaultSchemes()
svc.configFile = nil
svc.storage.Set("origin-a", "localStorage", "theme", "dark")
svc.configData["window"] = map[string]any{"default_width": 1024, "default_height": 768}
c.Action("gui.chat.models", func(_ context.Context, _ core.Options) core.Result {
return core.Result{
Value: []chat.ModelEntry{
{Name: "Alpha", Architecture: "gemma", SizeBytes: 2048, Loaded: true, Backend: "local"},
{Name: "Beta", Architecture: "phi", SizeBytes: 4096, Loaded: false},
},
OK: true,
}
})
c.RegisterQuery(func(_ *core.Core, q core.Query) core.Result {
switch q.(type) {
case chat.QueryConversationList:
return core.Result{
Value: []chat.ConversationSummary{{ID: "conv-1", Title: "Chat Route", MessageCount: 3}},
OK: true,
2026-04-15 17:27:40 +01:00
}
case chat.QueryHistory:
return core.Result{
Value: chat.Conversation{ID: "conv-1", Title: "Chat Route"},
OK: true,
2026-04-15 17:27:40 +01:00
}
case chat.QueryConversationSearch:
return core.Result{
Value: []any{"chat-match"},
OK: true,
2026-04-15 17:27:40 +01:00
}
default:
return core.Result{}
}
})
storeResult := svc.ResolveScheme(context.Background(), "core://store?q=theme")
require.True(t, storeResult.OK)
storePayload := storeResult.Value.(map[string]any)
assert.Equal(t, "text/html", storePayload["content_type"])
assert.Contains(t, storePayload["body"].(string), "origin-a")
assert.Contains(t, storePayload["body"].(string), "dark")
entryResult := svc.ResolveScheme(context.Background(), "core://store/localStorage/theme")
require.True(t, entryResult.OK)
entryPayload := entryResult.Value.(map[string]any)
assert.Equal(t, "store", entryPayload["route"])
assert.Contains(t, entryPayload["body"].(string), "localStorage")
assert.Contains(t, entryPayload["body"].(string), "theme")
settingsResult := svc.ResolveScheme(context.Background(), "core://settings/window")
require.True(t, settingsResult.OK)
settingsPayload := settingsResult.Value.(map[string]any)
assert.Equal(t, "settings", settingsPayload["route"])
assert.Contains(t, settingsPayload["body"].(string), "default_width")
assert.Contains(t, settingsPayload["body"].(string), "1024")
modelResult := svc.ResolveScheme(context.Background(), "core://models/alpha")
require.True(t, modelResult.OK)
modelPayload := modelResult.Value.(map[string]any)
assert.Equal(t, "models", modelPayload["route"])
assert.Contains(t, modelPayload["body"].(string), "Alpha")
assert.Contains(t, modelPayload["body"].(string), "2048")
chatListResult := svc.ResolveScheme(context.Background(), "core://chat")
require.True(t, chatListResult.OK)
chatListPayload := chatListResult.Value.(map[string]any)
assert.Equal(t, "chat", chatListPayload["route"])
assert.Contains(t, chatListPayload["body"].(string), "Chat Route")
chatHistoryResult := svc.ResolveScheme(context.Background(), "core://chat?conversation_id=conv-1")
require.True(t, chatHistoryResult.OK)
chatHistoryPayload := chatHistoryResult.Value.(map[string]any)
assert.Equal(t, "chat", chatHistoryPayload["route"])
assert.Contains(t, chatHistoryPayload["body"].(string), "conv-1")
chatSearchResult := svc.handleStoreSearch(context.Background(), url.Values{"q": []string{"chat"}})
require.True(t, chatSearchResult.OK)
chatSearchPayload := chatSearchResult.Value.(map[string]any)
assert.Contains(t, chatSearchPayload["body"].(string), "core://chat")
}
func TestScheme_ResolveScheme_Bad(t *testing.T) {
svc := &Service{}
emptyResult := svc.ResolveScheme(context.Background(), "")
require.False(t, emptyResult.OK)
malformedResult := svc.ResolveScheme(context.Background(), "://bad-url")
require.False(t, malformedResult.OK)
2026-04-15 18:52:20 +01:00
rootResult := svc.ResolveScheme(context.Background(), "core://")
require.False(t, rootResult.OK)
2026-04-15 17:27:40 +01:00
noHandlerResult := svc.ResolveScheme(context.Background(), "core://store")
require.False(t, noHandlerResult.OK)
}
func TestScheme_ResolveScheme_Ugly(t *testing.T) {
svc, _ := newTestDisplayService(t)
svc.registerDefaultSchemes()
result := svc.ResolveScheme(context.Background(), "core://wallet/treasury?amount=1")
require.True(t, result.OK)
payload := result.Value.(map[string]any)
assert.Equal(t, "wallet", payload["route"])
assert.Equal(t, false, payload["available"])
assert.Contains(t, payload["body"].(string), "no backend is registered for this route")
searchResult := svc.handleStoreSearch(context.Background(), url.Values{"q": []string{"missing"}})
require.True(t, searchResult.OK)
searchPayload := searchResult.Value.(map[string]any)
assert.Contains(t, searchPayload["body"].(string), "No matches found in Core storage.")
}
2026-04-15 19:16:45 +01:00
func TestScheme_ResolveScheme_NetworkPeers_Good(t *testing.T) {
c := core.New(
core.WithService(Register(nil)),
core.WithName("p2p", func(_ *core.Core) core.Result {
return core.Result{
Value: mockPeerRouter{
peers: []p2p.Peer{
{ID: "peer-2", Topic: "timeline", Connected: true},
{ID: "peer-1", Topic: "timeline", Connected: false},
},
},
OK: true,
}
}),
core.WithServiceLock(),
)
require.True(t, c.ServiceStartup(context.Background(), nil).OK)
svc := core.MustServiceFor[*Service](c, "display")
svc.registerDefaultSchemes()
result := svc.ResolveScheme(context.Background(), "core://network")
require.True(t, result.OK)
payload := result.Value.(map[string]any)
body := payload["body"].(string)
assert.Contains(t, body, "Registered peers")
assert.Contains(t, body, "peer-1")
assert.Contains(t, body, "peer-2")
assert.Contains(t, body, "timeline")
}
2026-04-15 17:27:40 +01:00
func TestScheme_AssetMiddleware_Good(t *testing.T) {
svc, _ := newTestDisplayService(t)
svc.registerDefaultSchemes()
recorder := newTestApplicationResponseWriter()
request := &application.Request{Method: "GET", URL: "core://store?q=theme"}
2026-04-15 17:27:40 +01:00
svc.AssetMiddleware()(&testApplicationHandler{}).ServeHTTP(recorder, request)
2026-04-15 17:27:40 +01:00
require.Equal(t, 200, recorder.status)
assert.Equal(t, "text/html; charset=utf-8", recorder.Header()["Content-Type"][0])
assert.Contains(t, string(recorder.body), "core://store")
2026-04-15 17:27:40 +01:00
}
func TestScheme_AssetMiddleware_Bad(t *testing.T) {
svc, _ := newTestDisplayService(t)
svc.registerDefaultSchemes()
recorder := newTestApplicationResponseWriter()
request := &application.Request{Method: "GET", URL: "https://example.com/app"}
next := &testApplicationHandler{}
2026-04-15 17:27:40 +01:00
svc.AssetMiddleware()(next).ServeHTTP(recorder, request)
2026-04-15 17:27:40 +01:00
require.True(t, next.called)
require.Equal(t, 0, recorder.status)
assert.Empty(t, recorder.body)
2026-04-15 17:27:40 +01:00
}
func TestScheme_AssetMiddleware_Ugly(t *testing.T) {
svc, _ := New()
recorder := newTestApplicationResponseWriter()
request := &application.Request{Method: "GET", URL: "core://missing"}
2026-04-15 17:27:40 +01:00
svc.AssetMiddleware()(&testApplicationHandler{}).ServeHTTP(recorder, request)
2026-04-15 17:27:40 +01:00
require.Equal(t, 404, recorder.status)
assert.Contains(t, string(recorder.body), "core route not found")
2026-04-15 17:27:40 +01:00
}