245 lines
7.9 KiB
Go
245 lines
7.9 KiB
Go
package display
|
|
|
|
import (
|
|
"context"
|
|
"net/url"
|
|
"testing"
|
|
|
|
core "dappco.re/go/core"
|
|
"forge.lthn.ai/core/gui/pkg/chat"
|
|
"forge.lthn.ai/core/gui/pkg/p2p"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"github.com/wailsapp/wails/v3/pkg/application"
|
|
)
|
|
|
|
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
|
|
}
|
|
|
|
type mockPeerRouter struct {
|
|
peers []p2p.Peer
|
|
}
|
|
|
|
func (m mockPeerRouter) Peers() []p2p.Peer {
|
|
return m.peers
|
|
}
|
|
|
|
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,
|
|
}
|
|
case chat.QueryHistory:
|
|
return core.Result{
|
|
Value: chat.Conversation{ID: "conv-1", Title: "Chat Route"},
|
|
OK: true,
|
|
}
|
|
case chat.QueryConversationSearch:
|
|
return core.Result{
|
|
Value: []any{"chat-match"},
|
|
OK: true,
|
|
}
|
|
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)
|
|
|
|
rootResult := svc.ResolveScheme(context.Background(), "core://")
|
|
require.False(t, rootResult.OK)
|
|
|
|
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.")
|
|
}
|
|
|
|
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")
|
|
}
|
|
|
|
func TestScheme_AssetMiddleware_Good(t *testing.T) {
|
|
svc, _ := newTestDisplayService(t)
|
|
svc.registerDefaultSchemes()
|
|
|
|
recorder := newTestApplicationResponseWriter()
|
|
request := &application.Request{Method: "GET", URL: "core://store?q=theme"}
|
|
|
|
svc.AssetMiddleware()(&testApplicationHandler{}).ServeHTTP(recorder, request)
|
|
|
|
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")
|
|
}
|
|
|
|
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{}
|
|
|
|
svc.AssetMiddleware()(next).ServeHTTP(recorder, request)
|
|
|
|
require.True(t, next.called)
|
|
require.Equal(t, 0, recorder.status)
|
|
assert.Empty(t, recorder.body)
|
|
}
|
|
|
|
func TestScheme_AssetMiddleware_Ugly(t *testing.T) {
|
|
svc, _ := New()
|
|
|
|
recorder := newTestApplicationResponseWriter()
|
|
request := &application.Request{Method: "GET", URL: "core://missing"}
|
|
|
|
svc.AssetMiddleware()(&testApplicationHandler{}).ServeHTTP(recorder, request)
|
|
|
|
require.Equal(t, 404, recorder.status)
|
|
assert.Contains(t, string(recorder.body), "core route not found")
|
|
}
|