refactor(*): 平台架构 - 拆分后端领域模块与画布前端组件并补充测试

This commit is contained in:
ddcat666
2026-09-30 10:01:39 +08:00
parent e0a2697c60
commit 7f5d87ef1a
186 changed files with 33727 additions and 29905 deletions

View File

@@ -69,6 +69,57 @@ func TestParsePluginPackageAcceptsTaggedRPCBackend(t *testing.T) {
}
}
// InspectPluginPackage 只解压清单:结构校验与 ParsePluginPackage 相同(路径白名单、运行时入口),
// 但返回值不携带文件内容,调用方无法把「只校验过结构」的可执行文件写盘。
func TestInspectPluginPackageValidatesStructureWithoutContents(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}}]}
}`)
info, err := InspectPluginPackage(zipPluginPackage(t, map[string][]byte{"manifest.json": manifest, "backend/provider-linux-amd64": []byte("binary")}))
if err != nil {
t.Fatal(err)
}
if info.Manifest.Metadata.ID != "tagged-payment" || len(info.ManifestRaw) == 0 {
t.Fatalf("info = %#v", info)
}
if _, err := InspectPluginPackage(zipPluginPackage(t, map[string][]byte{"manifest.json": manifest})); err == nil {
t.Fatal("rpc package without any backend artifact was accepted by inspection")
}
if _, err := InspectPluginPackage(zipPluginPackage(t, map[string][]byte{"manifest.json": manifest, "backend/provider": []byte("x"), "server/evil": []byte("x")})); err == nil {
t.Fatal("forbidden package path was accepted by inspection")
}
}
// ParsePluginPackageFiles 只解压选中的条目;未选中的条目以 nil 登记,便于存在性判断。
func TestParsePluginPackageFilesLoadsOnlySelectedEntries(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}}]}}`)
data := zipPluginPackage(t, map[string][]byte{
"manifest.json": manifest,
"backend/provider-linux-amd64": []byte("linux"),
"backend/provider-darwin-arm64": []byte("darwin"),
})
pkg, err := ParsePluginPackageFiles(data, func(name string) bool { return name == "backend/provider-linux-amd64" })
if err != nil {
t.Fatal(err)
}
if string(pkg.Files["backend/provider-linux-amd64"]) != "linux" {
t.Fatalf("selected entry content = %q", pkg.Files["backend/provider-linux-amd64"])
}
if content, listed := pkg.Files["backend/provider-darwin-arm64"]; !listed || content != nil {
t.Fatalf("unselected entry must be listed with nil content, got listed=%v content=%q", listed, content)
}
if len(pkg.ManifestRaw) == 0 {
t.Fatal("manifest must always be loaded")
}
}
func zipPluginPackage(t *testing.T, files map[string][]byte) []byte {
t.Helper()
var buffer bytes.Buffer