multica/server/internal/handler/auth_signup_test.go

115 lines
3.4 KiB
Go

package handler
import (
"context"
"strings"
"testing"
"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgconn"
db "github.com/multica-ai/multica/server/pkg/db/generated"
)
func newTestHandler(cfg Config) *Handler {
return &Handler{
cfg: cfg,
}
}
func TestSignupGating(t *testing.T) {
tests := []struct {
name string
cfg Config
email string
isNew bool
wantErr bool
}{
{"allow_signup_true_new", Config{AllowSignup: true}, "a@x.com", true, false},
{"allow_signup_false_new", Config{AllowSignup: false}, "a@x.com", true, true},
{"allow_signup_false_existing", Config{AllowSignup: false}, "a@x.com", false, false},
{"domain_allowlist_match", Config{AllowSignup: false, AllowedEmailDomains: []string{"company.com"}}, "user@company.com", true, false},
{"domain_allowlist_mismatch", Config{AllowSignup: false, AllowedEmailDomains: []string{"company.com"}}, "user@other.com", true, true},
{"email_allowlist_match", Config{AllowSignup: false, AllowedEmails: []string{"boss@x.com"}}, "boss@x.com", true, false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
h := newTestHandler(tt.cfg)
err := h.checkSignupAllowed(tt.email, tt.isNew)
if (err != nil) != tt.wantErr {
t.Fatalf("got err=%v wantErr=%v", err, tt.wantErr)
}
})
}
}
type mockDB struct {
db.DBTX
getUserErr error
}
func (m *mockDB) QueryRow(ctx context.Context, sql string, args ...interface{}) pgx.Row {
return &mockRow{err: m.getUserErr}
}
func (m *mockDB) Exec(ctx context.Context, sql string, args ...interface{}) (pgconn.CommandTag, error) {
return pgconn.NewCommandTag("INSERT 1"), nil
}
type mockRow struct {
pgx.Row
err error
}
func (m *mockRow) Scan(dest ...interface{}) error {
return m.err
}
func TestFindOrCreateUserGating(t *testing.T) {
t.Run("new_user_blocked", func(t *testing.T) {
cfg := Config{AllowSignup: false}
h := newTestHandler(cfg)
h.Queries = db.New(&mockDB{getUserErr: pgx.ErrNoRows})
_, isNew, err := h.findOrCreateUser(context.Background(), "new@blocked.com")
if err == nil {
t.Fatal("expected error for new user when signup disabled")
}
if isNew {
t.Fatal("isNew should be false when signup is blocked")
}
if !strings.Contains(err.Error(), "registration is disabled") {
t.Fatalf("expected registration disabled error, got %v", err)
}
})
t.Run("existing_user_allowed", func(t *testing.T) {
cfg := Config{AllowSignup: false}
h := newTestHandler(cfg)
// mockDB returns nil error for Scan, simulating user found
h.Queries = db.New(&mockDB{getUserErr: nil})
_, isNew, err := h.findOrCreateUser(context.Background(), "existing@test.com")
if err != nil {
t.Fatalf("expected no error for existing user, got %v", err)
}
if isNew {
t.Fatal("existing user should not be flagged as new")
}
})
t.Run("whitelisted_user_allowed", func(t *testing.T) {
cfg := Config{AllowSignup: false, AllowedEmails: []string{"whitelisted@test.com"}}
h := newTestHandler(cfg)
h.Queries = db.New(&mockDB{getUserErr: pgx.ErrNoRows})
// This will pass checkSignupAllowed and move to CreateUser.
// Our mockDB Exec returns success, but Queries.CreateUser might expect QueryRow for RETURNING id.
// Let's see if it works.
_, _, err := h.findOrCreateUser(context.Background(), "whitelisted@test.com")
if err != nil && strings.Contains(err.Error(), "registration is disabled") {
t.Fatalf("expected whitelisted user to pass signup check, but got %v", err)
}
})
}