fizzy-cli 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (156) hide show
  1. package/package.json +2 -1
  2. package/.env +0 -1
  3. package/.github/workflows/release.yml +0 -29
  4. package/.github/workflows/tests.yml +0 -24
  5. package/AGENTS.md +0 -33
  6. package/CHANGELOG.md +0 -194
  7. package/Makefile +0 -43
  8. package/bin/fizzy +0 -0
  9. package/cmd/account.go +0 -14
  10. package/cmd/account_list.go +0 -44
  11. package/cmd/account_list_test.go +0 -118
  12. package/cmd/board.go +0 -49
  13. package/cmd/board_create.go +0 -59
  14. package/cmd/board_create_test.go +0 -141
  15. package/cmd/board_delete.go +0 -40
  16. package/cmd/board_delete_test.go +0 -121
  17. package/cmd/board_list.go +0 -44
  18. package/cmd/board_list_test.go +0 -115
  19. package/cmd/board_show.go +0 -40
  20. package/cmd/board_show_test.go +0 -113
  21. package/cmd/board_test.go +0 -92
  22. package/cmd/board_update.go +0 -72
  23. package/cmd/board_update_test.go +0 -233
  24. package/cmd/card.go +0 -24
  25. package/cmd/card_assign.go +0 -55
  26. package/cmd/card_assign_test.go +0 -130
  27. package/cmd/card_close.go +0 -46
  28. package/cmd/card_close_test.go +0 -92
  29. package/cmd/card_create.go +0 -72
  30. package/cmd/card_create_test.go +0 -186
  31. package/cmd/card_delete.go +0 -46
  32. package/cmd/card_delete_test.go +0 -92
  33. package/cmd/card_golden.go +0 -46
  34. package/cmd/card_golden_test.go +0 -92
  35. package/cmd/card_list.go +0 -114
  36. package/cmd/card_list_test.go +0 -373
  37. package/cmd/card_not_now.go +0 -46
  38. package/cmd/card_not_now_test.go +0 -92
  39. package/cmd/card_reaction.go +0 -13
  40. package/cmd/card_reaction_create.go +0 -46
  41. package/cmd/card_reaction_create_test.go +0 -148
  42. package/cmd/card_reaction_delete.go +0 -46
  43. package/cmd/card_reaction_delete_test.go +0 -112
  44. package/cmd/card_reaction_list.go +0 -51
  45. package/cmd/card_reaction_list_test.go +0 -127
  46. package/cmd/card_reopen.go +0 -46
  47. package/cmd/card_reopen_test.go +0 -92
  48. package/cmd/card_show.go +0 -46
  49. package/cmd/card_show_test.go +0 -92
  50. package/cmd/card_tag.go +0 -51
  51. package/cmd/card_tag_test.go +0 -112
  52. package/cmd/card_triage.go +0 -46
  53. package/cmd/card_ungolden.go +0 -46
  54. package/cmd/card_ungolden_test.go +0 -92
  55. package/cmd/card_untriage.go +0 -46
  56. package/cmd/card_untriage_test.go +0 -92
  57. package/cmd/card_unwatch.go +0 -46
  58. package/cmd/card_unwatch_test.go +0 -92
  59. package/cmd/card_update.go +0 -82
  60. package/cmd/card_update_test.go +0 -149
  61. package/cmd/card_watch.go +0 -46
  62. package/cmd/card_watch_test.go +0 -92
  63. package/cmd/column.go +0 -14
  64. package/cmd/column_create.go +0 -79
  65. package/cmd/column_create_test.go +0 -178
  66. package/cmd/column_delete.go +0 -40
  67. package/cmd/column_delete_test.go +0 -121
  68. package/cmd/column_list.go +0 -44
  69. package/cmd/column_list_test.go +0 -138
  70. package/cmd/column_show.go +0 -40
  71. package/cmd/column_show_test.go +0 -111
  72. package/cmd/column_update.go +0 -67
  73. package/cmd/column_update_test.go +0 -198
  74. package/cmd/comment.go +0 -14
  75. package/cmd/comment_create.go +0 -51
  76. package/cmd/comment_create_test.go +0 -129
  77. package/cmd/comment_delete.go +0 -46
  78. package/cmd/comment_delete_test.go +0 -92
  79. package/cmd/comment_list.go +0 -51
  80. package/cmd/comment_list_test.go +0 -132
  81. package/cmd/comment_show.go +0 -46
  82. package/cmd/comment_show_test.go +0 -104
  83. package/cmd/comment_update.go +0 -51
  84. package/cmd/comment_update_test.go +0 -130
  85. package/cmd/login.go +0 -81
  86. package/cmd/login_test.go +0 -98
  87. package/cmd/notification.go +0 -14
  88. package/cmd/notification_list.go +0 -69
  89. package/cmd/notification_list_test.go +0 -288
  90. package/cmd/notification_read.go +0 -51
  91. package/cmd/notification_read_all.go +0 -38
  92. package/cmd/notification_read_all_test.go +0 -75
  93. package/cmd/notification_read_test.go +0 -138
  94. package/cmd/notification_unread.go +0 -44
  95. package/cmd/notification_unread_test.go +0 -99
  96. package/cmd/reaction.go +0 -13
  97. package/cmd/reaction_create.go +0 -46
  98. package/cmd/reaction_create_test.go +0 -113
  99. package/cmd/reaction_delete.go +0 -46
  100. package/cmd/reaction_delete_test.go +0 -92
  101. package/cmd/reaction_list.go +0 -51
  102. package/cmd/reaction_list_test.go +0 -125
  103. package/cmd/root.go +0 -38
  104. package/cmd/step.go +0 -14
  105. package/cmd/step_create.go +0 -53
  106. package/cmd/step_create_test.go +0 -171
  107. package/cmd/step_delete.go +0 -46
  108. package/cmd/step_delete_test.go +0 -92
  109. package/cmd/step_update.go +0 -66
  110. package/cmd/step_update_test.go +0 -190
  111. package/cmd/tag.go +0 -15
  112. package/cmd/tag_list.go +0 -47
  113. package/cmd/tag_list_test.go +0 -109
  114. package/cmd/use.go +0 -85
  115. package/cmd/use_test.go +0 -186
  116. package/cmd/user.go +0 -22
  117. package/cmd/user_deactivate.go +0 -40
  118. package/cmd/user_deactivate_test.go +0 -121
  119. package/cmd/user_list.go +0 -44
  120. package/cmd/user_list_test.go +0 -126
  121. package/cmd/user_show.go +0 -40
  122. package/cmd/user_show_test.go +0 -110
  123. package/cmd/user_update.go +0 -71
  124. package/cmd/user_update_test.go +0 -177
  125. package/go.mod +0 -31
  126. package/go.sum +0 -53
  127. package/internal/api/boards.go +0 -93
  128. package/internal/api/cards.go +0 -322
  129. package/internal/api/client.go +0 -99
  130. package/internal/api/columns.go +0 -113
  131. package/internal/api/comments.go +0 -108
  132. package/internal/api/identity.go +0 -24
  133. package/internal/api/notifications.go +0 -89
  134. package/internal/api/reactions.go +0 -130
  135. package/internal/api/steps.go +0 -101
  136. package/internal/api/tags.go +0 -24
  137. package/internal/api/types.go +0 -195
  138. package/internal/api/users.go +0 -75
  139. package/internal/app/app.go +0 -49
  140. package/internal/colors/colors.go +0 -32
  141. package/internal/config/config.go +0 -70
  142. package/internal/testutil/client.go +0 -26
  143. package/internal/ui/account_list.go +0 -14
  144. package/internal/ui/account_selector.go +0 -63
  145. package/internal/ui/board_list.go +0 -14
  146. package/internal/ui/board_show.go +0 -17
  147. package/internal/ui/card_list.go +0 -14
  148. package/internal/ui/card_show.go +0 -23
  149. package/internal/ui/column_list.go +0 -28
  150. package/internal/ui/column_show.go +0 -16
  151. package/internal/ui/comment_list.go +0 -25
  152. package/internal/ui/format.go +0 -27
  153. package/internal/ui/notification_list.go +0 -27
  154. package/internal/ui/reaction_list.go +0 -14
  155. package/internal/ui/user_list.go +0 -19
  156. package/internal/ui/user_show.go +0 -23
@@ -1,178 +0,0 @@
1
- package cmd
2
-
3
- import (
4
- "context"
5
- "encoding/json"
6
- "io"
7
- "net/http"
8
- "net/http/httptest"
9
- "testing"
10
-
11
- "github.com/rogeriopvl/fizzy/internal/api"
12
- "github.com/rogeriopvl/fizzy/internal/app"
13
- "github.com/rogeriopvl/fizzy/internal/testutil"
14
- )
15
-
16
- func TestColumnCreateCommandSuccess(t *testing.T) {
17
- server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
18
- if r.URL.Path != "/boards/board-123/columns" {
19
- t.Errorf("expected /boards/board-123/columns, got %s", r.URL.Path)
20
- }
21
- if r.Method != http.MethodPost {
22
- t.Errorf("expected POST, got %s", r.Method)
23
- }
24
-
25
- auth := r.Header.Get("Authorization")
26
- if auth != "Bearer test-token" {
27
- t.Errorf("expected Bearer test-token, got %s", auth)
28
- }
29
-
30
- if r.Header.Get("Content-Type") != "application/json" {
31
- t.Errorf("expected Content-Type: application/json, got %s", r.Header.Get("Content-Type"))
32
- }
33
-
34
- body, _ := io.ReadAll(r.Body)
35
- var payload map[string]api.CreateColumnPayload
36
- if err := json.Unmarshal(body, &payload); err != nil {
37
- t.Fatalf("failed to unmarshal request body: %v", err)
38
- }
39
-
40
- columnPayload := payload["column"]
41
- if columnPayload.Name != "Todo" {
42
- t.Errorf("expected name 'Todo', got %s", columnPayload.Name)
43
- }
44
- if columnPayload.Color != nil {
45
- t.Errorf("expected no color, got %v", columnPayload.Color)
46
- }
47
-
48
- w.WriteHeader(http.StatusCreated)
49
- w.Header().Set("Location", "/columns/col-123")
50
- }))
51
- defer server.Close()
52
-
53
- client := testutil.NewTestClient(server.URL, "", "board-123", "test-token")
54
- testApp := &app.App{Client: client}
55
-
56
- cmd := columnCreateCmd
57
- cmd.SetContext(testApp.ToContext(context.Background()))
58
- cmd.ParseFlags([]string{"--name", "Todo"})
59
-
60
- if err := handleCreateColumn(cmd); err != nil {
61
- t.Fatalf("handleCreateColumn failed: %v", err)
62
- }
63
- }
64
-
65
- func TestColumnCreateCommandWithColor(t *testing.T) {
66
- server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
67
- if r.Method != http.MethodPost {
68
- t.Errorf("expected POST, got %s", r.Method)
69
- }
70
-
71
- body, _ := io.ReadAll(r.Body)
72
- var payload map[string]api.CreateColumnPayload
73
- json.Unmarshal(body, &payload)
74
-
75
- columnPayload := payload["column"]
76
- if columnPayload.Name != "In Progress" {
77
- t.Errorf("expected name 'In Progress', got %s", columnPayload.Name)
78
- }
79
- if columnPayload.Color == nil {
80
- t.Error("expected color to be set")
81
- }
82
- if *columnPayload.Color != "var(--color-card-4)" {
83
- t.Errorf("expected color 'var(--color-card-4)', got %s", *columnPayload.Color)
84
- }
85
-
86
- w.WriteHeader(http.StatusCreated)
87
- }))
88
- defer server.Close()
89
-
90
- client := testutil.NewTestClient(server.URL, "", "board-123", "test-token")
91
- testApp := &app.App{Client: client}
92
-
93
- cmd := columnCreateCmd
94
- cmd.SetContext(testApp.ToContext(context.Background()))
95
- cmd.ParseFlags([]string{"--name", "In Progress", "--color", "lime"})
96
-
97
- if err := handleCreateColumn(cmd); err != nil {
98
- t.Fatalf("handleCreateColumn failed: %v", err)
99
- }
100
- }
101
-
102
- func TestColumnCreateCommandInvalidColor(t *testing.T) {
103
- client := testutil.NewTestClient("http://localhost", "", "board-123", "test-token")
104
- testApp := &app.App{Client: client}
105
-
106
- cmd := columnCreateCmd
107
- cmd.SetContext(testApp.ToContext(context.Background()))
108
- cmd.ParseFlags([]string{"--name", "Todo", "--color", "invalid"})
109
-
110
- err := handleCreateColumn(cmd)
111
- if err == nil {
112
- t.Errorf("expected error for invalid color")
113
- }
114
- if err.Error() != "invalid color 'invalid'. Available colors: blue, gray, tan, yellow, lime, aqua, violet, purple, pink" {
115
- t.Errorf("expected invalid color error, got %v", err)
116
- }
117
- }
118
-
119
- func TestColumnCreateCommandNoBoard(t *testing.T) {
120
- server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
121
- w.WriteHeader(http.StatusInternalServerError)
122
- }))
123
- defer server.Close()
124
-
125
- client := testutil.NewTestClient(server.URL, "", "", "test-token")
126
- testApp := &app.App{Client: client}
127
-
128
- cmd := columnCreateCmd
129
- cmd.SetContext(testApp.ToContext(context.Background()))
130
- cmd.ParseFlags([]string{"--name", "Todo", "--color", ""})
131
-
132
- err := handleCreateColumn(cmd)
133
- if err == nil {
134
- t.Errorf("expected error when board not selected")
135
- }
136
- if err.Error() != "creating column: please select a board first with 'fizzy use --board <board_name>'" {
137
- t.Errorf("expected 'board not selected' error, got %v", err)
138
- }
139
- }
140
-
141
- func TestColumnCreateCommandNoClient(t *testing.T) {
142
- testApp := &app.App{}
143
-
144
- cmd := columnCreateCmd
145
- cmd.SetContext(testApp.ToContext(context.Background()))
146
- cmd.ParseFlags([]string{"--name", "Todo", "--color", ""})
147
-
148
- err := handleCreateColumn(cmd)
149
- if err == nil {
150
- t.Errorf("expected error when client not available")
151
- }
152
- if err.Error() != "API client not available" {
153
- t.Errorf("expected 'client not available' error, got %v", err)
154
- }
155
- }
156
-
157
- func TestColumnCreateCommandAPIError(t *testing.T) {
158
- server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
159
- w.WriteHeader(http.StatusInternalServerError)
160
- w.Write([]byte("Internal Server Error"))
161
- }))
162
- defer server.Close()
163
-
164
- client := testutil.NewTestClient(server.URL, "", "board-123", "test-token")
165
- testApp := &app.App{Client: client}
166
-
167
- cmd := columnCreateCmd
168
- cmd.SetContext(testApp.ToContext(context.Background()))
169
- cmd.ParseFlags([]string{"--name", "Todo", "--color", ""})
170
-
171
- err := handleCreateColumn(cmd)
172
- if err == nil {
173
- t.Errorf("expected error for API failure")
174
- }
175
- if err.Error() != "creating column: unexpected status code 500: Internal Server Error" {
176
- t.Errorf("expected API error, got %v", err)
177
- }
178
- }
@@ -1,40 +0,0 @@
1
- package cmd
2
-
3
- import (
4
- "context"
5
- "fmt"
6
-
7
- "github.com/rogeriopvl/fizzy/internal/app"
8
- "github.com/spf13/cobra"
9
- )
10
-
11
- var columnDeleteCmd = &cobra.Command{
12
- Use: "delete <column_id>",
13
- Short: "Delete a column",
14
- Long: `Delete a column. Only board administrators can delete columns.`,
15
- Args: cobra.ExactArgs(1),
16
- Run: func(cmd *cobra.Command, args []string) {
17
- if err := handleDeleteColumn(cmd, args[0]); err != nil {
18
- fmt.Fprintf(cmd.OutOrStderr(), "Error: %v\n", err)
19
- }
20
- },
21
- }
22
-
23
- func handleDeleteColumn(cmd *cobra.Command, columnID string) error {
24
- a := app.FromContext(cmd.Context())
25
- if a == nil || a.Client == nil {
26
- return fmt.Errorf("API client not available")
27
- }
28
-
29
- err := a.Client.DeleteColumn(context.Background(), columnID)
30
- if err != nil {
31
- return fmt.Errorf("deleting column: %w", err)
32
- }
33
-
34
- fmt.Fprintf(cmd.OutOrStdout(), "✓ Column '%s' deleted successfully\n", columnID)
35
- return nil
36
- }
37
-
38
- func init() {
39
- columnCmd.AddCommand(columnDeleteCmd)
40
- }
@@ -1,121 +0,0 @@
1
- package cmd
2
-
3
- import (
4
- "context"
5
- "net/http"
6
- "net/http/httptest"
7
- "testing"
8
-
9
- "github.com/rogeriopvl/fizzy/internal/app"
10
- "github.com/rogeriopvl/fizzy/internal/testutil"
11
- )
12
-
13
- func TestColumnDeleteCommandSuccess(t *testing.T) {
14
- server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
15
- if r.URL.Path != "/boards/board-123/columns/col-456" {
16
- t.Errorf("expected /boards/board-123/columns/col-456, got %s", r.URL.Path)
17
- }
18
- if r.Method != http.MethodDelete {
19
- t.Errorf("expected DELETE, got %s", r.Method)
20
- }
21
-
22
- auth := r.Header.Get("Authorization")
23
- if auth != "Bearer test-token" {
24
- t.Errorf("expected Bearer test-token, got %s", auth)
25
- }
26
-
27
- w.WriteHeader(http.StatusNoContent)
28
- }))
29
- defer server.Close()
30
-
31
- client := testutil.NewTestClient(server.URL, "", "board-123", "test-token")
32
- testApp := &app.App{Client: client}
33
-
34
- cmd := columnDeleteCmd
35
- cmd.SetContext(testApp.ToContext(context.Background()))
36
-
37
- if err := handleDeleteColumn(cmd, "col-456"); err != nil {
38
- t.Fatalf("handleDeleteColumn failed: %v", err)
39
- }
40
- }
41
-
42
- func TestColumnDeleteCommandNotFound(t *testing.T) {
43
- server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
44
- w.WriteHeader(http.StatusNotFound)
45
- w.Write([]byte("Column not found"))
46
- }))
47
- defer server.Close()
48
-
49
- client := testutil.NewTestClient(server.URL, "", "board-123", "test-token")
50
- testApp := &app.App{Client: client}
51
-
52
- cmd := columnDeleteCmd
53
- cmd.SetContext(testApp.ToContext(context.Background()))
54
-
55
- err := handleDeleteColumn(cmd, "nonexistent-col")
56
- if err == nil {
57
- t.Errorf("expected error for column not found")
58
- }
59
- if err.Error() != "deleting column: unexpected status code 404: Column not found" {
60
- t.Errorf("expected column not found error, got %v", err)
61
- }
62
- }
63
-
64
- func TestColumnDeleteCommandForbidden(t *testing.T) {
65
- server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
66
- w.WriteHeader(http.StatusForbidden)
67
- w.Write([]byte("You don't have permission to delete this column"))
68
- }))
69
- defer server.Close()
70
-
71
- client := testutil.NewTestClient(server.URL, "", "board-123", "test-token")
72
- testApp := &app.App{Client: client}
73
-
74
- cmd := columnDeleteCmd
75
- cmd.SetContext(testApp.ToContext(context.Background()))
76
-
77
- err := handleDeleteColumn(cmd, "col-456")
78
- if err == nil {
79
- t.Errorf("expected error for forbidden access")
80
- }
81
- if err.Error() != "deleting column: unexpected status code 403: You don't have permission to delete this column" {
82
- t.Errorf("expected permission error, got %v", err)
83
- }
84
- }
85
-
86
- func TestColumnDeleteCommandAPIError(t *testing.T) {
87
- server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
88
- w.WriteHeader(http.StatusInternalServerError)
89
- w.Write([]byte("Internal Server Error"))
90
- }))
91
- defer server.Close()
92
-
93
- client := testutil.NewTestClient(server.URL, "", "board-123", "test-token")
94
- testApp := &app.App{Client: client}
95
-
96
- cmd := columnDeleteCmd
97
- cmd.SetContext(testApp.ToContext(context.Background()))
98
-
99
- err := handleDeleteColumn(cmd, "col-456")
100
- if err == nil {
101
- t.Errorf("expected error for API failure")
102
- }
103
- if err.Error() != "deleting column: unexpected status code 500: Internal Server Error" {
104
- t.Errorf("expected API error, got %v", err)
105
- }
106
- }
107
-
108
- func TestColumnDeleteCommandNoClient(t *testing.T) {
109
- testApp := &app.App{}
110
-
111
- cmd := columnDeleteCmd
112
- cmd.SetContext(testApp.ToContext(context.Background()))
113
-
114
- err := handleDeleteColumn(cmd, "col-456")
115
- if err == nil {
116
- t.Errorf("expected error when client not available")
117
- }
118
- if err.Error() != "API client not available" {
119
- t.Errorf("expected 'client not available' error, got %v", err)
120
- }
121
- }
@@ -1,44 +0,0 @@
1
- package cmd
2
-
3
- import (
4
- "context"
5
- "fmt"
6
-
7
- "github.com/rogeriopvl/fizzy/internal/app"
8
- "github.com/rogeriopvl/fizzy/internal/ui"
9
- "github.com/spf13/cobra"
10
- )
11
-
12
- var columnListCmd = &cobra.Command{
13
- Use: "list",
14
- Short: "List all columns",
15
- Long: `Retrieve and display all columns in the selected board`,
16
- Run: func(cmd *cobra.Command, args []string) {
17
- if err := handleListColumns(cmd); err != nil {
18
- fmt.Fprintf(cmd.OutOrStderr(), "Error: %v\n", err)
19
- }
20
- },
21
- }
22
-
23
- func handleListColumns(cmd *cobra.Command) error {
24
- a := app.FromContext(cmd.Context())
25
- if a == nil || a.Client == nil {
26
- return fmt.Errorf("API client not available")
27
- }
28
-
29
- columns, err := a.Client.GetColumns(context.Background())
30
- if err != nil {
31
- return fmt.Errorf("fetching columns: %w", err)
32
- }
33
-
34
- if len(columns) == 0 {
35
- fmt.Println("No columns found")
36
- return nil
37
- }
38
-
39
- return ui.DisplayColumns(columns)
40
- }
41
-
42
- func init() {
43
- columnCmd.AddCommand(columnListCmd)
44
- }
@@ -1,138 +0,0 @@
1
- package cmd
2
-
3
- import (
4
- "context"
5
- "encoding/json"
6
- "net/http"
7
- "net/http/httptest"
8
- "testing"
9
-
10
- "github.com/rogeriopvl/fizzy/internal/api"
11
- "github.com/rogeriopvl/fizzy/internal/app"
12
- "github.com/rogeriopvl/fizzy/internal/testutil"
13
- )
14
-
15
- func TestColumnListCommand(t *testing.T) {
16
- server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
17
- if r.URL.Path != "/boards/board-123/columns" {
18
- t.Errorf("expected /boards/board-123/columns, got %s", r.URL.Path)
19
- }
20
- if r.Method != http.MethodGet {
21
- t.Errorf("expected GET, got %s", r.Method)
22
- }
23
-
24
- auth := r.Header.Get("Authorization")
25
- if auth != "Bearer test-token" {
26
- t.Errorf("expected Bearer test-token, got %s", auth)
27
- }
28
-
29
- if r.Header.Get("Accept") != "application/json" {
30
- t.Errorf("expected Accept: application/json, got %s", r.Header.Get("Accept"))
31
- }
32
-
33
- w.Header().Set("Content-Type", "application/json")
34
- response := []api.Column{
35
- {
36
- ID: "col-123",
37
- Name: "Todo",
38
- Color: api.ColorObject{
39
- Name: "Blue",
40
- Value: "var(--color-card-default)",
41
- },
42
- CreatedAt: "2025-01-01T00:00:00Z",
43
- },
44
- {
45
- ID: "col-456",
46
- Name: "In Progress",
47
- Color: api.ColorObject{
48
- Name: "Lime",
49
- Value: "var(--color-card-4)",
50
- },
51
- CreatedAt: "2025-01-02T00:00:00Z",
52
- },
53
- }
54
- json.NewEncoder(w).Encode(response)
55
- }))
56
- defer server.Close()
57
-
58
- client := testutil.NewTestClient(server.URL, "", "board-123", "test-token")
59
- testApp := &app.App{Client: client}
60
-
61
- cmd := columnListCmd
62
- cmd.SetContext(testApp.ToContext(context.Background()))
63
-
64
- if err := handleListColumns(cmd); err != nil {
65
- t.Fatalf("handleListColumns failed: %v", err)
66
- }
67
- }
68
-
69
- func TestColumnListCommandNoColumns(t *testing.T) {
70
- server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
71
- w.Header().Set("Content-Type", "application/json")
72
- json.NewEncoder(w).Encode([]api.Column{})
73
- }))
74
- defer server.Close()
75
-
76
- client := testutil.NewTestClient(server.URL, "", "board-123", "test-token")
77
- testApp := &app.App{Client: client}
78
-
79
- cmd := columnListCmd
80
- cmd.SetContext(testApp.ToContext(context.Background()))
81
-
82
- if err := handleListColumns(cmd); err != nil {
83
- t.Fatalf("handleListColumns failed: %v", err)
84
- }
85
- }
86
-
87
- func TestColumnListCommandAPIError(t *testing.T) {
88
- server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
89
- w.WriteHeader(http.StatusInternalServerError)
90
- w.Write([]byte("Internal Server Error"))
91
- }))
92
- defer server.Close()
93
-
94
- client := testutil.NewTestClient(server.URL, "", "board-123", "test-token")
95
- testApp := &app.App{Client: client}
96
-
97
- cmd := columnListCmd
98
- cmd.SetContext(testApp.ToContext(context.Background()))
99
-
100
- err := handleListColumns(cmd)
101
- if err == nil {
102
- t.Errorf("expected error for API failure")
103
- }
104
- if err.Error() != "fetching columns: unexpected status code 500: Internal Server Error" {
105
- t.Errorf("expected API error, got %v", err)
106
- }
107
- }
108
-
109
- func TestColumnListCommandNoBoard(t *testing.T) {
110
- client := testutil.NewTestClient("http://localhost", "", "", "test-token")
111
- testApp := &app.App{Client: client}
112
-
113
- cmd := columnListCmd
114
- cmd.SetContext(testApp.ToContext(context.Background()))
115
-
116
- err := handleListColumns(cmd)
117
- if err == nil {
118
- t.Errorf("expected error when board not selected")
119
- }
120
- if err.Error() != "fetching columns: please select a board first with 'fizzy use --board <board_name>'" {
121
- t.Errorf("expected 'board not selected' error, got %v", err)
122
- }
123
- }
124
-
125
- func TestColumnListCommandNoClient(t *testing.T) {
126
- testApp := &app.App{}
127
-
128
- cmd := columnListCmd
129
- cmd.SetContext(testApp.ToContext(context.Background()))
130
-
131
- err := handleListColumns(cmd)
132
- if err == nil {
133
- t.Errorf("expected error when client not available")
134
- }
135
- if err.Error() != "API client not available" {
136
- t.Errorf("expected 'client not available' error, got %v", err)
137
- }
138
- }
@@ -1,40 +0,0 @@
1
- package cmd
2
-
3
- import (
4
- "context"
5
- "fmt"
6
-
7
- "github.com/rogeriopvl/fizzy/internal/app"
8
- "github.com/rogeriopvl/fizzy/internal/ui"
9
- "github.com/spf13/cobra"
10
- )
11
-
12
- var columnShowCmd = &cobra.Command{
13
- Use: "show <column_id>",
14
- Short: "Show column details",
15
- Long: `Retrieve and display detailed information about a specific column`,
16
- Args: cobra.ExactArgs(1),
17
- Run: func(cmd *cobra.Command, args []string) {
18
- if err := handleShowColumnDetails(cmd, args[0]); err != nil {
19
- fmt.Fprintf(cmd.OutOrStderr(), "Error: %v\n", err)
20
- }
21
- },
22
- }
23
-
24
- func handleShowColumnDetails(cmd *cobra.Command, columnID string) error {
25
- a := app.FromContext(cmd.Context())
26
- if a == nil || a.Client == nil {
27
- return fmt.Errorf("API client not available")
28
- }
29
-
30
- column, err := a.Client.GetColumn(context.Background(), columnID)
31
- if err != nil {
32
- return fmt.Errorf("fetching column: %w", err)
33
- }
34
-
35
- return ui.DisplayColumn(cmd.OutOrStdout(), column)
36
- }
37
-
38
- func init() {
39
- columnCmd.AddCommand(columnShowCmd)
40
- }
@@ -1,111 +0,0 @@
1
- package cmd
2
-
3
- import (
4
- "context"
5
- "encoding/json"
6
- "net/http"
7
- "net/http/httptest"
8
- "testing"
9
-
10
- "github.com/rogeriopvl/fizzy/internal/api"
11
- "github.com/rogeriopvl/fizzy/internal/app"
12
- "github.com/rogeriopvl/fizzy/internal/testutil"
13
- )
14
-
15
- func TestColumnShowCommandSuccess(t *testing.T) {
16
- server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
17
- if r.URL.Path != "/boards/board-123/columns/col-456" {
18
- t.Errorf("expected /boards/board-123/columns/col-456, got %s", r.URL.Path)
19
- }
20
- if r.Method != http.MethodGet {
21
- t.Errorf("expected GET, got %s", r.Method)
22
- }
23
-
24
- auth := r.Header.Get("Authorization")
25
- if auth != "Bearer test-token" {
26
- t.Errorf("expected Bearer test-token, got %s", auth)
27
- }
28
-
29
- w.Header().Set("Content-Type", "application/json")
30
- response := api.Column{
31
- ID: "col-456",
32
- Name: "In Progress",
33
- CreatedAt: "2025-01-01T00:00:00Z",
34
- Color: api.ColorObject{
35
- Name: "Lime",
36
- Value: api.Lime,
37
- },
38
- }
39
- json.NewEncoder(w).Encode(response)
40
- }))
41
- defer server.Close()
42
-
43
- client := testutil.NewTestClient(server.URL, "", "board-123", "test-token")
44
- testApp := &app.App{Client: client}
45
-
46
- cmd := columnShowCmd
47
- cmd.SetContext(testApp.ToContext(context.Background()))
48
-
49
- if err := handleShowColumnDetails(cmd, "col-456"); err != nil {
50
- t.Fatalf("handleShowColumnDetails failed: %v", err)
51
- }
52
- }
53
-
54
- func TestColumnShowCommandNotFound(t *testing.T) {
55
- server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
56
- w.WriteHeader(http.StatusNotFound)
57
- w.Write([]byte("Column not found"))
58
- }))
59
- defer server.Close()
60
-
61
- client := testutil.NewTestClient(server.URL, "", "board-123", "test-token")
62
- testApp := &app.App{Client: client}
63
-
64
- cmd := columnShowCmd
65
- cmd.SetContext(testApp.ToContext(context.Background()))
66
-
67
- err := handleShowColumnDetails(cmd, "nonexistent-col")
68
- if err == nil {
69
- t.Errorf("expected error for column not found")
70
- }
71
- if err.Error() != "fetching column: unexpected status code 404: Column not found" {
72
- t.Errorf("expected column not found error, got %v", err)
73
- }
74
- }
75
-
76
- func TestColumnShowCommandAPIError(t *testing.T) {
77
- server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
78
- w.WriteHeader(http.StatusInternalServerError)
79
- w.Write([]byte("Internal Server Error"))
80
- }))
81
- defer server.Close()
82
-
83
- client := testutil.NewTestClient(server.URL, "", "board-123", "test-token")
84
- testApp := &app.App{Client: client}
85
-
86
- cmd := columnShowCmd
87
- cmd.SetContext(testApp.ToContext(context.Background()))
88
-
89
- err := handleShowColumnDetails(cmd, "col-456")
90
- if err == nil {
91
- t.Errorf("expected error for API failure")
92
- }
93
- if err.Error() != "fetching column: unexpected status code 500: Internal Server Error" {
94
- t.Errorf("expected API error, got %v", err)
95
- }
96
- }
97
-
98
- func TestColumnShowCommandNoClient(t *testing.T) {
99
- testApp := &app.App{}
100
-
101
- cmd := columnShowCmd
102
- cmd.SetContext(testApp.ToContext(context.Background()))
103
-
104
- err := handleShowColumnDetails(cmd, "col-456")
105
- if err == nil {
106
- t.Errorf("expected error when client not available")
107
- }
108
- if err.Error() != "API client not available" {
109
- t.Errorf("expected 'client not available' error, got %v", err)
110
- }
111
- }