fix(pkg/api): emit installed change events
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
fe8c7e5982
commit
25667064ca
4 changed files with 99 additions and 3 deletions
2
go.mod
2
go.mod
|
|
@ -15,6 +15,7 @@ require (
|
|||
forge.lthn.ai/core/config v0.1.8
|
||||
github.com/gin-gonic/gin v1.12.0
|
||||
github.com/goccy/go-json v0.10.6
|
||||
github.com/gorilla/websocket v1.5.3
|
||||
github.com/stretchr/testify v1.11.1
|
||||
golang.org/x/net v0.52.0
|
||||
golang.org/x/sys v0.42.0
|
||||
|
|
@ -93,7 +94,6 @@ require (
|
|||
github.com/gorilla/context v1.1.2 // indirect
|
||||
github.com/gorilla/securecookie v1.1.2 // indirect
|
||||
github.com/gorilla/sessions v1.4.0 // indirect
|
||||
github.com/gorilla/websocket v1.5.3 // indirect
|
||||
github.com/hashicorp/go-version v1.8.0 // indirect
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
|
|
|
|||
|
|
@ -29,12 +29,19 @@ import (
|
|||
// and Renderable.
|
||||
type ScmProvider struct {
|
||||
index *marketplace.Index
|
||||
installer *marketplace.Installer
|
||||
installer marketplaceInstaller
|
||||
registry *repos.Registry
|
||||
hub *ws.Hub
|
||||
medium io.Medium
|
||||
}
|
||||
|
||||
type marketplaceInstaller interface {
|
||||
Install(context.Context, marketplace.Module) error
|
||||
Remove(string) error
|
||||
Update(context.Context, string) error
|
||||
Installed() ([]marketplace.InstalledModule, error)
|
||||
}
|
||||
|
||||
// compile-time interface checks
|
||||
var (
|
||||
_ provider.Provider = (*ScmProvider)(nil)
|
||||
|
|
@ -47,7 +54,7 @@ var (
|
|||
// installer, and registry. The WS hub is used to emit real-time events.
|
||||
// Pass nil for any dependency that is not available.
|
||||
// Usage: NewProvider(...)
|
||||
func NewProvider(idx *marketplace.Index, inst *marketplace.Installer, reg *repos.Registry, hub *ws.Hub) *ScmProvider {
|
||||
func NewProvider(idx *marketplace.Index, inst marketplaceInstaller, reg *repos.Registry, hub *ws.Hub) *ScmProvider {
|
||||
return &ScmProvider{
|
||||
index: idx,
|
||||
installer: inst,
|
||||
|
|
@ -81,6 +88,7 @@ func (p *ScmProvider) Channels() []string {
|
|||
"scm.marketplace.refreshed",
|
||||
"scm.marketplace.installed",
|
||||
"scm.marketplace.removed",
|
||||
"scm.installed.changed",
|
||||
"scm.manifest.verified",
|
||||
"scm.registry.changed",
|
||||
}
|
||||
|
|
@ -293,6 +301,11 @@ func (p *ScmProvider) installItem(c *gin.Context) {
|
|||
"code": mod.Code,
|
||||
"name": mod.Name,
|
||||
})
|
||||
p.emitEvent("scm.installed.changed", map[string]any{
|
||||
"action": "installed",
|
||||
"code": mod.Code,
|
||||
"name": mod.Name,
|
||||
})
|
||||
|
||||
c.JSON(http.StatusOK, api.OK(map[string]any{"installed": true, "code": mod.Code}))
|
||||
}
|
||||
|
|
@ -313,6 +326,10 @@ func (p *ScmProvider) removeItem(c *gin.Context) {
|
|||
}
|
||||
|
||||
p.emitEvent("scm.marketplace.removed", map[string]any{"code": code})
|
||||
p.emitEvent("scm.installed.changed", map[string]any{
|
||||
"action": "removed",
|
||||
"code": code,
|
||||
})
|
||||
|
||||
c.JSON(http.StatusOK, api.OK(map[string]any{"removed": true, "code": code}))
|
||||
}
|
||||
|
|
@ -474,6 +491,11 @@ func (p *ScmProvider) updateInstalled(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
p.emitEvent("scm.installed.changed", map[string]any{
|
||||
"action": "updated",
|
||||
"code": code,
|
||||
})
|
||||
|
||||
c.JSON(http.StatusOK, api.OK(map[string]any{"updated": true, "code": code}))
|
||||
}
|
||||
|
||||
|
|
|
|||
73
pkg/api/provider_events_test.go
Normal file
73
pkg/api/provider_events_test.go
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
// SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
package api_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"dappco.re/go/core/scm/marketplace"
|
||||
scmapi "dappco.re/go/core/scm/pkg/api"
|
||||
"dappco.re/go/core/ws"
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
type fakeInstaller struct {
|
||||
updateCalls []string
|
||||
}
|
||||
|
||||
func (f *fakeInstaller) Install(context.Context, marketplace.Module) error { return nil }
|
||||
|
||||
func (f *fakeInstaller) Remove(string) error { return nil }
|
||||
|
||||
func (f *fakeInstaller) Update(_ context.Context, code string) error {
|
||||
f.updateCalls = append(f.updateCalls, code)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *fakeInstaller) Installed() ([]marketplace.InstalledModule, error) { return nil, nil }
|
||||
|
||||
func TestScmProvider_UpdateInstalled_EmitsInstalledChangedEvent_Good(t *testing.T) {
|
||||
hub := ws.NewHub()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
t.Cleanup(cancel)
|
||||
go hub.Run(ctx)
|
||||
|
||||
server := httptest.NewServer(hub.Handler())
|
||||
t.Cleanup(server.Close)
|
||||
|
||||
wsURL := "ws" + strings.TrimPrefix(server.URL, "http")
|
||||
conn, _, err := websocket.DefaultDialer.Dial(wsURL, nil)
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() { _ = conn.Close() })
|
||||
|
||||
require.NoError(t, conn.WriteJSON(ws.Message{Type: ws.TypeSubscribe, Data: "scm.installed.changed"}))
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
|
||||
installer := &fakeInstaller{}
|
||||
p := scmapi.NewProvider(nil, installer, nil, hub)
|
||||
r := setupRouter(p)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("POST", "/api/v1/scm/installed/demo/update", nil)
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
require.Equal(t, http.StatusOK, w.Code)
|
||||
require.Equal(t, []string{"demo"}, installer.updateCalls)
|
||||
|
||||
var msg ws.Message
|
||||
require.NoError(t, conn.ReadJSON(&msg))
|
||||
assert.Equal(t, ws.TypeEvent, msg.Type)
|
||||
assert.Equal(t, "scm.installed.changed", msg.Channel)
|
||||
|
||||
data, ok := msg.Data.(map[string]any)
|
||||
require.True(t, ok)
|
||||
assert.Equal(t, "updated", data["action"])
|
||||
assert.Equal(t, "demo", data["code"])
|
||||
}
|
||||
|
|
@ -42,6 +42,7 @@ func TestScmProvider_Channels_Good(t *testing.T) {
|
|||
assert.Contains(t, channels, "scm.marketplace.refreshed")
|
||||
assert.Contains(t, channels, "scm.marketplace.installed")
|
||||
assert.Contains(t, channels, "scm.marketplace.removed")
|
||||
assert.Contains(t, channels, "scm.installed.changed")
|
||||
assert.Contains(t, channels, "scm.manifest.verified")
|
||||
assert.Contains(t, channels, "scm.registry.changed")
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue