Migrate from Gin to Echo framework and add comprehensive integration tests
Major changes: - Migrate all handlers from Gin to Echo framework - Add new apperrors, echohelpers, and validator packages - Update middleware for Echo compatibility - Add ArchivedHandler to task categorization chain (archived tasks go to cancelled_tasks column) - Add 6 new integration tests: - RecurringTaskLifecycle: NextDueDate advancement for weekly/monthly tasks - MultiUserSharing: Complex sharing with user removal - TaskStateTransitions: All state transitions and kanban column changes - DateBoundaryEdgeCases: Threshold boundary testing - CascadeOperations: Residence deletion cascade effects - MultiUserOperations: Shared residence collaboration - Add single-purpose repository functions for kanban columns (GetOverdueTasks, GetDueSoonTasks, etc.) - Fix RemoveUser route param mismatch (userId -> user_id) - Fix determineExpectedColumn helper to correctly prioritize in_progress over overdue 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -869,8 +869,12 @@ func TestEdgeCase_TaskDueExactlyAtThreshold(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestEdgeCase_TaskDueJustBeforeThreshold(t *testing.T) {
|
||||
// 29 days and 23 hours from now
|
||||
dueDate := time.Now().UTC().Add(29*24*time.Hour + 23*time.Hour)
|
||||
// Task due 29 days from today's start of day should be "due_soon"
|
||||
// (within the 30-day threshold)
|
||||
now := time.Now().UTC()
|
||||
startOfToday := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
|
||||
dueDate := startOfToday.AddDate(0, 0, 29) // 29 days from start of today
|
||||
|
||||
task := &models.Task{
|
||||
NextDueDate: &dueDate,
|
||||
}
|
||||
@@ -878,7 +882,7 @@ func TestEdgeCase_TaskDueJustBeforeThreshold(t *testing.T) {
|
||||
column := responses.DetermineKanbanColumn(task, 30)
|
||||
|
||||
assert.Equal(t, "due_soon_tasks", column,
|
||||
"Task due just before threshold should be in due_soon")
|
||||
"Task due 29 days from today should be in due_soon (within 30-day threshold)")
|
||||
}
|
||||
|
||||
func TestEdgeCase_TaskDueInPast_ButHasCompletionAfter(t *testing.T) {
|
||||
@@ -955,20 +959,23 @@ func TestEdgeCase_MonthlyRecurringTask(t *testing.T) {
|
||||
CompletedAt: completedAt,
|
||||
})
|
||||
|
||||
// Update NextDueDate
|
||||
// Update NextDueDate - set to 29 days from today (within 30-day threshold)
|
||||
task, _ = taskRepo.FindByID(task.ID)
|
||||
nextDue := completedAt.AddDate(0, 0, 30) // 30 days from now
|
||||
now := time.Now().UTC()
|
||||
startOfToday := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
|
||||
nextDue := startOfToday.AddDate(0, 0, 29) // 29 days from start of today (within threshold)
|
||||
task.NextDueDate = &nextDue
|
||||
db.Save(task)
|
||||
|
||||
task, _ = taskRepo.FindByID(task.ID)
|
||||
|
||||
// 30 days from now is at/within threshold boundary - due to time precision,
|
||||
// a task at exactly the threshold boundary is considered "due_soon" not "upcoming"
|
||||
// because the check is NextDueDate.Before(threshold) which includes boundary due to ms precision
|
||||
// With day-based comparisons:
|
||||
// - Threshold = start of today + 30 days
|
||||
// - A task due on day 29 is Before(threshold), so it's "due_soon"
|
||||
// - A task due on day 30+ is NOT Before(threshold), so it's "upcoming"
|
||||
column := responses.DetermineKanbanColumn(task, 30)
|
||||
assert.Equal(t, "due_soon_tasks", column,
|
||||
"Monthly task at 30-day boundary should be due_soon (at threshold)")
|
||||
"Monthly task within 30-day threshold should be due_soon")
|
||||
}
|
||||
|
||||
func TestEdgeCase_ZeroDayFrequency_TreatedAsOneTime(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user