162 lines
3.6 KiB
Go
162 lines
3.6 KiB
Go
package providers
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
)
|
|
|
|
func writeTempJSON(t *testing.T, content string) string {
|
|
t.Helper()
|
|
dir := t.TempDir()
|
|
path := filepath.Join(dir, "provider_types.json")
|
|
if err := os.WriteFile(path, []byte(content), 0644); err != nil {
|
|
t.Fatalf("failed to write temp file: %v", err)
|
|
}
|
|
return path
|
|
}
|
|
|
|
func TestLoadCustomTypes_Valid(t *testing.T) {
|
|
path := writeTempJSON(t, `[
|
|
{
|
|
"id": "test-ollama",
|
|
"name": "Test Ollama",
|
|
"description": "Local test",
|
|
"default_endpoint": "http://localhost:11434/v1",
|
|
"api": "openai"
|
|
},
|
|
{
|
|
"id": "test-litellm",
|
|
"name": "Test LiteLLM",
|
|
"description": "LiteLLM proxy",
|
|
"default_endpoint": "http://litellm:4000/v1",
|
|
"api": "openai"
|
|
}
|
|
]`)
|
|
|
|
n, err := LoadCustomTypes(path)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
if n != 2 {
|
|
t.Errorf("registered = %d, want 2", n)
|
|
}
|
|
|
|
// Verify they're in the registry
|
|
p, err := Get("test-ollama")
|
|
if err != nil {
|
|
t.Errorf("test-ollama not registered: %v", err)
|
|
}
|
|
if p == nil {
|
|
t.Error("test-ollama provider is nil")
|
|
}
|
|
|
|
// Verify type metadata
|
|
types := ListTypes()
|
|
found := false
|
|
for _, m := range types {
|
|
if m.ID == "test-litellm" {
|
|
found = true
|
|
if m.DefaultEndpoint != "http://litellm:4000/v1" {
|
|
t.Errorf("endpoint = %q", m.DefaultEndpoint)
|
|
}
|
|
}
|
|
}
|
|
if !found {
|
|
t.Error("test-litellm not in ListTypes()")
|
|
}
|
|
}
|
|
|
|
func TestLoadCustomTypes_SkipsBuiltins(t *testing.T) {
|
|
path := writeTempJSON(t, `[
|
|
{
|
|
"id": "openai",
|
|
"name": "Override OpenAI",
|
|
"description": "Should be skipped",
|
|
"default_endpoint": "http://evil.com",
|
|
"api": "openai"
|
|
},
|
|
{
|
|
"id": "test-custom-ok",
|
|
"name": "Valid Custom",
|
|
"description": "Should register",
|
|
"default_endpoint": "http://ok.com",
|
|
"api": "openai"
|
|
}
|
|
]`)
|
|
|
|
n, err := LoadCustomTypes(path)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
if n != 1 {
|
|
t.Errorf("registered = %d, want 1 (openai skipped)", n)
|
|
}
|
|
}
|
|
|
|
func TestLoadCustomTypes_SkipsInvalid(t *testing.T) {
|
|
path := writeTempJSON(t, `[
|
|
{"id": "", "name": "No ID", "api": "openai"},
|
|
{"id": "test-no-name", "name": "", "api": "openai"},
|
|
{"id": "test-no-api", "name": "No API", "api": ""},
|
|
{"id": "test-bad-api", "name": "Bad API", "api": "grpc", "default_endpoint": "http://x"},
|
|
{"id": "test-valid-entry", "name": "Valid", "description": "ok", "default_endpoint": "http://ok", "api": "openai"}
|
|
]`)
|
|
|
|
n, err := LoadCustomTypes(path)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
if n != 1 {
|
|
t.Errorf("registered = %d, want 1 (4 invalid skipped)", n)
|
|
}
|
|
}
|
|
|
|
func TestLoadCustomTypes_EmptyArray(t *testing.T) {
|
|
path := writeTempJSON(t, `[]`)
|
|
|
|
n, err := LoadCustomTypes(path)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
if n != 0 {
|
|
t.Errorf("registered = %d, want 0", n)
|
|
}
|
|
}
|
|
|
|
func TestLoadCustomTypes_InvalidJSON(t *testing.T) {
|
|
path := writeTempJSON(t, `not json`)
|
|
|
|
_, err := LoadCustomTypes(path)
|
|
if err == nil {
|
|
t.Error("expected error for invalid JSON")
|
|
}
|
|
}
|
|
|
|
func TestLoadCustomTypes_FileNotFound(t *testing.T) {
|
|
_, err := LoadCustomTypes("/nonexistent/path/providers.json")
|
|
if err == nil {
|
|
t.Error("expected error for missing file")
|
|
}
|
|
}
|
|
|
|
func TestLoadCustomTypes_NoDefaultEndpoint(t *testing.T) {
|
|
// default_endpoint is optional — should still register
|
|
path := writeTempJSON(t, `[
|
|
{
|
|
"id": "test-no-endpoint",
|
|
"name": "No Endpoint",
|
|
"description": "User must fill in endpoint",
|
|
"api": "openai"
|
|
}
|
|
]`)
|
|
|
|
n, err := LoadCustomTypes(path)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
if n != 1 {
|
|
t.Errorf("registered = %d, want 1", n)
|
|
}
|
|
}
|