Files
ttstd-infinite-canvas/backend/internal/protocol/package_test.go
ddCat a23df0cb32 feat(payment): 虎皮椒聚合支付 - 官方插件与跨平台可执行文件
新增 xunhupay 官方包,支付 RPC 与宿主只保留订单和验签边界;官方支付包同时带上各系统 provider,避免把 Linux ELF 当成本机入口。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 23:32:11 +08:00

90 lines
2.9 KiB
Go

package protocol
import (
"archive/zip"
"bytes"
"testing"
)
func TestParsePluginPackageRejectsBareManifest(t *testing.T) {
if _, err := ParsePluginPackage([]byte(`{"apiVersion":"yingce.plugin/v1"}`)); err == nil {
t.Fatal("bare JSON manifest was accepted as a plugin package")
}
}
func TestParsePluginPackageValidatesWebEntry(t *testing.T) {
manifest := []byte(`{
"apiVersion":"yingce.plugin/v1",
"id":"ui-extension",
"name":"UI Extension",
"version":"1.0.0",
"entry":"web/entry.js",
"surfaces":["fullscreen"],
"runtime":{"web":"sandbox"},
"contributes":{"commands":[{"id":"ui-extension/open","label":"Open UI"}]}
}`)
pkg, err := ParsePluginPackage(zipPluginPackage(t, map[string][]byte{"manifest.json": manifest, "web/entry.js": []byte("self.postMessage({type:'ready'})")}))
if err != nil {
t.Fatal(err)
}
if pkg.Manifest.Entry != "web/entry.js" || len(pkg.Files["web/entry.js"]) == 0 {
t.Fatalf("package = %#v", pkg)
}
missingEntry := zipPluginPackage(t, map[string][]byte{"manifest.json": manifest})
if _, err := ParsePluginPackage(missingEntry); err == nil {
t.Fatal("missing web entry was accepted")
}
forbidden := zipPluginPackage(t, map[string][]byte{"manifest.json": manifest, "web/entry.js": []byte("ready"), "server/entry.js": []byte("unsafe")})
if _, err := ParsePluginPackage(forbidden); err == nil {
t.Fatal("forbidden package path was accepted")
}
}
func TestParsePluginPackageAcceptsTaggedRPCBackend(t *testing.T) {
manifest := []byte(`{
"apiVersion":"yingce.plugin/v1",
"id":"tagged-payment",
"name":"Tagged Payment",
"version":"1.0.0",
"author":"Test",
"enabled":true,
"runtime":{"backend":"rpc","backendEntry":"backend/provider"},
"contributes":{"paymentProviders":[{"id":"tagged-pay","label":"Tagged","icon":"brand:test","checkoutMode":"qr_code","expiryPolicy":{"defaultMinutes":30,"minMinutes":5,"maxMinutes":1440}}]}
}`)
pkg, err := ParsePluginPackage(zipPluginPackage(t, map[string][]byte{
"manifest.json": manifest,
"backend/provider-darwin-arm64": []byte("darwin-provider"),
}))
if err != nil {
t.Fatal(err)
}
if _, ok := pkg.Files["backend/provider"]; ok {
t.Fatal("canonical backend/provider should not be required when a tagged artifact exists")
}
if _, err := ParsePluginPackage(zipPluginPackage(t, map[string][]byte{"manifest.json": manifest})); err == nil {
t.Fatal("rpc package without any backend artifact was accepted")
}
}
func zipPluginPackage(t *testing.T, files map[string][]byte) []byte {
t.Helper()
var buffer bytes.Buffer
writer := zip.NewWriter(&buffer)
for name, data := range files {
file, err := writer.Create(name)
if err != nil {
t.Fatal(err)
}
if _, err := file.Write(data); err != nil {
t.Fatal(err)
}
}
if err := writer.Close(); err != nil {
t.Fatal(err)
}
return buffer.Bytes()
}