Pin bouncer Scope serialization, party Activated order, lagoon migration, compile/overlap/mint/expiry/validation, guard/debounce/resolver, interactive-only, account token API and CLI on Postgres. Co-authored-by: Cursor <cursoragent@cursor.com>
60 lines
1.5 KiB
Go
60 lines
1.5 KiB
Go
package bouncer
|
|
|
|
import (
|
|
"encoding/json"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestPrincipalLocaleAndCutoff(t *testing.T) {
|
|
when := time.Unix(1_700_000_000, 0)
|
|
p := Principal{PreferredLocale: "pl", TokensValidAfter: when}
|
|
if p.PreferredLocale != "pl" || !p.TokensValidAfter.Equal(when) {
|
|
t.Fatalf("%+v", p)
|
|
}
|
|
}
|
|
|
|
func TestContextCredentialRoundTrip(t *testing.T) {
|
|
if _, ok := Credential(t.Context()); ok {
|
|
t.Fatal("empty context must have no credential")
|
|
}
|
|
if _, ok := Credential(nil); ok {
|
|
t.Fatal("nil context must have no credential")
|
|
}
|
|
token := &struct{ Name string }{Name: "parity"}
|
|
got, ok := Credential(WithCredential(t.Context(), token))
|
|
if !ok || got != token {
|
|
t.Fatalf("got %#v ok=%t", got, ok)
|
|
}
|
|
got, ok = Credential(WithCredential(nil, token))
|
|
if !ok || got != token {
|
|
t.Fatalf("nil ctx got %#v ok=%t", got, ok)
|
|
}
|
|
}
|
|
|
|
func TestPrincipalScopeNotSerialized(t *testing.T) {
|
|
p := Principal{
|
|
ID: 1,
|
|
Scope: &ScopeLimit{Full: true, Scopes: [][]string{{"a.b"}}},
|
|
}
|
|
raw, err := json.Marshal(p)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if strings.Contains(string(raw), "Scope") || strings.Contains(string(raw), "scope") || strings.Contains(string(raw), "Full") {
|
|
t.Fatalf("Scope leaked into JSON: %s", raw)
|
|
}
|
|
var decoded map[string]any
|
|
if err := json.Unmarshal(raw, &decoded); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, ok := decoded["Scope"]; ok {
|
|
t.Fatal("Scope key present")
|
|
}
|
|
var zero Principal
|
|
if zero.Scope != nil {
|
|
t.Fatal("nil Scope is not the zero value")
|
|
}
|
|
}
|