Initial commit of Descrybe v2 without local scratch artifacts.
Drop one-shot tmp/axe scripts and agent i18n scratch so the Gitea tree is deployable.
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestPreferMembershipRoleNeverDemotesAdmin(t *testing.T) {
|
||||
t.Parallel()
|
||||
cases := []struct {
|
||||
name string
|
||||
existing string
|
||||
invited string
|
||||
want string
|
||||
}{
|
||||
{name: "admin stays admin on member invite", existing: "admin", invited: "member", want: "admin"},
|
||||
{name: "admin stays admin on admin invite", existing: "admin", invited: "admin", want: "admin"},
|
||||
{name: "member promotes to admin", existing: "member", invited: "admin", want: "admin"},
|
||||
{name: "member stays member", existing: "member", invited: "member", want: "member"},
|
||||
{name: "unknown invited normalizes to member", existing: "member", invited: "owner", want: "member"},
|
||||
{name: "empty existing yields invited role", existing: "", invited: "admin", want: "admin"},
|
||||
}
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
got := preferMembershipRole(tc.existing, tc.invited)
|
||||
if got != tc.want {
|
||||
t.Fatalf("preferMembershipRole(%q, %q)=%q want %q", tc.existing, tc.invited, got, tc.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestHashInviteTokenMatchesAPIKeyHash(t *testing.T) {
|
||||
t.Parallel()
|
||||
const raw = "invite-plaintext-secret"
|
||||
got := HashInviteToken(raw)
|
||||
if got != HashAPIKey(raw) {
|
||||
t.Fatalf("HashInviteToken must match HashAPIKey construction")
|
||||
}
|
||||
if len(got) != 64 {
|
||||
t.Fatalf("expected sha256 hex length 64, got %d", len(got))
|
||||
}
|
||||
if got == raw {
|
||||
t.Fatal("invite token must not be stored as plaintext")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNormalizeInviteRole(t *testing.T) {
|
||||
t.Parallel()
|
||||
if normalizeInviteRole("Admin") != "admin" {
|
||||
t.Fatal("expected admin")
|
||||
}
|
||||
if normalizeInviteRole(" MEMBER ") != "member" {
|
||||
t.Fatal("expected member")
|
||||
}
|
||||
if normalizeInviteRole("owner") != "member" {
|
||||
t.Fatal("unknown roles collapse to member")
|
||||
}
|
||||
if NormalizeMembershipRole("Admin") != "admin" {
|
||||
t.Fatal("NormalizeMembershipRole should accept Admin")
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseMembershipRole(t *testing.T) {
|
||||
t.Parallel()
|
||||
got, err := ParseMembershipRole(" Admin ")
|
||||
if err != nil || got != "admin" {
|
||||
t.Fatalf("admin: got %q err=%v", got, err)
|
||||
}
|
||||
got, err = ParseMembershipRole("MEMBER")
|
||||
if err != nil || got != "member" {
|
||||
t.Fatalf("member: got %q err=%v", got, err)
|
||||
}
|
||||
if _, err := ParseMembershipRole("owner"); !errors.Is(err, ErrInvalidMembershipRole) {
|
||||
t.Fatalf("owner: err=%v want ErrInvalidMembershipRole", err)
|
||||
}
|
||||
if _, err := ParseMembershipRole(""); !errors.Is(err, ErrInvalidMembershipRole) {
|
||||
t.Fatalf("empty: err=%v want ErrInvalidMembershipRole", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsSyntheticLegacyEmail(t *testing.T) {
|
||||
t.Parallel()
|
||||
if !IsSyntheticLegacyEmail("user_abc@legacy.local") {
|
||||
t.Fatal("expected synthetic")
|
||||
}
|
||||
if !IsSyntheticLegacyEmail(" User@Legacy.Local ") {
|
||||
t.Fatal("expected case-insensitive synthetic")
|
||||
}
|
||||
if IsSyntheticLegacyEmail("real@example.com") {
|
||||
t.Fatal("real email must not be treated as synthetic")
|
||||
}
|
||||
if IsSyntheticLegacyEmail("legacy.local@example.com") {
|
||||
t.Fatal("suffix-only match; local-part must not trigger")
|
||||
}
|
||||
if IsSyntheticLegacyEmail("") {
|
||||
t.Fatal("empty must not be synthetic")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmailsEqual(t *testing.T) {
|
||||
t.Parallel()
|
||||
if !EmailsEqual("A@Example.COM", " a@example.com ") {
|
||||
t.Fatal("expected equal after normalize")
|
||||
}
|
||||
if EmailsEqual("a@example.com", "b@example.com") {
|
||||
t.Fatal("expected mismatch")
|
||||
}
|
||||
if !EmailsEqual("", "") {
|
||||
t.Fatal("empty emails should compare equal")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user