Some checks failed
CI / test (pull_request) Failing after 45s
Add `search issues <query>` and `search prs <query>`, the full-text escape hatch the forbidden `--search` flag on the list commands redirects to. Both hit Gitea's cross-repo issue-search endpoint with the query, a `type` of issues or pulls, and the owner param, then filter results to the current repository client-side via each result's `repository` field — the endpoint has no repo-name filter. The count line reports `count: N of T total` with `T` from the filtered set (ADR 0005), never the endpoint's cross-repo `X-Total-Count`. The positional query is required (VALIDATION_ERROR if missing). Flags: `--state` (default open), `--label` (comma-separated names passed straight through as the API `labels` param), `--limit` (default 30), and `--fields`. Default output is the locator schema (`number`, `title`, `state`, `author`, `created`) under `issues:` / `pull_requests:` blocks matching the list commands — search finds the number, `issue view` / `pr view` load the detail. Covered by fixture-server tests for both types, cross-repo filtering, the count rule, each flag, the empty state, and missing-query validation, plus end-to-end tests against a live Gitea instance.
73 lines
2.7 KiB
TypeScript
73 lines
2.7 KiB
TypeScript
import { beforeAll, describe, expect, it } from "vitest";
|
|
import { runCliTest } from "../harness.js";
|
|
import { provisionInstance, seedBranch, type E2EInstance } from "./provision.js";
|
|
|
|
/**
|
|
* The end-to-end tier for the search commands. The `/repos/issues/search`
|
|
* endpoint spans repositories and reports an unfiltered cross-repo total, so the
|
|
* live response shape and the `type`/`owner`/`q` query behavior are precisely
|
|
* what the fixture server can only simulate. Here both variants run against a
|
|
* live, disposable Gitea instance and are asserted to return real matches under
|
|
* the locator schema.
|
|
*/
|
|
const E2E_URL = process.env.GITEA_AXI_E2E_URL;
|
|
|
|
const RELATIVE_TIME = /(just now|\d+(m|h|d|mo|y) ago)/;
|
|
|
|
describe.skipIf(!E2E_URL)("end-to-end: search commands", () => {
|
|
let instance: E2EInstance;
|
|
const branch = "e2e-search-branch";
|
|
|
|
function env(overrides: Record<string, string> = {}): Record<string, string> {
|
|
return {
|
|
GITEA_AXI_API_URL: instance.baseUrl,
|
|
GITEA_AXI_TOKEN: instance.token,
|
|
GITEA_AXI_REPO: `${instance.owner}/${instance.repo}`,
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
beforeAll(async () => {
|
|
instance = await provisionInstance(E2E_URL!);
|
|
// A fresh repo has no pull requests; seed a branch with a diff and open one
|
|
// through the CLI dogfood path so `search prs` has a real match to find.
|
|
await seedBranch(instance, branch);
|
|
const created = await runCliTest(
|
|
[
|
|
"pr", "create",
|
|
"--title", "E2E search pull request",
|
|
"--head", branch,
|
|
"--base", "main",
|
|
],
|
|
{ env: env() },
|
|
);
|
|
expect(created.exitCode).toBe(0);
|
|
}, 150_000);
|
|
|
|
it("returns live issue matches under the locator schema", async () => {
|
|
const { stdout, exitCode } = await runCliTest(["search", "issues", "issue"], {
|
|
env: env(),
|
|
});
|
|
|
|
expect(exitCode).toBe(0);
|
|
// The block header is the default locator schema: the live search response
|
|
// is Issue-shaped and rendered by the same field set as `issue list`.
|
|
expect(stdout).toMatch(/^issues\[\d+\]\{number,title,state,author,created\}:$/m);
|
|
// Real matches from the current repo: a seeded open issue title, the author
|
|
// column (the instance owner), and a rendered relative-time `created`.
|
|
expect(stdout).toContain(instance.openTitles[0]!);
|
|
expect(stdout).toContain(instance.owner);
|
|
expect(stdout).toMatch(RELATIVE_TIME);
|
|
});
|
|
|
|
it("returns live pull-request matches under the locator schema", async () => {
|
|
const { stdout, exitCode } = await runCliTest(["search", "prs", "search"], {
|
|
env: env(),
|
|
});
|
|
|
|
expect(exitCode).toBe(0);
|
|
expect(stdout).toMatch(/^pull_requests\[\d+\]\{number,title,state,author,created\}:$/m);
|
|
expect(stdout).toContain("E2E search pull request");
|
|
});
|
|
});
|