mirror of
https://github.com/ReCloudStudio/WebHooker.git
synced 2026-09-22 16:11:29 +00:00
chore(quality): provider fixtures, formatter snapshots, platform contract tests, CI, CodeQL, dependabot
This commit is contained in:
parent
04fa52db52
commit
320e825bf8
15 changed files with 405 additions and 3 deletions
84
tests/__snapshots__/formatter-snapshot.test.ts.snap
Normal file
84
tests/__snapshots__/formatter-snapshot.test.ts.snap
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
// Bun Snapshot v1, https://bun.sh/docs/test/snapshots
|
||||
|
||||
exports[`formatter snapshots push 1`] = `
|
||||
{
|
||||
"author": {
|
||||
"iconUrl": undefined,
|
||||
"name": "octocat",
|
||||
"url": "https://github.com/octocat",
|
||||
},
|
||||
"color": 3056719,
|
||||
"description": "[View comparison](https://github.com/acme/widget/compare/aaa...bbb)",
|
||||
"fields": [
|
||||
{
|
||||
"inline": false,
|
||||
"name": "",
|
||||
"value": "[\`bbbbbbb\`](https://github.com/acme/widget/commit/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) Fix login bug",
|
||||
},
|
||||
],
|
||||
"footer": "acme/widget",
|
||||
"timestamp": "TIMESTAMP",
|
||||
"title": "acme/widget: Pushed 1 commit to [\`main\`](https://github.com/acme/widget/tree/main)",
|
||||
"url": "https://github.com/acme/widget/compare/aaa...bbb",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`formatter snapshots pull_request 1`] = `
|
||||
{
|
||||
"actions": [
|
||||
{
|
||||
"id": "ghpr|merge|acme|widget|7",
|
||||
"label": "Merge",
|
||||
"style": "primary",
|
||||
},
|
||||
{
|
||||
"id": "ghpr|close|acme|widget|7",
|
||||
"label": "Close",
|
||||
"style": "danger",
|
||||
},
|
||||
],
|
||||
"author": {
|
||||
"iconUrl": undefined,
|
||||
"name": "octocat",
|
||||
"url": "https://github.com/octocat",
|
||||
},
|
||||
"color": 2991182,
|
||||
"description":
|
||||
"🟢 **Opened** pull request
|
||||
|
||||
Implements the new feature."
|
||||
,
|
||||
"fields": [
|
||||
{
|
||||
"inline": true,
|
||||
"name": "Branch",
|
||||
"value": "[\`feature\`](https://github.com/acme/widget/tree/feature) → [\`main\`](https://github.com/acme/widget/tree/main)",
|
||||
},
|
||||
],
|
||||
"footer": "acme/widget",
|
||||
"timestamp": "TIMESTAMP",
|
||||
"title": "acme/widget#7: Add feature",
|
||||
"url": "https://github.com/acme/widget/pull/7",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`formatter snapshots issues 1`] = `
|
||||
{
|
||||
"author": {
|
||||
"iconUrl": undefined,
|
||||
"name": "octocat",
|
||||
"url": "https://github.com/octocat",
|
||||
},
|
||||
"color": 2991182,
|
||||
"description":
|
||||
"🟢 **Opened** issue
|
||||
|
||||
Login fails on iOS Safari."
|
||||
,
|
||||
"fields": undefined,
|
||||
"footer": "acme/widget",
|
||||
"timestamp": "TIMESTAMP",
|
||||
"title": "acme/widget#12: Broken login on mobile",
|
||||
"url": "https://github.com/acme/widget/issues/12",
|
||||
}
|
||||
`;
|
||||
9
tests/fixtures/custom.ts
vendored
Normal file
9
tests/fixtures/custom.ts
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
export const customPayload: Record<string, unknown> = {
|
||||
deliveryId: "custom-123",
|
||||
title: "Deploy finished",
|
||||
repository: {
|
||||
full_name: "acme/widget",
|
||||
html_url: "https://github.com/acme/widget",
|
||||
},
|
||||
message: "The latest build was deployed to staging.",
|
||||
};
|
||||
20
tests/fixtures/gitea.ts
vendored
Normal file
20
tests/fixtures/gitea.ts
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
export const giteaPush: Record<string, unknown> = {
|
||||
ref: "refs/heads/main",
|
||||
before: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
after: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
|
||||
compare_url: "https://git.example.com/acme/widget/compare/aaa...bbb",
|
||||
commits: [
|
||||
{
|
||||
id: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
|
||||
message: "Fix login bug",
|
||||
url: "https://git.example.com/acme/widget/commit/bbb",
|
||||
timestamp: "2026-08-15T00:00:00Z",
|
||||
author: { name: "Octocat", username: "octocat" },
|
||||
},
|
||||
],
|
||||
repository: {
|
||||
full_name: "acme/widget",
|
||||
html_url: "https://git.example.com/acme/widget",
|
||||
},
|
||||
pusher: { login: "octocat" },
|
||||
};
|
||||
66
tests/fixtures/github.ts
vendored
Normal file
66
tests/fixtures/github.ts
vendored
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
export const githubPush: Record<string, unknown> = {
|
||||
ref: "refs/heads/main",
|
||||
before: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
after: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
|
||||
compare: "https://github.com/acme/widget/compare/aaa...bbb",
|
||||
head_commit: {
|
||||
id: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
|
||||
message: "Fix login bug",
|
||||
timestamp: "2026-08-15T00:00:00Z",
|
||||
url: "https://github.com/acme/widget/commit/bbb",
|
||||
author: { name: "Octocat", username: "octocat" },
|
||||
},
|
||||
repository: {
|
||||
full_name: "acme/widget",
|
||||
html_url: "https://github.com/acme/widget",
|
||||
},
|
||||
sender: { login: "octocat" },
|
||||
pusher: { name: "octocat" },
|
||||
commits: [
|
||||
{
|
||||
id: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
|
||||
message: "Fix login bug",
|
||||
url: "https://github.com/acme/widget/commit/bbb",
|
||||
timestamp: "2026-08-15T00:00:00Z",
|
||||
author: { name: "Octocat", username: "octocat" },
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const githubPullRequest: Record<string, unknown> = {
|
||||
action: "opened",
|
||||
number: 7,
|
||||
pull_request: {
|
||||
number: 7,
|
||||
title: "Add feature",
|
||||
html_url: "https://github.com/acme/widget/pull/7",
|
||||
state: "open",
|
||||
user: { login: "octocat" },
|
||||
body: "Implements the new feature.",
|
||||
head: { ref: "feature" },
|
||||
base: { ref: "main" },
|
||||
merged: false,
|
||||
},
|
||||
repository: {
|
||||
full_name: "acme/widget",
|
||||
html_url: "https://github.com/acme/widget",
|
||||
},
|
||||
sender: { login: "octocat" },
|
||||
};
|
||||
|
||||
export const githubIssues: Record<string, unknown> = {
|
||||
action: "opened",
|
||||
issue: {
|
||||
number: 12,
|
||||
title: "Broken login on mobile",
|
||||
html_url: "https://github.com/acme/widget/issues/12",
|
||||
state: "open",
|
||||
user: { login: "octocat" },
|
||||
body: "Login fails on iOS Safari.",
|
||||
},
|
||||
repository: {
|
||||
full_name: "acme/widget",
|
||||
html_url: "https://github.com/acme/widget",
|
||||
},
|
||||
sender: { login: "octocat" },
|
||||
};
|
||||
3
tests/fixtures/index.ts
vendored
Normal file
3
tests/fixtures/index.ts
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
export { githubPush, githubPullRequest, githubIssues } from "./github";
|
||||
export { giteaPush } from "./gitea";
|
||||
export { customPayload } from "./custom";
|
||||
34
tests/formatter-snapshot.test.ts
Normal file
34
tests/formatter-snapshot.test.ts
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
import { describe, test, expect } from "bun:test";
|
||||
import { formatEvent } from "../server/lib/formatters";
|
||||
import type { NeutralMessage, Route, WebhookEvent } from "../server/lib/types";
|
||||
import { githubPush, githubPullRequest, githubIssues } from "./fixtures";
|
||||
|
||||
const route: Route = {
|
||||
id: "test",
|
||||
name: "Test",
|
||||
enabled: true,
|
||||
filters: [],
|
||||
targets: [{ channelId: "111" }],
|
||||
};
|
||||
|
||||
function event(ev: string, payload: Record<string, unknown>): WebhookEvent {
|
||||
return { event: ev, payload };
|
||||
}
|
||||
|
||||
function stable(msg: NeutralMessage): NeutralMessage {
|
||||
return { ...msg, timestamp: msg.timestamp ? "TIMESTAMP" : msg.timestamp };
|
||||
}
|
||||
|
||||
describe("formatter snapshots", () => {
|
||||
test("push", () => {
|
||||
expect(stable(formatEvent(route, event("push", githubPush)))).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test("pull_request", () => {
|
||||
expect(stable(formatEvent(route, event("pull_request", githubPullRequest)))).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test("issues", () => {
|
||||
expect(stable(formatEvent(route, event("issues", githubIssues)))).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
44
tests/platform-contract.test.ts
Normal file
44
tests/platform-contract.test.ts
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
import { describe, test, expect } from "bun:test";
|
||||
import { renderNeutralMessage as renderDiscord } from "../server/lib/drivers/discord/render";
|
||||
import { renderNeutralMessage as renderTelegram } from "../server/lib/drivers/telegram/render";
|
||||
import {
|
||||
MAX_TITLE,
|
||||
MAX_DESCRIPTION,
|
||||
MAX_FIELDS,
|
||||
MAX_FIELD_VALUE,
|
||||
MAX_FOOTER,
|
||||
} from "../server/lib/formatters/helpers";
|
||||
import type { NeutralMessage } from "../server/lib/types";
|
||||
|
||||
const big = "x".repeat(10000);
|
||||
|
||||
function oversized(): NeutralMessage {
|
||||
return {
|
||||
title: `acme/widget#1: ${big}`,
|
||||
url: "https://github.com/acme/widget",
|
||||
description: big,
|
||||
fields: Array.from({ length: 30 }, (_, i) => ({ name: `field-${i}`, value: big })),
|
||||
footer: big,
|
||||
};
|
||||
}
|
||||
|
||||
describe("platform contract", () => {
|
||||
test("discord render clamps all limits", () => {
|
||||
const embed = renderDiscord(oversized()).embeds?.[0];
|
||||
expect(embed).toBeDefined();
|
||||
expect(embed!.title!.length).toBeLessThanOrEqual(MAX_TITLE);
|
||||
expect(embed!.description!.length).toBeLessThanOrEqual(MAX_DESCRIPTION);
|
||||
expect(embed!.fields!.length).toBeLessThanOrEqual(MAX_FIELDS);
|
||||
for (const f of embed!.fields!) {
|
||||
expect(f.value.length).toBeLessThanOrEqual(MAX_FIELD_VALUE);
|
||||
}
|
||||
expect(embed!.footer).toBeDefined();
|
||||
expect(embed!.footer!.text.length).toBeLessThanOrEqual(MAX_FOOTER);
|
||||
});
|
||||
|
||||
test("telegram render stays within the 4096-char cap", () => {
|
||||
const html = renderTelegram(oversized());
|
||||
expect(html.length).toBeGreaterThan(4000);
|
||||
expect(html.length).toBeLessThan(4200);
|
||||
});
|
||||
});
|
||||
55
tests/provider-fixtures.test.ts
Normal file
55
tests/provider-fixtures.test.ts
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
import { describe, test, expect } from "bun:test";
|
||||
import { formatEvent } from "../server/lib/formatters";
|
||||
import { detectProvider } from "../server/lib/providers";
|
||||
import type { Route, WebhookEvent } from "../server/lib/types";
|
||||
import { githubPush, githubPullRequest, githubIssues, giteaPush, customPayload } from "./fixtures";
|
||||
|
||||
const route: Route = {
|
||||
id: "test",
|
||||
name: "Test",
|
||||
enabled: true,
|
||||
filters: [],
|
||||
targets: [{ channelId: "111" }],
|
||||
};
|
||||
|
||||
function event(ev: string, payload: Record<string, unknown>): WebhookEvent {
|
||||
return { event: ev, payload };
|
||||
}
|
||||
|
||||
describe("provider fixtures", () => {
|
||||
const githubFixtures = [
|
||||
{ event: "push", payload: githubPush },
|
||||
{ event: "pull_request", payload: githubPullRequest },
|
||||
{ event: "issues", payload: githubIssues },
|
||||
];
|
||||
|
||||
for (const { event: ev, payload } of githubFixtures) {
|
||||
test(`formats github ${ev} with a title`, () => {
|
||||
const msg = formatEvent(route, event(ev, payload));
|
||||
expect(msg.title.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
test(`github parse detects ${ev}`, () => {
|
||||
const headers = { "x-github-event": ev };
|
||||
const parsed = detectProvider(headers)?.parse(JSON.stringify(payload), headers);
|
||||
expect(parsed?.event).toBe(ev);
|
||||
});
|
||||
}
|
||||
|
||||
test("formats gitea push with a title", () => {
|
||||
const msg = formatEvent(route, event("push", giteaPush));
|
||||
expect(msg.title.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
test("gitea parse detects push", () => {
|
||||
const headers = { "x-gitea-event": "push" };
|
||||
const parsed = detectProvider(headers)?.parse(JSON.stringify(giteaPush), headers);
|
||||
expect(parsed?.event).toBe("push");
|
||||
});
|
||||
|
||||
test("custom parse detects custom event", () => {
|
||||
const headers = { "x-webhooker-signature": "sha256=abc" };
|
||||
const parsed = detectProvider(headers)?.parse(JSON.stringify(customPayload), headers);
|
||||
expect(parsed?.event).toBe("custom");
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue