package storage import ( "context" "os" "testing" "time" ) func setupTestDB(t *testing.T) *DynamoDBClient { ctx := context.Background() endpoint := os.Getenv("DYNAMODB_ENDPOINT") if endpoint == "" { endpoint = "http://localhost:8000" } db, err := NewDynamoDBClient(ctx, endpoint) if err != nil { t.Fatalf("Failed to create DynamoDB client: %v", err) } // Create Users table if err := db.CreateUsersTable(ctx); err != nil { t.Fatalf("Failed to create Users table: %v", err) } return db } func TestCreateUser(t *testing.T) { db := setupTestDB(t) storage := NewUserStorage(db) ctx := context.Background() user, err := storage.CreateUser(ctx, "test@example.com", "google", "google123") if err != nil { t.Fatalf("Failed to create user: %v", err) } if user.ID == "" { t.Error("User ID should not be empty") } if user.Email != "test@example.com" { t.Errorf("Expected email 'test@example.com', got '%s'", user.Email) } if user.OAuthProvider != "google" { t.Errorf("Expected oauth_provider 'google', got '%s'", user.OAuthProvider) } if user.OAuthID != "google123" { t.Errorf("Expected oauth_id 'google123', got '%s'", user.OAuthID) } if user.CreatedAt.IsZero() { t.Error("CreatedAt should not be zero") } if user.UpdatedAt.IsZero() { t.Error("UpdatedAt should not be zero") } } func TestGetUserByID(t *testing.T) { db := setupTestDB(t) storage := NewUserStorage(db) ctx := context.Background() // Create a user first createdUser, err := storage.CreateUser(ctx, "test@example.com", "google", "google123") if err != nil { t.Fatalf("Failed to create user: %v", err) } // Retrieve the user retrievedUser, err := storage.GetUserByID(ctx, createdUser.ID) if err != nil { t.Fatalf("Failed to get user: %v", err) } if retrievedUser.ID != createdUser.ID { t.Errorf("Expected ID '%s', got '%s'", createdUser.ID, retrievedUser.ID) } if retrievedUser.Email != createdUser.Email { t.Errorf("Expected email '%s', got '%s'", createdUser.Email, retrievedUser.Email) } } func TestGetUserByID_NotFound(t *testing.T) { db := setupTestDB(t) storage := NewUserStorage(db) ctx := context.Background() _, err := storage.GetUserByID(ctx, "nonexistent-id") if err == nil { t.Error("Expected error when getting nonexistent user") } } func TestGetUserByOAuth(t *testing.T) { db := setupTestDB(t) storage := NewUserStorage(db) ctx := context.Background() // Create a user first createdUser, err := storage.CreateUser(ctx, "test@example.com", "google", "google123") if err != nil { t.Fatalf("Failed to create user: %v", err) } // Retrieve the user by OAuth retrievedUser, err := storage.GetUserByOAuth(ctx, "google", "google123") if err != nil { t.Fatalf("Failed to get user by OAuth: %v", err) } if retrievedUser.ID != createdUser.ID { t.Errorf("Expected ID '%s', got '%s'", createdUser.ID, retrievedUser.ID) } if retrievedUser.Email != createdUser.Email { t.Errorf("Expected email '%s', got '%s'", createdUser.Email, retrievedUser.Email) } } func TestGetUserByOAuth_NotFound(t *testing.T) { db := setupTestDB(t) storage := NewUserStorage(db) ctx := context.Background() _, err := storage.GetUserByOAuth(ctx, "google", "nonexistent") if err == nil { t.Error("Expected error when getting nonexistent user") } } func TestUpdateUser(t *testing.T) { db := setupTestDB(t) storage := NewUserStorage(db) ctx := context.Background() // Create a user first user, err := storage.CreateUser(ctx, "test@example.com", "google", "google123") if err != nil { t.Fatalf("Failed to create user: %v", err) } originalUpdatedAt := user.UpdatedAt time.Sleep(10 * time.Millisecond) // Ensure time difference // Update the user user.Email = "updated@example.com" err = storage.UpdateUser(ctx, user) if err != nil { t.Fatalf("Failed to update user: %v", err) } // Retrieve and verify updatedUser, err := storage.GetUserByID(ctx, user.ID) if err != nil { t.Fatalf("Failed to get updated user: %v", err) } if updatedUser.Email != "updated@example.com" { t.Errorf("Expected email 'updated@example.com', got '%s'", updatedUser.Email) } if !updatedUser.UpdatedAt.After(originalUpdatedAt) { t.Error("UpdatedAt should be updated") } } func TestDeleteUser(t *testing.T) { db := setupTestDB(t) storage := NewUserStorage(db) ctx := context.Background() // Create a user first user, err := storage.CreateUser(ctx, "test@example.com", "google", "google123") if err != nil { t.Fatalf("Failed to create user: %v", err) } // Delete the user err = storage.DeleteUser(ctx, user.ID) if err != nil { t.Fatalf("Failed to delete user: %v", err) } // Verify deletion _, err = storage.GetUserByID(ctx, user.ID) if err == nil { t.Error("Expected error when getting deleted user") } } func TestCreateUser_MultipleUsers(t *testing.T) { db := setupTestDB(t) storage := NewUserStorage(db) ctx := context.Background() // Create multiple users user1, err := storage.CreateUser(ctx, "user1@example.com", "google", "google1") if err != nil { t.Fatalf("Failed to create user1: %v", err) } user2, err := storage.CreateUser(ctx, "user2@example.com", "github", "github1") if err != nil { t.Fatalf("Failed to create user2: %v", err) } // Verify both users exist and are different if user1.ID == user2.ID { t.Error("User IDs should be unique") } retrievedUser1, err := storage.GetUserByID(ctx, user1.ID) if err != nil { t.Fatalf("Failed to get user1: %v", err) } retrievedUser2, err := storage.GetUserByID(ctx, user2.ID) if err != nil { t.Fatalf("Failed to get user2: %v", err) } if retrievedUser1.Email != "user1@example.com" { t.Errorf("Expected user1 email 'user1@example.com', got '%s'", retrievedUser1.Email) } if retrievedUser2.Email != "user2@example.com" { t.Errorf("Expected user2 email 'user2@example.com', got '%s'", retrievedUser2.Email) } }