summaryrefslogtreecommitdiff
path: root/internal/handlers/atoms_test.go
blob: 7cb94a776af378056b58069515c9ff4ce07a79c7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package handlers

import (
	"context"
	"testing"

	"task-dashboard/internal/models"
	"task-dashboard/internal/store"
)

type mockClaudomatorClient struct {
	stories []models.ClaudomatorStory
}

func (m *mockClaudomatorClient) GetActiveStories(ctx context.Context) ([]models.ClaudomatorStory, error) {
	return m.stories, nil
}

func TestBuildUnifiedAtomList_WithNativeTasks(t *testing.T) {
	s, err := store.New(":memory:", "../../migrations")
	if err != nil {
		t.Fatalf("failed to create in-memory store: %v", err)
	}
	defer s.Close()

	if err := s.CreateNativeTask(models.Task{ID: "native-1", Content: "Buy milk"}); err != nil {
		t.Fatalf("failed to create native task: %v", err)
	}

	atoms, _, err := BuildUnifiedAtomList(s, nil)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	found := false
	for _, a := range atoms {
		if a.Source == "doot" && a.Title == "Buy milk" {
			found = true
			break
		}
	}
	if !found {
		t.Errorf("expected atom with Source='doot' and Title='Buy milk'; got atoms: %+v", atoms)
	}
}

func TestBuildUnifiedAtomList_ExcludesLockedChainTasks(t *testing.T) {
	s, err := store.New(":memory:", "../../migrations")
	if err != nil {
		t.Fatalf("failed to create in-memory store: %v", err)
	}
	defer s.Close()

	if _, err := s.CreateChain("Track", []models.ChainTaskInput{
		{Content: "Step 1"}, {Content: "Step 2"}, {Content: "Step 3"},
	}); err != nil {
		t.Fatal(err)
	}

	atoms, _, err := BuildUnifiedAtomList(s, nil)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	for _, a := range atoms {
		if a.Title == "Step 1" || a.Title == "Step 2" || a.Title == "Step 3" {
			t.Errorf("chain task %q should not appear in the flat atom list (chains get their own Chains section)", a.Title)
		}
	}
}

func TestBuildUnifiedAtomList_ExcludesDormantBucketItems(t *testing.T) {
	s, err := store.New(":memory:", "../../migrations")
	if err != nil {
		t.Fatalf("failed to create in-memory store: %v", err)
	}
	defer s.Close()

	bucket, err := s.CreateBucket("Gutters", 30, 1)
	if err != nil {
		t.Fatal(err)
	}
	if err := s.CreateNativeTask(models.Task{ID: "pool-item", Content: "Clean gutters", Priority: 1}); err != nil {
		t.Fatal(err)
	}
	if err := s.AddBucketItem(bucket.ID, "pool-item"); err != nil {
		t.Fatal(err)
	}

	atoms, _, err := BuildUnifiedAtomList(s, nil)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	for _, a := range atoms {
		if a.Title == "Clean gutters" {
			t.Error("dormant bucket-pool item should not appear in the flat atom list")
		}
	}
}

func TestBuildUnifiedAtomList_WithClaudomator(t *testing.T) {
	s, err := store.New(":memory:", "../../migrations")
	if err != nil {
		t.Fatalf("failed to create in-memory store: %v", err)
	}
	defer s.Close()

	mock := &mockClaudomatorClient{
		stories: []models.ClaudomatorStory{
			{ID: "s1", Title: "My story", Status: "IN_PROGRESS", ProjectID: "nav"},
		},
	}

	atoms, _, err := BuildUnifiedAtomList(s, mock)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	found := false
	for _, a := range atoms {
		if a.Source == "claudomator" && a.Title == "My story" {
			found = true
			break
		}
	}
	if !found {
		t.Error("expected atom with Source='claudomator' and Title='My story'")
	}
}