package sqlite import ( "context" "database/sql" "testing" "time" "apocapoc-api/internal/domain/entities" "apocapoc-api/internal/shared/errors" _ "modernc.org/sqlite" ) func setupTestDB(t *testing.T) *sql.DB { db, err := sql.Open("sqlite", ":memory:") if err != nil { t.Fatalf("Failed to open test database: %v", err) } if err := RunMigrations(db); err != nil { t.Fatalf("Failed to run migrations: %v", err) } return db } func TestUserRepositoryCreate(t *testing.T) { db := setupTestDB(t) defer db.Close() repo := NewUserRepository(db) ctx := context.Background() user := &entities.User{ Email: "test@example.com", PasswordHash: "hashed_password", CreatedAt: time.Now(), UpdatedAt: time.Now(), } err := repo.Create(ctx, user) if err != nil { t.Fatalf("Create failed: %v", err) } if user.ID == "" { t.Error("Expected user ID to be generated, got empty string") } } func TestUserRepositoryCreateDuplicateEmail(t *testing.T) { db := setupTestDB(t) defer db.Close() repo := NewUserRepository(db) ctx := context.Background() user1 := &entities.User{ Email: "duplicate@example.com", PasswordHash: "hash1", CreatedAt: time.Now(), UpdatedAt: time.Now(), } err := repo.Create(ctx, user1) if err != nil { t.Fatalf("First create failed: %v", err) } user2 := &entities.User{ Email: "duplicate@example.com", PasswordHash: "hash2", CreatedAt: time.Now(), UpdatedAt: time.Now(), } err = repo.Create(ctx, user2) if err != errors.ErrAlreadyExists { t.Errorf("Expected ErrAlreadyExists, got %v", err) } } func TestUserRepositoryFindByID(t *testing.T) { db := setupTestDB(t) defer db.Close() repo := NewUserRepository(db) ctx := context.Background() user := &entities.User{ Email: "find@example.com", PasswordHash: "hashed", CreatedAt: time.Now(), UpdatedAt: time.Now(), } err := repo.Create(ctx, user) if err != nil { t.Fatalf("Create failed: %v", err) } found, err := repo.FindByID(ctx, user.ID) if err != nil { t.Fatalf("FindByID failed: %v", err) } if found.ID != user.ID { t.Errorf("Expected ID %s, got %s", user.ID, found.ID) } if found.Email != user.Email { t.Errorf("Expected email %s, got %s", user.Email, found.Email) } } func TestUserRepositoryFindByIDNotFound(t *testing.T) { db := setupTestDB(t) defer db.Close() repo := NewUserRepository(db) ctx := context.Background() _, err := repo.FindByID(ctx, "non-existent-id") if err != errors.ErrNotFound { t.Errorf("Expected ErrNotFound, got %v", err) } } func TestUserRepositoryFindByEmail(t *testing.T) { db := setupTestDB(t) defer db.Close() repo := NewUserRepository(db) ctx := context.Background() user := &entities.User{ Email: "email@test.com", PasswordHash: "hashed", CreatedAt: time.Now(), UpdatedAt: time.Now(), } err := repo.Create(ctx, user) if err != nil { t.Fatalf("Create failed: %v", err) } found, err := repo.FindByEmail(ctx, user.Email) if err != nil { t.Fatalf("FindByEmail failed: %v", err) } if found.ID != user.ID { t.Errorf("Expected ID %s, got %s", user.ID, found.ID) } if found.Email != user.Email { t.Errorf("Expected email %s, got %s", user.Email, found.Email) } } func TestUserRepositoryFindByEmailNotFound(t *testing.T) { db := setupTestDB(t) defer db.Close() repo := NewUserRepository(db) ctx := context.Background() _, err := repo.FindByEmail(ctx, "nonexistent@example.com") if err != errors.ErrNotFound { t.Errorf("Expected ErrNotFound, got %v", err) } } func TestUserRepositoryUpdate(t *testing.T) { db := setupTestDB(t) defer db.Close() repo := NewUserRepository(db) ctx := context.Background() user := &entities.User{ Email: "original@example.com", PasswordHash: "hash1", CreatedAt: time.Now(), UpdatedAt: time.Now(), } err := repo.Create(ctx, user) if err != nil { t.Fatalf("Create failed: %v", err) } user.Email = "updated@example.com" user.UpdatedAt = time.Now() err = repo.Update(ctx, user) if err != nil { t.Fatalf("Update failed: %v", err) } found, err := repo.FindByID(ctx, user.ID) if err != nil { t.Fatalf("FindByID failed: %v", err) } if found.Email != "updated@example.com" { t.Errorf("Expected email updated@example.com, got %s", found.Email) } } func TestUserRepositoryUpdateNotFound(t *testing.T) { db := setupTestDB(t) defer db.Close() repo := NewUserRepository(db) ctx := context.Background() user := &entities.User{ ID: "non-existent", Email: "test@example.com", PasswordHash: "hash", CreatedAt: time.Now(), UpdatedAt: time.Now(), } err := repo.Update(ctx, user) if err != errors.ErrNotFound { t.Errorf("Expected ErrNotFound, got %v", err) } }