e87b7df979
Update module name and all imports from habit-tracker-api to apocapoc-api. This reflects the project's new branding as part of the apocapoc ecosystem (apocapoc-api, apocapoc-web, apocapoc-android).
245 lines
5.1 KiB
Go
245 lines
5.1 KiB
Go
package sqlite
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"testing"
|
|
"time"
|
|
|
|
"apocapoc-api/internal/domain/entities"
|
|
"apocapoc-api/internal/shared/errors"
|
|
|
|
_ "github.com/mattn/go-sqlite3"
|
|
)
|
|
|
|
func setupTestDB(t *testing.T) *sql.DB {
|
|
db, err := sql.Open("sqlite3", ":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",
|
|
Timezone: "UTC",
|
|
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",
|
|
Timezone: "UTC",
|
|
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",
|
|
Timezone: "UTC",
|
|
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",
|
|
Timezone: "America/New_York",
|
|
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)
|
|
}
|
|
if found.Timezone != user.Timezone {
|
|
t.Errorf("Expected timezone %s, got %s", user.Timezone, found.Timezone)
|
|
}
|
|
}
|
|
|
|
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",
|
|
Timezone: "UTC",
|
|
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",
|
|
Timezone: "UTC",
|
|
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.Timezone = "Europe/Madrid"
|
|
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)
|
|
}
|
|
if found.Timezone != "Europe/Madrid" {
|
|
t.Errorf("Expected timezone Europe/Madrid, got %s", found.Timezone)
|
|
}
|
|
}
|
|
|
|
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",
|
|
Timezone: "UTC",
|
|
CreatedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
}
|
|
|
|
err := repo.Update(ctx, user)
|
|
if err != errors.ErrNotFound {
|
|
t.Errorf("Expected ErrNotFound, got %v", err)
|
|
}
|
|
}
|