blob: 033e11c419c8351c7e0ead17d86474ff335901f8 [file] [log] [blame]
package git_tm
import (
"context"
"log/slog"
"os"
"path/filepath"
"testing"
"time"
"github.com/iomodo/staff/git"
"github.com/iomodo/staff/tm"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// Test helper functions
func setupTestDir(t *testing.T) (string, func()) {
tempDir, err := os.MkdirTemp("", "git-task-manager-test")
require.NoError(t, err)
cleanup := func() {
os.RemoveAll(tempDir)
}
return tempDir, cleanup
}
func createTestTaskManager(t *testing.T, repoPath string) (*GitTaskManager, git.GitInterface) {
// Initialize git repository
gitImpl := git.DefaultGit(repoPath)
ctx := context.Background()
err := gitImpl.Init(ctx, repoPath)
require.NoError(t, err)
// Set up git user config for commits
userConfig := git.UserConfig{
Name: "Test User",
Email: "test@example.com",
}
err = gitImpl.SetUserConfig(ctx, userConfig)
require.NoError(t, err)
// Create logger for testing
logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo}))
gtm := NewGitTaskManagerWithLogger(gitImpl, repoPath, logger)
return gtm, gitImpl
}
// Test cases
func TestNewGitTaskManager(t *testing.T) {
tempDir, cleanup := setupTestDir(t)
defer cleanup()
gitImpl := git.DefaultGit(tempDir)
// Create logger for testing
logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo}))
gtm := NewGitTaskManagerWithLogger(gitImpl, tempDir, logger)
assert.NotNil(t, gtm)
assert.Equal(t, gitImpl, gtm.git)
assert.Equal(t, tempDir, gtm.repoPath)
assert.Equal(t, filepath.Join(tempDir, "tasks"), gtm.tasksDir)
}
func TestEnsureTasksDir(t *testing.T) {
tempDir, cleanup := setupTestDir(t)
defer cleanup()
gtm, _ := createTestTaskManager(t, tempDir)
// Test creating tasks directory
err := gtm.ensureTasksDir()
assert.NoError(t, err)
// Verify directory exists
_, err = os.Stat(gtm.tasksDir)
assert.NoError(t, err)
// Test creating again (should not error)
err = gtm.ensureTasksDir()
assert.NoError(t, err)
}
func TestGenerateTaskID(t *testing.T) {
tempDir, cleanup := setupTestDir(t)
defer cleanup()
gtm, _ := createTestTaskManager(t, tempDir)
id1 := gtm.generateTaskID()
id2 := gtm.generateTaskID()
assert.NotEmpty(t, id1)
assert.NotEmpty(t, id2)
assert.NotEqual(t, id1, id2)
assert.Contains(t, id1, "task-")
}
func TestTaskToMarkdown(t *testing.T) {
tempDir, cleanup := setupTestDir(t)
defer cleanup()
gtm, _ := createTestTaskManager(t, tempDir)
now := time.Now()
dueDate := now.Add(24 * time.Hour)
completedAt := now.Add(12 * time.Hour)
task := &tm.Task{
ID: "test-task-123",
Title: "Test Task",
Description: "This is a test task",
Owner: tm.Owner{
ID: "user123",
Name: "Test User",
},
Status: tm.StatusToDo,
Priority: tm.PriorityHigh,
CreatedAt: now,
UpdatedAt: now,
DueDate: &dueDate,
CompletedAt: &completedAt,
}
markdown, err := gtm.taskToMarkdown(task)
assert.NoError(t, err)
assert.NotEmpty(t, markdown)
assert.Contains(t, markdown, "---")
assert.Contains(t, markdown, "id: test-task-123")
assert.Contains(t, markdown, "title: Test Task")
assert.Contains(t, markdown, "description: This is a test task")
assert.Contains(t, markdown, "owner_id: user123")
assert.Contains(t, markdown, "owner_name: Test User")
assert.Contains(t, markdown, "status: todo")
assert.Contains(t, markdown, "priority: high")
assert.Contains(t, markdown, "# Task Description")
assert.Contains(t, markdown, "This is a test task")
}
func TestParseTaskFromMarkdown(t *testing.T) {
tempDir, cleanup := setupTestDir(t)
defer cleanup()
gtm, _ := createTestTaskManager(t, tempDir)
markdown := `---
id: test-task-123
title: Test Task
description: This is a test task
owner_id: user123
owner_name: Test User
status: todo
priority: high
created_at: 2023-01-01T00:00:00Z
updated_at: 2023-01-01T00:00:00Z
due_date: 2023-01-02T00:00:00Z
completed_at: 2023-01-01T12:00:00Z
---
# Task Description
This is a test task
`
task, err := gtm.parseTaskFromMarkdown(markdown)
assert.NoError(t, err)
assert.NotNil(t, task)
assert.Equal(t, "test-task-123", task.ID)
assert.Equal(t, "Test Task", task.Title)
assert.Equal(t, "This is a test task", task.Description)
assert.Equal(t, "user123", task.Owner.ID)
assert.Equal(t, "Test User", task.Owner.Name)
assert.Equal(t, tm.StatusToDo, task.Status)
assert.Equal(t, tm.PriorityHigh, task.Priority)
}
func TestParseTaskFromMarkdownInvalid(t *testing.T) {
tempDir, cleanup := setupTestDir(t)
defer cleanup()
gtm, _ := createTestTaskManager(t, tempDir)
// Test invalid markdown format
invalidMarkdown := "This is not valid markdown"
task, err := gtm.parseTaskFromMarkdown(invalidMarkdown)
assert.Error(t, err)
assert.Nil(t, task)
assert.Contains(t, err.Error(), "invalid markdown format")
}
func TestWriteAndReadTaskFile(t *testing.T) {
tempDir, cleanup := setupTestDir(t)
defer cleanup()
gtm, _ := createTestTaskManager(t, tempDir)
// Ensure tasks directory exists
err := gtm.ensureTasksDir()
require.NoError(t, err)
// Create test task
task := &tm.Task{
ID: "test-task-123",
Title: "Test Task",
Description: "This is a test task",
Owner: tm.Owner{
ID: "user123",
Name: "Test User",
},
Status: tm.StatusToDo,
Priority: tm.PriorityHigh,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
// Write task file
err = gtm.writeTaskFile(task)
assert.NoError(t, err)
// Verify file exists
filePath := filepath.Join(gtm.tasksDir, task.ID+".md")
_, err = os.Stat(filePath)
assert.NoError(t, err)
// Read task file
readTask, err := gtm.readTaskFile(task.ID)
assert.NoError(t, err)
assert.NotNil(t, readTask)
assert.Equal(t, task.ID, readTask.ID)
assert.Equal(t, task.Title, readTask.Title)
assert.Equal(t, task.Description, readTask.Description)
assert.Equal(t, task.Owner.ID, readTask.Owner.ID)
assert.Equal(t, task.Owner.Name, readTask.Owner.Name)
assert.Equal(t, task.Status, readTask.Status)
assert.Equal(t, task.Priority, readTask.Priority)
}
func TestReadTaskFileNotFound(t *testing.T) {
tempDir, cleanup := setupTestDir(t)
defer cleanup()
gtm, _ := createTestTaskManager(t, tempDir)
// Try to read non-existent task
task, err := gtm.readTaskFile("non-existent-task")
assert.Error(t, err)
assert.Nil(t, task)
assert.Equal(t, tm.ErrTaskNotFound, err)
}
func TestListTaskFiles(t *testing.T) {
tempDir, cleanup := setupTestDir(t)
defer cleanup()
gtm, _ := createTestTaskManager(t, tempDir)
// Ensure tasks directory exists
err := gtm.ensureTasksDir()
require.NoError(t, err)
// Create some test task files
taskIDs := []string{"task-1", "task-2", "task-3"}
for _, id := range taskIDs {
task := &tm.Task{
ID: id,
Title: "Test Task " + id,
Description: "Test task description",
Owner: tm.Owner{
ID: "user123",
Name: "Test User",
},
Status: tm.StatusToDo,
Priority: tm.PriorityMedium,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
err = gtm.writeTaskFile(task)
require.NoError(t, err)
}
// Create a non-task file
nonTaskFile := filepath.Join(gtm.tasksDir, "readme.txt")
err = os.WriteFile(nonTaskFile, []byte("This is not a task"), 0644)
require.NoError(t, err)
// List task files
taskFiles, err := gtm.listTaskFiles()
assert.NoError(t, err)
assert.Len(t, taskFiles, 3)
// Verify all task IDs are present
for _, id := range taskIDs {
assert.Contains(t, taskFiles, id)
}
}
func TestListTaskFilesEmpty(t *testing.T) {
tempDir, cleanup := setupTestDir(t)
defer cleanup()
gtm, _ := createTestTaskManager(t, tempDir)
// List task files in non-existent directory
taskFiles, err := gtm.listTaskFiles()
assert.NoError(t, err)
assert.Empty(t, taskFiles)
}
func TestCommitTaskChange(t *testing.T) {
tempDir, cleanup := setupTestDir(t)
defer cleanup()
gtm, gitImpl := createTestTaskManager(t, tempDir)
// Create a test task file first
task := &tm.Task{
ID: "test-task-123",
Title: "Test Task",
Description: "Test description",
Owner: tm.Owner{
ID: "user123",
Name: "Test User",
},
Status: tm.StatusToDo,
Priority: tm.PriorityMedium,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
err := gtm.ensureTasksDir()
require.NoError(t, err)
err = gtm.writeTaskFile(task)
require.NoError(t, err)
// Test successful commit
err = gtm.commitTaskChange("test-task-123", "created", task.Owner)
assert.NoError(t, err)
// Verify commit was created
ctx := context.Background()
commits, err := gitImpl.Log(ctx, git.LogOptions{MaxCount: 1})
assert.NoError(t, err)
if len(commits) > 0 {
assert.Contains(t, commits[0].Message, "test-task-123")
assert.Contains(t, commits[0].Message, "created")
}
}
func TestCreateTask(t *testing.T) {
tempDir, cleanup := setupTestDir(t)
defer cleanup()
gtm, gitImpl := createTestTaskManager(t, tempDir)
ctx := context.Background()
req := &tm.TaskCreateRequest{
Title: "New Test Task",
Description: "This is a new test task",
OwnerID: "user123",
Priority: tm.PriorityHigh,
}
task, err := gtm.CreateTask(ctx, req)
assert.NoError(t, err)
assert.NotNil(t, task)
// Verify task properties
assert.NotEmpty(t, task.ID)
assert.Contains(t, task.ID, "task-")
assert.Equal(t, req.Title, task.Title)
assert.Equal(t, req.Description, task.Description)
assert.Equal(t, req.OwnerID, task.Owner.ID)
assert.Equal(t, req.OwnerID, task.Owner.Name) // TODO: Should look up actual name
assert.Equal(t, tm.StatusToDo, task.Status)
assert.Equal(t, req.Priority, task.Priority)
assert.False(t, task.CreatedAt.IsZero())
assert.False(t, task.UpdatedAt.IsZero())
// Verify git commit was created
commits, err := gitImpl.Log(ctx, git.LogOptions{MaxCount: 1})
assert.NoError(t, err)
if len(commits) > 0 {
assert.Contains(t, commits[0].Message, task.ID)
assert.Contains(t, commits[0].Message, "created")
}
}
func TestCreateTaskInvalidData(t *testing.T) {
tempDir, cleanup := setupTestDir(t)
defer cleanup()
gtm, _ := createTestTaskManager(t, tempDir)
ctx := context.Background()
// Test empty title
req := &tm.TaskCreateRequest{
Title: "",
OwnerID: "user123",
}
task, err := gtm.CreateTask(ctx, req)
assert.Error(t, err)
assert.Nil(t, task)
assert.Equal(t, tm.ErrInvalidTaskData, err)
// Test empty owner ID
req = &tm.TaskCreateRequest{
Title: "Valid Title",
OwnerID: "",
}
task, err = gtm.CreateTask(ctx, req)
assert.Error(t, err)
assert.Nil(t, task)
assert.Equal(t, tm.ErrInvalidOwner, err)
}
func TestGetTask(t *testing.T) {
tempDir, cleanup := setupTestDir(t)
defer cleanup()
gtm, _ := createTestTaskManager(t, tempDir)
// Create a test task
task := &tm.Task{
ID: "test-task-123",
Title: "Test Task",
Description: "Test task description",
Owner: tm.Owner{
ID: "user123",
Name: "Test User",
},
Status: tm.StatusToDo,
Priority: tm.PriorityMedium,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
err := gtm.ensureTasksDir()
require.NoError(t, err)
err = gtm.writeTaskFile(task)
require.NoError(t, err)
// Get the task
ctx := context.Background()
retrievedTask, err := gtm.GetTask(ctx, task.ID)
assert.NoError(t, err)
assert.NotNil(t, retrievedTask)
assert.Equal(t, task.ID, retrievedTask.ID)
assert.Equal(t, task.Title, retrievedTask.Title)
}
func TestGetTaskNotFound(t *testing.T) {
tempDir, cleanup := setupTestDir(t)
defer cleanup()
gtm, _ := createTestTaskManager(t, tempDir)
ctx := context.Background()
task, err := gtm.GetTask(ctx, "non-existent-task")
assert.Error(t, err)
assert.Nil(t, task)
assert.Equal(t, tm.ErrTaskNotFound, err)
}
func TestUpdateTask(t *testing.T) {
tempDir, cleanup := setupTestDir(t)
defer cleanup()
gtm, gitImpl := createTestTaskManager(t, tempDir)
// Create a test task
originalTask := &tm.Task{
ID: "test-task-123",
Title: "Original Title",
Description: "Original description",
Owner: tm.Owner{
ID: "user123",
Name: "Original User",
},
Status: tm.StatusToDo,
Priority: tm.PriorityLow,
CreatedAt: time.Now().Add(-time.Hour),
UpdatedAt: time.Now().Add(-time.Hour),
}
err := gtm.ensureTasksDir()
require.NoError(t, err)
err = gtm.writeTaskFile(originalTask)
require.NoError(t, err)
// Commit the initial task
err = gtm.commitTaskChange(originalTask.ID, "created", originalTask.Owner)
require.NoError(t, err)
// Update the task
ctx := context.Background()
newTitle := "Updated Title"
newDescription := "Updated description"
newStatus := tm.StatusInProgress
newPriority := tm.PriorityHigh
newOwnerID := "user456"
req := &tm.TaskUpdateRequest{
Title: &newTitle,
Description: &newDescription,
Status: &newStatus,
Priority: &newPriority,
OwnerID: &newOwnerID,
}
updatedTask, err := gtm.UpdateTask(ctx, originalTask.ID, req)
assert.NoError(t, err)
assert.NotNil(t, updatedTask)
// Verify updated properties
assert.Equal(t, newTitle, updatedTask.Title)
assert.Equal(t, newDescription, updatedTask.Description)
assert.Equal(t, newStatus, updatedTask.Status)
assert.Equal(t, newPriority, updatedTask.Priority)
assert.Equal(t, newOwnerID, updatedTask.Owner.ID)
assert.Equal(t, newOwnerID, updatedTask.Owner.Name)
// Verify timestamps were updated
assert.True(t, updatedTask.UpdatedAt.After(originalTask.UpdatedAt))
// Verify git commit was created
commits, err := gitImpl.Log(ctx, git.LogOptions{MaxCount: 2})
assert.NoError(t, err)
if len(commits) > 0 {
assert.Contains(t, commits[0].Message, "updated")
}
}
func TestUpdateTaskNotFound(t *testing.T) {
tempDir, cleanup := setupTestDir(t)
defer cleanup()
gtm, _ := createTestTaskManager(t, tempDir)
ctx := context.Background()
newTitle := "Updated Title"
req := &tm.TaskUpdateRequest{
Title: &newTitle,
}
task, err := gtm.UpdateTask(ctx, "non-existent-task", req)
assert.Error(t, err)
assert.Nil(t, task)
assert.Equal(t, tm.ErrTaskNotFound, err)
}
func TestUpdateTaskNoChanges(t *testing.T) {
tempDir, cleanup := setupTestDir(t)
defer cleanup()
gtm, _ := createTestTaskManager(t, tempDir)
// Create a test task
originalTask := &tm.Task{
ID: "test-task-123",
Title: "Test Task",
Description: "Test description",
Owner: tm.Owner{
ID: "user123",
Name: "Test User",
},
Status: tm.StatusToDo,
Priority: tm.PriorityMedium,
CreatedAt: time.Now().Add(-time.Hour),
UpdatedAt: time.Now().Add(-time.Hour),
}
err := gtm.ensureTasksDir()
require.NoError(t, err)
err = gtm.writeTaskFile(originalTask)
require.NoError(t, err)
// Update with no changes
ctx := context.Background()
req := &tm.TaskUpdateRequest{}
updatedTask, err := gtm.UpdateTask(ctx, originalTask.ID, req)
assert.NoError(t, err)
assert.NotNil(t, updatedTask)
// Verify no changes were made
assert.Equal(t, originalTask.Title, updatedTask.Title)
assert.Equal(t, originalTask.Description, updatedTask.Description)
assert.Equal(t, originalTask.Status, updatedTask.Status)
assert.Equal(t, originalTask.Priority, updatedTask.Priority)
assert.Equal(t, originalTask.Owner.ID, updatedTask.Owner.ID)
}
func TestUpdateTaskStatusTimestamps(t *testing.T) {
tempDir, cleanup := setupTestDir(t)
defer cleanup()
gtm, _ := createTestTaskManager(t, tempDir)
// Create a test task
task := &tm.Task{
ID: "test-task-123",
Title: "Test Task",
Description: "Test description",
Owner: tm.Owner{
ID: "user123",
Name: "Test User",
},
Status: tm.StatusToDo,
Priority: tm.PriorityMedium,
CreatedAt: time.Now().Add(-time.Hour),
UpdatedAt: time.Now().Add(-time.Hour),
}
err := gtm.ensureTasksDir()
require.NoError(t, err)
err = gtm.writeTaskFile(task)
require.NoError(t, err)
ctx := context.Background()
// Test completing a task
completedStatus := tm.StatusCompleted
req := &tm.TaskUpdateRequest{
Status: &completedStatus,
}
updatedTask, err := gtm.UpdateTask(ctx, task.ID, req)
assert.NoError(t, err)
assert.NotNil(t, updatedTask)
assert.Equal(t, tm.StatusCompleted, updatedTask.Status)
assert.NotNil(t, updatedTask.CompletedAt)
// Test archiving a task
archivedStatus := tm.StatusArchived
req = &tm.TaskUpdateRequest{
Status: &archivedStatus,
}
updatedTask, err = gtm.UpdateTask(ctx, task.ID, req)
assert.NoError(t, err)
assert.NotNil(t, updatedTask)
assert.Equal(t, tm.StatusArchived, updatedTask.Status)
assert.NotNil(t, updatedTask.ArchivedAt)
}
func TestArchiveTask(t *testing.T) {
tempDir, cleanup := setupTestDir(t)
defer cleanup()
gtm, _ := createTestTaskManager(t, tempDir)
// Create a test task
task := &tm.Task{
ID: "test-task-123",
Title: "Test Task",
Description: "Test description",
Owner: tm.Owner{
ID: "user123",
Name: "Test User",
},
Status: tm.StatusToDo,
Priority: tm.PriorityMedium,
CreatedAt: time.Now().Add(-time.Hour),
UpdatedAt: time.Now().Add(-time.Hour),
}
err := gtm.ensureTasksDir()
require.NoError(t, err)
err = gtm.writeTaskFile(task)
require.NoError(t, err)
// Archive the task
ctx := context.Background()
err = gtm.ArchiveTask(ctx, task.ID)
assert.NoError(t, err)
// Verify task was archived
archivedTask, err := gtm.GetTask(ctx, task.ID)
assert.NoError(t, err)
assert.Equal(t, tm.StatusArchived, archivedTask.Status)
assert.NotNil(t, archivedTask.ArchivedAt)
}
func TestStartTask(t *testing.T) {
tempDir, cleanup := setupTestDir(t)
defer cleanup()
gtm, _ := createTestTaskManager(t, tempDir)
// Create a test task
task := &tm.Task{
ID: "test-task-123",
Title: "Test Task",
Description: "Test description",
Owner: tm.Owner{
ID: "user123",
Name: "Test User",
},
Status: tm.StatusToDo,
Priority: tm.PriorityMedium,
CreatedAt: time.Now().Add(-time.Hour),
UpdatedAt: time.Now().Add(-time.Hour),
}
err := gtm.ensureTasksDir()
require.NoError(t, err)
err = gtm.writeTaskFile(task)
require.NoError(t, err)
// Start the task
ctx := context.Background()
startedTask, err := gtm.StartTask(ctx, task.ID)
assert.NoError(t, err)
assert.NotNil(t, startedTask)
assert.Equal(t, tm.StatusInProgress, startedTask.Status)
}
func TestCompleteTask(t *testing.T) {
tempDir, cleanup := setupTestDir(t)
defer cleanup()
gtm, _ := createTestTaskManager(t, tempDir)
// Create a test task
task := &tm.Task{
ID: "test-task-123",
Title: "Test Task",
Description: "Test description",
Owner: tm.Owner{
ID: "user123",
Name: "Test User",
},
Status: tm.StatusInProgress,
Priority: tm.PriorityMedium,
CreatedAt: time.Now().Add(-time.Hour),
UpdatedAt: time.Now().Add(-time.Hour),
}
err := gtm.ensureTasksDir()
require.NoError(t, err)
err = gtm.writeTaskFile(task)
require.NoError(t, err)
// Complete the task
ctx := context.Background()
completedTask, err := gtm.CompleteTask(ctx, task.ID)
assert.NoError(t, err)
assert.NotNil(t, completedTask)
assert.Equal(t, tm.StatusCompleted, completedTask.Status)
assert.NotNil(t, completedTask.CompletedAt)
}
func TestListTasks(t *testing.T) {
tempDir, cleanup := setupTestDir(t)
defer cleanup()
gtm, _ := createTestTaskManager(t, tempDir)
// Create test tasks
tasks := []*tm.Task{
{
ID: "task-1",
Title: "Task 1",
Description: "First task",
Owner: tm.Owner{ID: "user1", Name: "User 1"},
Status: tm.StatusToDo,
Priority: tm.PriorityHigh,
CreatedAt: time.Now().Add(-2 * time.Hour),
UpdatedAt: time.Now().Add(-2 * time.Hour),
},
{
ID: "task-2",
Title: "Task 2",
Description: "Second task",
Owner: tm.Owner{ID: "user2", Name: "User 2"},
Status: tm.StatusInProgress,
Priority: tm.PriorityMedium,
CreatedAt: time.Now().Add(-1 * time.Hour),
UpdatedAt: time.Now().Add(-1 * time.Hour),
},
{
ID: "task-3",
Title: "Task 3",
Description: "Third task",
Owner: tm.Owner{ID: "user1", Name: "User 1"},
Status: tm.StatusCompleted,
Priority: tm.PriorityLow,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
},
}
err := gtm.ensureTasksDir()
require.NoError(t, err)
for _, task := range tasks {
err = gtm.writeTaskFile(task)
require.NoError(t, err)
}
ctx := context.Background()
// Test listing all tasks
taskList, err := gtm.ListTasks(ctx, nil, 0, 10)
assert.NoError(t, err)
assert.NotNil(t, taskList)
assert.Len(t, taskList.Tasks, 3)
assert.Equal(t, 3, taskList.TotalCount)
assert.Equal(t, 0, taskList.Page)
assert.Equal(t, 10, taskList.PageSize)
assert.False(t, taskList.HasMore)
// Test pagination
taskList, err = gtm.ListTasks(ctx, nil, 0, 2)
assert.NoError(t, err)
assert.Len(t, taskList.Tasks, 2)
assert.Equal(t, 3, taskList.TotalCount)
assert.True(t, taskList.HasMore)
// Test filtering by owner
ownerFilter := &tm.TaskFilter{OwnerID: stringPtr("user1")}
taskList, err = gtm.ListTasks(ctx, ownerFilter, 0, 10)
assert.NoError(t, err)
assert.Len(t, taskList.Tasks, 2)
// Test filtering by status
statusFilter := &tm.TaskFilter{Status: taskStatusPtr(tm.StatusToDo)}
taskList, err = gtm.ListTasks(ctx, statusFilter, 0, 10)
assert.NoError(t, err)
assert.Len(t, taskList.Tasks, 1)
assert.Equal(t, "task-1", taskList.Tasks[0].ID)
// Test filtering by priority
priorityFilter := &tm.TaskFilter{Priority: taskPriorityPtr(tm.PriorityHigh)}
taskList, err = gtm.ListTasks(ctx, priorityFilter, 0, 10)
assert.NoError(t, err)
assert.Len(t, taskList.Tasks, 1)
assert.Equal(t, "task-1", taskList.Tasks[0].ID)
}
func TestGetTasksByOwner(t *testing.T) {
tempDir, cleanup := setupTestDir(t)
defer cleanup()
gtm, _ := createTestTaskManager(t, tempDir)
// Create test tasks
tasks := []*tm.Task{
{
ID: "task-1",
Title: "Task 1",
Owner: tm.Owner{ID: "user1", Name: "User 1"},
Status: tm.StatusToDo,
Priority: tm.PriorityHigh,
CreatedAt: time.Now().Add(-2 * time.Hour),
UpdatedAt: time.Now().Add(-2 * time.Hour),
},
{
ID: "task-2",
Title: "Task 2",
Owner: tm.Owner{ID: "user2", Name: "User 2"},
Status: tm.StatusInProgress,
Priority: tm.PriorityMedium,
CreatedAt: time.Now().Add(-1 * time.Hour),
UpdatedAt: time.Now().Add(-1 * time.Hour),
},
{
ID: "task-3",
Title: "Task 3",
Owner: tm.Owner{ID: "user1", Name: "User 1"},
Status: tm.StatusCompleted,
Priority: tm.PriorityLow,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
},
}
err := gtm.ensureTasksDir()
require.NoError(t, err)
for _, task := range tasks {
err = gtm.writeTaskFile(task)
require.NoError(t, err)
}
ctx := context.Background()
// Get tasks by owner
taskList, err := gtm.GetTasksByOwner(ctx, "user1", 0, 10)
assert.NoError(t, err)
assert.NotNil(t, taskList)
assert.Len(t, taskList.Tasks, 2)
for _, task := range taskList.Tasks {
assert.Equal(t, "user1", task.Owner.ID)
}
}
func TestGetTasksByStatus(t *testing.T) {
tempDir, cleanup := setupTestDir(t)
defer cleanup()
gtm, _ := createTestTaskManager(t, tempDir)
// Create test tasks
tasks := []*tm.Task{
{
ID: "task-1",
Title: "Task 1",
Owner: tm.Owner{ID: "user1", Name: "User 1"},
Status: tm.StatusToDo,
Priority: tm.PriorityHigh,
CreatedAt: time.Now().Add(-2 * time.Hour),
UpdatedAt: time.Now().Add(-2 * time.Hour),
},
{
ID: "task-2",
Title: "Task 2",
Owner: tm.Owner{ID: "user2", Name: "User 2"},
Status: tm.StatusInProgress,
Priority: tm.PriorityMedium,
CreatedAt: time.Now().Add(-1 * time.Hour),
UpdatedAt: time.Now().Add(-1 * time.Hour),
},
{
ID: "task-3",
Title: "Task 3",
Owner: tm.Owner{ID: "user1", Name: "User 1"},
Status: tm.StatusCompleted,
Priority: tm.PriorityLow,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
},
}
err := gtm.ensureTasksDir()
require.NoError(t, err)
for _, task := range tasks {
err = gtm.writeTaskFile(task)
require.NoError(t, err)
}
ctx := context.Background()
// Get tasks by status
taskList, err := gtm.GetTasksByStatus(ctx, tm.StatusToDo, 0, 10)
assert.NoError(t, err)
assert.NotNil(t, taskList)
assert.Len(t, taskList.Tasks, 1)
assert.Equal(t, tm.StatusToDo, taskList.Tasks[0].Status)
}
func TestGetTasksByPriority(t *testing.T) {
tempDir, cleanup := setupTestDir(t)
defer cleanup()
gtm, _ := createTestTaskManager(t, tempDir)
// Create test tasks
tasks := []*tm.Task{
{
ID: "task-1",
Title: "Task 1",
Owner: tm.Owner{ID: "user1", Name: "User 1"},
Status: tm.StatusToDo,
Priority: tm.PriorityHigh,
CreatedAt: time.Now().Add(-2 * time.Hour),
UpdatedAt: time.Now().Add(-2 * time.Hour),
},
{
ID: "task-2",
Title: "Task 2",
Owner: tm.Owner{ID: "user2", Name: "User 2"},
Status: tm.StatusInProgress,
Priority: tm.PriorityMedium,
CreatedAt: time.Now().Add(-1 * time.Hour),
UpdatedAt: time.Now().Add(-1 * time.Hour),
},
{
ID: "task-3",
Title: "Task 3",
Owner: tm.Owner{ID: "user1", Name: "User 1"},
Status: tm.StatusCompleted,
Priority: tm.PriorityLow,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
},
}
err := gtm.ensureTasksDir()
require.NoError(t, err)
for _, task := range tasks {
err = gtm.writeTaskFile(task)
require.NoError(t, err)
}
ctx := context.Background()
// Get tasks by priority
taskList, err := gtm.GetTasksByPriority(ctx, tm.PriorityHigh, 0, 10)
assert.NoError(t, err)
assert.NotNil(t, taskList)
assert.Len(t, taskList.Tasks, 1)
assert.Equal(t, tm.PriorityHigh, taskList.Tasks[0].Priority)
}
// Helper functions for creating pointers to string, TaskStatus, and TaskPriority
func stringPtr(s string) *string {
return &s
}
func taskStatusPtr(status tm.TaskStatus) *tm.TaskStatus {
return &status
}
func taskPriorityPtr(priority tm.TaskPriority) *tm.TaskPriority {
return &priority
}