- Merge TestCreateRun_nonInteractive, TestCreateRun_tty, and related tests
into a single TestCreateRun table with 11 cases
- Add partial-flag cases for missing title, body, and category
- Add tty blank body returns error case
- Add tty does not prompt when all flags provided case
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Move non-interactive flag validation to arg parsing stage
- Add blank title/body/category validation at flag parsing
- Keep interactive blank-title/body checks after prompts
- Always print URL to stdout; success message to stderr in TTY mode
- Consolidate test cases and add isTTY field
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Resolve labels before creating discussion so a bad label name
doesn't leave an orphaned discussion (atomicity fix)
- Validate --title/--category/--body non-interactively before calling
ListCategories to avoid an unnecessary network round-trip
- Set blankAllowed=false so the markdown editor rejects empty bodies
- Clarify help text: --body is required when not running interactively
- Update tests to match new behavior; rename label-not-found test to
make the atomicity guarantee explicit
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add "paginates labels across multiple pages" case (two pages, one label each)
- Add "stops paginating labels when all found" case (early break verified via reg.Verify)
- Update "creates discussion with labels" to two labels with variable assertions
- Update "label not found" to verify all missing labels reported at once
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Break early from pagination when all wanted labels are found
- Collect all missing labels and report them in a single error message
- Guard missing-label check with len(found) != len(wanted)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Implement the createDiscussion GraphQL mutation in the discussion client.
- Add getRepositoryMeta helper to resolve repo node ID and check
discussions-enabled flag before mutating
- Skip repo lookup when CreateDiscussionInput.RepositoryID is provided
- Reuse discussionListNode mapping for consistent field coverage
- Table-driven tests: field mapping, pre-resolved repo ID, discussions
disabled, repo not found, mutation error
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace scattered standalone test functions with a single table-driven
TestNewCmdView covering all arg/flag parsing: number, hash, URL, web,
comments, replies, limit, after, order, mutual exclusivity, and invalid
inputs. Uses shlex.Split for arg parsing and asserts opts fields
individually per case.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Inline all JSON response helpers (getCommentRepliesResp, wrapRepliesBlock,
bareCommentNode, replyNode) to avoid cross-test coupling. Fix JSON response
shape to place "node" as sibling of "repository" under "data", matching the
real GraphQL query structure. Populate "maps all fields" with non-zero
values and use a single assert.Equal for the full Discussion struct.
Match real API error responses: discussions disabled returns NOT_FOUND on
discussion, node not found returns NOT_FOUND with null node, wrong-type
node returns empty object. Add missing test cases for repo not found and
first page newest reversal.
Move shared wantComments/wantTotal/wantCursor/wantNext/wantDirection fields
into assertDisc callbacks for both TestGetWithComments and
TestGetCommentReplies, giving each case full ownership of its assertions.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Inline all JSON response helpers (getWithCommentsResp, wrapCommentsBlock,
commentNode) to avoid cross-test coupling. Add missing test cases for
empty comments, first page newest reversal, multiple replies on a single
comment, and repo not found. Populate the "maps comments with replies"
case with non-zero field values and use a single assert.Equal for the
full Discussion struct. Match real API error responses for discussions
disabled and repo not found cases. Rename wantDisc to assertDisc across
all client test functions and require it for non-error cases.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Inline mock JSON responses, use non-default values for all fields to
verify mapping, add repo-not-found test case, and match real API
behaviour for discussions-disabled response (null discussion with
NOT_FOUND error).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add --replies <COMMENT-ID> flag to view paginated replies on a specific
discussion comment. Mutually exclusive with --comments and --web. Works
with --limit, --after, and --order for pagination control. Supports TTY,
raw, and JSON output modes.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Extract discussionReplyNode and mapReplyFromNode as reusable types for
reply nodes. Add GetCommentReplies to the DiscussionClient interface,
implemented using a combined node(id:) and repository.discussion query
since the Discussion type does not expose a comment(id:) field.
Add ExportReply() for leaf reply nodes (no nested replies) and include
cursor/next pagination fields in the comment Export() replies object.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Fix two issues in the discussion view command:
1. GraphQL injection via cursor interpolation: The --after cursor value
was interpolated directly into the raw GraphQL query string using
fmt.Sprintf, which is unsafe since cursor values come from user input.
Now uses GraphQL variables ($cursor: String) instead, matching the
pattern used by issue list, pr list, and other commands.
2. Incomplete --json comments output: Running `gh discussion view N
--json comments` silently returned only totalCount with no comment
nodes, because the data fetch was gated solely on the --comments flag.
Now checks if the JSON exporter requests the comments field and
fetches full comment data accordingly, matching how issue view and
pr view drive data loading from exporter fields.
Also fixes example text that said "newest" but showed --order oldest.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add --limit and --after flags for paginating through discussion comments.
Cursor output is shown in TTY (hint message), raw (next: field), and JSON.
Change GetWithComments to accept 'after' cursor and 'newest' bool instead
of order string. Implement forward/backward cursor-based pagination in
GraphQL queries depending on comment order.
Change Replies from []DiscussionComment to DiscussionCommentList with
Direction field. Display direction-aware messages (newer/older) for both
comments and replies.
Move DiscussionFields and reactionGroupList from shared to view package.
Delete shared/display.go.
Add 7 new pagination tests and update existing test fixtures.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Implement the --comments flag for discussion view, showing threaded
comments with replies.
Features:
- --comments flag fetches and displays discussion comments
- --order flag (oldest/newest) controls comment ordering
- Answer badge (✓ Answer) on marked answer comments
- Threaded replies with indentation
- Truncation messages when more replies exist than fetched
- TTY: markdown-rendered comments with author/timestamp/reactions
- Non-TTY: stable tab-delimited format for scripting
- JSON: populated comment nodes via ExportData
Implementation:
- GetWithComments uses raw GraphQL to dynamically switch between
first/last based on ordering. Fetches 30 comments with 4 replies
each. Explicitly reverses for newest-first ordering.
- --order without --comments returns a flag error
- Reuses existing shared.ReactionGroupList for reaction display
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Rewrite GetByNumber to use strongly-typed GraphQL query instead of
removed raw string interpolation (discussionFields/discussionNode)
- Fix State string references to use Closed bool throughout view.go
- Fix DiscussionAuthor → DiscussionActor type rename in tests
- Add ReactionGroups field to Discussion domain type and ExportData
- Add computed "state" field to ExportData for JSON output
- Add shared.DiscussionFields for view command's --json flag
- Regenerate client mock
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Implement `gh discussion view` for viewing a single discussion with:
- Number or URL argument via shared.ParseDiscussionArg
- TTY output: title, metadata (state, category, author, age, comment
count), labels, markdown-rendered body, reactions
- Context-aware author attribution: "Asked by" for answerable
categories (Q&A), "Started by" for others
- Non-TTY output: key-value pairs matching `gh issue view` format
- JSON output via Exporter (Discussion.ExportData)
- --web flag to open in browser
- Pager support for TTY output
Also adds:
- GetByNumber client method with not-found detection
- shared.ParseDiscussionArg for number/URL/#number parsing
- shared.ReactionGroupList for emoji reaction display
Comment threading (--comments) is deferred to the next PR.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The fetch loop already assigns "first" on each iteration, so the
initial assignment in the variables map is dead code. Remove it from
both List and Search.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace responses/checkVarsFns with httpStubs func per test case in
TestList, TestSearch, and TestListCategories, matching the pattern used
in agent-task/capi tests. Expand inline JSON to heredoc, remove flower
box comments, and add "empty list" and "exact fit" test cases.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>