mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-06-23 06:25:51 +08:00
219 lines
6.1 KiB
Go
219 lines
6.1 KiB
Go
package pluginstore
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestParseRegistryValidatesRegistry(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
registry, errParse := ParseRegistry([]byte(`{
|
|
"schema_version": 1,
|
|
"plugins": [{
|
|
"id": "sample-provider",
|
|
"name": "Sample Provider",
|
|
"description": "Adds sample provider support.",
|
|
"author": "author-name",
|
|
"version": "0.1.0",
|
|
"repository": "https://github.com/author-name/cliproxy-sample-provider-plugin",
|
|
"logo": "https://example.com/logo.png",
|
|
"homepage": "https://github.com/author-name/cliproxy-sample-provider-plugin",
|
|
"license": "MIT",
|
|
"tags": ["provider"]
|
|
}]
|
|
}`))
|
|
if errParse != nil {
|
|
t.Fatalf("ParseRegistry() error = %v", errParse)
|
|
}
|
|
plugin, ok := registry.PluginByID("sample-provider")
|
|
if !ok {
|
|
t.Fatal("PluginByID(sample-provider) missing")
|
|
}
|
|
if plugin.Version != "0.1.0" {
|
|
t.Fatalf("plugin version = %q, want 0.1.0", plugin.Version)
|
|
}
|
|
}
|
|
|
|
func TestParseRegistryNormalizesPluginFields(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
registry, errParse := ParseRegistry([]byte(`{
|
|
"schema_version": 1,
|
|
"plugins": [{
|
|
"id": " sample-provider ",
|
|
"name": " Sample Provider ",
|
|
"description": " Adds sample provider support. ",
|
|
"author": " author-name ",
|
|
"version": " 0.1.0 ",
|
|
"repository": " https://github.com/author-name/cliproxy-sample-provider-plugin ",
|
|
"logo": " https://example.com/logo.png ",
|
|
"homepage": " https://github.com/author-name/cliproxy-sample-provider-plugin ",
|
|
"license": " MIT ",
|
|
"tags": [" provider "]
|
|
}]
|
|
}`))
|
|
if errParse != nil {
|
|
t.Fatalf("ParseRegistry() error = %v", errParse)
|
|
}
|
|
plugin, ok := registry.PluginByID("sample-provider")
|
|
if !ok {
|
|
t.Fatal("PluginByID(sample-provider) missing")
|
|
}
|
|
if plugin.ID != "sample-provider" || plugin.Version != "0.1.0" || plugin.Repository != "https://github.com/author-name/cliproxy-sample-provider-plugin" {
|
|
t.Fatalf("plugin not normalized: %#v", plugin)
|
|
}
|
|
if plugin.Name != "Sample Provider" || plugin.Tags[0] != "provider" {
|
|
t.Fatalf("plugin display fields not normalized: %#v", plugin)
|
|
}
|
|
}
|
|
|
|
func TestValidateRegistryAllowsMissingVersion(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
registry := Registry{SchemaVersion: 1, Plugins: []Plugin{{
|
|
ID: "sample-provider",
|
|
Name: "Sample Provider",
|
|
Description: "Adds sample provider support.",
|
|
Author: "author-name",
|
|
Repository: "https://github.com/author-name/cliproxy-sample-provider-plugin",
|
|
}}}
|
|
if errValidate := ValidateRegistry(registry); errValidate != nil {
|
|
t.Fatalf("ValidateRegistry() error = %v, want nil for missing version", errValidate)
|
|
}
|
|
}
|
|
|
|
func TestValidateRegistryRejectsInvalidEntries(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
valid := Plugin{
|
|
ID: "sample-provider",
|
|
Name: "Sample Provider",
|
|
Description: "Adds sample provider support.",
|
|
Author: "author-name",
|
|
Version: "0.1.0",
|
|
Repository: "https://github.com/author-name/cliproxy-sample-provider-plugin",
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
mutate func(*Registry)
|
|
wantErr string
|
|
}{
|
|
{
|
|
name: "schema version",
|
|
mutate: func(registry *Registry) {
|
|
registry.SchemaVersion = 2
|
|
},
|
|
wantErr: "unsupported schema_version",
|
|
},
|
|
{
|
|
name: "missing required field",
|
|
mutate: func(registry *Registry) {
|
|
registry.Plugins[0].Name = ""
|
|
},
|
|
wantErr: "missing required field name",
|
|
},
|
|
{
|
|
name: "duplicate id",
|
|
mutate: func(registry *Registry) {
|
|
registry.Plugins = append(registry.Plugins, valid)
|
|
},
|
|
wantErr: "duplicate plugin id",
|
|
},
|
|
{
|
|
name: "invalid id",
|
|
mutate: func(registry *Registry) {
|
|
registry.Plugins[0].ID = "../sample-provider"
|
|
},
|
|
wantErr: "invalid plugin id",
|
|
},
|
|
{
|
|
name: "v-prefixed version",
|
|
mutate: func(registry *Registry) {
|
|
registry.Plugins[0].Version = "v0.1.0"
|
|
},
|
|
wantErr: "invalid plugin version",
|
|
},
|
|
{
|
|
name: "invalid repository",
|
|
mutate: func(registry *Registry) {
|
|
registry.Plugins[0].Repository = "https://example.com/author/repo"
|
|
},
|
|
wantErr: "repository must be",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
registry := Registry{SchemaVersion: 1, Plugins: []Plugin{valid}}
|
|
tt.mutate(®istry)
|
|
errValidate := ValidateRegistry(registry)
|
|
if errValidate == nil {
|
|
t.Fatal("ValidateRegistry() error = nil")
|
|
}
|
|
if !strings.Contains(errValidate.Error(), tt.wantErr) {
|
|
t.Fatalf("ValidateRegistry() error = %v, want substring %q", errValidate, tt.wantErr)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestNormalizeSourcesAppendsURLsToDefaultSource(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
sources, errNormalize := NormalizeSources([]string{" https://community.example/registry.json "})
|
|
if errNormalize != nil {
|
|
t.Fatalf("NormalizeSources() error = %v", errNormalize)
|
|
}
|
|
if len(sources) != 2 {
|
|
t.Fatalf("sources len = %d, want 2", len(sources))
|
|
}
|
|
if sources[0].ID != DefaultSourceID || sources[0].URL != DefaultRegistryURL {
|
|
t.Fatalf("default source = %#v", sources[0])
|
|
}
|
|
if sources[1].ID != SourceID("https://community.example/registry.json") ||
|
|
sources[1].Name != "community.example" ||
|
|
sources[1].URL != "https://community.example/registry.json" {
|
|
t.Fatalf("third-party source = %#v", sources[1])
|
|
}
|
|
}
|
|
|
|
func TestNormalizeSourcesSkipsDuplicates(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
sources, errNormalize := NormalizeSources([]string{
|
|
DefaultRegistryURL,
|
|
"https://community.example/registry.json",
|
|
"https://community.example/registry.json",
|
|
})
|
|
if errNormalize != nil {
|
|
t.Fatalf("NormalizeSources() error = %v", errNormalize)
|
|
}
|
|
if len(sources) != 2 {
|
|
t.Fatalf("sources len = %d, want 2: %#v", len(sources), sources)
|
|
}
|
|
}
|
|
|
|
func TestGitHubRepositoryPartsRejectsNonRepositoryURLs(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tests := []string{
|
|
"http://github.com/owner/repo",
|
|
"https://github.com/owner",
|
|
"https://github.com/owner/repo/issues",
|
|
"https://github.com/owner/repo.git",
|
|
"https://github.com/owner/repo?tab=readme",
|
|
}
|
|
for _, repository := range tests {
|
|
t.Run(repository, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
if _, _, errParse := GitHubRepositoryParts(repository); errParse == nil {
|
|
t.Fatalf("GitHubRepositoryParts(%q) error = nil", repository)
|
|
}
|
|
})
|
|
}
|
|
}
|