Files
welshman/packages/dvm/__tests__/request.test.ts
T
2025-02-28 14:18:02 -08:00

220 lines
5.2 KiB
TypeScript

import {now} from "@welshman/lib"
import {subscribe, publish, SubscriptionEvent} from "@welshman/net"
import type {SignedEvent, TrustedEvent} from "@welshman/util"
import {vi, describe, it, expect, beforeEach} from "vitest"
import {makeDvmRequest, DVMEvent} from "../src/request"
// Mock dependencies
vi.mock(import("@welshman/lib"), async importOriginal => ({
...(await importOriginal()),
Emitter: vi.fn().mockImplementation(() => ({
emit: vi.fn(),
on: vi.fn(),
})),
}))
vi.mock("@welshman/net", () => ({
subscribe: vi.fn(),
publish: vi.fn(),
SubscriptionEvent: {
Event: "event",
},
}))
describe("DVM Request", () => {
let mockSubscription: any
let mockPublish: any
let baseEvent: SignedEvent
const id = "dd".repeat(32)
const pubkey = "ee".repeat(32)
const sig = "ff".repeat(64)
beforeEach(() => {
vi.clearAllMocks()
// Setup mock subscription
mockSubscription = {
on: vi.fn(),
close: vi.fn(),
}
vi.mocked(subscribe).mockReturnValue(mockSubscription)
// Setup mock publish
mockPublish = {
emitter: {on: vi.fn()},
}
vi.mocked(publish).mockReturnValue(mockPublish)
// Base event for testing
baseEvent = {
id,
kind: 5000,
pubkey,
content: "",
tags: [],
created_at: now(),
sig,
}
})
describe("makeDvmRequest", () => {
it("should create subscription with correct filters", () => {
const request = makeDvmRequest({
event: baseEvent,
relays: ["relay1", "relay2"],
})
expect(subscribe).toHaveBeenCalledWith({
relays: ["relay1", "relay2"],
timeout: 30000,
filters: [
{
kinds: [6000, 7000], // kind + 1000 and progress events
since: now() - 60, // now() - 60
"#e": [id],
},
],
})
})
it("should respect custom timeout", () => {
const request = makeDvmRequest({
event: baseEvent,
relays: ["relay1"],
timeout: 5000,
})
expect(subscribe).toHaveBeenCalledWith(
expect.objectContaining({
timeout: 5000,
}),
)
})
it("should disable progress events when reportProgress is false", () => {
makeDvmRequest({
event: baseEvent,
relays: ["relay1"],
reportProgress: false,
})
expect(subscribe).toHaveBeenCalledWith(
expect.objectContaining({
filters: [
{
kinds: [6000], // Only result kind, no progress events
since: expect.any(Number),
"#e": [baseEvent.id],
},
],
}),
)
})
it("should publish request event", () => {
makeDvmRequest({
event: baseEvent,
relays: ["relay1"],
})
expect(publish).toHaveBeenCalledWith({
event: baseEvent,
relays: ["relay1"],
timeout: 30000,
})
})
})
describe("event handling", () => {
it("should emit progress events", () => {
const request = makeDvmRequest({
event: baseEvent,
relays: ["relay1"],
})
// Get the event handler
const eventHandler = mockSubscription.on.mock.calls.find(
call => call[0] === SubscriptionEvent.Event,
)[1]
// Simulate progress event
const progressEvent = {
kind: 7000,
content: "progress",
} as TrustedEvent
eventHandler("relay1", progressEvent)
expect(request.emitter.emit).toHaveBeenCalledWith(DVMEvent.Progress, "relay1", progressEvent)
})
it("should emit and auto-close on result events", () => {
const request = makeDvmRequest({
event: baseEvent,
relays: ["relay1"],
})
// Get the event handler
const eventHandler = mockSubscription.on.mock.calls.find(
call => call[0] === SubscriptionEvent.Event,
)[1]
// Simulate result event
const resultEvent = {
kind: 6000,
content: "result",
} as TrustedEvent
eventHandler("relay1", resultEvent)
expect(request.emitter.emit).toHaveBeenCalledWith(DVMEvent.Result, "relay1", resultEvent)
expect(request.sub.close).toHaveBeenCalled()
})
it("should not auto-close when autoClose is false", () => {
const request = makeDvmRequest({
event: baseEvent,
relays: ["relay1"],
autoClose: false,
})
// Get the event handler
const eventHandler = mockSubscription.on.mock.calls.find(
call => call[0] === SubscriptionEvent.Event,
)[1]
// Simulate result event
const resultEvent = {
kind: 6000,
content: "result",
} as TrustedEvent
eventHandler("relay1", resultEvent)
expect(request.sub.close).not.toHaveBeenCalled()
})
})
describe("request object structure", () => {
it("should return correctly structured request object", () => {
const requestOpts = {
event: baseEvent,
relays: ["relay1"],
timeout: 5000,
autoClose: false,
reportProgress: false,
}
const request = makeDvmRequest(requestOpts)
expect(request).toEqual({
request: requestOpts,
emitter: expect.any(Object),
sub: mockSubscription,
pub: mockPublish,
})
})
})
})