diff --git a/internal/commands/search.go b/internal/commands/search.go index 21e3007..aa93fec 100644 --- a/internal/commands/search.go +++ b/internal/commands/search.go @@ -42,10 +42,10 @@ var searchCmd = &cobra.Command{ params = append(params, "terms[]="+term) } - // Add optional filters - boardID := defaultBoard(searchBoard) - if boardID != "" { - params = append(params, "board_ids[]="+boardID) + // Add optional filters (search is cross-board by default; + // only scope to a board when explicitly requested via --board) + if searchBoard != "" { + params = append(params, "board_ids[]="+searchBoard) } if searchTag != "" { params = append(params, "tag_ids[]="+searchTag) diff --git a/internal/commands/search_test.go b/internal/commands/search_test.go index 4cdace6..be4feea 100644 --- a/internal/commands/search_test.go +++ b/internal/commands/search_test.go @@ -122,6 +122,82 @@ func TestSearch(t *testing.T) { } }) + t.Run("does not inject default board into search", func(t *testing.T) { + mock := NewMockClient() + mock.GetWithPaginationResponse = &client.APIResponse{ + StatusCode: 200, + Data: []any{}, + } + + SetTestModeWithSDK(mock) + SetTestConfig("token", "account", "https://api.example.com") + cfg.Board = "default-board-id" + defer resetTest() + + err := searchCmd.RunE(searchCmd, []string{"bug"}) + + assertExitCode(t, err, 0) + if len(mock.GetWithPaginationCalls) != 1 { + t.Fatalf("expected 1 GetWithPagination call, got %d", len(mock.GetWithPaginationCalls)) + } + path := mock.GetWithPaginationCalls[0].Path + if path != "/cards.json?terms[]=bug" { + t.Errorf("expected no board_ids in path, got '%s'", path) + } + }) + + t.Run("tag filter works cross-board with default board set", func(t *testing.T) { + mock := NewMockClient() + mock.GetWithPaginationResponse = &client.APIResponse{ + StatusCode: 200, + Data: []any{}, + } + + SetTestModeWithSDK(mock) + SetTestConfig("token", "account", "https://api.example.com") + cfg.Board = "default-board-id" + defer resetTest() + + searchTag = "tag-123" + err := searchCmd.RunE(searchCmd, []string{"bug"}) + searchTag = "" + + assertExitCode(t, err, 0) + if len(mock.GetWithPaginationCalls) != 1 { + t.Fatalf("expected 1 GetWithPagination call, got %d", len(mock.GetWithPaginationCalls)) + } + path := mock.GetWithPaginationCalls[0].Path + if path != "/cards.json?terms[]=bug&tag_ids[]=tag-123" { + t.Errorf("expected tag filter without board_ids, got '%s'", path) + } + }) + + t.Run("assignee filter works cross-board with default board set", func(t *testing.T) { + mock := NewMockClient() + mock.GetWithPaginationResponse = &client.APIResponse{ + StatusCode: 200, + Data: []any{}, + } + + SetTestModeWithSDK(mock) + SetTestConfig("token", "account", "https://api.example.com") + cfg.Board = "default-board-id" + defer resetTest() + + searchAssignee = "user-456" + err := searchCmd.RunE(searchCmd, []string{"bug"}) + searchAssignee = "" + + assertExitCode(t, err, 0) + if len(mock.GetWithPaginationCalls) != 1 { + t.Fatalf("expected 1 GetWithPagination call, got %d", len(mock.GetWithPaginationCalls)) + } + path := mock.GetWithPaginationCalls[0].Path + if path != "/cards.json?terms[]=bug&assignee_ids[]=user-456" { + t.Errorf("expected assignee filter without board_ids, got '%s'", path) + } + }) + t.Run("requires authentication", func(t *testing.T) { mock := NewMockClient() SetTestModeWithSDK(mock)