- 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>
218 lines
7.8 KiB
Go
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, ¬if.ID)
|
|
require.NoError(t, err)
|
|
assert.NotNil(t, logEntry.NotificationID)
|
|
assert.Equal(t, notif.ID, *logEntry.NotificationID)
|
|
}
|