From aee13bd693861671047443acbc98a54350d38153 Mon Sep 17 00:00:00 2001 From: Raymond Tukpe Date: Thu, 14 Nov 2024 15:09:51 +0100 Subject: [PATCH] feat: fixed user repo --- database/sqlite3/sqlite3.go | 43 +++- database/sqlite3/sqlite_test.go | 2 +- database/sqlite3/users.go | 99 ++++++--- database/sqlite3/users_test.go | 354 ++++++++++++++++---------------- 4 files changed, 289 insertions(+), 209 deletions(-) diff --git a/database/sqlite3/sqlite3.go b/database/sqlite3/sqlite3.go index 1bacc629a6..723fbd97e2 100644 --- a/database/sqlite3/sqlite3.go +++ b/database/sqlite3/sqlite3.go @@ -7,17 +7,21 @@ import ( "fmt" "github.com/frain-dev/convoy/database/hooks" "github.com/frain-dev/convoy/pkg/log" + "gopkg.in/guregu/null.v4" "io" + "time" "github.com/jmoiron/sqlx" _ "github.com/mattn/go-sqlite3" ) -const pkgName = "sqlite3" - type DbCtxKey string -const TransactionCtx DbCtxKey = "transaction" +const ( + pkgName = "sqlite3" + Rfc3339Milli = "2006-01-02T15:04:05.000Z" + TransactionCtx DbCtxKey = "transaction" +) type Sqlite struct { dbx *sqlx.DB @@ -103,3 +107,36 @@ func GetTx(ctx context.Context, db *sqlx.DB) (*sqlx.Tx, bool, error) { return tx, isWrapped, nil } + +func timeAsString(t time.Time) string { + return t.Format(Rfc3339Milli) +} + +func nullTimeAsString(t null.Time) *string { + strVal := "" + if t.Valid { + strVal = t.Time.Format(Rfc3339Milli) + return &strVal + } + return &strVal +} + +func asTime(ts string) time.Time { + t, err := time.Parse(Rfc3339Milli, ts) + if err != nil { + return time.Now() + } + return t +} + +func asNullTime(ts *string) null.Time { + if ts == nil { + return null.NewTime(time.Time{}, false) + } + + t, err := time.Parse(Rfc3339Milli, *ts) + if err != nil { + return null.NewTime(time.Now(), false) + } + return null.NewTime(t, true) +} diff --git a/database/sqlite3/sqlite_test.go b/database/sqlite3/sqlite_test.go index 5724da0ed6..651b5becec 100644 --- a/database/sqlite3/sqlite_test.go +++ b/database/sqlite3/sqlite_test.go @@ -32,7 +32,7 @@ func getDB(t *testing.T) (database.Database, func()) { dbHooks := hooks.Init() dbHooks.RegisterHook(datastore.EndpointCreated, func(data interface{}, changelog interface{}) {}) - _db, err = NewDB("file::memory:?cache=shared", log.NewLogger(os.Stdout)) + _db, err = NewDB("test.db?cache=shared", log.NewLogger(os.Stdout)) require.NoError(t, err) // run migrations diff --git a/database/sqlite3/users.go b/database/sqlite3/users.go index 768e2ac97d..bf66153338 100644 --- a/database/sqlite3/users.go +++ b/database/sqlite3/users.go @@ -5,34 +5,35 @@ import ( "database/sql" "errors" "fmt" - "strings" - "github.com/frain-dev/convoy/database" "github.com/frain-dev/convoy/datastore" "github.com/jmoiron/sqlx" + "strings" + "time" ) const ( createUser = ` INSERT INTO users ( - id,first_name,last_name,email,password, - email_verified,reset_password_token, email_verification_token, - reset_password_expires_at,email_verification_expires_at, auth_type) + id,first_name,last_name,email,password, email_verified, + reset_password_token, email_verification_token, reset_password_expires_at, + email_verification_expires_at, auth_type) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11) ` updateUser = ` UPDATE users SET - first_name = $2, - last_name=$3, - email=$4, - password=$5, - email_verified=$6, - reset_password_token=$7, - email_verification_token=$8, - reset_password_expires_at=$9, - email_verification_expires_at=$10 - WHERE id = $1 AND deleted_at IS NULL; + first_name=$1, + last_name=$2, + email=$3, + password=$4, + email_verified=$5, + reset_password_token=$6, + email_verification_token=$7, + reset_password_expires_at=$8, + email_verification_expires_at=$9, + updated_at=$10 + WHERE id = $11 AND deleted_at IS NULL; ` fetchUsers = ` @@ -75,7 +76,7 @@ func (u *userRepo) CreateUser(ctx context.Context, user *datastore.User) error { user.AuthType, ) if err != nil { - if strings.Contains(err.Error(), "duplicate") { + if strings.Contains(err.Error(), "constraint") { return datastore.ErrDuplicateEmail } return err @@ -94,9 +95,9 @@ func (u *userRepo) CreateUser(ctx context.Context, user *datastore.User) error { } func (u *userRepo) UpdateUser(ctx context.Context, user *datastore.User) error { - result, err := u.db.Exec( - updateUser, user.UID, user.FirstName, user.LastName, user.Email, user.Password, user.EmailVerified, user.ResetPasswordToken, - user.EmailVerificationToken, user.ResetPasswordExpiresAt, user.EmailVerificationExpiresAt, + result, err := u.db.ExecContext(ctx, + updateUser, user.FirstName, user.LastName, user.Email, user.Password, user.EmailVerified, user.ResetPasswordToken, + user.EmailVerificationToken, user.ResetPasswordExpiresAt, user.EmailVerificationExpiresAt, time.Now(), user.UID, ) if err != nil { return err @@ -115,7 +116,7 @@ func (u *userRepo) UpdateUser(ctx context.Context, user *datastore.User) error { } func (u *userRepo) FindUserByEmail(ctx context.Context, email string) (*datastore.User, error) { - user := &datastore.User{} + user := &dbUser{} err := u.db.QueryRowxContext(ctx, fmt.Sprintf("%s AND email = $1;", fetchUsers), email).StructScan(user) if err != nil { if errors.Is(err, sql.ErrNoRows) { @@ -124,11 +125,11 @@ func (u *userRepo) FindUserByEmail(ctx context.Context, email string) (*datastor return nil, err } - return user, nil + return user.toDatastoreUser(), nil } func (u *userRepo) FindUserByID(ctx context.Context, id string) (*datastore.User, error) { - user := &datastore.User{} + user := &dbUser{} err := u.db.QueryRowxContext(ctx, fmt.Sprintf("%s AND id = $1;", fetchUsers), id).StructScan(user) if err != nil { if errors.Is(err, sql.ErrNoRows) { @@ -137,11 +138,11 @@ func (u *userRepo) FindUserByID(ctx context.Context, id string) (*datastore.User return nil, err } - return user, nil + return user.toDatastoreUser(), nil } func (u *userRepo) FindUserByToken(ctx context.Context, token string) (*datastore.User, error) { - user := &datastore.User{} + user := &dbUser{} err := u.db.QueryRowxContext(ctx, fmt.Sprintf("%s AND reset_password_token = $1;", fetchUsers), token).StructScan(user) if err != nil { if errors.Is(err, sql.ErrNoRows) { @@ -150,11 +151,11 @@ func (u *userRepo) FindUserByToken(ctx context.Context, token string) (*datastor return nil, err } - return user, nil + return user.toDatastoreUser(), nil } func (u *userRepo) FindUserByEmailVerificationToken(ctx context.Context, token string) (*datastore.User, error) { - user := &datastore.User{} + user := &dbUser{} err := u.db.QueryRowxContext(ctx, fmt.Sprintf("%s AND email_verification_token = $1;", fetchUsers), token).StructScan(user) if err != nil { if errors.Is(err, sql.ErrNoRows) { @@ -163,15 +164,51 @@ func (u *userRepo) FindUserByEmailVerificationToken(ctx context.Context, token s return nil, err } - return user, nil + return user.toDatastoreUser(), nil } -func (o *userRepo) CountUsers(ctx context.Context) (int64, error) { - var count int64 - err := o.db.GetContext(ctx, &count, countUsers) +func (u *userRepo) CountUsers(ctx context.Context) (int64, error) { + var userCount int64 + err := u.db.GetContext(ctx, &userCount, countUsers) if err != nil { return 0, err } - return count, nil + return userCount, nil +} + +type dbUser struct { + UID string `db:"id"` + FirstName string `db:"first_name"` + LastName string `db:"last_name"` + Email string `db:"email"` + EmailVerified bool `db:"email_verified"` + Password string `db:"password"` + ResetPasswordToken string `db:"reset_password_token"` + EmailVerificationToken string `db:"email_verification_token"` + CreatedAt string `db:"created_at,omitempty"` + UpdatedAt string `db:"updated_at,omitempty"` + DeletedAt *string `db:"deleted_at"` + ResetPasswordExpiresAt string `db:"reset_password_expires_at,omitempty"` + EmailVerificationExpiresAt string `db:"email_verification_expires_at,omitempty"` + AuthType string `db:"auth_type"` +} + +func (uu *dbUser) toDatastoreUser() *datastore.User { + return &datastore.User{ + UID: uu.UID, + FirstName: uu.FirstName, + LastName: uu.LastName, + Email: uu.Email, + AuthType: uu.AuthType, + EmailVerified: uu.EmailVerified, + Password: uu.Password, + ResetPasswordToken: uu.ResetPasswordToken, + EmailVerificationToken: uu.EmailVerificationToken, + CreatedAt: asTime(uu.CreatedAt), + UpdatedAt: asTime(uu.UpdatedAt), + DeletedAt: asNullTime(uu.DeletedAt), + ResetPasswordExpiresAt: asTime(uu.ResetPasswordExpiresAt), + EmailVerificationExpiresAt: asTime(uu.EmailVerificationExpiresAt), + } } diff --git a/database/sqlite3/users_test.go b/database/sqlite3/users_test.go index afb95f24e2..aedb271a79 100644 --- a/database/sqlite3/users_test.go +++ b/database/sqlite3/users_test.go @@ -7,6 +7,7 @@ import ( "context" "errors" "fmt" + "gopkg.in/guregu/null.v4" "testing" "time" @@ -15,31 +16,39 @@ import ( "github.com/stretchr/testify/require" ) -func Test_CreateUser(t *testing.T) { - db, closeFn := getDB(t) - defer closeFn() - - tt := []struct { - name string - users []datastore.User - isDuplicateEmail bool - }{ - { - name: "create user", - users: []datastore.User{ - { +func TestUsers(t *testing.T) { + t.Run("Test_CreateUser", func(t *testing.T) { + db, closeFn := getDB(t) + defer closeFn() + + tt := []struct { + name string + user datastore.User + fn func(datastore.UserRepository) + isDuplicateEmail bool + }{ + { + name: "create user", + user: datastore.User{ UID: ulid.Make().String(), FirstName: "test", LastName: "test", Email: fmt.Sprintf("%s@test.com", ulid.Make().String()), }, }, - }, - { - name: "cannot create user with existing email", - isDuplicateEmail: true, - users: []datastore.User{ - { + { + name: "cannot create user with existing email", + isDuplicateEmail: true, + fn: func(ur datastore.UserRepository) { + err := ur.CreateUser(context.Background(), &datastore.User{ + UID: ulid.Make().String(), + FirstName: "test", + LastName: "test", + Email: "test@test.com", + }) + require.NoError(t, err) + }, + user: datastore.User{ UID: ulid.Make().String(), FirstName: "test", LastName: "test", @@ -51,232 +60,229 @@ func Test_CreateUser(t *testing.T) { ResetPasswordExpiresAt: time.Now(), EmailVerificationExpiresAt: time.Now(), }, - { - UID: ulid.Make().String(), - FirstName: "test", - LastName: "test", - Email: "test@test.com", - }, }, - }, - } + } - for _, tc := range tt { - t.Run(tc.name, func(t *testing.T) { - userRepo := NewUserRepo(db) + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + repo := NewUserRepo(db) - for i, user := range tc.users { - if i == 0 { - require.NoError(t, userRepo.CreateUser(context.Background(), &user)) + if tc.fn != nil { + tc.fn(repo) } - user := &datastore.User{ - UID: user.UID, - FirstName: user.FirstName, - LastName: user.LastName, - Email: user.Email, + u := &datastore.User{ + UID: tc.user.UID, + FirstName: tc.user.FirstName, + LastName: tc.user.LastName, + Email: tc.user.Email, } - if i > 0 && tc.isDuplicateEmail { - err := userRepo.CreateUser(context.Background(), user) + if tc.isDuplicateEmail { + err := repo.CreateUser(context.Background(), u) require.Error(t, err) require.ErrorIs(t, err, datastore.ErrDuplicateEmail) } - } - }) - } -} + }) + } + }) -func TestCountUsers(t *testing.T) { - db, closeFn := getDB(t) - defer closeFn() + t.Run("TestCountUsers", func(t *testing.T) { + db, closeFn := getDB(t) + defer closeFn() - userRepo := NewUserRepo(db) - count := 10 + repo := NewUserRepo(db) + c := 10 - for i := 0; i < count; i++ { - u := &datastore.User{ - UID: ulid.Make().String(), - FirstName: "test", - LastName: "test", - Email: fmt.Sprintf("%s@test.com", ulid.Make().String()), - } + for i := 0; i < c; i++ { + u := &datastore.User{ + UID: ulid.Make().String(), + FirstName: "test", + LastName: "test", + Email: fmt.Sprintf("%s@test.com", ulid.Make().String()), + } - err := userRepo.CreateUser(context.Background(), u) - require.NoError(t, err) - } + err := repo.CreateUser(context.Background(), u) + require.NoError(t, err) + } - userCount, err := userRepo.CountUsers(context.Background()) + userCount, err := repo.CountUsers(context.Background()) - require.NoError(t, err) - require.Equal(t, int64(count), userCount) -} + require.NoError(t, err) + require.Equal(t, int64(c), userCount) + }) -func Test_FindUserByEmail(t *testing.T) { - db, closeFn := getDB(t) - defer closeFn() + t.Run("Test_FindUserByEmail", func(t *testing.T) { + db, closeFn := getDB(t) + defer closeFn() - userRepo := NewUserRepo(db) + repo := NewUserRepo(db) - user := generateUser(t) + user := generateUser(t) - _, err := userRepo.FindUserByEmail(context.Background(), user.Email) - require.Error(t, err) - require.True(t, errors.Is(err, datastore.ErrUserNotFound)) + _, err := repo.FindUserByEmail(context.Background(), user.Email) + require.Error(t, err) + require.True(t, errors.Is(err, datastore.ErrUserNotFound)) - require.NoError(t, userRepo.CreateUser(context.Background(), user)) + require.NoError(t, repo.CreateUser(context.Background(), user)) - newUser, err := userRepo.FindUserByEmail(context.Background(), user.Email) - require.NoError(t, err) + newUser, err := repo.FindUserByEmail(context.Background(), user.Email) + require.NoError(t, err) - require.NotEmpty(t, newUser.CreatedAt) - require.NotEmpty(t, newUser.UpdatedAt) + require.NotEmpty(t, newUser.CreatedAt) + require.NotEmpty(t, newUser.UpdatedAt) - newUser.CreatedAt = time.Time{} - newUser.UpdatedAt = time.Time{} + newUser.CreatedAt = time.Time{} + newUser.UpdatedAt = time.Time{} - require.InDelta(t, user.EmailVerificationExpiresAt.Unix(), newUser.EmailVerificationExpiresAt.Unix(), float64(time.Hour)) - require.InDelta(t, user.ResetPasswordExpiresAt.Unix(), newUser.ResetPasswordExpiresAt.Unix(), float64(time.Hour)) + require.InDelta(t, user.EmailVerificationExpiresAt.Unix(), newUser.EmailVerificationExpiresAt.Unix(), float64(time.Hour)) + require.InDelta(t, user.ResetPasswordExpiresAt.Unix(), newUser.ResetPasswordExpiresAt.Unix(), float64(time.Hour)) - user.EmailVerificationExpiresAt, user.ResetPasswordExpiresAt = time.Time{}, time.Time{} - newUser.EmailVerificationExpiresAt, newUser.ResetPasswordExpiresAt = time.Time{}, time.Time{} + user.EmailVerificationExpiresAt, user.ResetPasswordExpiresAt = time.Time{}, time.Time{} + newUser.EmailVerificationExpiresAt, newUser.ResetPasswordExpiresAt = time.Time{}, time.Time{} - require.Equal(t, user, newUser) -} + require.Equal(t, user, newUser) + }) -func Test_FindUserByID(t *testing.T) { - db, closeFn := getDB(t) - defer closeFn() + t.Run("Test_FindUserByID", func(t *testing.T) { + db, closeFn := getDB(t) + defer closeFn() - userRepo := NewUserRepo(db) + repo := NewUserRepo(db) - user := generateUser(t) + user := generateUser(t) - _, err := userRepo.FindUserByID(context.Background(), user.UID) - require.Error(t, err) - require.True(t, errors.Is(err, datastore.ErrUserNotFound)) + _, err := repo.FindUserByID(context.Background(), user.UID) + require.Error(t, err) + require.True(t, errors.Is(err, datastore.ErrUserNotFound)) - require.NoError(t, userRepo.CreateUser(context.Background(), user)) - newUser, err := userRepo.FindUserByID(context.Background(), user.UID) - require.NoError(t, err) + require.NoError(t, repo.CreateUser(context.Background(), user)) + newUser, err := repo.FindUserByID(context.Background(), user.UID) + require.NoError(t, err) - require.NotEmpty(t, newUser.CreatedAt) - require.NotEmpty(t, newUser.UpdatedAt) + require.NotEmpty(t, newUser.CreatedAt) + require.NotEmpty(t, newUser.UpdatedAt) - newUser.CreatedAt = time.Time{} - newUser.UpdatedAt = time.Time{} + newUser.CreatedAt = time.Time{} + newUser.UpdatedAt = time.Time{} + newUser.DeletedAt = null.NewTime(time.Time{}, false) - require.InDelta(t, user.EmailVerificationExpiresAt.Unix(), newUser.EmailVerificationExpiresAt.Unix(), float64(time.Hour)) - require.InDelta(t, user.ResetPasswordExpiresAt.Unix(), newUser.ResetPasswordExpiresAt.Unix(), float64(time.Hour)) + require.InDelta(t, user.EmailVerificationExpiresAt.Unix(), newUser.EmailVerificationExpiresAt.Unix(), float64(time.Hour)) + require.InDelta(t, user.ResetPasswordExpiresAt.Unix(), newUser.ResetPasswordExpiresAt.Unix(), float64(time.Hour)) - user.EmailVerificationExpiresAt, user.ResetPasswordExpiresAt = time.Time{}, time.Time{} - newUser.EmailVerificationExpiresAt, newUser.ResetPasswordExpiresAt = time.Time{}, time.Time{} + user.EmailVerificationExpiresAt, user.ResetPasswordExpiresAt = time.Time{}, time.Time{} + newUser.EmailVerificationExpiresAt, newUser.ResetPasswordExpiresAt = time.Time{}, time.Time{} - require.Equal(t, user, newUser) -} + require.Equal(t, user, newUser) + }) -func Test_FindUserByToken(t *testing.T) { - db, closeFn := getDB(t) - defer closeFn() + t.Run("Test_FindUserByToken", func(t *testing.T) { + db, closeFn := getDB(t) + defer closeFn() - userRepo := NewUserRepo(db) + repo := NewUserRepo(db) - user := generateUser(t) - token := "fd7fidyfhdjhfdjhfjdh" + user := generateUser(t) + token := "fd7fidyfhdjhfdjhfjdh" - user.ResetPasswordToken = token + user.ResetPasswordToken = token - require.NoError(t, userRepo.CreateUser(context.Background(), user)) - newUser, err := userRepo.FindUserByToken(context.Background(), token) - require.NoError(t, err) + require.NoError(t, repo.CreateUser(context.Background(), user)) + newUser, err := repo.FindUserByToken(context.Background(), token) + require.NoError(t, err) - require.NotEmpty(t, newUser.CreatedAt) - require.NotEmpty(t, newUser.UpdatedAt) + require.NotEmpty(t, newUser.CreatedAt) + require.NotEmpty(t, newUser.UpdatedAt) - newUser.CreatedAt = time.Time{} - newUser.UpdatedAt = time.Time{} + newUser.CreatedAt = time.Time{} + newUser.UpdatedAt = time.Time{} + newUser.DeletedAt = null.NewTime(time.Time{}, false) - require.InDelta(t, user.EmailVerificationExpiresAt.Unix(), newUser.EmailVerificationExpiresAt.Unix(), float64(time.Hour)) - require.InDelta(t, user.ResetPasswordExpiresAt.Unix(), newUser.ResetPasswordExpiresAt.Unix(), float64(time.Hour)) + require.InDelta(t, user.EmailVerificationExpiresAt.Unix(), newUser.EmailVerificationExpiresAt.Unix(), float64(time.Hour)) + require.InDelta(t, user.ResetPasswordExpiresAt.Unix(), newUser.ResetPasswordExpiresAt.Unix(), float64(time.Hour)) - user.EmailVerificationExpiresAt, user.ResetPasswordExpiresAt = time.Time{}, time.Time{} - newUser.EmailVerificationExpiresAt, newUser.ResetPasswordExpiresAt = time.Time{}, time.Time{} + user.EmailVerificationExpiresAt, user.ResetPasswordExpiresAt = time.Time{}, time.Time{} + newUser.EmailVerificationExpiresAt, newUser.ResetPasswordExpiresAt = time.Time{}, time.Time{} - require.Equal(t, user, newUser) -} + require.Equal(t, user, newUser) + }) -func Test_FindUserByEmailVerificationToken(t *testing.T) { - db, closeFn := getDB(t) - defer closeFn() + t.Run("Test_FindUserByEmailVerificationToken", func(t *testing.T) { + db, closeFn := getDB(t) + defer closeFn() - userRepo := NewUserRepo(db) + repo := NewUserRepo(db) - user := generateUser(t) - token := "fd7fidyfhdjhfdjhfjdh" + user := generateUser(t) + token := "fd7fidyfhdjhfdjhfjdh" - user.EmailVerificationToken = token + user.EmailVerificationToken = token - require.NoError(t, userRepo.CreateUser(context.Background(), user)) - newUser, err := userRepo.FindUserByEmailVerificationToken(context.Background(), token) - require.NoError(t, err) + require.NoError(t, repo.CreateUser(context.Background(), user)) + newUser, err := repo.FindUserByEmailVerificationToken(context.Background(), token) + require.NoError(t, err) - require.NotEmpty(t, newUser.CreatedAt) - require.NotEmpty(t, newUser.UpdatedAt) + require.NotEmpty(t, newUser.CreatedAt) + require.NotEmpty(t, newUser.UpdatedAt) - newUser.CreatedAt = time.Time{} - newUser.UpdatedAt = time.Time{} + newUser.CreatedAt = time.Time{} + newUser.UpdatedAt = time.Time{} + newUser.DeletedAt = null.NewTime(time.Time{}, false) - require.InDelta(t, user.EmailVerificationExpiresAt.Unix(), newUser.EmailVerificationExpiresAt.Unix(), float64(time.Hour)) - require.InDelta(t, user.ResetPasswordExpiresAt.Unix(), newUser.ResetPasswordExpiresAt.Unix(), float64(time.Hour)) + require.InDelta(t, user.EmailVerificationExpiresAt.Unix(), newUser.EmailVerificationExpiresAt.Unix(), float64(time.Hour)) + require.InDelta(t, user.ResetPasswordExpiresAt.Unix(), newUser.ResetPasswordExpiresAt.Unix(), float64(time.Hour)) - user.EmailVerificationExpiresAt, user.ResetPasswordExpiresAt = time.Time{}, time.Time{} - newUser.EmailVerificationExpiresAt, newUser.ResetPasswordExpiresAt = time.Time{}, time.Time{} + user.EmailVerificationExpiresAt, user.ResetPasswordExpiresAt = time.Time{}, time.Time{} + newUser.EmailVerificationExpiresAt, newUser.ResetPasswordExpiresAt = time.Time{}, time.Time{} - require.Equal(t, user, newUser) -} + require.Equal(t, user, newUser) + }) -func Test_UpdateUser(t *testing.T) { - db, closeFn := getDB(t) - defer closeFn() + t.Run("Test_UpdateUser", func(t *testing.T) { + db, closeFn := getDB(t) + defer closeFn() - userRepo := NewUserRepo(db) - user := generateUser(t) + repo := NewUserRepo(db) + user := generateUser(t) - require.NoError(t, userRepo.CreateUser(context.Background(), user)) + require.NoError(t, repo.CreateUser(context.Background(), user)) - updatedUser := &datastore.User{ - UID: user.UID, - FirstName: fmt.Sprintf("test%s", ulid.Make().String()), - LastName: fmt.Sprintf("test%s", ulid.Make().String()), - Email: fmt.Sprintf("%s@test.com", ulid.Make().String()), - EmailVerified: !user.EmailVerified, - Password: ulid.Make().String(), - ResetPasswordToken: fmt.Sprintf("%s-reset-password-token", ulid.Make().String()), - EmailVerificationToken: fmt.Sprintf("%s-verification-token", ulid.Make().String()), - ResetPasswordExpiresAt: time.Now().Add(time.Hour).UTC(), - EmailVerificationExpiresAt: time.Now().Add(time.Hour).UTC(), - } + updatedUser := &datastore.User{ + UID: user.UID, + FirstName: fmt.Sprintf("test%s", ulid.Make().String()), + LastName: fmt.Sprintf("test%s", ulid.Make().String()), + Email: user.Email, + EmailVerified: !user.EmailVerified, + Password: ulid.Make().String(), + ResetPasswordToken: fmt.Sprintf("%s-reset-password-token", ulid.Make().String()), + EmailVerificationToken: fmt.Sprintf("%s-verification-token", ulid.Make().String()), + ResetPasswordExpiresAt: time.Now().Add(time.Hour).UTC(), + EmailVerificationExpiresAt: time.Now().Add(time.Hour).UTC(), + } - require.NoError(t, userRepo.UpdateUser(context.Background(), updatedUser)) + require.NoError(t, repo.UpdateUser(context.Background(), updatedUser)) - dbUser, err := userRepo.FindUserByID(context.Background(), user.UID) - require.NoError(t, err) + userByID, err := repo.FindUserByID(context.Background(), user.UID) + require.NoError(t, err) - require.Equal(t, dbUser.UID, updatedUser.UID) + require.Equal(t, userByID.UID, updatedUser.UID) - dbUser.CreatedAt = time.Time{} - dbUser.UpdatedAt = time.Time{} + userByID.CreatedAt = time.Time{} + userByID.UpdatedAt = time.Time{} + userByID.DeletedAt = null.NewTime(time.Time{}, false) - require.InDelta(t, user.EmailVerificationExpiresAt.Unix(), dbUser.EmailVerificationExpiresAt.Unix(), float64(time.Hour)) - require.InDelta(t, user.ResetPasswordExpiresAt.Unix(), dbUser.ResetPasswordExpiresAt.Unix(), float64(time.Hour)) + require.InDelta(t, user.EmailVerificationExpiresAt.Unix(), userByID.EmailVerificationExpiresAt.Unix(), float64(time.Hour)) + require.InDelta(t, user.ResetPasswordExpiresAt.Unix(), userByID.ResetPasswordExpiresAt.Unix(), float64(time.Hour)) - updatedUser.EmailVerificationExpiresAt, updatedUser.ResetPasswordExpiresAt = time.Time{}, time.Time{} - dbUser.EmailVerificationExpiresAt, dbUser.ResetPasswordExpiresAt = time.Time{}, time.Time{} + updatedUser.EmailVerificationExpiresAt, updatedUser.ResetPasswordExpiresAt = time.Time{}, time.Time{} + userByID.EmailVerificationExpiresAt, userByID.ResetPasswordExpiresAt = time.Time{}, time.Time{} - require.Equal(t, updatedUser, dbUser) + require.Equal(t, updatedUser, userByID) + }) } func generateUser(t *testing.T) *datastore.User { + t.Helper() return &datastore.User{ UID: ulid.Make().String(), FirstName: "test",