fix: use stable public ids for card webhook (#463)

Signed-off-by: Vikram Vaswani <2571660+vvaswani@users.noreply.github.com>
This commit is contained in:
vvaswani
2026-04-21 01:49:31 +05:30
committed by GitHub
parent b46979f539
commit e39faa1172
4 changed files with 95 additions and 27 deletions

View File

@@ -1,9 +1,20 @@
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
const { mockLogger } = vi.hoisted(() => ({
mockLogger: {
error: vi.fn(),
info: vi.fn(),
},
}));
vi.mock("@kan/db/repository/webhook.repo", () => ({
getActiveByWorkspaceId: vi.fn(),
}));
vi.mock("@kan/logger", () => ({
createLogger: vi.fn(() => mockLogger),
}));
import * as webhookRepo from "@kan/db/repository/webhook.repo";
import {
sendWebhookToUrl,
@@ -155,6 +166,33 @@ describe("webhook utilities", () => {
title: { from: "Old Title", to: "Updated Title" },
});
});
it("preserves public list IDs in moved payloads", () => {
const payload = createCardWebhookPayload(
"card.moved",
{
id: "card-123",
title: "Moved Card",
listId: "list-public-done",
},
{
boardId: "board-789",
listName: "Done",
changes: {
listId: { from: "list-public-backlog", to: "list-public-done" },
},
},
);
expect(payload.data.card.listId).toBe("list-public-done");
expect(payload.data.list).toEqual({
id: "list-public-done",
name: "Done",
});
expect(payload.data.changes).toEqual({
listId: { from: "list-public-backlog", to: "list-public-done" },
});
});
});
describe("sendWebhookToUrl", () => {
@@ -434,8 +472,6 @@ describe("webhook utilities", () => {
});
it("continues sending to other webhooks when one fails", async () => {
const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => {});
mockGetActiveByWorkspaceId.mockResolvedValueOnce([
{
id: 1,
@@ -462,11 +498,15 @@ describe("webhook utilities", () => {
await sendWebhooksForWorkspace(mockDb, 1, mockPayload);
expect(global.fetch).toHaveBeenCalledTimes(2);
expect(consoleSpy).toHaveBeenCalledWith(
expect.stringContaining("Webhook delivery failed"),
expect(mockLogger.error).toHaveBeenCalledWith(
expect.objectContaining({
url: "https://example.com/webhook1",
event: "card.created",
error: "500 Error",
statusCode: 500,
}),
"Webhook delivery failed",
);
consoleSpy.mockRestore();
});
it("handles empty webhook list", async () => {
@@ -478,9 +518,6 @@ describe("webhook utilities", () => {
});
it("catches and logs DB errors without throwing", async () => {
const consoleSpy = vi
.spyOn(console, "error")
.mockImplementation(() => {});
mockGetActiveByWorkspaceId.mockRejectedValueOnce(
new Error("DB connection failed"),
);
@@ -490,12 +527,13 @@ describe("webhook utilities", () => {
sendWebhooksForWorkspace(mockDb, 1, mockPayload),
).resolves.toBeUndefined();
expect(consoleSpy).toHaveBeenCalledWith(
"Failed to send webhooks for workspace:",
expect.any(Error),
expect(mockLogger.error).toHaveBeenCalledWith(
expect.objectContaining({
err: expect.any(Error),
workspaceId: 1,
}),
"Failed to send webhooks for workspace",
);
consoleSpy.mockRestore();
});
});