Test users and workspaces

This commit is contained in:
2024-11-25 21:58:16 +01:00
parent 32bd202d6f
commit e8868dde39
2 changed files with 843 additions and 0 deletions

View File

@@ -0,0 +1,413 @@
package db_test
import (
"strings"
"testing"
"novamd/internal/db"
"novamd/internal/models"
)
func TestUserOperations(t *testing.T) {
database, err := db.NewTestDB(":memory:", &mockSecrets{})
if err != nil {
t.Fatalf("failed to create test database: %v", err)
}
defer database.Close()
if err := database.Migrate(); err != nil {
t.Fatalf("failed to run migrations: %v", err)
}
t.Run("CreateUser", func(t *testing.T) {
testCases := []struct {
name string
user *models.User
wantErr bool
errContains string
}{
{
name: "valid user",
user: &models.User{
Email: "test@example.com",
DisplayName: "Test User",
PasswordHash: "hashed_password",
Role: models.RoleEditor,
},
wantErr: false,
},
{
name: "duplicate email",
user: &models.User{
Email: "test@example.com", // Same as above
DisplayName: "Another User",
PasswordHash: "different_hash",
Role: models.RoleViewer,
},
wantErr: true,
errContains: "UNIQUE constraint failed",
},
{
name: "invalid role",
user: &models.User{
Email: "invalid@example.com",
DisplayName: "Invalid Role User",
PasswordHash: "hash",
Role: "invalid_role",
},
wantErr: true,
errContains: "CHECK constraint failed",
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
user, err := database.CreateUser(tc.user)
if tc.wantErr {
if err == nil {
t.Error("expected error, got nil")
} else if !strings.Contains(err.Error(), tc.errContains) {
t.Errorf("error = %v, want error containing %v", err, tc.errContains)
}
return
}
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
// Verify user was created properly
if user.ID == 0 {
t.Error("expected non-zero user ID")
}
if user.Email != tc.user.Email {
t.Errorf("Email = %v, want %v", user.Email, tc.user.Email)
}
if user.DisplayName != tc.user.DisplayName {
t.Errorf("DisplayName = %v, want %v", user.DisplayName, tc.user.DisplayName)
}
if user.Role != tc.user.Role {
t.Errorf("Role = %v, want %v", user.Role, tc.user.Role)
}
if user.CreatedAt.IsZero() {
t.Error("CreatedAt should not be zero")
}
if user.LastWorkspaceID == 0 {
t.Error("expected non-zero LastWorkspaceID (default workspace)")
}
})
}
})
t.Run("GetUserByID", func(t *testing.T) {
// Create a test user first
createdUser, err := database.CreateUser(&models.User{
Email: "getbyid@example.com",
DisplayName: "Get By ID User",
PasswordHash: "hash",
Role: models.RoleEditor,
})
if err != nil {
t.Fatalf("failed to create test user: %v", err)
}
testCases := []struct {
name string
userID int
wantErr bool
}{
{
name: "existing user",
userID: createdUser.ID,
wantErr: false,
},
{
name: "non-existent user",
userID: 99999,
wantErr: true,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
user, err := database.GetUserByID(tc.userID)
if tc.wantErr {
if err == nil {
t.Error("expected error, got nil")
}
return
}
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if user.ID != tc.userID {
t.Errorf("ID = %v, want %v", user.ID, tc.userID)
}
})
}
})
t.Run("GetUserByEmail", func(t *testing.T) {
// Create a test user first
createdUser, err := database.CreateUser(&models.User{
Email: "getbyemail@example.com",
DisplayName: "Get By Email User",
PasswordHash: "hash",
Role: models.RoleEditor,
})
if err != nil {
t.Fatalf("failed to create test user: %v", err)
}
testCases := []struct {
name string
email string
wantErr bool
}{
{
name: "existing user",
email: createdUser.Email,
wantErr: false,
},
{
name: "non-existent user",
email: "nonexistent@example.com",
wantErr: true,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
user, err := database.GetUserByEmail(tc.email)
if tc.wantErr {
if err == nil {
t.Error("expected error, got nil")
}
return
}
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if user.Email != tc.email {
t.Errorf("Email = %v, want %v", user.Email, tc.email)
}
})
}
})
t.Run("UpdateUser", func(t *testing.T) {
// Create a test user first
user, err := database.CreateUser(&models.User{
Email: "update@example.com",
DisplayName: "Original Name",
PasswordHash: "original_hash",
Role: models.RoleEditor,
})
if err != nil {
t.Fatalf("failed to create test user: %v", err)
}
// Update user details
user.DisplayName = "Updated Name"
user.PasswordHash = "new_hash"
user.Role = models.RoleAdmin
if err := database.UpdateUser(user); err != nil {
t.Fatalf("failed to update user: %v", err)
}
// Verify updates
updated, err := database.GetUserByID(user.ID)
if err != nil {
t.Fatalf("failed to get updated user: %v", err)
}
if updated.DisplayName != "Updated Name" {
t.Errorf("DisplayName = %v, want %v", updated.DisplayName, "Updated Name")
}
if updated.PasswordHash != "new_hash" {
t.Errorf("PasswordHash = %v, want %v", updated.PasswordHash, "new_hash")
}
if updated.Role != models.RoleAdmin {
t.Errorf("Role = %v, want %v", updated.Role, models.RoleAdmin)
}
})
t.Run("GetAllUsers", func(t *testing.T) {
// Create several test users
testUsers := []*models.User{
{
Email: "user1@example.com",
DisplayName: "User One",
PasswordHash: "hash1",
Role: models.RoleEditor,
},
{
Email: "user2@example.com",
DisplayName: "User Two",
PasswordHash: "hash2",
Role: models.RoleViewer,
},
}
for _, u := range testUsers {
_, err := database.CreateUser(u)
if err != nil {
t.Fatalf("failed to create test user: %v", err)
}
}
// Get all users
users, err := database.GetAllUsers()
if err != nil {
t.Fatalf("failed to get all users: %v", err)
}
// We should have at least as many users as we just created
// (there might be more from previous tests)
if len(users) < len(testUsers) {
t.Errorf("got %d users, want at least %d", len(users), len(testUsers))
}
// Verify each test user exists in the result
for _, expected := range testUsers {
found := false
for _, u := range users {
if u.Email == expected.Email {
found = true
if u.DisplayName != expected.DisplayName {
t.Errorf("DisplayName = %v, want %v", u.DisplayName, expected.DisplayName)
}
if u.Role != expected.Role {
t.Errorf("Role = %v, want %v", u.Role, expected.Role)
}
break
}
}
if !found {
t.Errorf("user with email %s not found in results", expected.Email)
}
}
})
t.Run("UpdateLastWorkspace", func(t *testing.T) {
// Create a test user with multiple workspaces
user, err := database.CreateUser(&models.User{
Email: "workspace@example.com",
DisplayName: "Workspace User",
PasswordHash: "hash",
Role: models.RoleEditor,
})
if err != nil {
t.Fatalf("failed to create test user: %v", err)
}
// Create additional workspace
workspace := &models.Workspace{
UserID: user.ID,
Name: "Second Workspace",
}
if err := database.CreateWorkspace(workspace); err != nil {
t.Fatalf("failed to create additional workspace: %v", err)
}
// Update last workspace
err = database.UpdateLastWorkspace(user.ID, workspace.Name)
if err != nil {
t.Fatalf("failed to update last workspace: %v", err)
}
// Verify update
lastWorkspace, err := database.GetLastWorkspaceName(user.ID)
if err != nil {
t.Fatalf("failed to get last workspace: %v", err)
}
if lastWorkspace != workspace.Name {
t.Errorf("LastWorkspace = %v, want %v", lastWorkspace, workspace.Name)
}
})
t.Run("DeleteUser", func(t *testing.T) {
// Create a test user
user, err := database.CreateUser(&models.User{
Email: "delete@example.com",
DisplayName: "Delete User",
PasswordHash: "hash",
Role: models.RoleEditor,
})
if err != nil {
t.Fatalf("failed to create test user: %v", err)
}
// Delete the user
if err := database.DeleteUser(user.ID); err != nil {
t.Fatalf("failed to delete user: %v", err)
}
// Verify user is gone
_, err = database.GetUserByID(user.ID)
if err == nil {
t.Error("expected error getting deleted user, got nil")
}
// Verify workspaces are gone
workspaces, err := database.GetWorkspacesByUserID(user.ID)
if err != nil {
t.Fatalf("unexpected error checking workspaces: %v", err)
}
if len(workspaces) > 0 {
t.Error("expected no workspaces for deleted user")
}
})
t.Run("CountAdminUsers", func(t *testing.T) {
// Create users with different roles
testUsers := []*models.User{
{
Email: "admin1@example.com",
DisplayName: "Admin One",
PasswordHash: "hash1",
Role: models.RoleAdmin,
},
{
Email: "admin2@example.com",
DisplayName: "Admin Two",
PasswordHash: "hash2",
Role: models.RoleAdmin,
},
{
Email: "editor@example.com",
DisplayName: "Editor",
PasswordHash: "hash3",
Role: models.RoleEditor,
},
}
for _, u := range testUsers {
_, err := database.CreateUser(u)
if err != nil {
t.Fatalf("failed to create test user: %v", err)
}
}
// Count admin users
count, err := database.CountAdminUsers()
if err != nil {
t.Fatalf("failed to count admin users: %v", err)
}
// We should have at least 2 admin users (from our test cases)
// There might be more from previous tests
if count < 2 {
t.Errorf("AdminCount = %d, want at least 2", count)
}
})
}