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.
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user