fix: support gh pr list state filter
This commit is contained in:
@@ -99,6 +99,14 @@ async function startMockGitHub(): Promise<{ baseUrl: string; requests: MockReque
|
||||
sendJson(res, 200, [pullRequest]);
|
||||
return;
|
||||
}
|
||||
if (req.method === "GET" && req.url === "/repos/pikasTech/unidesk/pulls?state=open&per_page=4") {
|
||||
sendJson(res, 200, [pullRequest]);
|
||||
return;
|
||||
}
|
||||
if (req.method === "GET" && req.url === "/repos/pikasTech/unidesk/pulls?state=closed&per_page=4") {
|
||||
sendJson(res, 200, [{ ...pullRequest, number: 43, state: "closed", html_url: "https://github.com/pikasTech/unidesk/pull/43" }]);
|
||||
return;
|
||||
}
|
||||
if (req.method === "GET" && req.url === "/repos/pikasTech/unidesk/pulls/42") {
|
||||
sendJson(res, 200, pullRequest);
|
||||
return;
|
||||
@@ -162,6 +170,12 @@ function dataOf(response: JsonRecord): JsonRecord {
|
||||
return response.data as JsonRecord;
|
||||
}
|
||||
|
||||
function failedDataOf(response: JsonRecord): JsonRecord {
|
||||
assertCondition(response.ok === false, "CLI command should fail", response);
|
||||
assertCondition(typeof response.data === "object" && response.data !== null && !Array.isArray(response.data), "failure data should be object", response);
|
||||
return response.data as JsonRecord;
|
||||
}
|
||||
|
||||
export async function runGhCliPrContract(): Promise<JsonRecord> {
|
||||
const help = await runCli(["gh", "help"]);
|
||||
assertCondition(help.status === 0, "gh help should succeed", help.json ?? { stdout: help.stdout });
|
||||
@@ -173,8 +187,10 @@ export async function runGhCliPrContract(): Promise<JsonRecord> {
|
||||
assertCondition(usage.some((line) => line.includes("gh pr view")), "gh help should list pr view", { usage });
|
||||
assertCondition(usage.some((line) => line.includes("gh pr create")), "gh help should list pr create", { usage });
|
||||
assertCondition(usage.some((line) => line.includes("gh pr comment")), "gh help should list pr comment", { usage });
|
||||
assertCondition(usage.some((line) => line.includes("gh pr list") && line.includes("--state open|closed|all")), "gh help should document pr list state filtering", { usage });
|
||||
assertCondition(notes.some((line) => line.includes("canonical read path")), "gh help should state pr read is canonical", { notes });
|
||||
assertCondition(notes.some((line) => line.includes("compatibility alias")), "gh help should state pr view is alias", { notes });
|
||||
assertCondition(notes.some((line) => line.includes("PR list defaults to --state all")), "gh help should document pr list default state", { notes });
|
||||
|
||||
const mock = await startMockGitHub();
|
||||
const env = {
|
||||
@@ -185,9 +201,34 @@ export async function runGhCliPrContract(): Promise<JsonRecord> {
|
||||
const list = await runCli(["gh", "pr", "list", "--repo", "pikasTech/unidesk", "--limit", "4"], env);
|
||||
assertCondition(list.status === 0, "pr list should succeed through REST", list.json ?? { stdout: list.stdout });
|
||||
const listData = dataOf(list.json ?? {});
|
||||
assertCondition(listData.state === "all", "pr list should keep default state=all compatibility", listData);
|
||||
const pullRequests = listData.pullRequests as JsonRecord[];
|
||||
assertCondition(Array.isArray(pullRequests) && pullRequests.length === 1, "pr list should return pullRequests", listData);
|
||||
assertCondition(pullRequests[0]?.number === 42 && pullRequests[0]?.base && pullRequests[0]?.head, "pr list should expose PR summary", pullRequests[0]);
|
||||
assertCondition(mock.requests.some((request) => request.method === "GET" && request.url === "/repos/pikasTech/unidesk/pulls?state=all&per_page=4"), "default pr list should query state=all", mock.requests);
|
||||
|
||||
const listOpen = await runCli(["gh", "pr", "list", "--repo", "pikasTech/unidesk", "--state", "open", "--limit", "4", "--json", "number,title,state,url"], env);
|
||||
assertCondition(listOpen.status === 0, "pr list should support --state open", listOpen.json ?? { stdout: listOpen.stdout });
|
||||
const listOpenData = dataOf(listOpen.json ?? {});
|
||||
assertCondition(listOpenData.state === "open", "pr list should preserve requested state", listOpenData);
|
||||
const listOpenPrs = listOpenData.pullRequests as JsonRecord[];
|
||||
assertCondition(Array.isArray(listOpenPrs) && listOpenPrs[0]?.state === "open", "pr list --state open should return selected PR fields", listOpenData);
|
||||
assertCondition(!("body" in listOpenPrs[0]), "pr list --json should keep progressive disclosure", listOpenPrs[0]);
|
||||
assertCondition(mock.requests.some((request) => request.method === "GET" && request.url === "/repos/pikasTech/unidesk/pulls?state=open&per_page=4"), "pr list --state open should query REST state=open", mock.requests);
|
||||
|
||||
const listClosed = await runCli(["gh", "pr", "list", "--repo", "pikasTech/unidesk", "--state", "closed", "--limit", "4", "--json", "number,state,url"], env);
|
||||
assertCondition(listClosed.status === 0, "pr list should support --state closed", listClosed.json ?? { stdout: listClosed.stdout });
|
||||
const listClosedData = dataOf(listClosed.json ?? {});
|
||||
assertCondition(listClosedData.state === "closed", "pr list should preserve requested closed state", listClosedData);
|
||||
const listClosedPrs = listClosedData.pullRequests as JsonRecord[];
|
||||
assertCondition(Array.isArray(listClosedPrs) && listClosedPrs[0]?.number === 43 && listClosedPrs[0]?.state === "closed", "pr list --state closed should return closed PR summaries", listClosedData);
|
||||
assertCondition(mock.requests.some((request) => request.method === "GET" && request.url === "/repos/pikasTech/unidesk/pulls?state=closed&per_page=4"), "pr list --state closed should query REST state=closed", mock.requests);
|
||||
|
||||
const badState = await runCli(["gh", "pr", "list", "--repo", "pikasTech/unidesk", "--state", "merged"], env);
|
||||
assertCondition(badState.status !== 0, "pr list unsupported state should fail", badState.json ?? { stdout: badState.stdout });
|
||||
const badStateData = failedDataOf(badState.json ?? {});
|
||||
assertCondition(badStateData.degradedReason === "validation-failed", "pr list unsupported state should be validation-failed", badStateData);
|
||||
assertCondition(badStateData.runnerDisposition === "business-failed", "pr list unsupported state should be business-failed", badStateData);
|
||||
|
||||
const read = await runCli(["gh", "pr", "read", "42", "--repo", "pikasTech/unidesk", "--json", "body,title,state,head,base"], env);
|
||||
assertCondition(read.status === 0, "pr read should succeed through REST", read.json ?? { stdout: read.stdout });
|
||||
|
||||
Reference in New Issue
Block a user