Files
honeyDueAPI/internal/repositories/task_template_repo_test.go
Trey T bec880886b Coverage priorities 1-5: test pure functions, extract interfaces, mock-based handler tests
- Priority 1: Test NewSendEmailTask + NewSendPushTask (5 tests)
- Priority 2: Test customHTTPErrorHandler — all 15+ branches (21 tests)
- Priority 3: Extract Enqueuer interface + payload builders in worker pkg (5 tests)
- Priority 4: Extract ClassifyFile/ComputeRelPath in migrate-encrypt (6 tests)
- Priority 5: Define Handler interfaces, refactor to accept them, mock-based tests (14 tests)
- Fix .gitignore: /worker instead of worker to stop ignoring internal/worker/

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-01 20:30:09 -05:00

237 lines
7.6 KiB
Go

package repositories
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/treytartt/honeydue-api/internal/models"
"github.com/treytartt/honeydue-api/internal/testutil"
)
func TestTaskTemplateRepository_Create(t *testing.T) {
db := testutil.SetupTestDB(t)
testutil.SeedLookupData(t, db)
repo := NewTaskTemplateRepository(db)
var cat models.TaskCategory
require.NoError(t, db.First(&cat).Error)
var freq models.TaskFrequency
require.NoError(t, db.First(&freq).Error)
template := &models.TaskTemplate{
Title: "Change HVAC Filter",
Description: "Replace the HVAC air filter",
CategoryID: &cat.ID,
FrequencyID: &freq.ID,
IsActive: true,
Tags: "hvac,filter,maintenance",
}
err := repo.Create(template)
require.NoError(t, err)
assert.NotZero(t, template.ID)
}
func TestTaskTemplateRepository_GetAll(t *testing.T) {
t.Skip("requires PostgreSQL: SQLite cannot scan jsonb default into json.RawMessage")
db := testutil.SetupTestDB(t)
testutil.SeedLookupData(t, db)
repo := NewTaskTemplateRepository(db)
// Create active and inactive templates
t1 := &models.TaskTemplate{Title: "Active Template", IsActive: true}
t2 := &models.TaskTemplate{Title: "Inactive Template", IsActive: false}
require.NoError(t, db.Create(t1).Error)
require.NoError(t, db.Create(t2).Error)
templates, err := repo.GetAll()
require.NoError(t, err)
assert.Len(t, templates, 1) // Only active
assert.Equal(t, "Active Template", templates[0].Title)
}
func TestTaskTemplateRepository_GetByCategory(t *testing.T) {
t.Skip("requires PostgreSQL: SQLite cannot scan jsonb default into json.RawMessage")
db := testutil.SetupTestDB(t)
testutil.SeedLookupData(t, db)
repo := NewTaskTemplateRepository(db)
var cat models.TaskCategory
require.NoError(t, db.First(&cat).Error)
t1 := &models.TaskTemplate{Title: "Cat Template", CategoryID: &cat.ID, IsActive: true}
t2 := &models.TaskTemplate{Title: "No Cat Template", IsActive: true}
require.NoError(t, db.Create(t1).Error)
require.NoError(t, db.Create(t2).Error)
templates, err := repo.GetByCategory(cat.ID)
require.NoError(t, err)
assert.Len(t, templates, 1)
assert.Equal(t, "Cat Template", templates[0].Title)
}
func TestTaskTemplateRepository_Search(t *testing.T) {
t.Skip("requires PostgreSQL: SQLite cannot scan jsonb default into json.RawMessage")
db := testutil.SetupTestDB(t)
repo := NewTaskTemplateRepository(db)
t1 := &models.TaskTemplate{Title: "Change HVAC Filter", Tags: "hvac,filter", IsActive: true}
t2 := &models.TaskTemplate{Title: "Fix Faucet", Tags: "plumbing", IsActive: true}
require.NoError(t, db.Create(t1).Error)
require.NoError(t, db.Create(t2).Error)
// Search by title
results, err := repo.Search("hvac")
require.NoError(t, err)
assert.Len(t, results, 1)
assert.Equal(t, "Change HVAC Filter", results[0].Title)
// Search by tag
results, err = repo.Search("plumbing")
require.NoError(t, err)
assert.Len(t, results, 1)
assert.Equal(t, "Fix Faucet", results[0].Title)
// No match
results, err = repo.Search("nonexistent")
require.NoError(t, err)
assert.Empty(t, results)
}
func TestTaskTemplateRepository_GetByID(t *testing.T) {
t.Skip("requires PostgreSQL: SQLite cannot scan jsonb default into json.RawMessage")
db := testutil.SetupTestDB(t)
repo := NewTaskTemplateRepository(db)
tmpl := &models.TaskTemplate{Title: "Test Template", IsActive: true}
require.NoError(t, db.Create(tmpl).Error)
found, err := repo.GetByID(tmpl.ID)
require.NoError(t, err)
assert.Equal(t, "Test Template", found.Title)
}
func TestTaskTemplateRepository_GetByID_NotFound(t *testing.T) {
db := testutil.SetupTestDB(t)
repo := NewTaskTemplateRepository(db)
_, err := repo.GetByID(9999)
assert.Error(t, err)
}
func TestTaskTemplateRepository_Update(t *testing.T) {
db := testutil.SetupTestDB(t)
repo := NewTaskTemplateRepository(db)
tmpl := &models.TaskTemplate{Title: "Original", IsActive: true}
require.NoError(t, db.Create(tmpl).Error)
tmpl.Title = "Updated"
err := repo.Update(tmpl)
require.NoError(t, err)
found, err := repo.GetByID(tmpl.ID)
require.NoError(t, err)
assert.Equal(t, "Updated", found.Title)
}
func TestTaskTemplateRepository_Delete(t *testing.T) {
db := testutil.SetupTestDB(t)
repo := NewTaskTemplateRepository(db)
tmpl := &models.TaskTemplate{Title: "To Delete", IsActive: true}
require.NoError(t, db.Create(tmpl).Error)
err := repo.Delete(tmpl.ID)
require.NoError(t, err)
_, err = repo.GetByID(tmpl.ID)
assert.Error(t, err)
}
func TestTaskTemplateRepository_GetAllIncludingInactive(t *testing.T) {
t.Skip("requires PostgreSQL: SQLite cannot scan jsonb default into json.RawMessage")
db := testutil.SetupTestDB(t)
repo := NewTaskTemplateRepository(db)
t1 := &models.TaskTemplate{Title: "Active", IsActive: true}
t2 := &models.TaskTemplate{Title: "Inactive", IsActive: false}
require.NoError(t, db.Create(t1).Error)
require.NoError(t, db.Create(t2).Error)
templates, err := repo.GetAllIncludingInactive()
require.NoError(t, err)
assert.Len(t, templates, 2) // Both active and inactive
}
func TestTaskTemplateRepository_Count(t *testing.T) {
db := testutil.SetupTestDB(t)
repo := NewTaskTemplateRepository(db)
t1 := &models.TaskTemplate{Title: "Active 1", IsActive: true}
t2 := &models.TaskTemplate{Title: "Active 2", IsActive: true}
require.NoError(t, db.Create(t1).Error)
require.NoError(t, db.Create(t2).Error)
// Use raw SQL for inactive record to avoid GORM default:true overriding IsActive=false
require.NoError(t, db.Exec(
"INSERT INTO task_tasktemplate (title, is_active, display_order, created_at, updated_at) VALUES (?, ?, ?, datetime('now'), datetime('now'))",
"Inactive", false, 0,
).Error)
count, err := repo.Count()
require.NoError(t, err)
assert.Equal(t, int64(2), count) // Only active
}
func TestTaskTemplateRepository_GetByRegion(t *testing.T) {
t.Skip("requires PostgreSQL: SQLite cannot scan jsonb default into json.RawMessage")
db := testutil.SetupTestDB(t)
repo := NewTaskTemplateRepository(db)
// Create a climate region
region := &models.ClimateRegion{Name: "Hot-Humid", ZoneNumber: 1, IsActive: true}
require.NoError(t, db.Create(region).Error)
// Create template with region association
tmpl := &models.TaskTemplate{Title: "Regional Task", IsActive: true}
require.NoError(t, db.Create(tmpl).Error)
// Associate template with region via join table
err := db.Exec("INSERT INTO task_tasktemplate_regions (task_template_id, climate_region_id) VALUES (?, ?)", tmpl.ID, region.ID).Error
require.NoError(t, err)
// Create template without region
tmpl2 := &models.TaskTemplate{Title: "Non-Regional Task", IsActive: true}
require.NoError(t, db.Create(tmpl2).Error)
templates, err := repo.GetByRegion(region.ID)
require.NoError(t, err)
assert.Len(t, templates, 1)
assert.Equal(t, "Regional Task", templates[0].Title)
}
func TestTaskTemplateRepository_GetGroupedByCategory(t *testing.T) {
t.Skip("requires PostgreSQL: SQLite cannot scan jsonb default into json.RawMessage")
db := testutil.SetupTestDB(t)
testutil.SeedLookupData(t, db)
repo := NewTaskTemplateRepository(db)
var cat models.TaskCategory
require.NoError(t, db.First(&cat).Error)
t1 := &models.TaskTemplate{Title: "Categorized", CategoryID: &cat.ID, IsActive: true}
t2 := &models.TaskTemplate{Title: "Uncategorized", IsActive: true}
require.NoError(t, db.Create(t1).Error)
require.NoError(t, db.Create(t2).Error)
grouped, err := repo.GetGroupedByCategory()
require.NoError(t, err)
assert.GreaterOrEqual(t, len(grouped), 2) // At least the category + "Uncategorized"
// Uncategorized should have the template without category
assert.Len(t, grouped["Uncategorized"], 1)
assert.Equal(t, "Uncategorized", grouped["Uncategorized"][0].Title)
}