102 lines
3.2 KiB
TypeScript
102 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();
|
||
|
|
});
|
||
|
|
});
|