This commit is contained in:
184
test/label.test.ts
Normal file
184
test/label.test.ts
Normal file
@@ -0,0 +1,184 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { startFixtureServer, type FixtureServer } from "./fixture-server.js";
|
||||
import { postedBody, runCliTest, testModeEnv } from "./harness.js";
|
||||
|
||||
const LABELS_PATH = "/api/v1/repos/testowner/testrepo/labels";
|
||||
|
||||
let server: FixtureServer;
|
||||
|
||||
afterEach(async () => {
|
||||
await server.close();
|
||||
});
|
||||
|
||||
describe("label list", () => {
|
||||
it("renders the count line and a labels block of names", async () => {
|
||||
server = await startFixtureServer([
|
||||
{
|
||||
method: "GET",
|
||||
path: LABELS_PATH,
|
||||
headers: { "X-Total-Count": "2" },
|
||||
body: [
|
||||
{ id: 11, name: "bug" },
|
||||
{ id: 22, name: "enhancement" },
|
||||
],
|
||||
},
|
||||
]);
|
||||
const { stdout, exitCode } = await runCliTest(["label", "list"], {
|
||||
env: testModeEnv(server.url),
|
||||
});
|
||||
|
||||
expect(exitCode).toBe(0);
|
||||
const lines = stdout.split("\n");
|
||||
expect(lines).toContain("count: 2 of 2 total");
|
||||
expect(lines).toContain("labels[2]{name}:");
|
||||
expect(lines).toContain(" bug");
|
||||
expect(lines).toContain(" enhancement");
|
||||
});
|
||||
|
||||
it("emits an explicit empty state for a repo with no labels", async () => {
|
||||
server = await startFixtureServer([
|
||||
{
|
||||
method: "GET",
|
||||
path: LABELS_PATH,
|
||||
headers: { "X-Total-Count": "0" },
|
||||
body: [],
|
||||
},
|
||||
]);
|
||||
const { stdout, exitCode } = await runCliTest(["label", "list"], {
|
||||
env: testModeEnv(server.url),
|
||||
});
|
||||
|
||||
expect(exitCode).toBe(0);
|
||||
expect(stdout).toContain("count: 0 of 0 total");
|
||||
expect(stdout).toContain("labels[0]: (none)");
|
||||
});
|
||||
});
|
||||
|
||||
describe("label create", () => {
|
||||
it("creates the label, prepending # to the color, and reports success", async () => {
|
||||
server = await startFixtureServer([
|
||||
{ method: "GET", path: LABELS_PATH, body: [] },
|
||||
{
|
||||
method: "POST",
|
||||
path: LABELS_PATH,
|
||||
status: 201,
|
||||
body: { id: 5, name: "bug", color: "#ff0000" },
|
||||
},
|
||||
]);
|
||||
const { stdout, exitCode } = await runCliTest(
|
||||
["label", "create", "--name", "bug", "--color", "ff0000"],
|
||||
{ env: testModeEnv(server.url) },
|
||||
);
|
||||
|
||||
expect(exitCode).toBe(0);
|
||||
expect(postedBody(server, LABELS_PATH)).toEqual({ name: "bug", color: "#ff0000" });
|
||||
expect(stdout).toContain("created: ok");
|
||||
expect(stdout).toContain("label: bug");
|
||||
});
|
||||
|
||||
it("is idempotent: an existing label (case-insensitive) is not re-created", async () => {
|
||||
server = await startFixtureServer([
|
||||
{ method: "GET", path: LABELS_PATH, body: [{ id: 11, name: "bug" }] },
|
||||
]);
|
||||
const { stdout, exitCode } = await runCliTest(
|
||||
["label", "create", "--name", "BUG", "--color", "ff0000"],
|
||||
{ env: testModeEnv(server.url) },
|
||||
);
|
||||
|
||||
expect(exitCode).toBe(0);
|
||||
expect(stdout).toContain("create: already_exists");
|
||||
expect(stdout).toContain("label: bug");
|
||||
expect(server.requests.some((r) => r.method === "POST")).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("label edit", () => {
|
||||
it("resolves the positional by name, PATCHes by id with # prepended to color", async () => {
|
||||
server = await startFixtureServer([
|
||||
{
|
||||
method: "GET",
|
||||
path: LABELS_PATH,
|
||||
body: [{ id: 11, name: "bug", color: "ff0000" }],
|
||||
},
|
||||
{
|
||||
method: "PATCH",
|
||||
path: `${LABELS_PATH}/11`,
|
||||
status: 200,
|
||||
body: { id: 11, name: "defect", color: "#00ff00", description: "A bug" },
|
||||
},
|
||||
]);
|
||||
const { stdout, exitCode } = await runCliTest(
|
||||
[
|
||||
"label", "edit", "bug",
|
||||
"--name", "defect",
|
||||
"--color", "00ff00",
|
||||
"--description", "A bug",
|
||||
],
|
||||
{ env: testModeEnv(server.url) },
|
||||
);
|
||||
|
||||
expect(exitCode).toBe(0);
|
||||
const patch = server.requests.find(
|
||||
(r) => r.method === "PATCH" && r.path === `${LABELS_PATH}/11`,
|
||||
);
|
||||
expect(patch?.body).toMatchObject({
|
||||
name: "defect",
|
||||
color: "#00ff00",
|
||||
description: "A bug",
|
||||
});
|
||||
expect(stdout).toContain("edit: ok");
|
||||
expect(stdout).toContain("label: defect");
|
||||
});
|
||||
|
||||
it("rejects an unknown label name with a VALIDATION_ERROR and no mutation", async () => {
|
||||
server = await startFixtureServer([
|
||||
{ method: "GET", path: LABELS_PATH, body: [{ id: 11, name: "bug" }] },
|
||||
]);
|
||||
const { stdout, exitCode } = await runCliTest(
|
||||
["label", "edit", "ghost", "--name", "x"],
|
||||
{ env: testModeEnv(server.url) },
|
||||
);
|
||||
|
||||
expect(exitCode).toBe(2);
|
||||
expect(stdout).toContain("code: VALIDATION_ERROR");
|
||||
expect(
|
||||
server.requests.some((r) => r.method === "PATCH" || r.method === "DELETE"),
|
||||
).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("label delete", () => {
|
||||
it("resolves the positional by name and DELETEs by id", async () => {
|
||||
server = await startFixtureServer([
|
||||
{ method: "GET", path: LABELS_PATH, body: [{ id: 11, name: "bug" }] },
|
||||
{ method: "DELETE", path: `${LABELS_PATH}/11`, status: 204 },
|
||||
]);
|
||||
const { stdout, exitCode } = await runCliTest(["label", "delete", "bug"], {
|
||||
env: testModeEnv(server.url),
|
||||
});
|
||||
|
||||
expect(exitCode).toBe(0);
|
||||
expect(
|
||||
server.requests.some(
|
||||
(r) => r.method === "DELETE" && r.path === `${LABELS_PATH}/11`,
|
||||
),
|
||||
).toBe(true);
|
||||
expect(stdout).toContain("delete: ok");
|
||||
expect(stdout).toContain("label: bug");
|
||||
});
|
||||
|
||||
it("rejects an unknown label name with a VALIDATION_ERROR and no mutation", async () => {
|
||||
server = await startFixtureServer([
|
||||
{ method: "GET", path: LABELS_PATH, body: [{ id: 11, name: "bug" }] },
|
||||
]);
|
||||
const { stdout, exitCode } = await runCliTest(["label", "delete", "ghost"], {
|
||||
env: testModeEnv(server.url),
|
||||
});
|
||||
|
||||
expect(exitCode).toBe(2);
|
||||
expect(stdout).toContain("code: VALIDATION_ERROR");
|
||||
expect(
|
||||
server.requests.some((r) => r.method === "PATCH" || r.method === "DELETE"),
|
||||
).toBe(false);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user