1
0
mirror of https://github.com/pocketbase/pocketbase.git synced 2025-01-27 23:46:18 +02:00
pocketbase/core/otp_model_test.go
2024-09-29 21:09:46 +03:00

279 lines
5.9 KiB
Go

package core_test
import (
"fmt"
"testing"
"time"
"github.com/pocketbase/pocketbase/core"
"github.com/pocketbase/pocketbase/tests"
"github.com/pocketbase/pocketbase/tools/types"
)
func TestNewOTP(t *testing.T) {
t.Parallel()
app, _ := tests.NewTestApp()
defer app.Cleanup()
otp := core.NewOTP(app)
if otp.Collection().Name != core.CollectionNameOTPs {
t.Fatalf("Expected record with %q collection, got %q", core.CollectionNameOTPs, otp.Collection().Name)
}
}
func TestOTPProxyRecord(t *testing.T) {
t.Parallel()
record := core.NewRecord(core.NewBaseCollection("test"))
record.Id = "test_id"
otp := core.OTP{}
otp.SetProxyRecord(record)
if otp.ProxyRecord() == nil || otp.ProxyRecord().Id != record.Id {
t.Fatalf("Expected proxy record with id %q, got %v", record.Id, otp.ProxyRecord())
}
}
func TestOTPRecordRef(t *testing.T) {
t.Parallel()
app, _ := tests.NewTestApp()
defer app.Cleanup()
otp := core.NewOTP(app)
testValues := []string{"test_1", "test2", ""}
for i, testValue := range testValues {
t.Run(fmt.Sprintf("%d_%q", i, testValue), func(t *testing.T) {
otp.SetRecordRef(testValue)
if v := otp.RecordRef(); v != testValue {
t.Fatalf("Expected getter %q, got %q", testValue, v)
}
if v := otp.GetString("recordRef"); v != testValue {
t.Fatalf("Expected field value %q, got %q", testValue, v)
}
})
}
}
func TestOTPCollectionRef(t *testing.T) {
t.Parallel()
app, _ := tests.NewTestApp()
defer app.Cleanup()
otp := core.NewOTP(app)
testValues := []string{"test_1", "test2", ""}
for i, testValue := range testValues {
t.Run(fmt.Sprintf("%d_%q", i, testValue), func(t *testing.T) {
otp.SetCollectionRef(testValue)
if v := otp.CollectionRef(); v != testValue {
t.Fatalf("Expected getter %q, got %q", testValue, v)
}
if v := otp.GetString("collectionRef"); v != testValue {
t.Fatalf("Expected field value %q, got %q", testValue, v)
}
})
}
}
func TestOTPCreated(t *testing.T) {
t.Parallel()
app, _ := tests.NewTestApp()
defer app.Cleanup()
otp := core.NewOTP(app)
if v := otp.Created().String(); v != "" {
t.Fatalf("Expected empty created, got %q", v)
}
now := types.NowDateTime()
otp.SetRaw("created", now)
if v := otp.Created().String(); v != now.String() {
t.Fatalf("Expected %q created, got %q", now.String(), v)
}
}
func TestOTPUpdated(t *testing.T) {
t.Parallel()
app, _ := tests.NewTestApp()
defer app.Cleanup()
otp := core.NewOTP(app)
if v := otp.Updated().String(); v != "" {
t.Fatalf("Expected empty updated, got %q", v)
}
now := types.NowDateTime()
otp.SetRaw("updated", now)
if v := otp.Updated().String(); v != now.String() {
t.Fatalf("Expected %q updated, got %q", now.String(), v)
}
}
func TestOTPHasExpired(t *testing.T) {
t.Parallel()
app, _ := tests.NewTestApp()
defer app.Cleanup()
now := types.NowDateTime()
otp := core.NewOTP(app)
otp.SetRaw("created", now.Add(-5*time.Minute))
scenarios := []struct {
maxElapsed time.Duration
expected bool
}{
{0 * time.Minute, true},
{3 * time.Minute, true},
{5 * time.Minute, true},
{6 * time.Minute, false},
}
for i, s := range scenarios {
t.Run(fmt.Sprintf("%d_%s", i, s.maxElapsed.String()), func(t *testing.T) {
result := otp.HasExpired(s.maxElapsed)
if result != s.expected {
t.Fatalf("Expected %v, got %v", s.expected, result)
}
})
}
}
func TestOTPPreValidate(t *testing.T) {
t.Parallel()
app, _ := tests.NewTestApp()
defer app.Cleanup()
otpsCol, err := app.FindCollectionByNameOrId(core.CollectionNameOTPs)
if err != nil {
t.Fatal(err)
}
user, err := app.FindAuthRecordByEmail("users", "test@example.com")
if err != nil {
t.Fatal(err)
}
t.Run("no proxy record", func(t *testing.T) {
otp := &core.OTP{}
if err := app.Validate(otp); err == nil {
t.Fatal("Expected collection validation error")
}
})
t.Run("non-OTP collection", func(t *testing.T) {
otp := &core.OTP{}
otp.SetProxyRecord(core.NewRecord(core.NewBaseCollection("invalid")))
otp.SetRecordRef(user.Id)
otp.SetCollectionRef(user.Collection().Id)
otp.SetPassword("test123")
if err := app.Validate(otp); err == nil {
t.Fatal("Expected collection validation error")
}
})
t.Run("OTP collection", func(t *testing.T) {
otp := &core.OTP{}
otp.SetProxyRecord(core.NewRecord(otpsCol))
otp.SetRecordRef(user.Id)
otp.SetCollectionRef(user.Collection().Id)
otp.SetPassword("test123")
if err := app.Validate(otp); err != nil {
t.Fatalf("Expected nil validation error, got %v", err)
}
})
}
func TestOTPValidateHook(t *testing.T) {
t.Parallel()
app, _ := tests.NewTestApp()
defer app.Cleanup()
user, err := app.FindAuthRecordByEmail("users", "test@example.com")
if err != nil {
t.Fatal(err)
}
demo1, err := app.FindRecordById("demo1", "84nmscqy84lsi1t")
if err != nil {
t.Fatal(err)
}
scenarios := []struct {
name string
otp func() *core.OTP
expectErrors []string
}{
{
"empty",
func() *core.OTP {
return core.NewOTP(app)
},
[]string{"collectionRef", "recordRef", "password"},
},
{
"non-auth collection",
func() *core.OTP {
otp := core.NewOTP(app)
otp.SetCollectionRef(demo1.Collection().Id)
otp.SetRecordRef(demo1.Id)
otp.SetPassword("test123")
return otp
},
[]string{"collectionRef"},
},
{
"missing record id",
func() *core.OTP {
otp := core.NewOTP(app)
otp.SetCollectionRef(user.Collection().Id)
otp.SetRecordRef("missing")
otp.SetPassword("test123")
return otp
},
[]string{"recordRef"},
},
{
"valid ref",
func() *core.OTP {
otp := core.NewOTP(app)
otp.SetCollectionRef(user.Collection().Id)
otp.SetRecordRef(user.Id)
otp.SetPassword("test123")
return otp
},
[]string{},
},
}
for _, s := range scenarios {
t.Run(s.name, func(t *testing.T) {
errs := app.Validate(s.otp())
tests.TestValidationErrors(t, errs, s.expectErrors)
})
}
}