Files
plumber/internal/store/memory_test.go
T
codegirl007 f4cec32afb Make web tests database-free and finish review hardening.
Introduce a Store interface with Postgres and in-memory backends, cover mutations/CSRF/session rotation without Postgres, bound avatar decode dimensions, add truncate/prepareAvatar unit tests, and run go test -race in CI.
2026-08-22 07:36:13 -07:00

57 lines
1.1 KiB
Go

package store
import (
"context"
"sync"
"testing"
)
func TestMemoryConcurrentLastAdminDemotion(t *testing.T) {
m := NewMemory()
ctx := context.Background()
a := &User{Username: "admin_a", PasswordHash: "x", Role: RoleAdmin}
b := &User{Username: "admin_b", PasswordHash: "x", Role: RoleAdmin}
if err := m.CreateUser(ctx, a); err != nil {
t.Fatal(err)
}
if err := m.CreateUser(ctx, b); err != nil {
t.Fatal(err)
}
var wg sync.WaitGroup
errs := make(chan error, 2)
wg.Add(2)
go func() {
defer wg.Done()
errs <- m.SetUserRole(ctx, a.ID, RoleUser)
}()
go func() {
defer wg.Done()
errs <- m.SetUserRole(ctx, b.ID, RoleUser)
}()
wg.Wait()
close(errs)
var ok, lastAdmin int
for err := range errs {
switch err {
case nil:
ok++
case ErrLastAdmin:
lastAdmin++
default:
t.Fatalf("unexpected error: %v", err)
}
}
if ok != 1 || lastAdmin != 1 {
t.Fatalf("want 1 success and 1 ErrLastAdmin, got ok=%d lastAdmin=%d", ok, lastAdmin)
}
n, err := m.CountAdmins(ctx)
if err != nil {
t.Fatal(err)
}
if n != 1 {
t.Fatalf("admins remaining = %d, want 1", n)
}
}