Add comprehensive kanban board tests and fix test suite
- Add 13 tests for task kanban categorization and button types - Fix i18n initialization in test setup (was causing nil pointer panics) - Add TaskCompletionImage to test DB auto-migrate - Update ListTasks tests to expect kanban board response instead of array 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -313,3 +313,525 @@ func TestTaskRepository_CountByResidence(t *testing.T) {
|
||||
assert.Equal(t, int64(3), count)
|
||||
}
|
||||
|
||||
// === Kanban Board Categorization Tests ===
|
||||
|
||||
func TestKanbanBoard_CancelledTasksGoToCancelledColumn(t *testing.T) {
|
||||
db := testutil.SetupTestDB(t)
|
||||
repo := NewTaskRepository(db)
|
||||
testutil.SeedLookupData(t, db)
|
||||
|
||||
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "password")
|
||||
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
||||
|
||||
// Create a cancelled task
|
||||
task := testutil.CreateTestTask(t, db, residence.ID, user.ID, "Cancelled Task")
|
||||
repo.Cancel(task.ID)
|
||||
|
||||
board, err := repo.GetKanbanData(residence.ID, 30)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Find cancelled column
|
||||
var cancelledColumn *models.KanbanColumn
|
||||
for i := range board.Columns {
|
||||
if board.Columns[i].Name == "cancelled_tasks" {
|
||||
cancelledColumn = &board.Columns[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
require.NotNil(t, cancelledColumn, "cancelled_tasks column should exist")
|
||||
assert.Equal(t, 1, cancelledColumn.Count)
|
||||
assert.Len(t, cancelledColumn.Tasks, 1)
|
||||
assert.Equal(t, "Cancelled Task", cancelledColumn.Tasks[0].Title)
|
||||
|
||||
// Verify button types for cancelled column
|
||||
assert.ElementsMatch(t, []string{"uncancel", "delete"}, cancelledColumn.ButtonTypes)
|
||||
}
|
||||
|
||||
func TestKanbanBoard_CompletedTasksGoToCompletedColumn(t *testing.T) {
|
||||
db := testutil.SetupTestDB(t)
|
||||
repo := NewTaskRepository(db)
|
||||
testutil.SeedLookupData(t, db)
|
||||
|
||||
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "password")
|
||||
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
||||
|
||||
// Create a task with a completion
|
||||
task := testutil.CreateTestTask(t, db, residence.ID, user.ID, "Completed Task")
|
||||
completion := &models.TaskCompletion{
|
||||
TaskID: task.ID,
|
||||
CompletedByID: user.ID,
|
||||
CompletedAt: time.Now().UTC(),
|
||||
Notes: "Done!",
|
||||
}
|
||||
err := repo.CreateCompletion(completion)
|
||||
require.NoError(t, err)
|
||||
|
||||
board, err := repo.GetKanbanData(residence.ID, 30)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Find completed column
|
||||
var completedColumn *models.KanbanColumn
|
||||
for i := range board.Columns {
|
||||
if board.Columns[i].Name == "completed_tasks" {
|
||||
completedColumn = &board.Columns[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
require.NotNil(t, completedColumn, "completed_tasks column should exist")
|
||||
assert.Equal(t, 1, completedColumn.Count)
|
||||
assert.Len(t, completedColumn.Tasks, 1)
|
||||
assert.Equal(t, "Completed Task", completedColumn.Tasks[0].Title)
|
||||
|
||||
// Verify button types for completed column (view only)
|
||||
assert.ElementsMatch(t, []string{"view"}, completedColumn.ButtonTypes)
|
||||
}
|
||||
|
||||
func TestKanbanBoard_InProgressTasksGoToInProgressColumn(t *testing.T) {
|
||||
db := testutil.SetupTestDB(t)
|
||||
repo := NewTaskRepository(db)
|
||||
testutil.SeedLookupData(t, db)
|
||||
|
||||
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "password")
|
||||
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
||||
|
||||
// Get "In Progress" status
|
||||
var inProgressStatus models.TaskStatus
|
||||
db.Where("name = ?", "In Progress").First(&inProgressStatus)
|
||||
|
||||
// Create a task with "In Progress" status
|
||||
task := &models.Task{
|
||||
ResidenceID: residence.ID,
|
||||
CreatedByID: user.ID,
|
||||
Title: "In Progress Task",
|
||||
StatusID: &inProgressStatus.ID,
|
||||
}
|
||||
err := db.Create(task).Error
|
||||
require.NoError(t, err)
|
||||
|
||||
board, err := repo.GetKanbanData(residence.ID, 30)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Find in_progress column
|
||||
var inProgressColumn *models.KanbanColumn
|
||||
for i := range board.Columns {
|
||||
if board.Columns[i].Name == "in_progress_tasks" {
|
||||
inProgressColumn = &board.Columns[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
require.NotNil(t, inProgressColumn, "in_progress_tasks column should exist")
|
||||
assert.Equal(t, 1, inProgressColumn.Count)
|
||||
assert.Len(t, inProgressColumn.Tasks, 1)
|
||||
assert.Equal(t, "In Progress Task", inProgressColumn.Tasks[0].Title)
|
||||
|
||||
// Verify button types for in-progress column (no mark_in_progress since already in progress)
|
||||
assert.ElementsMatch(t, []string{"edit", "complete", "cancel"}, inProgressColumn.ButtonTypes)
|
||||
}
|
||||
|
||||
func TestKanbanBoard_OverdueTasksGoToOverdueColumn(t *testing.T) {
|
||||
db := testutil.SetupTestDB(t)
|
||||
repo := NewTaskRepository(db)
|
||||
testutil.SeedLookupData(t, db)
|
||||
|
||||
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "password")
|
||||
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
||||
|
||||
// Create a task with due date in the past
|
||||
pastDue := time.Now().UTC().AddDate(0, 0, -5) // 5 days ago
|
||||
task := &models.Task{
|
||||
ResidenceID: residence.ID,
|
||||
CreatedByID: user.ID,
|
||||
Title: "Overdue Task",
|
||||
DueDate: &pastDue,
|
||||
}
|
||||
err := db.Create(task).Error
|
||||
require.NoError(t, err)
|
||||
|
||||
board, err := repo.GetKanbanData(residence.ID, 30)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Find overdue column
|
||||
var overdueColumn *models.KanbanColumn
|
||||
for i := range board.Columns {
|
||||
if board.Columns[i].Name == "overdue_tasks" {
|
||||
overdueColumn = &board.Columns[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
require.NotNil(t, overdueColumn, "overdue_tasks column should exist")
|
||||
assert.Equal(t, 1, overdueColumn.Count)
|
||||
assert.Len(t, overdueColumn.Tasks, 1)
|
||||
assert.Equal(t, "Overdue Task", overdueColumn.Tasks[0].Title)
|
||||
|
||||
// Verify button types for overdue column
|
||||
assert.ElementsMatch(t, []string{"edit", "complete", "cancel", "mark_in_progress"}, overdueColumn.ButtonTypes)
|
||||
}
|
||||
|
||||
func TestKanbanBoard_DueSoonTasksGoToDueSoonColumn(t *testing.T) {
|
||||
db := testutil.SetupTestDB(t)
|
||||
repo := NewTaskRepository(db)
|
||||
testutil.SeedLookupData(t, db)
|
||||
|
||||
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "password")
|
||||
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
||||
|
||||
// Create a task with due date within threshold (default 30 days)
|
||||
dueSoon := time.Now().UTC().AddDate(0, 0, 15) // 15 days from now
|
||||
task := &models.Task{
|
||||
ResidenceID: residence.ID,
|
||||
CreatedByID: user.ID,
|
||||
Title: "Due Soon Task",
|
||||
DueDate: &dueSoon,
|
||||
}
|
||||
err := db.Create(task).Error
|
||||
require.NoError(t, err)
|
||||
|
||||
board, err := repo.GetKanbanData(residence.ID, 30)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Find due_soon column
|
||||
var dueSoonColumn *models.KanbanColumn
|
||||
for i := range board.Columns {
|
||||
if board.Columns[i].Name == "due_soon_tasks" {
|
||||
dueSoonColumn = &board.Columns[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
require.NotNil(t, dueSoonColumn, "due_soon_tasks column should exist")
|
||||
assert.Equal(t, 1, dueSoonColumn.Count)
|
||||
assert.Len(t, dueSoonColumn.Tasks, 1)
|
||||
assert.Equal(t, "Due Soon Task", dueSoonColumn.Tasks[0].Title)
|
||||
|
||||
// Verify button types for due_soon column
|
||||
assert.ElementsMatch(t, []string{"edit", "complete", "cancel", "mark_in_progress"}, dueSoonColumn.ButtonTypes)
|
||||
}
|
||||
|
||||
func TestKanbanBoard_UpcomingTasksGoToUpcomingColumn(t *testing.T) {
|
||||
db := testutil.SetupTestDB(t)
|
||||
repo := NewTaskRepository(db)
|
||||
testutil.SeedLookupData(t, db)
|
||||
|
||||
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "password")
|
||||
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
||||
|
||||
// Create a task with due date beyond threshold (default 30 days)
|
||||
upcoming := time.Now().UTC().AddDate(0, 0, 45) // 45 days from now
|
||||
task := &models.Task{
|
||||
ResidenceID: residence.ID,
|
||||
CreatedByID: user.ID,
|
||||
Title: "Upcoming Task",
|
||||
DueDate: &upcoming,
|
||||
}
|
||||
err := db.Create(task).Error
|
||||
require.NoError(t, err)
|
||||
|
||||
board, err := repo.GetKanbanData(residence.ID, 30)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Find upcoming column
|
||||
var upcomingColumn *models.KanbanColumn
|
||||
for i := range board.Columns {
|
||||
if board.Columns[i].Name == "upcoming_tasks" {
|
||||
upcomingColumn = &board.Columns[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
require.NotNil(t, upcomingColumn, "upcoming_tasks column should exist")
|
||||
assert.Equal(t, 1, upcomingColumn.Count)
|
||||
assert.Len(t, upcomingColumn.Tasks, 1)
|
||||
assert.Equal(t, "Upcoming Task", upcomingColumn.Tasks[0].Title)
|
||||
|
||||
// Verify button types for upcoming column
|
||||
assert.ElementsMatch(t, []string{"edit", "complete", "cancel", "mark_in_progress"}, upcomingColumn.ButtonTypes)
|
||||
}
|
||||
|
||||
func TestKanbanBoard_TasksWithNoDueDateGoToUpcomingColumn(t *testing.T) {
|
||||
db := testutil.SetupTestDB(t)
|
||||
repo := NewTaskRepository(db)
|
||||
testutil.SeedLookupData(t, db)
|
||||
|
||||
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "password")
|
||||
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
||||
|
||||
// Create a task with no due date
|
||||
task := testutil.CreateTestTask(t, db, residence.ID, user.ID, "No Due Date Task")
|
||||
|
||||
board, err := repo.GetKanbanData(residence.ID, 30)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Find upcoming column
|
||||
var upcomingColumn *models.KanbanColumn
|
||||
for i := range board.Columns {
|
||||
if board.Columns[i].Name == "upcoming_tasks" {
|
||||
upcomingColumn = &board.Columns[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
require.NotNil(t, upcomingColumn, "upcoming_tasks column should exist")
|
||||
assert.Equal(t, 1, upcomingColumn.Count)
|
||||
assert.Equal(t, task.ID, upcomingColumn.Tasks[0].ID)
|
||||
}
|
||||
|
||||
func TestKanbanBoard_ArchivedTasksAreExcluded(t *testing.T) {
|
||||
db := testutil.SetupTestDB(t)
|
||||
repo := NewTaskRepository(db)
|
||||
testutil.SeedLookupData(t, db)
|
||||
|
||||
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "password")
|
||||
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
||||
|
||||
// Create a regular task and an archived task
|
||||
testutil.CreateTestTask(t, db, residence.ID, user.ID, "Regular Task")
|
||||
archivedTask := testutil.CreateTestTask(t, db, residence.ID, user.ID, "Archived Task")
|
||||
repo.Archive(archivedTask.ID)
|
||||
|
||||
board, err := repo.GetKanbanData(residence.ID, 30)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Count total tasks across all columns
|
||||
totalTasks := 0
|
||||
for _, col := range board.Columns {
|
||||
totalTasks += col.Count
|
||||
}
|
||||
|
||||
// Only the non-archived task should be in the board
|
||||
assert.Equal(t, 1, totalTasks)
|
||||
}
|
||||
|
||||
func TestKanbanBoard_CategoryPriority_CancelledTakesPrecedence(t *testing.T) {
|
||||
db := testutil.SetupTestDB(t)
|
||||
repo := NewTaskRepository(db)
|
||||
testutil.SeedLookupData(t, db)
|
||||
|
||||
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "password")
|
||||
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
||||
|
||||
// Create a task that is BOTH overdue AND cancelled
|
||||
// Cancelled should take precedence
|
||||
pastDue := time.Now().UTC().AddDate(0, 0, -5)
|
||||
task := &models.Task{
|
||||
ResidenceID: residence.ID,
|
||||
CreatedByID: user.ID,
|
||||
Title: "Overdue and Cancelled Task",
|
||||
DueDate: &pastDue,
|
||||
IsCancelled: true,
|
||||
}
|
||||
err := db.Create(task).Error
|
||||
require.NoError(t, err)
|
||||
|
||||
board, err := repo.GetKanbanData(residence.ID, 30)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Find cancelled column
|
||||
var cancelledColumn *models.KanbanColumn
|
||||
var overdueColumn *models.KanbanColumn
|
||||
for i := range board.Columns {
|
||||
if board.Columns[i].Name == "cancelled_tasks" {
|
||||
cancelledColumn = &board.Columns[i]
|
||||
}
|
||||
if board.Columns[i].Name == "overdue_tasks" {
|
||||
overdueColumn = &board.Columns[i]
|
||||
}
|
||||
}
|
||||
|
||||
// Task should be in cancelled, not overdue
|
||||
assert.Equal(t, 1, cancelledColumn.Count, "Task should be in cancelled column")
|
||||
assert.Equal(t, 0, overdueColumn.Count, "Task should NOT be in overdue column")
|
||||
}
|
||||
|
||||
func TestKanbanBoard_CategoryPriority_CompletedTakesPrecedenceOverInProgress(t *testing.T) {
|
||||
db := testutil.SetupTestDB(t)
|
||||
repo := NewTaskRepository(db)
|
||||
testutil.SeedLookupData(t, db)
|
||||
|
||||
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "password")
|
||||
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
||||
|
||||
// Get "In Progress" status
|
||||
var inProgressStatus models.TaskStatus
|
||||
db.Where("name = ?", "In Progress").First(&inProgressStatus)
|
||||
|
||||
// Create a task that has "In Progress" status AND a completion
|
||||
// Completed should take precedence
|
||||
task := &models.Task{
|
||||
ResidenceID: residence.ID,
|
||||
CreatedByID: user.ID,
|
||||
Title: "In Progress with Completion",
|
||||
StatusID: &inProgressStatus.ID,
|
||||
}
|
||||
err := db.Create(task).Error
|
||||
require.NoError(t, err)
|
||||
|
||||
// Add a completion
|
||||
completion := &models.TaskCompletion{
|
||||
TaskID: task.ID,
|
||||
CompletedByID: user.ID,
|
||||
CompletedAt: time.Now().UTC(),
|
||||
}
|
||||
err = repo.CreateCompletion(completion)
|
||||
require.NoError(t, err)
|
||||
|
||||
board, err := repo.GetKanbanData(residence.ID, 30)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Find columns
|
||||
var completedColumn, inProgressColumn *models.KanbanColumn
|
||||
for i := range board.Columns {
|
||||
if board.Columns[i].Name == "completed_tasks" {
|
||||
completedColumn = &board.Columns[i]
|
||||
}
|
||||
if board.Columns[i].Name == "in_progress_tasks" {
|
||||
inProgressColumn = &board.Columns[i]
|
||||
}
|
||||
}
|
||||
|
||||
// Task should be in completed, not in_progress
|
||||
assert.Equal(t, 1, completedColumn.Count, "Task should be in completed column")
|
||||
assert.Equal(t, 0, inProgressColumn.Count, "Task should NOT be in in_progress column")
|
||||
}
|
||||
|
||||
func TestKanbanBoard_DaysThresholdAffectsCategorization(t *testing.T) {
|
||||
db := testutil.SetupTestDB(t)
|
||||
repo := NewTaskRepository(db)
|
||||
testutil.SeedLookupData(t, db)
|
||||
|
||||
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "password")
|
||||
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
||||
|
||||
// Create a task due in 10 days
|
||||
dueIn10Days := time.Now().UTC().AddDate(0, 0, 10)
|
||||
task := &models.Task{
|
||||
ResidenceID: residence.ID,
|
||||
CreatedByID: user.ID,
|
||||
Title: "Task Due in 10 Days",
|
||||
DueDate: &dueIn10Days,
|
||||
}
|
||||
err := db.Create(task).Error
|
||||
require.NoError(t, err)
|
||||
|
||||
// With 30-day threshold, should be in "due_soon"
|
||||
board30, err := repo.GetKanbanData(residence.ID, 30)
|
||||
require.NoError(t, err)
|
||||
|
||||
var dueSoon30, upcoming30 *models.KanbanColumn
|
||||
for i := range board30.Columns {
|
||||
if board30.Columns[i].Name == "due_soon_tasks" {
|
||||
dueSoon30 = &board30.Columns[i]
|
||||
}
|
||||
if board30.Columns[i].Name == "upcoming_tasks" {
|
||||
upcoming30 = &board30.Columns[i]
|
||||
}
|
||||
}
|
||||
assert.Equal(t, 1, dueSoon30.Count, "With 30-day threshold, task should be in due_soon")
|
||||
assert.Equal(t, 0, upcoming30.Count, "With 30-day threshold, task should NOT be in upcoming")
|
||||
|
||||
// With 5-day threshold, should be in "upcoming"
|
||||
board5, err := repo.GetKanbanData(residence.ID, 5)
|
||||
require.NoError(t, err)
|
||||
|
||||
var dueSoon5, upcoming5 *models.KanbanColumn
|
||||
for i := range board5.Columns {
|
||||
if board5.Columns[i].Name == "due_soon_tasks" {
|
||||
dueSoon5 = &board5.Columns[i]
|
||||
}
|
||||
if board5.Columns[i].Name == "upcoming_tasks" {
|
||||
upcoming5 = &board5.Columns[i]
|
||||
}
|
||||
}
|
||||
assert.Equal(t, 0, dueSoon5.Count, "With 5-day threshold, task should NOT be in due_soon")
|
||||
assert.Equal(t, 1, upcoming5.Count, "With 5-day threshold, task should be in upcoming")
|
||||
}
|
||||
|
||||
func TestKanbanBoard_ColumnMetadata(t *testing.T) {
|
||||
db := testutil.SetupTestDB(t)
|
||||
repo := NewTaskRepository(db)
|
||||
testutil.SeedLookupData(t, db)
|
||||
|
||||
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "password")
|
||||
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
|
||||
|
||||
board, err := repo.GetKanbanData(residence.ID, 30)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Verify all 6 columns exist with correct metadata
|
||||
expectedColumns := []struct {
|
||||
name string
|
||||
displayName string
|
||||
color string
|
||||
buttonTypes []string
|
||||
iosIcon string
|
||||
androidIcon string
|
||||
}{
|
||||
{"overdue_tasks", "Overdue", "#FF3B30", []string{"edit", "complete", "cancel", "mark_in_progress"}, "exclamationmark.triangle", "Warning"},
|
||||
{"due_soon_tasks", "Due Soon", "#FF9500", []string{"edit", "complete", "cancel", "mark_in_progress"}, "clock", "Schedule"},
|
||||
{"upcoming_tasks", "Upcoming", "#007AFF", []string{"edit", "complete", "cancel", "mark_in_progress"}, "calendar", "Event"},
|
||||
{"in_progress_tasks", "In Progress", "#5856D6", []string{"edit", "complete", "cancel"}, "hammer", "Build"},
|
||||
{"completed_tasks", "Completed", "#34C759", []string{"view"}, "checkmark.circle", "CheckCircle"},
|
||||
{"cancelled_tasks", "Cancelled", "#8E8E93", []string{"uncancel", "delete"}, "xmark.circle", "Cancel"},
|
||||
}
|
||||
|
||||
assert.Len(t, board.Columns, 6, "Board should have 6 columns")
|
||||
|
||||
for i, expected := range expectedColumns {
|
||||
col := board.Columns[i]
|
||||
assert.Equal(t, expected.name, col.Name, "Column %d name mismatch", i)
|
||||
assert.Equal(t, expected.displayName, col.DisplayName, "Column %d display name mismatch", i)
|
||||
assert.Equal(t, expected.color, col.Color, "Column %d color mismatch", i)
|
||||
assert.ElementsMatch(t, expected.buttonTypes, col.ButtonTypes, "Column %d button types mismatch", i)
|
||||
assert.Equal(t, expected.iosIcon, col.Icons["ios"], "Column %d iOS icon mismatch", i)
|
||||
assert.Equal(t, expected.androidIcon, col.Icons["android"], "Column %d Android icon mismatch", i)
|
||||
}
|
||||
|
||||
// Verify days threshold is returned
|
||||
assert.Equal(t, 30, board.DaysThreshold)
|
||||
}
|
||||
|
||||
func TestKanbanBoard_MultipleResidences(t *testing.T) {
|
||||
db := testutil.SetupTestDB(t)
|
||||
repo := NewTaskRepository(db)
|
||||
testutil.SeedLookupData(t, 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")
|
||||
|
||||
// Create tasks in both residences
|
||||
testutil.CreateTestTask(t, db, residence1.ID, user.ID, "Task in House 1")
|
||||
testutil.CreateTestTask(t, db, residence2.ID, user.ID, "Task in House 2")
|
||||
|
||||
// Create a cancelled task in house 1
|
||||
cancelledTask := testutil.CreateTestTask(t, db, residence1.ID, user.ID, "Cancelled in House 1")
|
||||
repo.Cancel(cancelledTask.ID)
|
||||
|
||||
board, err := repo.GetKanbanDataForMultipleResidences([]uint{residence1.ID, residence2.ID}, 30)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Count total tasks
|
||||
totalTasks := 0
|
||||
for _, col := range board.Columns {
|
||||
totalTasks += col.Count
|
||||
}
|
||||
assert.Equal(t, 3, totalTasks, "Should have 3 tasks total across both residences")
|
||||
|
||||
// Find upcoming and cancelled columns
|
||||
var upcomingColumn, cancelledColumn *models.KanbanColumn
|
||||
for i := range board.Columns {
|
||||
if board.Columns[i].Name == "upcoming_tasks" {
|
||||
upcomingColumn = &board.Columns[i]
|
||||
}
|
||||
if board.Columns[i].Name == "cancelled_tasks" {
|
||||
cancelledColumn = &board.Columns[i]
|
||||
}
|
||||
}
|
||||
|
||||
assert.Equal(t, 2, upcomingColumn.Count, "Should have 2 upcoming tasks")
|
||||
assert.Equal(t, 1, cancelledColumn.Count, "Should have 1 cancelled task")
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user