Features: - PDF service for generating task reports with ReportLab-style formatting - Storage service for file uploads (local and S3-compatible) - Admin authentication middleware with JWT support - Admin user model and repository Infrastructure: - Updated Docker configuration for admin panel builds - Email service enhancements for task notifications - Updated router with admin and file upload routes - Environment configuration updates Tests: - Unit tests for handlers (auth, residence, task) - Unit tests for models (user, residence, task) - Unit tests for repositories (user, residence, task) - Unit tests for services (residence, task) - Integration test setup - Test utilities for mocking database and services Database: - Admin user seed data - Updated test data seeds 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
316 lines
9.3 KiB
Go
316 lines
9.3 KiB
Go
package repositories
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/treytartt/mycrib-api/internal/models"
|
|
"github.com/treytartt/mycrib-api/internal/testutil"
|
|
)
|
|
|
|
func TestTaskRepository_Create(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
repo := NewTaskRepository(db)
|
|
|
|
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "password")
|
|
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
|
|
|
task := &models.Task{
|
|
ResidenceID: residence.ID,
|
|
CreatedByID: user.ID,
|
|
Title: "Fix leaky faucet",
|
|
Description: "Kitchen faucet is dripping",
|
|
}
|
|
|
|
err := repo.Create(task)
|
|
require.NoError(t, err)
|
|
assert.NotZero(t, task.ID)
|
|
}
|
|
|
|
func TestTaskRepository_FindByID(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
repo := NewTaskRepository(db)
|
|
|
|
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "password")
|
|
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
|
task := testutil.CreateTestTask(t, db, residence.ID, user.ID, "Test Task")
|
|
|
|
found, err := repo.FindByID(task.ID)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, task.ID, found.ID)
|
|
assert.Equal(t, "Test Task", found.Title)
|
|
}
|
|
|
|
func TestTaskRepository_FindByID_NotFound(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
repo := NewTaskRepository(db)
|
|
|
|
_, err := repo.FindByID(9999)
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
func TestTaskRepository_FindByResidence(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
repo := NewTaskRepository(db)
|
|
|
|
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "password")
|
|
residence1 := testutil.CreateTestResidence(t, db, user.ID, "House 1")
|
|
residence2 := testutil.CreateTestResidence(t, db, user.ID, "House 2")
|
|
|
|
testutil.CreateTestTask(t, db, residence1.ID, user.ID, "Task 1")
|
|
testutil.CreateTestTask(t, db, residence1.ID, user.ID, "Task 2")
|
|
testutil.CreateTestTask(t, db, residence2.ID, user.ID, "Task 3")
|
|
|
|
tasks, err := repo.FindByResidence(residence1.ID)
|
|
require.NoError(t, err)
|
|
assert.Len(t, tasks, 2)
|
|
}
|
|
|
|
func TestTaskRepository_Update(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
repo := NewTaskRepository(db)
|
|
|
|
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "password")
|
|
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
|
task := testutil.CreateTestTask(t, db, residence.ID, user.ID, "Original Title")
|
|
|
|
task.Title = "Updated Title"
|
|
task.Description = "Updated description"
|
|
err := repo.Update(task)
|
|
require.NoError(t, err)
|
|
|
|
found, err := repo.FindByID(task.ID)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "Updated Title", found.Title)
|
|
assert.Equal(t, "Updated description", found.Description)
|
|
}
|
|
|
|
func TestTaskRepository_Delete(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
repo := NewTaskRepository(db)
|
|
|
|
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "password")
|
|
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
|
task := testutil.CreateTestTask(t, db, residence.ID, user.ID, "Test Task")
|
|
|
|
err := repo.Delete(task.ID)
|
|
require.NoError(t, err)
|
|
|
|
_, err = repo.FindByID(task.ID)
|
|
assert.Error(t, err) // Should not be found
|
|
}
|
|
|
|
func TestTaskRepository_Cancel(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
repo := NewTaskRepository(db)
|
|
|
|
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "password")
|
|
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
|
task := testutil.CreateTestTask(t, db, residence.ID, user.ID, "Test Task")
|
|
|
|
assert.False(t, task.IsCancelled)
|
|
|
|
err := repo.Cancel(task.ID)
|
|
require.NoError(t, err)
|
|
|
|
found, err := repo.FindByID(task.ID)
|
|
require.NoError(t, err)
|
|
assert.True(t, found.IsCancelled)
|
|
}
|
|
|
|
func TestTaskRepository_Uncancel(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
repo := NewTaskRepository(db)
|
|
|
|
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "password")
|
|
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
|
task := testutil.CreateTestTask(t, db, residence.ID, user.ID, "Test Task")
|
|
|
|
repo.Cancel(task.ID)
|
|
err := repo.Uncancel(task.ID)
|
|
require.NoError(t, err)
|
|
|
|
found, err := repo.FindByID(task.ID)
|
|
require.NoError(t, err)
|
|
assert.False(t, found.IsCancelled)
|
|
}
|
|
|
|
func TestTaskRepository_Archive(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
repo := NewTaskRepository(db)
|
|
|
|
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "password")
|
|
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
|
task := testutil.CreateTestTask(t, db, residence.ID, user.ID, "Test Task")
|
|
|
|
err := repo.Archive(task.ID)
|
|
require.NoError(t, err)
|
|
|
|
found, err := repo.FindByID(task.ID)
|
|
require.NoError(t, err)
|
|
assert.True(t, found.IsArchived)
|
|
}
|
|
|
|
func TestTaskRepository_Unarchive(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
repo := NewTaskRepository(db)
|
|
|
|
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "password")
|
|
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
|
task := testutil.CreateTestTask(t, db, residence.ID, user.ID, "Test Task")
|
|
|
|
repo.Archive(task.ID)
|
|
err := repo.Unarchive(task.ID)
|
|
require.NoError(t, err)
|
|
|
|
found, err := repo.FindByID(task.ID)
|
|
require.NoError(t, err)
|
|
assert.False(t, found.IsArchived)
|
|
}
|
|
|
|
func TestTaskRepository_CreateCompletion(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
repo := NewTaskRepository(db)
|
|
|
|
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "password")
|
|
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
|
task := testutil.CreateTestTask(t, db, residence.ID, user.ID, "Test Task")
|
|
|
|
completion := &models.TaskCompletion{
|
|
TaskID: task.ID,
|
|
CompletedByID: user.ID,
|
|
CompletedAt: time.Now().UTC(),
|
|
Notes: "Completed successfully",
|
|
}
|
|
|
|
err := repo.CreateCompletion(completion)
|
|
require.NoError(t, err)
|
|
assert.NotZero(t, completion.ID)
|
|
}
|
|
|
|
func TestTaskRepository_FindCompletionByID(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
repo := NewTaskRepository(db)
|
|
|
|
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "password")
|
|
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
|
task := testutil.CreateTestTask(t, db, residence.ID, user.ID, "Test Task")
|
|
|
|
completion := &models.TaskCompletion{
|
|
TaskID: task.ID,
|
|
CompletedByID: user.ID,
|
|
CompletedAt: time.Now().UTC(),
|
|
Notes: "Test notes",
|
|
}
|
|
db.Create(completion)
|
|
|
|
found, err := repo.FindCompletionByID(completion.ID)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, completion.ID, found.ID)
|
|
assert.Equal(t, "Test notes", found.Notes)
|
|
}
|
|
|
|
func TestTaskRepository_FindCompletionsByTask(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
repo := NewTaskRepository(db)
|
|
|
|
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "password")
|
|
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
|
task := testutil.CreateTestTask(t, db, residence.ID, user.ID, "Test Task")
|
|
|
|
// Create multiple completions
|
|
for i := 0; i < 3; i++ {
|
|
db.Create(&models.TaskCompletion{
|
|
TaskID: task.ID,
|
|
CompletedByID: user.ID,
|
|
CompletedAt: time.Now().UTC(),
|
|
})
|
|
}
|
|
|
|
completions, err := repo.FindCompletionsByTask(task.ID)
|
|
require.NoError(t, err)
|
|
assert.Len(t, completions, 3)
|
|
}
|
|
|
|
func TestTaskRepository_DeleteCompletion(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
repo := NewTaskRepository(db)
|
|
|
|
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "password")
|
|
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
|
task := testutil.CreateTestTask(t, db, residence.ID, user.ID, "Test Task")
|
|
|
|
completion := &models.TaskCompletion{
|
|
TaskID: task.ID,
|
|
CompletedByID: user.ID,
|
|
CompletedAt: time.Now().UTC(),
|
|
}
|
|
db.Create(completion)
|
|
|
|
err := repo.DeleteCompletion(completion.ID)
|
|
require.NoError(t, err)
|
|
|
|
_, err = repo.FindCompletionByID(completion.ID)
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
func TestTaskRepository_GetAllCategories(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
repo := NewTaskRepository(db)
|
|
testutil.SeedLookupData(t, db)
|
|
|
|
categories, err := repo.GetAllCategories()
|
|
require.NoError(t, err)
|
|
assert.Greater(t, len(categories), 0)
|
|
}
|
|
|
|
func TestTaskRepository_GetAllPriorities(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
repo := NewTaskRepository(db)
|
|
testutil.SeedLookupData(t, db)
|
|
|
|
priorities, err := repo.GetAllPriorities()
|
|
require.NoError(t, err)
|
|
assert.Greater(t, len(priorities), 0)
|
|
}
|
|
|
|
func TestTaskRepository_GetAllStatuses(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
repo := NewTaskRepository(db)
|
|
testutil.SeedLookupData(t, db)
|
|
|
|
statuses, err := repo.GetAllStatuses()
|
|
require.NoError(t, err)
|
|
assert.Greater(t, len(statuses), 0)
|
|
}
|
|
|
|
func TestTaskRepository_GetAllFrequencies(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
repo := NewTaskRepository(db)
|
|
testutil.SeedLookupData(t, db)
|
|
|
|
frequencies, err := repo.GetAllFrequencies()
|
|
require.NoError(t, err)
|
|
assert.Greater(t, len(frequencies), 0)
|
|
}
|
|
|
|
func TestTaskRepository_CountByResidence(t *testing.T) {
|
|
db := testutil.SetupTestDB(t)
|
|
repo := NewTaskRepository(db)
|
|
|
|
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "password")
|
|
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
|
|
|
testutil.CreateTestTask(t, db, residence.ID, user.ID, "Task 1")
|
|
testutil.CreateTestTask(t, db, residence.ID, user.ID, "Task 2")
|
|
testutil.CreateTestTask(t, db, residence.ID, user.ID, "Task 3")
|
|
|
|
count, err := repo.CountByResidence(residence.ID)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int64(3), count)
|
|
}
|
|
|