Files
probo/pkg/connector/provider/registry_test.go
Aurélien Sibiril 0149ca4f55 Support HTTP Basic auth in API-key connections
Cursor's Admin API authenticates with the admin key as the HTTP
Basic auth username (empty password) and rejects Bearer tokens.
The API-key connection previously supported only Bearer and a
custom header (Anthropic's x-api-key); add a Basic-auth mode
selected by Registration.APIKeyBasicAuth, and reject providers
that set both it and APIKeyHeader.

Signed-off-by: Aurélien Sibiril <81782+aureliensibiril@users.noreply.github.com>
2026-05-29 00:05:48 +02:00

171 lines
5.6 KiB
Go

// Copyright (c) 2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
package provider_test
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.probo.inc/probo/pkg/connector/provider"
"go.probo.inc/probo/pkg/coredata"
)
// TestEveryProviderRegistered asserts that every
// coredata.ConnectorProvider constant has a matching Registration in
// the registry, that the registration carries the minimum metadata
// (Provider, DisplayName), and that the access-review NewDriver
// closure is wired — so the provider can actually drive a review.
func TestEveryProviderRegistered(t *testing.T) {
t.Parallel()
r := provider.NewBuiltinRegistry()
for _, p := range coredata.ConnectorProviders() {
t.Run(string(p), func(t *testing.T) {
t.Parallel()
reg, ok := r.Get(p)
require.Truef(t, ok, "provider %q has no Registration", p)
require.NotNil(t, reg, "provider %q Registration is nil", p)
require.Equalf(t, p, reg.Provider, "provider %q has mismatching Registration.Provider", p)
assert.NotEmptyf(t, reg.DisplayName, "provider %q has empty DisplayName", p)
assert.NotNilf(t, reg.NewDriver, "provider %q has nil NewDriver", p)
})
}
}
// TestRegistry_Register exercises the validation and duplicate-detection
// paths on Register. Programmer errors at NewBuiltinRegistry time —
// nil, empty Provider, empty DisplayName, duplicate — must all surface
// as errors rather than silently registering a malformed entry.
func TestRegistry_Register(t *testing.T) {
t.Parallel()
t.Run("nil Registration", func(t *testing.T) {
t.Parallel()
r := provider.NewRegistry()
err := r.Register(nil)
require.Error(t, err)
assert.Contains(t, err.Error(), "nil Registration")
})
t.Run("empty Provider", func(t *testing.T) {
t.Parallel()
r := provider.NewRegistry()
err := r.Register(&provider.Registration{DisplayName: "X"})
require.Error(t, err)
assert.Contains(t, err.Error(), "missing Provider")
})
t.Run("empty DisplayName", func(t *testing.T) {
t.Parallel()
r := provider.NewRegistry()
err := r.Register(&provider.Registration{Provider: coredata.ConnectorProviderSlack})
require.Error(t, err)
assert.Contains(t, err.Error(), "missing DisplayName")
})
t.Run("APIKeyBasicAuth and APIKeyHeader mutually exclusive", func(t *testing.T) {
t.Parallel()
r := provider.NewRegistry()
err := r.Register(&provider.Registration{
Provider: coredata.ConnectorProviderSlack,
DisplayName: "Slack",
APIKeyBasicAuth: true,
APIKeyHeader: "x-api-key",
})
require.Error(t, err)
assert.Contains(t, err.Error(), "mutually exclusive")
})
t.Run("duplicate registration", func(t *testing.T) {
t.Parallel()
r := provider.NewRegistry()
require.NoError(t, r.Register(&provider.Registration{
Provider: coredata.ConnectorProviderSlack,
DisplayName: "Slack",
}))
err := r.Register(&provider.Registration{
Provider: coredata.ConnectorProviderSlack,
DisplayName: "Slack-bis",
})
require.Error(t, err)
assert.Contains(t, err.Error(), "duplicate registration")
})
t.Run("valid Registration round-trips through Get", func(t *testing.T) {
t.Parallel()
r := provider.NewRegistry()
want := &provider.Registration{
Provider: coredata.ConnectorProviderSlack,
DisplayName: "Slack",
}
require.NoError(t, r.Register(want))
got, ok := r.Get(coredata.ConnectorProviderSlack)
require.True(t, ok)
assert.Same(t, want, got)
})
}
// TestRegistry_All asserts the registry returns the same number of
// entries that have been registered. The builtin registry is the
// canonical source of truth: every coredata.ConnectorProvider has
// exactly one matching Registration, no more.
func TestRegistry_All(t *testing.T) {
t.Parallel()
r := provider.NewBuiltinRegistry()
assert.Len(t, r.All(), len(coredata.ConnectorProviders()))
}
// TestRegistry_ProviderDisplayName covers the fallback path: an
// unregistered provider returns its raw constant string.
func TestRegistry_ProviderDisplayName(t *testing.T) {
t.Parallel()
r := provider.NewBuiltinRegistry()
assert.Equal(t, "Slack", r.ProviderDisplayName(coredata.ConnectorProviderSlack))
assert.Equal(t, "UNKNOWN", r.ProviderDisplayName(coredata.ConnectorProvider("UNKNOWN")))
}
// TestRegistry_ProviderOAuth2Scopes covers the nil path for an
// unregistered provider and the populated path for a registered one.
func TestRegistry_ProviderOAuth2Scopes(t *testing.T) {
t.Parallel()
r := provider.NewBuiltinRegistry()
assert.NotEmpty(t, r.ProviderOAuth2Scopes(coredata.ConnectorProviderSlack))
assert.Nil(t, r.ProviderOAuth2Scopes(coredata.ConnectorProvider("UNKNOWN")))
}
// TestRegistry_ProbeURL covers the registered and unregistered paths.
// Slack ships a probe URL in its Registration; an unknown provider
// returns the empty string.
func TestRegistry_ProbeURL(t *testing.T) {
t.Parallel()
r := provider.NewBuiltinRegistry()
assert.NotEmpty(t, r.ProbeURL("SLACK"))
assert.Empty(t, r.ProbeURL("UNKNOWN"))
}