diff --git a/pkg/display/manifest_test.go b/pkg/display/manifest_test.go index 852f5ca5..dfe705aa 100644 --- a/pkg/display/manifest_test.go +++ b/pkg/display/manifest_test.go @@ -107,3 +107,52 @@ func TestManifest_DiscoverManifestPath_Ugly(t *testing.T) { require.NoError(t, err) assert.Equal(t, manifestPath, got) } + +func TestManifest_ManifestWindowConfig_Good(t *testing.T) { + root := t.TempDir() + require.NoError(t, os.MkdirAll(filepath.Join(root, ".core"), 0o755)) + require.NoError(t, os.WriteFile(filepath.Join(root, "index.html"), []byte(""), 0o644)) + require.NoError(t, os.WriteFile(filepath.Join(root, ".core", "view.yaml"), []byte(strings.Join([]string{ + "windows:", + " main:", + " title: Core GUI", + " width: 1280", + " height: 720", + " preload: true", + }, "\n")), 0o644)) + + svc, err := New() + require.NoError(t, err) + + got := svc.manifestWindowConfig(filepath.Join(root, "index.html")) + + require.NotNil(t, got) + require.Contains(t, got, "main") + assert.Equal(t, "Core GUI", got["main"].Title) + assert.Equal(t, 1280, got["main"].Width) + assert.Equal(t, 720, got["main"].Height) + assert.True(t, got["main"].Preload) +} + +func TestManifest_ManifestWindowConfig_Bad(t *testing.T) { + svc, err := New() + require.NoError(t, err) + + got := svc.manifestWindowConfig(filepath.Join(t.TempDir(), "missing.html")) + + assert.Nil(t, got) +} + +func TestManifest_ManifestWindowConfig_Ugly(t *testing.T) { + root := t.TempDir() + require.NoError(t, os.MkdirAll(filepath.Join(root, ".core"), 0o755)) + require.NoError(t, os.WriteFile(filepath.Join(root, "index.html"), []byte(""), 0o644)) + require.NoError(t, os.WriteFile(filepath.Join(root, ".core", "view.yaml"), []byte("windows: [\n"), 0o644)) + + svc, err := New() + require.NoError(t, err) + + got := svc.manifestWindowConfig(filepath.Join(root, "index.html")) + + assert.Nil(t, got) +} diff --git a/pkg/display/network_test.go b/pkg/display/network_test.go index 588ea0c9..e61cd7c6 100644 --- a/pkg/display/network_test.go +++ b/pkg/display/network_test.go @@ -79,3 +79,62 @@ func TestNetwork_RenderNetworkPage_Ugly(t *testing.T) { assert.Contains(t, body, "<addr>") assert.Contains(t, body, "loopback") } + +func TestNetwork_RenderNetworkInterfacePage_Good(t *testing.T) { + svc := &Service{} + state := NetworkState{ + Hostname: "core-host", + ObservedAt: time.Unix(1_700_000_000, 0).UTC(), + Peers: []NetworkPeerState{ + {ID: "peer-1", Topic: "timeline", Connected: true, SeenAt: time.Unix(1_700_000_100, 0).UTC()}, + }, + } + iface := NetworkInterfaceState{ + Name: "en0", + Index: 2, + MTU: 1500, + Addresses: []string{"192.168.0.10/24"}, + Flags: []string{"up", "running"}, + Up: true, + } + + body := svc.renderNetworkInterfacePage(state, iface) + + assert.Contains(t, body, "core://network/en0") + assert.Contains(t, body, "core-host") + assert.Contains(t, body, "192.168.0.10/24") + assert.Contains(t, body, "Flags: up, running") + assert.Contains(t, body, "Registered peers") + assert.Contains(t, body, "peer-1") +} + +func TestNetwork_RenderNetworkInterfacePage_Bad(t *testing.T) { + svc := &Service{} + state := NetworkState{Hostname: "core-host", ObservedAt: time.Unix(1, 0).UTC()} + iface := NetworkInterfaceState{Name: "en0", Index: 2, MTU: 1500, Up: false} + + body := svc.renderNetworkInterfacePage(state, iface) + + assert.Contains(t, body, "Flags: none") + assert.NotContains(t, body, "Registered peers") +} + +func TestNetwork_RenderNetworkInterfacePage_Ugly(t *testing.T) { + svc := &Service{} + state := NetworkState{Hostname: "", ObservedAt: time.Unix(1, 0).UTC()} + iface := NetworkInterfaceState{ + Name: "\"quoted\"", + Index: 99, + MTU: 9, + Addresses: []string{""}, + Up: false, + Loopback: true, + } + + body := svc.renderNetworkInterfacePage(state, iface) + + assert.Contains(t, body, ""quoted"") + assert.Contains(t, body, "<addr>") + assert.Contains(t, body, "<host>") + assert.Contains(t, body, "loopback") +} diff --git a/pkg/marketplace/marketplace_test.go b/pkg/marketplace/marketplace_test.go index 2b52ce61..fb20d7ec 100644 --- a/pkg/marketplace/marketplace_test.go +++ b/pkg/marketplace/marketplace_test.go @@ -62,14 +62,53 @@ func TestMarketplace_FetchManifest_Bad(t *testing.T) { } func TestMarketplace_FetchManifest_Ugly(t *testing.T) { + t.Run("invalid yaml", func(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + _, _ = w.Write([]byte(": not-yaml")) + })) + t.Cleanup(server.Close) + + installer := Installer{HTTPClient: server.Client()} + _, err := installer.FetchManifest(context.Background(), server.URL) + require.Error(t, err) + }) + + t.Run("size limit", func(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + _, _ = w.Write([]byte("name: " + strings.Repeat("x", maxManifestBytes))) + })) + t.Cleanup(server.Close) + + installer := Installer{HTTPClient: server.Client()} + _, err := installer.FetchManifest(context.Background(), server.URL) + require.Error(t, err) + assert.Contains(t, err.Error(), "exceeds") + }) +} + +func TestMarketplace_List_Bad(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { - _, _ = w.Write([]byte(": not-yaml")) + w.WriteHeader(http.StatusBadGateway) + _, _ = w.Write([]byte("boom")) })) t.Cleanup(server.Close) installer := Installer{HTTPClient: server.Client()} - _, err := installer.FetchManifest(context.Background(), server.URL) + _, err := installer.List(context.Background(), server.URL) require.Error(t, err) + assert.Contains(t, err.Error(), "marketplace list failed") +} + +func TestMarketplace_List_Ugly(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + _, _ = w.Write([]byte(strings.Repeat("a", maxManifestBytes+1))) + })) + t.Cleanup(server.Close) + + installer := Installer{HTTPClient: server.Client()} + _, err := installer.List(context.Background(), server.URL) + require.Error(t, err) + assert.Contains(t, err.Error(), "exceeds") } func TestMarketplace_VerifyManifest_Good(t *testing.T) {