init push
This commit is contained in:
205
internal/repository/mysql/user_repo_test.go
Normal file
205
internal/repository/mysql/user_repo_test.go
Normal file
@@ -0,0 +1,205 @@
|
||||
package mysql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"wucher/internal/domain/auth"
|
||||
"wucher/internal/domain/user"
|
||||
"wucher/internal/shared/pkg/appctx"
|
||||
"wucher/internal/shared/pkg/uuidv7"
|
||||
)
|
||||
|
||||
func setupUserRepoFixture(t *testing.T) (*UserRepository, context.Context, []byte) {
|
||||
t.Helper()
|
||||
db := openDBTestSQLite(t)
|
||||
if err := AutoMigrate(db); err != nil {
|
||||
t.Fatalf("auto migrate: %v", err)
|
||||
}
|
||||
repo := NewUserRepository(db)
|
||||
roleID := uuidv7.MustBytes()
|
||||
if err := db.Create(&auth.Role{
|
||||
ID: roleID,
|
||||
Code: "admin",
|
||||
Name: "admin",
|
||||
Description: "admin role",
|
||||
}).Error; err != nil {
|
||||
t.Fatalf("seed role: %v", err)
|
||||
}
|
||||
return repo, context.Background(), roleID
|
||||
}
|
||||
|
||||
func TestUserRepository_CRUDAndLookupBranches(t *testing.T) {
|
||||
repo, baseCtx, roleID := setupUserRepoFixture(t)
|
||||
actorID := uuidv7.MustBytes()
|
||||
ctx := appctx.WithUserID(baseCtx, actorID)
|
||||
|
||||
u := &user.User{
|
||||
Email: "john@example.com",
|
||||
Username: "john",
|
||||
FirstName: "John",
|
||||
LastName: "Doe",
|
||||
Timezone: "UTC",
|
||||
RoleID: roleID,
|
||||
}
|
||||
if err := repo.Create(ctx, u); err != nil {
|
||||
t.Fatalf("create: %v", err)
|
||||
}
|
||||
if len(u.CreatedBy) != 16 || len(u.UpdatedBy) != 16 {
|
||||
t.Fatalf("expected created_by and updated_by set by actor")
|
||||
}
|
||||
|
||||
byEmail, err := repo.GetByEmail(ctx, u.Email)
|
||||
if err != nil || byEmail == nil {
|
||||
t.Fatalf("get by email failed: user=%v err=%v", byEmail, err)
|
||||
}
|
||||
byUsername, err := repo.GetByUsername(ctx, u.Username)
|
||||
if err != nil || byUsername == nil {
|
||||
t.Fatalf("get by username failed: user=%v err=%v", byUsername, err)
|
||||
}
|
||||
lastName, err := repo.GetLastNameByID(ctx, u.ID)
|
||||
if err != nil || lastName != "Doe" {
|
||||
t.Fatalf("get last name failed: lastName=%q err=%v", lastName, err)
|
||||
}
|
||||
|
||||
// Update branch: RoleIDs nil should skip role-replacement path.
|
||||
byEmail.FirstName = "Johnny"
|
||||
byEmail.RoleIDs = nil
|
||||
if err := repo.Update(ctx, byEmail); err != nil {
|
||||
t.Fatalf("update (roleIDs nil): %v", err)
|
||||
}
|
||||
|
||||
// Update branch: RoleIDs provided should execute role-replacement path.
|
||||
byEmail.LastName = "Doe-Updated"
|
||||
byEmail.RoleIDs = [][]byte{roleID}
|
||||
if err := repo.Update(ctx, byEmail); err != nil {
|
||||
t.Fatalf("update (roleIDs set): %v", err)
|
||||
}
|
||||
|
||||
// List branches: with/without filter, sort, and limit.
|
||||
list, total, err := repo.List(ctx, "john", "users.email ASC", 1, 0)
|
||||
if err != nil {
|
||||
t.Fatalf("list with filter: %v", err)
|
||||
}
|
||||
if total < 1 || len(list) != 1 {
|
||||
t.Fatalf("expected one filtered result, total=%d len=%d", total, len(list))
|
||||
}
|
||||
list, total, err = repo.List(ctx, "", "", 0, 0)
|
||||
if err != nil {
|
||||
t.Fatalf("list without limit: %v", err)
|
||||
}
|
||||
if total < 1 || len(list) < 1 {
|
||||
t.Fatalf("expected at least one user, total=%d len=%d", total, len(list))
|
||||
}
|
||||
|
||||
// Not found branches.
|
||||
if got, err := repo.GetByID(ctx, uuidv7.MustBytes()); err != nil || got != nil {
|
||||
t.Fatalf("expected not found by id => nil,nil; got=%v err=%v", got, err)
|
||||
}
|
||||
if got, err := repo.GetByEmail(ctx, "missing@example.com"); err != nil || got != nil {
|
||||
t.Fatalf("expected not found by email => nil,nil; got=%v err=%v", got, err)
|
||||
}
|
||||
if got, err := repo.GetByUsername(ctx, "missing-user"); err != nil || got != nil {
|
||||
t.Fatalf("expected not found by username => nil,nil; got=%v err=%v", got, err)
|
||||
}
|
||||
if got, err := repo.GetLastNameByID(ctx, uuidv7.MustBytes()); err != nil || got != "" {
|
||||
t.Fatalf("expected not found last_name => empty,nil; got=%q err=%v", got, err)
|
||||
}
|
||||
|
||||
if err := repo.Delete(ctx, u.ID); err != nil {
|
||||
t.Fatalf("delete: %v", err)
|
||||
}
|
||||
// Delete branch with invalid uuid bytes (skip attachment cleanup query branch).
|
||||
if err := repo.Delete(ctx, []byte("short")); err != nil {
|
||||
t.Fatalf("delete short id should be noop-success, err=%v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUserRepository_ErrorBranchesWhenDatabaseClosed(t *testing.T) {
|
||||
db := openDBTestSQLite(t)
|
||||
if err := AutoMigrate(db); err != nil {
|
||||
t.Fatalf("auto migrate: %v", err)
|
||||
}
|
||||
repo := NewUserRepository(db)
|
||||
sqlDB, err := db.DB()
|
||||
if err != nil {
|
||||
t.Fatalf("db.DB: %v", err)
|
||||
}
|
||||
if err := sqlDB.Close(); err != nil {
|
||||
t.Fatalf("close db: %v", err)
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
roleID := uuidv7.MustBytes()
|
||||
userID := uuidv7.MustBytes()
|
||||
u := &user.User{
|
||||
ID: userID,
|
||||
Email: "closed@example.com",
|
||||
Username: "closed",
|
||||
FirstName: "Closed",
|
||||
LastName: "DB",
|
||||
Timezone: "UTC",
|
||||
RoleID: roleID,
|
||||
}
|
||||
|
||||
if err := repo.Create(ctx, u); err == nil {
|
||||
t.Fatalf("expected create error on closed db")
|
||||
}
|
||||
if err := repo.Update(ctx, u); err == nil {
|
||||
t.Fatalf("expected update error on closed db")
|
||||
}
|
||||
if err := repo.Delete(ctx, userID); err == nil {
|
||||
t.Fatalf("expected delete error on closed db")
|
||||
}
|
||||
if _, err := repo.GetByID(ctx, userID); err == nil {
|
||||
t.Fatalf("expected get by id error on closed db")
|
||||
}
|
||||
if _, err := repo.GetByEmail(ctx, u.Email); err == nil {
|
||||
t.Fatalf("expected get by email error on closed db")
|
||||
}
|
||||
if _, err := repo.GetByUsername(ctx, u.Username); err == nil {
|
||||
t.Fatalf("expected get by username error on closed db")
|
||||
}
|
||||
if _, err := repo.GetLastNameByID(ctx, userID); err == nil {
|
||||
t.Fatalf("expected get last name error on closed db")
|
||||
}
|
||||
if _, _, err := repo.List(ctx, "", "", 10, 0); err == nil {
|
||||
t.Fatalf("expected list error on closed db")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUserRepository_CreateDuplicateAndDeleteAttachmentCleanupError(t *testing.T) {
|
||||
repo, ctx, roleID := setupUserRepoFixture(t)
|
||||
|
||||
u := &user.User{
|
||||
Email: "dup@example.com",
|
||||
Username: "dup-user",
|
||||
FirstName: "Dup",
|
||||
LastName: "User",
|
||||
Timezone: "UTC",
|
||||
RoleID: roleID,
|
||||
}
|
||||
if err := repo.Create(ctx, u); err != nil {
|
||||
t.Fatalf("create first user: %v", err)
|
||||
}
|
||||
|
||||
dup := &user.User{
|
||||
Email: "dup@example.com",
|
||||
Username: "dup-user-2",
|
||||
FirstName: "Dup2",
|
||||
LastName: "User2",
|
||||
Timezone: "UTC",
|
||||
RoleID: roleID,
|
||||
}
|
||||
if err := repo.Create(ctx, dup); err == nil {
|
||||
t.Fatalf("expected duplicate-email create error")
|
||||
}
|
||||
|
||||
// Force attachment cleanup statement to fail so delete returns error branch.
|
||||
if err := repo.db.Exec("DROP TABLE attachments").Error; err != nil {
|
||||
t.Fatalf("drop attachments table: %v", err)
|
||||
}
|
||||
if err := repo.Delete(ctx, u.ID); err == nil {
|
||||
t.Fatalf("expected delete error when attachments table missing")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user