Files
welshman/packages/net/__tests__/publish.test.ts
T
2025-04-11 08:03:44 -07:00

205 lines
5.3 KiB
TypeScript

import {describe, expect, it, vi, beforeEach, afterEach} from "vitest"
import {publishOne, publish} from "../src/publish"
import {MockAdapter} from "../src/adapter"
import {ClientMessageType} from "../src/message"
import {makeEvent} from "@welshman/util"
import {Nip01Signer} from "@welshman/signer"
describe("publishOne", () => {
beforeEach(() => {
vi.useFakeTimers()
})
afterEach(() => {
vi.useRealTimers()
})
it("success works", async () => {
const sendSpy = vi.fn()
const adapter = new MockAdapter("1", sendSpy)
const signer = Nip01Signer.ephemeral()
const event = await signer.sign(makeEvent(1))
const successSpy = vi.fn()
const failureSpy = vi.fn()
const completeSpy = vi.fn()
publishOne({
event,
relay: "1",
context: {getAdapter: () => adapter},
onSuccess: successSpy,
onFailure: failureSpy,
onComplete: completeSpy,
})
await vi.advanceTimersByTimeAsync(200)
expect(sendSpy).toHaveBeenCalledWith([ClientMessageType.Event, event])
adapter.receive(["OK", event.id, true, "hi"])
await vi.runAllTimers()
expect(successSpy).toHaveBeenCalledWith("hi", "1")
expect(failureSpy).not.toHaveBeenCalled()
expect(completeSpy).toHaveBeenCalled()
})
it("failure works", async () => {
const sendSpy = vi.fn()
const adapter = new MockAdapter("1", sendSpy)
const signer = Nip01Signer.ephemeral()
const event = await signer.sign(makeEvent(1))
const successSpy = vi.fn()
const failureSpy = vi.fn()
const completeSpy = vi.fn()
publishOne({
event,
relay: "1",
context: {getAdapter: () => adapter},
onSuccess: successSpy,
onFailure: failureSpy,
onComplete: completeSpy,
})
await vi.advanceTimersByTimeAsync(200)
expect(sendSpy).toHaveBeenCalledWith([ClientMessageType.Event, event])
adapter.receive(["OK", event.id, false, "hi"])
await vi.runAllTimers()
expect(successSpy).not.toHaveBeenCalled()
expect(failureSpy).toHaveBeenCalledWith("hi", "1")
expect(completeSpy).toHaveBeenCalled()
})
it("timeout works", async () => {
const sendSpy = vi.fn()
const adapter = new MockAdapter("1", sendSpy)
const signer = Nip01Signer.ephemeral()
const event = await signer.sign(makeEvent(1))
const successSpy = vi.fn()
const failureSpy = vi.fn()
const completeSpy = vi.fn()
const timeoutSpy = vi.fn()
publishOne({
event,
relay: "1",
context: {getAdapter: () => adapter},
onSuccess: successSpy,
onFailure: failureSpy,
onComplete: completeSpy,
onTimeout: timeoutSpy,
})
await vi.runAllTimers()
expect(sendSpy).toHaveBeenCalledWith([ClientMessageType.Event, event])
await vi.runAllTimers()
expect(successSpy).not.toHaveBeenCalled()
expect(failureSpy).not.toHaveBeenCalled()
expect(completeSpy).toHaveBeenCalled()
expect(timeoutSpy).toHaveBeenCalled()
})
it("abort works", async () => {
const sendSpy = vi.fn()
const adapter = new MockAdapter("1", sendSpy)
const signer = Nip01Signer.ephemeral()
const event = await signer.sign(makeEvent(1))
const ctrl = new AbortController()
const successSpy = vi.fn()
const failureSpy = vi.fn()
const completeSpy = vi.fn()
const abortSpy = vi.fn()
publishOne({
event,
relay: "1",
signal: ctrl.signal,
context: {getAdapter: () => adapter},
onSuccess: successSpy,
onFailure: failureSpy,
onComplete: completeSpy,
onTimeout: abortSpy,
})
await vi.runAllTimers()
expect(sendSpy).toHaveBeenCalledWith([ClientMessageType.Event, event])
ctrl.abort()
await vi.runAllTimers()
expect(successSpy).not.toHaveBeenCalled()
expect(failureSpy).not.toHaveBeenCalled()
expect(completeSpy).toHaveBeenCalled()
expect(abortSpy).toHaveBeenCalled()
})
})
describe("publish", () => {
beforeEach(() => {
vi.useFakeTimers()
})
afterEach(() => {
vi.useRealTimers()
})
it("should all basically work", async () => {
const send1Spy = vi.fn()
const adapter1 = new MockAdapter("1", send1Spy)
const send2Spy = vi.fn()
const adapter2 = new MockAdapter("2", send2Spy)
const send3Spy = vi.fn()
const adapter3 = new MockAdapter("3", send3Spy)
const signer = Nip01Signer.ephemeral()
const event = await signer.sign(makeEvent(1))
const successSpy = vi.fn()
const failureSpy = vi.fn()
const completeSpy = vi.fn()
const timeoutSpy = vi.fn()
publish({
event,
relays: ["1", "2", "3"],
context: {
getAdapter: (url: string) => {
switch (url) {
case "1":
return adapter1
case "2":
return adapter2
case "3":
return adapter3
default:
throw new Error(`Unknown relay: ${url}`)
}
},
},
onSuccess: successSpy,
onFailure: failureSpy,
onComplete: completeSpy,
onTimeout: timeoutSpy,
})
adapter1.receive(["OK", event.id, true, "hi"])
adapter2.receive(["OK", event.id, false, "hi"])
await vi.runAllTimersAsync()
expect(successSpy).toHaveBeenCalledWith("hi", "1")
expect(failureSpy).toHaveBeenCalledWith("hi", "2")
expect(completeSpy).toHaveBeenCalledTimes(1)
expect(timeoutSpy).toHaveBeenCalledWith("3")
})
})