package service_test import ( "context" "log/slog" "testing" "gitea.michaelthomson.dev/mthomson/habits/internal/test" "gitea.michaelthomson.dev/mthomson/habits/internal/user/repository" "gitea.michaelthomson.dev/mthomson/habits/internal/user/service" "github.com/gofrs/uuid/v5" ) func TestCreateUser(t *testing.T) { t.Parallel() ctx := context.Background() logger := slog.Default() tdb := test.NewTestDatabase(t) defer tdb.TearDown() r := repository.NewUserRepository(logger, tdb.Db) userService := service.NewUserService(logger, r) t.Run("Create user", func(t *testing.T) { uuid := NewUUID(t) user := service.NewUser(uuid, "test@test.com", "supersecurehash") _, err := userService.CreateUser(ctx, user) AssertNoError(t, err) }) } func TestGetUser(t *testing.T) { t.Parallel() ctx := context.Background() logger := slog.Default() tdb := test.NewTestDatabase(t) defer tdb.TearDown() r := repository.NewUserRepository(logger, tdb.Db) uuid := NewUUID(t) row := repository.UserRow{Id: uuid, Email: "test@test.com", HashedPassword: "supersecurehash"} _, err := r.Create(ctx, row) AssertNoError(t, err); userService := service.NewUserService(logger, r) t.Run("Get exisiting user", func(t *testing.T) { _, err := userService.GetUser(ctx, uuid) AssertNoError(t, err) }) t.Run("Get non-existant user", func(t *testing.T) { _, err := userService.GetUser(ctx, NewUUID(t)) AssertErrors(t, err, service.ErrNotFound) }) } func TestDeleteUser(t *testing.T) { t.Parallel() ctx := context.Background() logger := slog.Default() tdb := test.NewTestDatabase(t) defer tdb.TearDown() r := repository.NewUserRepository(logger, tdb.Db) uuid := NewUUID(t) row := repository.UserRow{Id: uuid, Email: "test@test.com", HashedPassword: "supersecurehash"} _, err := r.Create(ctx, row) AssertNoError(t, err); userService := service.NewUserService(logger, r) t.Run("Delete exisiting user", func(t *testing.T) { err := userService.DeleteUser(ctx, uuid) AssertNoError(t, err) }) t.Run("Delete non-existant user", func(t *testing.T) { err := userService.DeleteUser(ctx, uuid) AssertErrors(t, err, service.ErrNotFound) }) } func TestUpdateUser(t *testing.T) { t.Parallel() ctx := context.Background() logger := slog.Default() tdb := test.NewTestDatabase(t) defer tdb.TearDown() r := repository.NewUserRepository(logger, tdb.Db) uuid := NewUUID(t) row := repository.UserRow{Id: uuid, Email: "test@test.com", HashedPassword: "supersecurehash"} _, err := r.Create(ctx, row) AssertNoError(t, err); userService := service.NewUserService(logger, r) t.Run("Update exisiting user", func(t *testing.T) { user := service.User{uuid, "new@email.com", "supersecurehash"} err := userService.UpdateUser(ctx, user) AssertNoError(t, err) newUser, err := userService.GetUser(ctx, uuid) AssertNoError(t, err) AssertUsers(t, newUser, user) }) t.Run("Update non-existant user", func(t *testing.T) { user := service.User{NewUUID(t), "new@email.com", "supersecurehash"} err := userService.UpdateUser(ctx, user) AssertErrors(t, err, service.ErrNotFound) }) } func AssertErrors(t testing.TB, got, want error) { t.Helper() if got != want { t.Errorf("got error: %v, want error: %v", want, got) } } func AssertNoError(t testing.TB, err error) { t.Helper() if err != nil { t.Errorf("expected no error, got %v", err) } } func AssertUsers(t testing.TB, got, want service.User) { if !got.Equal(want) { t.Errorf("got %+v want %+v", got, want) } } func NewUUID(t testing.TB) uuid.UUID { t.Helper() uuid, err := uuid.NewV4() if err != nil { t.Errorf("error generation uuid: %v", err) } return uuid }