go-scm/pkg/api/provider_test.go
Snider 81deee8598
Some checks failed
Security Scan / security (push) Failing after 7s
Test / test (push) Failing after 1m16s
feat(api): add SCM service provider with Lit custom elements
ScmProvider implements Provider + Streamable + Describable + Renderable,
wrapping marketplace, manifest, installed, and registry endpoints as REST
API with WS event streaming. Includes Lit custom element bundle with
panel, marketplace browser, manifest viewer, installed manager, and
registry status display. All 14 tests pass.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-14 10:42:37 +00:00

237 lines
6.4 KiB
Go

// SPDX-Licence-Identifier: EUPL-1.2
package api_test
import (
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
goapi "forge.lthn.ai/core/api"
"forge.lthn.ai/core/go-scm/marketplace"
scmapi "forge.lthn.ai/core/go-scm/pkg/api"
"github.com/gin-gonic/gin"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func init() {
gin.SetMode(gin.TestMode)
}
// -- Provider Identity --------------------------------------------------------
func TestScmProvider_Name_Good(t *testing.T) {
p := scmapi.NewProvider(nil, nil, nil, nil)
assert.Equal(t, "scm", p.Name())
}
func TestScmProvider_BasePath_Good(t *testing.T) {
p := scmapi.NewProvider(nil, nil, nil, nil)
assert.Equal(t, "/api/v1/scm", p.BasePath())
}
func TestScmProvider_Channels_Good(t *testing.T) {
p := scmapi.NewProvider(nil, nil, nil, nil)
channels := p.Channels()
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.manifest.verified")
assert.Contains(t, channels, "scm.registry.changed")
}
func TestScmProvider_Element_Good(t *testing.T) {
p := scmapi.NewProvider(nil, nil, nil, nil)
el := p.Element()
assert.Equal(t, "core-scm-panel", el.Tag)
assert.Equal(t, "/assets/core-scm.js", el.Source)
}
func TestScmProvider_Describe_Good(t *testing.T) {
p := scmapi.NewProvider(nil, nil, nil, nil)
descs := p.Describe()
assert.GreaterOrEqual(t, len(descs), 11)
for _, d := range descs {
assert.NotEmpty(t, d.Method)
assert.NotEmpty(t, d.Path)
assert.NotEmpty(t, d.Summary)
assert.NotEmpty(t, d.Tags)
}
}
// -- Marketplace Endpoints ----------------------------------------------------
func TestScmProvider_ListMarketplace_Good(t *testing.T) {
idx := &marketplace.Index{
Version: 1,
Modules: []marketplace.Module{
{Code: "analytics", Name: "Analytics", Category: "product"},
{Code: "bio", Name: "Bio Links", Category: "product"},
},
Categories: []string{"product"},
}
p := scmapi.NewProvider(idx, nil, nil, nil)
r := setupRouter(p)
w := httptest.NewRecorder()
req, _ := http.NewRequest("GET", "/api/v1/scm/marketplace", nil)
r.ServeHTTP(w, req)
assert.Equal(t, http.StatusOK, w.Code)
var resp goapi.Response[[]marketplace.Module]
err := json.Unmarshal(w.Body.Bytes(), &resp)
require.NoError(t, err)
assert.True(t, resp.Success)
assert.Len(t, resp.Data, 2)
}
func TestScmProvider_ListMarketplace_Search_Good(t *testing.T) {
idx := &marketplace.Index{
Version: 1,
Modules: []marketplace.Module{
{Code: "analytics", Name: "Analytics", Category: "product"},
{Code: "bio", Name: "Bio Links", Category: "product"},
},
}
p := scmapi.NewProvider(idx, nil, nil, nil)
r := setupRouter(p)
w := httptest.NewRecorder()
req, _ := http.NewRequest("GET", "/api/v1/scm/marketplace?q=bio", nil)
r.ServeHTTP(w, req)
assert.Equal(t, http.StatusOK, w.Code)
var resp goapi.Response[[]marketplace.Module]
err := json.Unmarshal(w.Body.Bytes(), &resp)
require.NoError(t, err)
assert.Len(t, resp.Data, 1)
assert.Equal(t, "bio", resp.Data[0].Code)
}
func TestScmProvider_ListMarketplace_NilIndex_Good(t *testing.T) {
p := scmapi.NewProvider(nil, nil, nil, nil)
r := setupRouter(p)
w := httptest.NewRecorder()
req, _ := http.NewRequest("GET", "/api/v1/scm/marketplace", nil)
r.ServeHTTP(w, req)
assert.Equal(t, http.StatusOK, w.Code)
var resp goapi.Response[[]marketplace.Module]
err := json.Unmarshal(w.Body.Bytes(), &resp)
require.NoError(t, err)
assert.True(t, resp.Success)
assert.Empty(t, resp.Data)
}
func TestScmProvider_GetMarketplaceItem_Good(t *testing.T) {
idx := &marketplace.Index{
Version: 1,
Modules: []marketplace.Module{
{Code: "analytics", Name: "Analytics", Category: "product"},
},
}
p := scmapi.NewProvider(idx, nil, nil, nil)
r := setupRouter(p)
w := httptest.NewRecorder()
req, _ := http.NewRequest("GET", "/api/v1/scm/marketplace/analytics", nil)
r.ServeHTTP(w, req)
assert.Equal(t, http.StatusOK, w.Code)
var resp goapi.Response[marketplace.Module]
err := json.Unmarshal(w.Body.Bytes(), &resp)
require.NoError(t, err)
assert.Equal(t, "analytics", resp.Data.Code)
}
func TestScmProvider_GetMarketplaceItem_Bad(t *testing.T) {
idx := &marketplace.Index{Version: 1}
p := scmapi.NewProvider(idx, nil, nil, nil)
r := setupRouter(p)
w := httptest.NewRecorder()
req, _ := http.NewRequest("GET", "/api/v1/scm/marketplace/nonexistent", nil)
r.ServeHTTP(w, req)
assert.Equal(t, http.StatusNotFound, w.Code)
}
// -- Installed Endpoints ------------------------------------------------------
func TestScmProvider_ListInstalled_NilInstaller_Good(t *testing.T) {
p := scmapi.NewProvider(nil, nil, nil, nil)
r := setupRouter(p)
w := httptest.NewRecorder()
req, _ := http.NewRequest("GET", "/api/v1/scm/installed", nil)
r.ServeHTTP(w, req)
assert.Equal(t, http.StatusOK, w.Code)
var resp goapi.Response[[]marketplace.InstalledModule]
err := json.Unmarshal(w.Body.Bytes(), &resp)
require.NoError(t, err)
assert.True(t, resp.Success)
assert.Empty(t, resp.Data)
}
// -- Registry Endpoints -------------------------------------------------------
func TestScmProvider_ListRegistry_NilRegistry_Good(t *testing.T) {
p := scmapi.NewProvider(nil, nil, nil, nil)
r := setupRouter(p)
w := httptest.NewRecorder()
req, _ := http.NewRequest("GET", "/api/v1/scm/registry", nil)
r.ServeHTTP(w, req)
assert.Equal(t, http.StatusOK, w.Code)
var resp goapi.Response[[]any]
err := json.Unmarshal(w.Body.Bytes(), &resp)
require.NoError(t, err)
assert.True(t, resp.Success)
assert.Empty(t, resp.Data)
}
// -- Route Registration -------------------------------------------------------
func TestScmProvider_RegistersAsRouteGroup_Good(t *testing.T) {
p := scmapi.NewProvider(nil, nil, nil, nil)
engine, err := goapi.New()
require.NoError(t, err)
engine.Register(p)
assert.Len(t, engine.Groups(), 1)
assert.Equal(t, "scm", engine.Groups()[0].Name())
}
func TestScmProvider_Channels_RegisterAsStreamGroup_Good(t *testing.T) {
p := scmapi.NewProvider(nil, nil, nil, nil)
engine, err := goapi.New()
require.NoError(t, err)
engine.Register(p)
channels := engine.Channels()
assert.Contains(t, channels, "scm.marketplace.refreshed")
}
// -- Test helpers -------------------------------------------------------------
func setupRouter(p *scmapi.ScmProvider) *gin.Engine {
r := gin.New()
rg := r.Group(p.BasePath())
p.RegisterRoutes(rg)
return r
}