pluginsdk v0.2.7. The packer validates public_routes (reserved prefixes, traversal, duplicates), requires an HTTP handler for routes or sitemap, and stamps both into manifest.pb; codeless builds reject them; writeMod round-trips the new plugin.mod keys so a version bump cannot strip live route claims. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
74 lines
2.4 KiB
Go
74 lines
2.4 KiB
Go
package bnp
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
abiv1 "git.dev.alexdunmow.com/block/pluginsdk/abi/v1"
|
|
core "git.dev.alexdunmow.com/block/pluginsdk/plugin"
|
|
)
|
|
|
|
func TestStampPublicRoutes(t *testing.T) {
|
|
manifest := &abiv1.PluginManifest{HasHttpHandler: true}
|
|
mod := &core.ModFile{Plugin: core.ModPlugin{
|
|
PublicRoutes: []core.ModPublicRoute{
|
|
{Path: "/area", Prefix: true},
|
|
{Path: "/api/semantic-search"},
|
|
},
|
|
Sitemap: true,
|
|
}}
|
|
if err := stampPublicRoutes(manifest, mod); err != nil {
|
|
t.Fatalf("stampPublicRoutes: %v", err)
|
|
}
|
|
routes := manifest.GetPublicRoutes()
|
|
if len(routes) != 2 {
|
|
t.Fatalf("manifest routes len = %d, want 2", len(routes))
|
|
}
|
|
if routes[0].GetPath() != "/area" || !routes[0].GetPrefix() {
|
|
t.Errorf("routes[0] = %+v, want /area prefix", routes[0])
|
|
}
|
|
if routes[1].GetPath() != "/api/semantic-search" || routes[1].GetPrefix() {
|
|
t.Errorf("routes[1] = %+v, want exact /api/semantic-search", routes[1])
|
|
}
|
|
if !manifest.GetSitemap() {
|
|
t.Errorf("manifest sitemap not stamped")
|
|
}
|
|
}
|
|
|
|
func TestStampPublicRoutes_RejectsReservedPrefix(t *testing.T) {
|
|
manifest := &abiv1.PluginManifest{HasHttpHandler: true}
|
|
mod := &core.ModFile{Plugin: core.ModPlugin{
|
|
PublicRoutes: []core.ModPublicRoute{{Path: "/api/plugins/mine", Prefix: true}},
|
|
}}
|
|
err := stampPublicRoutes(manifest, mod)
|
|
if err == nil {
|
|
t.Fatal("reserved prefix accepted; want error")
|
|
}
|
|
if !strings.Contains(err.Error(), "public_routes") || !strings.Contains(err.Error(), "reserved prefix") {
|
|
t.Errorf("error %q should name public_routes and the reserved prefix", err.Error())
|
|
}
|
|
}
|
|
|
|
func TestStampPublicRoutes_RequiresHTTPHandler(t *testing.T) {
|
|
mod := &core.ModFile{Plugin: core.ModPlugin{
|
|
PublicRoutes: []core.ModPublicRoute{{Path: "/area"}},
|
|
}}
|
|
if err := stampPublicRoutes(&abiv1.PluginManifest{}, mod); err == nil {
|
|
t.Error("public_routes without HTTP handler accepted; want error")
|
|
}
|
|
sitemapOnly := &core.ModFile{Plugin: core.ModPlugin{Sitemap: true}}
|
|
if err := stampPublicRoutes(&abiv1.PluginManifest{}, sitemapOnly); err == nil {
|
|
t.Error("sitemap without HTTP handler accepted; want error")
|
|
}
|
|
}
|
|
|
|
func TestStampPublicRoutes_NoDeclarationIsNoop(t *testing.T) {
|
|
manifest := &abiv1.PluginManifest{}
|
|
if err := stampPublicRoutes(manifest, &core.ModFile{}); err != nil {
|
|
t.Fatalf("empty declaration: %v", err)
|
|
}
|
|
if len(manifest.GetPublicRoutes()) != 0 || manifest.GetSitemap() {
|
|
t.Errorf("manifest gained routes from an empty mod: %+v", manifest)
|
|
}
|
|
}
|