Something went wrong. Try again.
CLI for Linear via GraphQL API
Something went wrong. Try again.
3.6 kB · 129 lines
TypeScript
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130/** * Tests for graphql() and API helpers. */
import { afterEach, describe, expect, mock, test } from "bun:test";import { fetchOrganization, graphql } from "./api.ts";
function makeJsonResponse(body: unknown, status = 200): Response { return new Response(JSON.stringify(body), { status, headers: { "Content-Type": "application/json" }, });}
const SUCCESS_BODY = { data: { viewer: { id: "1", name: "Test", email: "t@t.com" } },};
afterEach(() => { mock.restore();});
describe("fetchOrganization", () => { test("returns organization metadata", async () => { const fetchMock = mock(async () => makeJsonResponse({ data: { organization: { id: "org-1", name: "Acme Inc", urlKey: "acme" }, }, }), ); const originalFetch = globalThis.fetch; globalThis.fetch = fetchMock as unknown as typeof fetch;
try { const org = await fetchOrganization("api-token"); expect(org.id).toBe("org-1"); expect(org.name).toBe("Acme Inc"); expect(org.urlKey).toBe("acme"); } finally { globalThis.fetch = originalFetch; } });});
describe("graphql() with plain string token", () => { test("works with a plain string auth header", async () => { const fetchMock = mock(async () => makeJsonResponse(SUCCESS_BODY)); const originalFetch = globalThis.fetch; globalThis.fetch = fetchMock as unknown as typeof fetch;
try { const result = await graphql<(typeof SUCCESS_BODY)["data"]>( "api-token", "query { viewer { id name email } }", ); expect(result.viewer.name).toBe("Test"); } finally { globalThis.fetch = originalFetch; } });
test("returns invalid API token on 401", async () => { const fetchMock = mock( async () => new Response("Unauthorized", { status: 401 }), ); const originalFetch = globalThis.fetch; globalThis.fetch = fetchMock as unknown as typeof fetch;
try { await expect( graphql("api-token", "query { viewer { id } }"), ).rejects.toThrow("Invalid API token"); } finally { globalThis.fetch = originalFetch; } });});
describe("graphql() error handling", () => { test("truncates large non-JSON HTTP error bodies", async () => { const fetchMock = mock( async () => new Response("x".repeat(400), { status: 503, statusText: "Service Unavailable", }), ); const originalFetch = globalThis.fetch; globalThis.fetch = fetchMock as unknown as typeof fetch;
try { await expect( graphql("api-token", "query { viewer { id } }"), ).rejects.toThrow( /Linear API request failed with 503 Service Unavailable: x{50}/, ); await expect( graphql("api-token", "query { viewer { id } }"), ).rejects.not.toThrow(/x{250}/); } finally { globalThis.fetch = originalFetch; } });
test("surfaces generic entity-not-found hints using the provided id variable", async () => { const fetchMock = mock(async () => makeJsonResponse({ errors: [{ message: "Entity not found: Project" }], }), ); const originalFetch = globalThis.fetch; globalThis.fetch = fetchMock as unknown as typeof fetch;
try { await expect( graphql( "api-token", "query Project($id: String!) { project(id: $id) { id } }", { id: "project-123", }, ), ).rejects.toThrow("Project not found: project-123"); } finally { globalThis.fetch = originalFetch; } });});