xworkmate-bridge/internal/acp/providers_sync_test.go

157 lines
4.4 KiB
Go

package acp
import (
"encoding/json"
"testing"
"xworkmate-bridge/internal/shared"
)
func setTestBridgeProvider(server *Server, provider syncedProvider) {
server.mu.Lock()
defer server.mu.Unlock()
if server.providers == nil {
server.providers = make(map[string]ProviderCompat)
}
server.providers[provider.ProviderID] = newProviderCompat(provider)
if server.catalog != nil {
server.catalog.ProviderCatalog = append(server.catalog.ProviderCatalog, map[string]any{
"providerId": provider.ProviderID,
"label": provider.Label,
"targets": []string{"agent"},
})
}
}
func TestCapabilitiesExposeBuiltInProductionProviderCatalog(t *testing.T) {
t.Setenv("BRIDGE_CONFIG_PATH", "../../example/config.yaml")
server := NewServer()
response, err := server.handleRequest(shared.RPCRequest{
Method: "acp.capabilities",
Params: map[string]any{},
}, nil)
if err != nil {
t.Fatalf("handleRequest error: %v", err)
}
capabilities := response
if capabilities["multiAgent"] != false {
t.Fatalf("expected multiAgent capability to be disabled, got %#v", capabilities["multiAgent"])
}
nestedCapabilities := shared.AsMap(capabilities["capabilities"])
if nestedCapabilities["multi_agent"] != false {
t.Fatalf("expected nested multi_agent capability to be disabled, got %#v", nestedCapabilities["multi_agent"])
}
targets, ok := capabilities["availableExecutionTargets"].([]any)
if !ok {
// Try fallback decoding if it was serialized
data, _ := json.Marshal(capabilities["availableExecutionTargets"])
if err := json.Unmarshal(data, &targets); err != nil {
t.Fatalf("expected availableExecutionTargets array, got %T", capabilities["availableExecutionTargets"])
}
}
foundAgent := false
for _, target := range targets {
if target == "agent" {
foundAgent = true
break
}
}
if !foundAgent {
t.Fatalf("expected agent target in availableExecutionTargets, got %v", targets)
}
var catalog []map[string]any
// Try decoding if it was serialized
data, _ := json.Marshal(capabilities["providerCatalog"])
if err := json.Unmarshal(data, &catalog); err != nil {
t.Fatalf("expected providerCatalog array, got %T", capabilities["providerCatalog"])
}
if len(catalog) < 4 {
t.Fatalf("expected at least 4 production providers, got %d", len(catalog))
}
providers := make(map[string]map[string]any)
for _, p := range catalog {
providers[p["providerId"].(string)] = p
}
if _, ok := providers["codex"]; !ok {
t.Error("missing codex provider")
}
if _, ok := providers["opencode"]; !ok {
t.Error("missing opencode provider")
}
if _, ok := providers["gemini"]; !ok {
t.Error("missing gemini provider")
}
if _, ok := providers["hermes"]; !ok {
t.Error("missing hermes provider")
}
}
func TestProductionProviderCatalogFallsBackToBridgeAuthToken(t *testing.T) {
t.Setenv("AI_WORKSPACE_AUTH_TOKEN", "")
t.Setenv("BRIDGE_AUTH_TOKEN", "bridge-token")
_, catalog, _ := newProductionProviderCatalog()
p, ok := catalog["codex"]
if !ok {
t.Fatal("missing codex")
}
if got := p.AuthorizationHeader; got != "Bearer bridge-token" {
t.Fatalf("expected bearer header, got %q", got)
}
}
func TestProductionProviderCatalogPrefersAIWorkspaceAuthToken(t *testing.T) {
t.Setenv("AI_WORKSPACE_AUTH_TOKEN", "ai-workspace-token")
t.Setenv("BRIDGE_AUTH_TOKEN", "bridge-token")
_, catalog, _ := newProductionProviderCatalog()
p, ok := catalog["codex"]
if !ok {
t.Fatal("missing codex")
}
if got := p.AuthorizationHeader; got != "Bearer ai-workspace-token" {
t.Fatalf("expected AI workspace bearer header, got %q", got)
}
}
func TestProductionProviderCatalogPrefersDedicatedBridgeAuthToken(t *testing.T) {
t.Setenv("AI_WORKSPACE_AUTH_TOKEN", "")
t.Setenv("BRIDGE_AUTH_TOKEN", "dedicated-token")
_, catalog, _ := newProductionProviderCatalog()
p, ok := catalog["codex"]
if !ok {
t.Fatal("missing codex")
}
if got := p.AuthorizationHeader; got != "Bearer dedicated-token" {
t.Fatalf("expected dedicated bearer header, got %q", got)
}
}
func TestProductionProviderCatalogIgnoresInternalServiceToken(t *testing.T) {
t.Setenv("AI_WORKSPACE_AUTH_TOKEN", "")
t.Setenv("BRIDGE_AUTH_TOKEN", "")
t.Setenv("INTERNAL_SERVICE_TOKEN", "legacy-token")
_, catalog, _ := newProductionProviderCatalog()
p, ok := catalog["codex"]
if !ok {
t.Fatal("missing codex")
}
if got := p.AuthorizationHeader; got != "" {
t.Fatalf("expected empty auth header when BRIDGE_AUTH_TOKEN is unset, got %q", got)
}
}