test: trim async waits in webhook tests
This commit is contained in:
@@ -220,6 +220,12 @@ function createMockResponse(): ServerResponse & { body: string; statusCode: numb
|
||||
return res;
|
||||
}
|
||||
|
||||
const flushAsync = async () => {
|
||||
for (let i = 0; i < 2; i += 1) {
|
||||
await new Promise<void>((resolve) => setImmediate(resolve));
|
||||
}
|
||||
};
|
||||
|
||||
describe("BlueBubbles webhook monitor", () => {
|
||||
let unregister: () => void;
|
||||
|
||||
@@ -506,7 +512,7 @@ describe("BlueBubbles webhook monitor", () => {
|
||||
const res = createMockResponse();
|
||||
|
||||
await handleBlueBubblesWebhookRequest(req, res);
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
await flushAsync();
|
||||
|
||||
expect(resolveChatGuidForTarget).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
@@ -554,7 +560,7 @@ describe("BlueBubbles webhook monitor", () => {
|
||||
const res = createMockResponse();
|
||||
|
||||
await handleBlueBubblesWebhookRequest(req, res);
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
await flushAsync();
|
||||
|
||||
expect(resolveChatGuidForTarget).not.toHaveBeenCalled();
|
||||
expect(sendMessageBlueBubbles).toHaveBeenCalledWith(
|
||||
@@ -601,7 +607,7 @@ describe("BlueBubbles webhook monitor", () => {
|
||||
await handleBlueBubblesWebhookRequest(req, res);
|
||||
|
||||
// Wait for async processing
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
await flushAsync();
|
||||
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(mockDispatchReplyWithBufferedBlockDispatcher).toHaveBeenCalled();
|
||||
@@ -640,7 +646,7 @@ describe("BlueBubbles webhook monitor", () => {
|
||||
const res = createMockResponse();
|
||||
|
||||
await handleBlueBubblesWebhookRequest(req, res);
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
await flushAsync();
|
||||
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(mockDispatchReplyWithBufferedBlockDispatcher).not.toHaveBeenCalled();
|
||||
@@ -681,7 +687,7 @@ describe("BlueBubbles webhook monitor", () => {
|
||||
const res = createMockResponse();
|
||||
|
||||
await handleBlueBubblesWebhookRequest(req, res);
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
await flushAsync();
|
||||
|
||||
expect(mockUpsertPairingRequest).toHaveBeenCalled();
|
||||
expect(mockDispatchReplyWithBufferedBlockDispatcher).not.toHaveBeenCalled();
|
||||
@@ -724,7 +730,7 @@ describe("BlueBubbles webhook monitor", () => {
|
||||
const res = createMockResponse();
|
||||
|
||||
await handleBlueBubblesWebhookRequest(req, res);
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
await flushAsync();
|
||||
|
||||
expect(mockUpsertPairingRequest).toHaveBeenCalled();
|
||||
// Should not send pairing reply since created=false
|
||||
@@ -765,7 +771,7 @@ describe("BlueBubbles webhook monitor", () => {
|
||||
const res = createMockResponse();
|
||||
|
||||
await handleBlueBubblesWebhookRequest(req, res);
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
await flushAsync();
|
||||
|
||||
expect(mockDispatchReplyWithBufferedBlockDispatcher).toHaveBeenCalled();
|
||||
});
|
||||
@@ -802,7 +808,7 @@ describe("BlueBubbles webhook monitor", () => {
|
||||
const res = createMockResponse();
|
||||
|
||||
await handleBlueBubblesWebhookRequest(req, res);
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
await flushAsync();
|
||||
|
||||
expect(mockDispatchReplyWithBufferedBlockDispatcher).not.toHaveBeenCalled();
|
||||
});
|
||||
@@ -842,7 +848,7 @@ describe("BlueBubbles webhook monitor", () => {
|
||||
const res = createMockResponse();
|
||||
|
||||
await handleBlueBubblesWebhookRequest(req, res);
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
await flushAsync();
|
||||
|
||||
expect(mockDispatchReplyWithBufferedBlockDispatcher).toHaveBeenCalled();
|
||||
});
|
||||
@@ -880,7 +886,7 @@ describe("BlueBubbles webhook monitor", () => {
|
||||
const res = createMockResponse();
|
||||
|
||||
await handleBlueBubblesWebhookRequest(req, res);
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
await flushAsync();
|
||||
|
||||
expect(mockDispatchReplyWithBufferedBlockDispatcher).not.toHaveBeenCalled();
|
||||
});
|
||||
@@ -919,7 +925,7 @@ describe("BlueBubbles webhook monitor", () => {
|
||||
const res = createMockResponse();
|
||||
|
||||
await handleBlueBubblesWebhookRequest(req, res);
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
await flushAsync();
|
||||
|
||||
expect(mockDispatchReplyWithBufferedBlockDispatcher).not.toHaveBeenCalled();
|
||||
});
|
||||
@@ -958,7 +964,7 @@ describe("BlueBubbles webhook monitor", () => {
|
||||
const res = createMockResponse();
|
||||
|
||||
await handleBlueBubblesWebhookRequest(req, res);
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
await flushAsync();
|
||||
|
||||
expect(mockDispatchReplyWithBufferedBlockDispatcher).toHaveBeenCalled();
|
||||
});
|
||||
@@ -999,7 +1005,7 @@ describe("BlueBubbles webhook monitor", () => {
|
||||
const res = createMockResponse();
|
||||
|
||||
await handleBlueBubblesWebhookRequest(req, res);
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
await flushAsync();
|
||||
|
||||
expect(mockDispatchReplyWithBufferedBlockDispatcher).toHaveBeenCalled();
|
||||
const callArgs = mockDispatchReplyWithBufferedBlockDispatcher.mock.calls[0][0];
|
||||
@@ -1040,7 +1046,7 @@ describe("BlueBubbles webhook monitor", () => {
|
||||
const res = createMockResponse();
|
||||
|
||||
await handleBlueBubblesWebhookRequest(req, res);
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
await flushAsync();
|
||||
|
||||
expect(mockDispatchReplyWithBufferedBlockDispatcher).not.toHaveBeenCalled();
|
||||
});
|
||||
@@ -1078,7 +1084,7 @@ describe("BlueBubbles webhook monitor", () => {
|
||||
const res = createMockResponse();
|
||||
|
||||
await handleBlueBubblesWebhookRequest(req, res);
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
await flushAsync();
|
||||
|
||||
expect(mockDispatchReplyWithBufferedBlockDispatcher).toHaveBeenCalled();
|
||||
});
|
||||
@@ -1121,7 +1127,7 @@ describe("BlueBubbles webhook monitor", () => {
|
||||
const res = createMockResponse();
|
||||
|
||||
await handleBlueBubblesWebhookRequest(req, res);
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
await flushAsync();
|
||||
|
||||
expect(mockDispatchReplyWithBufferedBlockDispatcher).toHaveBeenCalled();
|
||||
const callArgs = mockDispatchReplyWithBufferedBlockDispatcher.mock.calls[0][0];
|
||||
@@ -1167,7 +1173,7 @@ describe("BlueBubbles webhook monitor", () => {
|
||||
const res = createMockResponse();
|
||||
|
||||
await handleBlueBubblesWebhookRequest(req, res);
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
await flushAsync();
|
||||
|
||||
expect(mockDispatchReplyWithBufferedBlockDispatcher).toHaveBeenCalled();
|
||||
const callArgs = mockDispatchReplyWithBufferedBlockDispatcher.mock.calls[0][0];
|
||||
@@ -1213,7 +1219,7 @@ describe("BlueBubbles webhook monitor", () => {
|
||||
const originalRes = createMockResponse();
|
||||
|
||||
await handleBlueBubblesWebhookRequest(originalReq, originalRes);
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
await flushAsync();
|
||||
|
||||
// Only assert the reply message behavior below.
|
||||
mockDispatchReplyWithBufferedBlockDispatcher.mockClear();
|
||||
@@ -1237,7 +1243,7 @@ describe("BlueBubbles webhook monitor", () => {
|
||||
const replyRes = createMockResponse();
|
||||
|
||||
await handleBlueBubblesWebhookRequest(replyReq, replyRes);
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
await flushAsync();
|
||||
|
||||
expect(mockDispatchReplyWithBufferedBlockDispatcher).toHaveBeenCalled();
|
||||
const callArgs = mockDispatchReplyWithBufferedBlockDispatcher.mock.calls[0][0];
|
||||
@@ -1283,7 +1289,7 @@ describe("BlueBubbles webhook monitor", () => {
|
||||
const res = createMockResponse();
|
||||
|
||||
await handleBlueBubblesWebhookRequest(req, res);
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
await flushAsync();
|
||||
|
||||
expect(mockDispatchReplyWithBufferedBlockDispatcher).toHaveBeenCalled();
|
||||
const callArgs = mockDispatchReplyWithBufferedBlockDispatcher.mock.calls[0][0];
|
||||
@@ -1331,7 +1337,7 @@ describe("BlueBubbles webhook monitor", () => {
|
||||
const res = createMockResponse();
|
||||
|
||||
await handleBlueBubblesWebhookRequest(req, res);
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
await flushAsync();
|
||||
|
||||
expect(sendBlueBubblesReaction).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
@@ -1384,7 +1390,7 @@ describe("BlueBubbles webhook monitor", () => {
|
||||
const res = createMockResponse();
|
||||
|
||||
await handleBlueBubblesWebhookRequest(req, res);
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
await flushAsync();
|
||||
|
||||
// Should process even without mention because it's an authorized control command
|
||||
expect(mockDispatchReplyWithBufferedBlockDispatcher).toHaveBeenCalled();
|
||||
@@ -1427,7 +1433,7 @@ describe("BlueBubbles webhook monitor", () => {
|
||||
const res = createMockResponse();
|
||||
|
||||
await handleBlueBubblesWebhookRequest(req, res);
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
await flushAsync();
|
||||
|
||||
expect(mockDispatchReplyWithBufferedBlockDispatcher).not.toHaveBeenCalled();
|
||||
});
|
||||
@@ -1470,7 +1476,7 @@ describe("BlueBubbles webhook monitor", () => {
|
||||
const res = createMockResponse();
|
||||
|
||||
await handleBlueBubblesWebhookRequest(req, res);
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
await flushAsync();
|
||||
|
||||
expect(markBlueBubblesChatRead).toHaveBeenCalled();
|
||||
});
|
||||
@@ -1511,7 +1517,7 @@ describe("BlueBubbles webhook monitor", () => {
|
||||
const res = createMockResponse();
|
||||
|
||||
await handleBlueBubblesWebhookRequest(req, res);
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
await flushAsync();
|
||||
|
||||
expect(markBlueBubblesChatRead).not.toHaveBeenCalled();
|
||||
});
|
||||
@@ -1554,7 +1560,7 @@ describe("BlueBubbles webhook monitor", () => {
|
||||
const res = createMockResponse();
|
||||
|
||||
await handleBlueBubblesWebhookRequest(req, res);
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
await flushAsync();
|
||||
|
||||
// Should call typing start when reply flow triggers it.
|
||||
expect(sendBlueBubblesTyping).toHaveBeenCalledWith(
|
||||
@@ -1604,7 +1610,7 @@ describe("BlueBubbles webhook monitor", () => {
|
||||
const res = createMockResponse();
|
||||
|
||||
await handleBlueBubblesWebhookRequest(req, res);
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
await flushAsync();
|
||||
|
||||
expect(sendBlueBubblesTyping).toHaveBeenCalledWith(
|
||||
expect.any(String),
|
||||
@@ -1649,7 +1655,7 @@ describe("BlueBubbles webhook monitor", () => {
|
||||
const res = createMockResponse();
|
||||
|
||||
await handleBlueBubblesWebhookRequest(req, res);
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
await flushAsync();
|
||||
|
||||
expect(sendBlueBubblesTyping).toHaveBeenCalledWith(
|
||||
expect.any(String),
|
||||
@@ -1697,7 +1703,7 @@ describe("BlueBubbles webhook monitor", () => {
|
||||
const res = createMockResponse();
|
||||
|
||||
await handleBlueBubblesWebhookRequest(req, res);
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
await flushAsync();
|
||||
|
||||
// Outbound message ID uses short ID "2" (inbound msg-1 is "1", outbound msg-123 is "2")
|
||||
expect(mockEnqueueSystemEvent).toHaveBeenCalledWith(
|
||||
@@ -1742,7 +1748,7 @@ describe("BlueBubbles webhook monitor", () => {
|
||||
const res = createMockResponse();
|
||||
|
||||
await handleBlueBubblesWebhookRequest(req, res);
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
await flushAsync();
|
||||
|
||||
expect(mockEnqueueSystemEvent).toHaveBeenCalledWith(
|
||||
expect.stringContaining("reaction added"),
|
||||
@@ -1782,7 +1788,7 @@ describe("BlueBubbles webhook monitor", () => {
|
||||
const res = createMockResponse();
|
||||
|
||||
await handleBlueBubblesWebhookRequest(req, res);
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
await flushAsync();
|
||||
|
||||
expect(mockEnqueueSystemEvent).toHaveBeenCalledWith(
|
||||
expect.stringContaining("reaction removed"),
|
||||
@@ -1822,7 +1828,7 @@ describe("BlueBubbles webhook monitor", () => {
|
||||
const res = createMockResponse();
|
||||
|
||||
await handleBlueBubblesWebhookRequest(req, res);
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
await flushAsync();
|
||||
|
||||
expect(mockEnqueueSystemEvent).not.toHaveBeenCalled();
|
||||
});
|
||||
@@ -1860,7 +1866,7 @@ describe("BlueBubbles webhook monitor", () => {
|
||||
const res = createMockResponse();
|
||||
|
||||
await handleBlueBubblesWebhookRequest(req, res);
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
await flushAsync();
|
||||
|
||||
expect(mockEnqueueSystemEvent).toHaveBeenCalledWith(
|
||||
expect.stringContaining("👍"),
|
||||
@@ -1901,7 +1907,7 @@ describe("BlueBubbles webhook monitor", () => {
|
||||
const res = createMockResponse();
|
||||
|
||||
await handleBlueBubblesWebhookRequest(req, res);
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
await flushAsync();
|
||||
|
||||
expect(mockDispatchReplyWithBufferedBlockDispatcher).toHaveBeenCalled();
|
||||
const callArgs = mockDispatchReplyWithBufferedBlockDispatcher.mock.calls[0][0];
|
||||
@@ -1941,7 +1947,7 @@ describe("BlueBubbles webhook monitor", () => {
|
||||
const res = createMockResponse();
|
||||
|
||||
await handleBlueBubblesWebhookRequest(req, res);
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
await flushAsync();
|
||||
|
||||
// The short ID "1" should resolve back to the full UUID
|
||||
expect(resolveBlueBubblesMessageId("1")).toBe("msg-uuid-12345");
|
||||
@@ -1993,7 +1999,7 @@ describe("BlueBubbles webhook monitor", () => {
|
||||
const res = createMockResponse();
|
||||
|
||||
await handleBlueBubblesWebhookRequest(req, res);
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
await flushAsync();
|
||||
|
||||
expect(mockDispatchReplyWithBufferedBlockDispatcher).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@@ -14,6 +14,19 @@ vi.mock("./store.js", () => ({
|
||||
|
||||
const { startMediaServer } = await import("./server.js");
|
||||
|
||||
const waitForFileRemoval = async (file: string, timeoutMs = 200) => {
|
||||
const start = Date.now();
|
||||
while (Date.now() - start < timeoutMs) {
|
||||
try {
|
||||
await fs.stat(file);
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
await new Promise((resolve) => setTimeout(resolve, 5));
|
||||
}
|
||||
throw new Error(`timed out waiting for ${file} removal`);
|
||||
};
|
||||
|
||||
describe("media server", () => {
|
||||
beforeAll(async () => {
|
||||
await fs.rm(MEDIA_DIR, { recursive: true, force: true });
|
||||
@@ -32,8 +45,7 @@ describe("media server", () => {
|
||||
const res = await fetch(`http://localhost:${port}/media/file1`);
|
||||
expect(res.status).toBe(200);
|
||||
expect(await res.text()).toBe("hello");
|
||||
await new Promise((r) => setTimeout(r, 600));
|
||||
await expect(fs.stat(file)).rejects.toThrow();
|
||||
await waitForFileRemoval(file);
|
||||
await new Promise((r) => server.close(r));
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user