test: cover nostr publish rejections
This commit is contained in:
parent
cd5172bbb6
commit
e83f05bd80
100
extensions/nostr/src/nostr-bus.publish.test.ts
Normal file
100
extensions/nostr/src/nostr-bus.publish.test.ts
Normal file
@ -0,0 +1,100 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
|
||||
const TEST_HEX_KEY = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef";
|
||||
const TEST_PUBKEY = "f".repeat(64);
|
||||
|
||||
let lastPool: {
|
||||
publish: ReturnType<typeof vi.fn>;
|
||||
subscribeMany: ReturnType<typeof vi.fn>;
|
||||
} | null = null;
|
||||
|
||||
vi.mock("nostr-tools", async () => {
|
||||
const actual = await vi.importActual<typeof import("nostr-tools")>("nostr-tools");
|
||||
class MockPool {
|
||||
publish = vi.fn();
|
||||
subscribeMany = vi.fn(() => ({ close: vi.fn() }));
|
||||
constructor() {
|
||||
lastPool = this as unknown as {
|
||||
publish: ReturnType<typeof vi.fn>;
|
||||
subscribeMany: ReturnType<typeof vi.fn>;
|
||||
};
|
||||
}
|
||||
}
|
||||
return {
|
||||
...actual,
|
||||
SimplePool: MockPool,
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock("nostr-tools/nip04", async () => {
|
||||
return {
|
||||
encrypt: vi.fn(async () => "cipher"),
|
||||
decrypt: vi.fn(async () => "plain"),
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock("./nostr-state-store.js", () => {
|
||||
return {
|
||||
readNostrBusState: vi.fn(async () => null),
|
||||
writeNostrBusState: vi.fn(async () => undefined),
|
||||
computeSinceTimestamp: vi.fn(() => 0),
|
||||
readNostrProfileState: vi.fn(async () => null),
|
||||
writeNostrProfileState: vi.fn(async () => undefined),
|
||||
};
|
||||
});
|
||||
|
||||
describe("startNostrBus publish handling", () => {
|
||||
it("awaits publish rejections for DMs without unhandled rejection", async () => {
|
||||
const { startNostrBus } = await import("./nostr-bus.js");
|
||||
const onError = vi.fn();
|
||||
const bus = await startNostrBus({
|
||||
privateKey: TEST_HEX_KEY,
|
||||
relays: ["wss://relay.test"],
|
||||
onMessage: async () => {},
|
||||
onError,
|
||||
});
|
||||
|
||||
expect(lastPool).not.toBeNull();
|
||||
lastPool?.publish.mockReturnValue([Promise.reject(new Error("rate-limited"))]);
|
||||
|
||||
let unhandled: unknown;
|
||||
process.once("unhandledRejection", (reason) => {
|
||||
unhandled = reason;
|
||||
});
|
||||
|
||||
await expect(bus.sendDm(TEST_PUBKEY, "hi")).rejects.toThrow("rate-limited");
|
||||
await new Promise((resolve) => setImmediate(resolve));
|
||||
|
||||
expect(unhandled).toBeUndefined();
|
||||
expect(onError).toHaveBeenCalled();
|
||||
|
||||
bus.close();
|
||||
});
|
||||
|
||||
it("does not throw on typing publish failures", async () => {
|
||||
const { startNostrBus } = await import("./nostr-bus.js");
|
||||
const onError = vi.fn();
|
||||
const bus = await startNostrBus({
|
||||
privateKey: TEST_HEX_KEY,
|
||||
relays: ["wss://relay.test"],
|
||||
onMessage: async () => {},
|
||||
onError,
|
||||
});
|
||||
|
||||
expect(lastPool).not.toBeNull();
|
||||
lastPool?.publish.mockReturnValue([Promise.reject(new Error("rate-limited"))]);
|
||||
|
||||
let unhandled: unknown;
|
||||
process.once("unhandledRejection", (reason) => {
|
||||
unhandled = reason;
|
||||
});
|
||||
|
||||
await expect(bus.sendTypingStart(TEST_PUBKEY)).resolves.toBeUndefined();
|
||||
await new Promise((resolve) => setImmediate(resolve));
|
||||
|
||||
expect(unhandled).toBeUndefined();
|
||||
expect(onError).toHaveBeenCalled();
|
||||
|
||||
bus.close();
|
||||
});
|
||||
});
|
||||
Loading…
Reference in New Issue
Block a user