Files
honeyDueAPI/internal/repositories/reminder_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

218 lines
7.8 KiB
Go

package repositories
import (
"testing"
"time"
"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 TestReminderRepository_LogReminder(t *testing.T) {
db := testutil.SetupTestDB(t)
repo := NewReminderRepository(db)
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
task := testutil.CreateTestTask(t, db, residence.ID, user.ID, "Fix Roof")
dueDate := time.Date(2026, 4, 15, 0, 0, 0, 0, time.UTC)
logEntry, err := repo.LogReminder(task.ID, user.ID, dueDate, models.ReminderStage7Days, nil)
require.NoError(t, err)
assert.NotZero(t, logEntry.ID)
assert.Equal(t, task.ID, logEntry.TaskID)
assert.Equal(t, user.ID, logEntry.UserID)
assert.Equal(t, models.ReminderStage7Days, logEntry.ReminderStage)
}
func TestReminderRepository_HasSentReminder(t *testing.T) {
db := testutil.SetupTestDB(t)
repo := NewReminderRepository(db)
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
task := testutil.CreateTestTask(t, db, residence.ID, user.ID, "Fix Roof")
dueDate := time.Date(2026, 4, 15, 12, 30, 0, 0, time.UTC) // Has time component
// Not sent yet
sent, err := repo.HasSentReminder(task.ID, user.ID, dueDate, models.ReminderStage7Days)
require.NoError(t, err)
assert.False(t, sent)
// Log it
_, err = repo.LogReminder(task.ID, user.ID, dueDate, models.ReminderStage7Days, nil)
require.NoError(t, err)
// Now should be sent
sent, err = repo.HasSentReminder(task.ID, user.ID, dueDate, models.ReminderStage7Days)
require.NoError(t, err)
assert.True(t, sent)
// Different stage should not be sent
sent, err = repo.HasSentReminder(task.ID, user.ID, dueDate, models.ReminderStage3Days)
require.NoError(t, err)
assert.False(t, sent)
}
func TestReminderRepository_HasSentReminderBatch(t *testing.T) {
db := testutil.SetupTestDB(t)
repo := NewReminderRepository(db)
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
task1 := testutil.CreateTestTask(t, db, residence.ID, user.ID, "Task 1")
task2 := testutil.CreateTestTask(t, db, residence.ID, user.ID, "Task 2")
dueDate := time.Date(2026, 4, 15, 0, 0, 0, 0, time.UTC)
// Log reminder for task1
_, err := repo.LogReminder(task1.ID, user.ID, dueDate, models.ReminderStage7Days, nil)
require.NoError(t, err)
keys := []ReminderKey{
{TaskID: task1.ID, UserID: user.ID, DueDate: dueDate, Stage: models.ReminderStage7Days},
{TaskID: task2.ID, UserID: user.ID, DueDate: dueDate, Stage: models.ReminderStage7Days},
}
result, err := repo.HasSentReminderBatch(keys)
require.NoError(t, err)
assert.True(t, result[0], "task1 reminder should be sent")
assert.False(t, result[1], "task2 reminder should not be sent")
}
func TestReminderRepository_HasSentReminderBatch_Empty(t *testing.T) {
db := testutil.SetupTestDB(t)
repo := NewReminderRepository(db)
result, err := repo.HasSentReminderBatch([]ReminderKey{})
require.NoError(t, err)
assert.Empty(t, result)
}
func TestReminderRepository_GetSentRemindersForTask(t *testing.T) {
db := testutil.SetupTestDB(t)
repo := NewReminderRepository(db)
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
task := testutil.CreateTestTask(t, db, residence.ID, user.ID, "Fix Roof")
dueDate := time.Date(2026, 4, 15, 0, 0, 0, 0, time.UTC)
_, err := repo.LogReminder(task.ID, user.ID, dueDate, models.ReminderStage7Days, nil)
require.NoError(t, err)
_, err = repo.LogReminder(task.ID, user.ID, dueDate, models.ReminderStage3Days, nil)
require.NoError(t, err)
logs, err := repo.GetSentRemindersForTask(task.ID, user.ID)
require.NoError(t, err)
assert.Len(t, logs, 2)
}
func TestReminderRepository_GetSentRemindersForDueDate(t *testing.T) {
db := testutil.SetupTestDB(t)
repo := NewReminderRepository(db)
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
task := testutil.CreateTestTask(t, db, residence.ID, user.ID, "Fix Roof")
dueDate1 := time.Date(2026, 4, 15, 0, 0, 0, 0, time.UTC)
dueDate2 := time.Date(2026, 5, 15, 0, 0, 0, 0, time.UTC)
_, err := repo.LogReminder(task.ID, user.ID, dueDate1, models.ReminderStage7Days, nil)
require.NoError(t, err)
_, err = repo.LogReminder(task.ID, user.ID, dueDate2, models.ReminderStage7Days, nil)
require.NoError(t, err)
logs, err := repo.GetSentRemindersForDueDate(task.ID, user.ID, dueDate1)
require.NoError(t, err)
assert.Len(t, logs, 1)
}
func TestReminderRepository_CleanupOldLogs(t *testing.T) {
db := testutil.SetupTestDB(t)
repo := NewReminderRepository(db)
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
task := testutil.CreateTestTask(t, db, residence.ID, user.ID, "Fix Roof")
// Create old log entry (100 days ago)
oldLog := &models.TaskReminderLog{
TaskID: task.ID,
UserID: user.ID,
DueDate: time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC),
ReminderStage: models.ReminderStage7Days,
SentAt: time.Now().UTC().AddDate(0, 0, -100),
}
require.NoError(t, db.Create(oldLog).Error)
// Create recent log entry
recentLog := &models.TaskReminderLog{
TaskID: task.ID,
UserID: user.ID,
DueDate: time.Date(2026, 4, 15, 0, 0, 0, 0, time.UTC),
ReminderStage: models.ReminderStage3Days,
SentAt: time.Now().UTC(),
}
require.NoError(t, db.Create(recentLog).Error)
deleted, err := repo.CleanupOldLogs(90)
require.NoError(t, err)
assert.Equal(t, int64(1), deleted)
// Recent log should still exist
var count int64
db.Model(&models.TaskReminderLog{}).Count(&count)
assert.Equal(t, int64(1), count)
}
func TestReminderRepository_GetRecentReminderStats(t *testing.T) {
db := testutil.SetupTestDB(t)
repo := NewReminderRepository(db)
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
task := testutil.CreateTestTask(t, db, residence.ID, user.ID, "Fix Roof")
dueDate := time.Date(2026, 4, 15, 0, 0, 0, 0, time.UTC)
// Create recent reminders
_, err := repo.LogReminder(task.ID, user.ID, dueDate, models.ReminderStage7Days, nil)
require.NoError(t, err)
_, err = repo.LogReminder(task.ID, user.ID, dueDate, models.ReminderStage3Days, nil)
require.NoError(t, err)
stats, err := repo.GetRecentReminderStats(24) // last 24 hours
require.NoError(t, err)
assert.Equal(t, int64(1), stats[string(models.ReminderStage7Days)])
assert.Equal(t, int64(1), stats[string(models.ReminderStage3Days)])
}
func TestReminderRepository_LogReminder_WithNotificationID(t *testing.T) {
db := testutil.SetupTestDB(t)
repo := NewReminderRepository(db)
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
task := testutil.CreateTestTask(t, db, residence.ID, user.ID, "Fix Roof")
// Create a notification
notif := &models.Notification{
UserID: user.ID,
NotificationType: models.NotificationTaskDueSoon,
Title: "Test",
Body: "Test body",
}
require.NoError(t, db.Create(notif).Error)
dueDate := time.Date(2026, 4, 15, 0, 0, 0, 0, time.UTC)
logEntry, err := repo.LogReminder(task.ID, user.ID, dueDate, models.ReminderStage7Days, &notif.ID)
require.NoError(t, err)
assert.NotNil(t, logEntry.NotificationID)
assert.Equal(t, notif.ID, *logEntry.NotificationID)
}