220 lines
5.2 KiB
TypeScript
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,
|
|
})
|
|
})
|
|
})
|
|
})
|