paperclip-forgejo-issue-plugin/tests/forgejo-client.spec.ts

101 lines
3.2 KiB
TypeScript

import { describe, expect, it, vi } from "vitest";
import { validateConfig } from "../src/config.js";
import { createForgejoIssue } from "../src/forgejo-client.js";
describe("forgejo client", () => {
it("resolves a Paperclip-managed secret ref and sends the Forgejo token", async () => {
const secretRef = "11111111-1111-4111-8111-111111111111";
const resolveSecret = vi.fn(async () => "forgejo-token");
const fetch = vi.fn(async () => ({
ok: true,
json: async () => ({
id: 42,
number: 7,
html_url: "https://forgejo.example/acme/repo/issues/7",
url: "https://forgejo.example/api/v1/repos/acme/repo/issues/7"
})
}));
const result = await createForgejoIssue(
{
config: {
get: async () => ({
forgejoBaseUrl: "https://forgejo.example",
forgejoTokenRef: secretRef,
forgejoOwner: "acme",
forgejoRepo: "repo"
})
},
secrets: { resolve: resolveSecret },
http: { fetch }
} as never,
{
title: "Example issue",
body: "body"
}
);
expect(resolveSecret).toHaveBeenCalledWith(secretRef);
expect(fetch).toHaveBeenCalledWith(
"https://forgejo.example/api/v1/repos/acme/repo/issues",
expect.objectContaining({
method: "POST",
headers: expect.objectContaining({
authorization: "token forgejo-token"
})
})
);
expect(result).toEqual({
id: 42,
number: 7,
url: "https://forgejo.example/acme/repo/issues/7",
apiUrl: "https://forgejo.example/api/v1/repos/acme/repo/issues/7"
});
});
it("rejects visible secret names with an actionable, sanitized error", async () => {
const invalidRef = "forgejo-ake-paperclip-forgejo-issue-plugin-issues";
const resolveSecret = vi.fn();
const fetch = vi.fn();
expect(validateConfig({
forgejoBaseUrl: "https://forgejo.example",
forgejoTokenRef: invalidRef,
forgejoOwner: "acme",
forgejoRepo: "repo"
})).toEqual({
ok: false,
errors: [
"forgejoTokenRef must be a Paperclip secret reference UUID. Re-save the field through the Paperclip secret picker or paste the secret UUID, not the visible secret name."
],
warnings: [
"defaultCompanyId is not set; the reconciliation job cannot backfill unsynced issues across a company.",
"syncIssueLabel is not set; the plugin will use the default label \"forgejo-sync\"."
]
});
await expect(createForgejoIssue(
{
config: {
get: async () => ({
forgejoBaseUrl: "https://forgejo.example",
forgejoTokenRef: invalidRef,
forgejoOwner: "acme",
forgejoRepo: "repo"
})
},
secrets: { resolve: resolveSecret },
http: { fetch }
} as never,
{
title: "Example issue",
body: "body"
}
)).rejects.toThrow(
"forgejoTokenRef must be a Paperclip secret reference UUID. Re-save the field through the Paperclip secret picker or paste the secret UUID, not the visible secret name."
);
expect(resolveSecret).not.toHaveBeenCalled();
expect(fetch).not.toHaveBeenCalled();
});
});