auth/oidc: test slice-typed extra claims comparison (#1245)

## Summary
Follow-up to #1238 (closes #988). Adds direct unit-test coverage for the
`claimMatches` helper, which was the actual change in #1238.

`claimMatches` and `toAnySlice` are unexported, so the tests live in
`oidc_internal_test.go` (`package auth`) — same pattern as
`http_internal_test.go`. Cases covered:

- scalar/scalar match and mismatch
- scalar actual against array expected (both directions of overlap)
- array actual against scalar expected
- **array/array** — pre-#1238 this combination panicked with `comparing
uncomparable type []interface {}`
- `[]string` typed slice (exercises the typed-slice branch of
`toAnySlice`, which `[]any` skips)
- non-string scalars (int, bool)
- empty actual array

Test values use single letters (`x`, `y`, `p`, `q`) rather than role
labels — only the relationships matter, and short tokens keep `goconst`
quiet.

## Test plan
- [x] `go test ./internal/api/handlers/v0/auth/...` — all 13 subtests
pass
- [x] `golangci-lint run ./internal/api/handlers/v0/auth/...` — no new
issues vs main
This commit is contained in:
Radoslav Dimitrov 2026-05-04 06:52:12 -04:00 • committed by GitHub
commit dfaa8f3b82
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -0,0 +1,41 @@
package auth
import "testing"
func TestClaimMatches(t *testing.T) {
tests := []struct {
name string
actual any
expected any
want bool
}{
{"scalar/scalar match", "x", "x", true},
{"scalar/scalar mismatch", "x", "y", false},
{"scalar actual in array expected", "x", []any{"x", "y"}, true},
{"scalar actual not in array expected", "z", []any{"x", "y"}, false},
{"array actual contains scalar expected", []any{"x", "y"}, "x", true},
{"array actual missing scalar expected", []any{"y", "z"}, "x", false},
// Pre-#1238 array/array comparison panicked with "comparing uncomparable type []interface {}".
{"array/array overlap", []any{"a", "b"}, []any{"b", "c"}, true},
{"array/array disjoint", []any{"a", "b"}, []any{"c", "d"}, false},
// Exercises the []string branch of toAnySlice (concrete typed slice, not []any).
{"[]string actual matches scalar", []string{"p", "q"}, "p", true},
{"scalar matches []string expected", "p", []string{"p", "q"}, true},
{"non-string scalar match", 42, 42, true},
{"bool scalar match", true, true, true},
{"empty actual array", []any{}, "x", false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := claimMatches(tt.actual, tt.expected); got != tt.want {
t.Errorf("claimMatches(%v, %v) = %v, want %v", tt.actual, tt.expected, got, tt.want)
}
})
}
}