Files
Pulse/internal/api/security_oidc_response_test.go
rcourtman 3fdf753a5b Enhance devcontainer and CI workflows
- Add persistent volume mounts for Go/npm caches (faster rebuilds)
- Add shell config with helpful aliases and custom prompt
- Add comprehensive devcontainer documentation
- Add pre-commit hooks for Go formatting and linting
- Use go-version-file in CI workflows instead of hardcoded versions
- Simplify docker compose commands with --wait flag
- Add gitignore entries for devcontainer auth files

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 22:29:15 +00:00

183 lines
4.9 KiB
Go

package api
import (
"testing"
"github.com/rcourtman/pulse-go-rewrite/internal/config"
)
func TestMakeOIDCResponse_NilConfig(t *testing.T) {
t.Parallel()
resp := makeOIDCResponse(nil, "https://pulse.example.com")
// Should return a default config when nil is passed
if resp.Enabled {
t.Error("expected Enabled to be false for nil config")
}
// Should have appropriate defaults
if resp.DefaultRedirect == "" {
t.Error("expected DefaultRedirect to be set")
}
}
func TestMakeOIDCResponse_EmptyConfig(t *testing.T) {
t.Parallel()
cfg := config.NewOIDCConfig()
resp := makeOIDCResponse(cfg, "https://pulse.example.com")
if resp.Enabled {
t.Error("expected Enabled to be false for new config")
}
if resp.ClientSecretSet {
t.Error("expected ClientSecretSet to be false when no secret")
}
}
func TestMakeOIDCResponse_EnabledWithSecret(t *testing.T) {
t.Parallel()
cfg := &config.OIDCConfig{
Enabled: true,
IssuerURL: "https://auth.example.com",
ClientID: "pulse-client",
ClientSecret: "super-secret-value",
RedirectURL: "https://pulse.example.com/auth/callback",
Scopes: []string{"openid", "profile", "email"},
UsernameClaim: "preferred_username",
EmailClaim: "email",
GroupsClaim: "groups",
}
resp := makeOIDCResponse(cfg, "https://pulse.example.com")
if !resp.Enabled {
t.Error("expected Enabled to be true")
}
if resp.IssuerURL != "https://auth.example.com" {
t.Errorf("expected IssuerURL 'https://auth.example.com', got %q", resp.IssuerURL)
}
if resp.ClientID != "pulse-client" {
t.Errorf("expected ClientID 'pulse-client', got %q", resp.ClientID)
}
if !resp.ClientSecretSet {
t.Error("expected ClientSecretSet to be true when secret is set")
}
// Client secret should NOT be exposed in response
// (this is handled by the response struct not having a ClientSecret field)
if len(resp.Scopes) != 3 {
t.Errorf("expected 3 scopes, got %d", len(resp.Scopes))
}
if resp.UsernameClaim != "preferred_username" {
t.Errorf("expected UsernameClaim 'preferred_username', got %q", resp.UsernameClaim)
}
if resp.EmailClaim != "email" {
t.Errorf("expected EmailClaim 'email', got %q", resp.EmailClaim)
}
}
func TestMakeOIDCResponse_WithEnvOverrides(t *testing.T) {
t.Parallel()
cfg := &config.OIDCConfig{
Enabled: true,
IssuerURL: "https://auth.example.com",
ClientID: "env-client",
EnvOverrides: map[string]bool{
"OIDC_ENABLED": true,
"OIDC_ISSUER_URL": true,
"OIDC_CLIENT_ID": true,
},
}
resp := makeOIDCResponse(cfg, "https://pulse.example.com")
if resp.EnvOverrides == nil {
t.Fatal("expected EnvOverrides to be set")
}
if len(resp.EnvOverrides) != 3 {
t.Errorf("expected 3 env overrides, got %d", len(resp.EnvOverrides))
}
if !resp.EnvOverrides["OIDC_ENABLED"] {
t.Error("expected OIDC_ENABLED override to be true")
}
if !resp.EnvOverrides["OIDC_ISSUER_URL"] {
t.Error("expected OIDC_ISSUER_URL override to be true")
}
}
func TestMakeOIDCResponse_AllowedFilters(t *testing.T) {
t.Parallel()
cfg := &config.OIDCConfig{
Enabled: true,
IssuerURL: "https://auth.example.com",
ClientID: "pulse-client",
AllowedGroups: []string{"admins", "ops"},
AllowedDomains: []string{"example.com", "corp.example.com"},
AllowedEmails: []string{"admin@example.com"},
}
resp := makeOIDCResponse(cfg, "https://pulse.example.com")
if len(resp.AllowedGroups) != 2 {
t.Errorf("expected 2 allowed groups, got %d", len(resp.AllowedGroups))
}
if len(resp.AllowedDomains) != 2 {
t.Errorf("expected 2 allowed domains, got %d", len(resp.AllowedDomains))
}
if len(resp.AllowedEmails) != 1 {
t.Errorf("expected 1 allowed email, got %d", len(resp.AllowedEmails))
}
}
func TestMakeOIDCResponse_CABundle(t *testing.T) {
t.Parallel()
cfg := &config.OIDCConfig{
Enabled: true,
IssuerURL: "https://auth.internal.example.com",
ClientID: "pulse-client",
CABundle: "-----BEGIN CERTIFICATE-----\nMIIB...\n-----END CERTIFICATE-----",
}
resp := makeOIDCResponse(cfg, "https://pulse.example.com")
if resp.CABundle == "" {
t.Error("expected CABundle to be set")
}
if resp.CABundle != cfg.CABundle {
t.Error("expected CABundle to match input")
}
}
func TestMakeOIDCResponse_SlicesCopied(t *testing.T) {
t.Parallel()
// Ensure that slices are copied, not shared
cfg := &config.OIDCConfig{
Enabled: true,
IssuerURL: "https://auth.example.com",
ClientID: "pulse-client",
Scopes: []string{"openid", "profile"},
AllowedGroups: []string{"admins"},
}
resp := makeOIDCResponse(cfg, "https://pulse.example.com")
// Modify the original slices
cfg.Scopes = append(cfg.Scopes, "email")
cfg.AllowedGroups[0] = "modified"
// Response should not be affected
if len(resp.Scopes) != 2 {
t.Errorf("expected response scopes to be unchanged, got %d", len(resp.Scopes))
}
if resp.AllowedGroups[0] == "modified" {
t.Error("response AllowedGroups should be a copy, not a reference")
}
}