Fix some tests
This commit is contained in:
@@ -206,8 +206,6 @@ describe("tags", () => {
|
|||||||
|
|
||||||
// a[0] should be the address of the replaceable event
|
// a[0] should be the address of the replaceable event
|
||||||
expect(a[0][1]).toBe(getAddress(replaceableEvent))
|
expect(a[0][1]).toBe(getAddress(replaceableEvent))
|
||||||
|
|
||||||
console.log(result)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
import {now} from "@welshman/lib"
|
import {now} from "@welshman/lib"
|
||||||
import {publish, PublishStatus} from "@welshman/net"
|
import {publish, PublishStatus, MockAdapter} from "@welshman/net"
|
||||||
import {NOTE} from "@welshman/util"
|
import {NOTE, makeEvent} from "@welshman/util"
|
||||||
|
import {Nip01Signer} from "@welshman/signer"
|
||||||
|
import {LOCAL_RELAY_URL} from "@welshman/relay"
|
||||||
|
import {getPubkey, makeSecret} from "@welshman/signer"
|
||||||
import {EventEmitter} from "events"
|
import {EventEmitter} from "events"
|
||||||
import {afterEach, beforeEach, describe, expect, it, vi} from "vitest"
|
import {afterEach, beforeEach, describe, expect, it, vi} from "vitest"
|
||||||
import {repository, tracker} from "../src/core"
|
import {repository, tracker} from "../src/core"
|
||||||
import * as sessionModule from "../src/session"
|
import {addSession, dropSession} from "../src/session"
|
||||||
import {
|
import {
|
||||||
abortThunk,
|
abortThunk,
|
||||||
makeThunk,
|
makeThunk,
|
||||||
@@ -16,100 +19,31 @@ import {
|
|||||||
walkThunks,
|
walkThunks,
|
||||||
} from "../src/thunk"
|
} from "../src/thunk"
|
||||||
|
|
||||||
// Mock dependencies
|
const secret = makeSecret()
|
||||||
vi.mock("@welshman/net", () => ({
|
|
||||||
publish: vi.fn().mockReturnValue({emitter: {on: vi.fn()}}),
|
|
||||||
PublishStatus: {
|
|
||||||
Pending: "pending",
|
|
||||||
Success: "success",
|
|
||||||
Failure: "failure",
|
|
||||||
Timeout: "timeout",
|
|
||||||
Aborted: "aborted",
|
|
||||||
},
|
|
||||||
}))
|
|
||||||
|
|
||||||
vi.mock("../src/session", () => ({
|
const pubkey = getPubkey(secret)
|
||||||
pubkey: {
|
|
||||||
get: vi.fn().mockReturnValue("aa".repeat(32)),
|
|
||||||
},
|
|
||||||
getSession: vi.fn(),
|
|
||||||
getSigner: vi.fn(),
|
|
||||||
}))
|
|
||||||
|
|
||||||
vi.mock("../src/core", () => ({
|
|
||||||
repository: {
|
|
||||||
publish: vi.fn(),
|
|
||||||
removeEvent: vi.fn(),
|
|
||||||
getEvent: vi.fn(),
|
|
||||||
},
|
|
||||||
tracker: {
|
|
||||||
track: vi.fn(),
|
|
||||||
},
|
|
||||||
}))
|
|
||||||
|
|
||||||
const pubkey = "aa".repeat(32)
|
|
||||||
const id = "00".repeat(32)
|
|
||||||
const mockEvent = {
|
|
||||||
id,
|
|
||||||
pubkey,
|
|
||||||
kind: NOTE,
|
|
||||||
created_at: now(),
|
|
||||||
content: "test content",
|
|
||||||
tags: [],
|
|
||||||
}
|
|
||||||
|
|
||||||
const mockRequest = {
|
const mockRequest = {
|
||||||
event: mockEvent,
|
event: prepEvent({...makeEvent(NOTE), pubkey}),
|
||||||
relays: ["relay1", "relay2"],
|
relays: [LOCAL_RELAY_URL],
|
||||||
}
|
}
|
||||||
|
|
||||||
describe("thunk", () => {
|
describe("thunk", () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.useFakeTimers()
|
vi.useFakeTimers()
|
||||||
vi.clearAllMocks()
|
addSession({method: 'nip01', secret, pubkey})
|
||||||
})
|
})
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
vi.useRealTimers()
|
vi.useRealTimers()
|
||||||
vi.resetModules()
|
vi.clearAllMocks()
|
||||||
thunkWorker.clear()
|
thunkWorker.clear()
|
||||||
thunkWorker.pause() // clear timeout
|
thunkWorker.pause()
|
||||||
thunkWorker.resume()
|
thunkWorker.resume()
|
||||||
})
|
dropSession(pubkey)
|
||||||
|
|
||||||
describe("prepEvent", () => {
|
|
||||||
it("should prepare an event with stamp, own, and hash", () => {
|
|
||||||
const result = prepEvent(mockEvent)
|
|
||||||
expect(result).toHaveProperty("id")
|
|
||||||
expect(result).toHaveProperty("pubkey")
|
|
||||||
expect(result).toHaveProperty("created_at")
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe("makeThunk", () => {
|
|
||||||
it("should create a thunk with required properties", () => {
|
|
||||||
const thunk = makeThunk(mockRequest)
|
|
||||||
expect(thunk).toHaveProperty("event")
|
|
||||||
expect(thunk).toHaveProperty("request")
|
|
||||||
expect(thunk).toHaveProperty("controller")
|
|
||||||
expect(thunk).toHaveProperty("result")
|
|
||||||
expect(thunk).toHaveProperty("status")
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("mergeThunks", () => {
|
describe("mergeThunks", () => {
|
||||||
it("should merge multiple thunks", () => {
|
|
||||||
const thunk1 = makeThunk(mockRequest)
|
|
||||||
const thunk2 = makeThunk(mockRequest)
|
|
||||||
const merged = mergeThunks([thunk1, thunk2])
|
|
||||||
|
|
||||||
expect(merged).toHaveProperty("thunks")
|
|
||||||
expect(merged.thunks).toHaveLength(2)
|
|
||||||
expect(merged).toHaveProperty("controller")
|
|
||||||
expect(merged).toHaveProperty("result")
|
|
||||||
expect(merged).toHaveProperty("status")
|
|
||||||
})
|
|
||||||
|
|
||||||
it("should abort all thunks when merged controller aborts", () => {
|
it("should abort all thunks when merged controller aborts", () => {
|
||||||
const thunk1 = makeThunk(mockRequest)
|
const thunk1 = makeThunk(mockRequest)
|
||||||
const thunk2 = makeThunk(mockRequest)
|
const thunk2 = makeThunk(mockRequest)
|
||||||
@@ -135,18 +69,21 @@ describe("thunk", () => {
|
|||||||
|
|
||||||
describe("publishThunk", () => {
|
describe("publishThunk", () => {
|
||||||
it("should create and publish a thunk", async () => {
|
it("should create and publish a thunk", async () => {
|
||||||
|
const publishSpy = vi.spyOn(repository, 'publish')
|
||||||
const result = publishThunk(mockRequest)
|
const result = publishThunk(mockRequest)
|
||||||
|
|
||||||
expect(repository.publish).toHaveBeenCalled()
|
expect(publishSpy).toHaveBeenCalled()
|
||||||
expect(result).toHaveProperty("event")
|
expect(result).toHaveProperty("event")
|
||||||
expect(result).toHaveProperty("request")
|
expect(result).toHaveProperty("request")
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should handle abort", () => {
|
it("should handle abort", () => {
|
||||||
|
const removeEventSpy = vi.spyOn(repository, 'removeEvent')
|
||||||
const thunk = publishThunk(mockRequest)
|
const thunk = publishThunk(mockRequest)
|
||||||
|
|
||||||
thunk.controller.abort()
|
thunk.controller.abort()
|
||||||
|
|
||||||
expect(repository.removeEvent).toHaveBeenCalledWith(thunk.event.id)
|
expect(removeEventSpy).toHaveBeenCalledWith(thunk.event.id)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -163,62 +100,18 @@ describe("thunk", () => {
|
|||||||
describe("abortThunk", () => {
|
describe("abortThunk", () => {
|
||||||
it("should abort a thunk and clean up", () => {
|
it("should abort a thunk and clean up", () => {
|
||||||
const thunk = makeThunk(mockRequest)
|
const thunk = makeThunk(mockRequest)
|
||||||
|
|
||||||
abortThunk(thunk)
|
abortThunk(thunk)
|
||||||
|
|
||||||
expect(repository.removeEvent).toHaveBeenCalledWith(thunk.event.id)
|
expect(repository.removeEvent).toHaveBeenCalledWith(thunk.event.id)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
|
||||||
|
|
||||||
describe("thunkWorker", async () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
vi.useFakeTimers()
|
|
||||||
vi.clearAllMocks()
|
|
||||||
})
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
vi.useRealTimers()
|
|
||||||
vi.resetModules()
|
|
||||||
thunkWorker.clear()
|
|
||||||
})
|
|
||||||
|
|
||||||
const mockSigner = {
|
|
||||||
sign: vi.fn().mockResolvedValue({...mockEvent, sig: "test-sig"}),
|
|
||||||
}
|
|
||||||
vi.mocked(sessionModule.getSigner).mockReturnValue(mockSigner)
|
|
||||||
|
|
||||||
it("should handle publishing events", async () => {
|
|
||||||
const thunk = makeThunk(mockRequest)
|
|
||||||
|
|
||||||
thunkWorker.push(thunk)
|
|
||||||
|
|
||||||
await vi.runAllTimersAsync()
|
|
||||||
|
|
||||||
expect(mockSigner.sign).toHaveBeenCalled()
|
|
||||||
})
|
|
||||||
|
|
||||||
it("should handle delayed publishing", async () => {
|
|
||||||
const thunk = makeThunk({...mockRequest, delay: 100})
|
|
||||||
const startTime = Date.now()
|
|
||||||
|
|
||||||
thunkWorker.push(thunk)
|
|
||||||
|
|
||||||
await vi.runAllTimersAsync()
|
|
||||||
|
|
||||||
const endTime = Date.now()
|
|
||||||
// worker delays work by 50ms, so total delay should be 150ms
|
|
||||||
expect(endTime - startTime).toBe(150)
|
|
||||||
})
|
|
||||||
|
|
||||||
it("should update status during publishing", async () => {
|
it("should update status during publishing", async () => {
|
||||||
// Create mock emitter
|
const send = vi.fn()
|
||||||
const mockEmitter = new EventEmitter()
|
const track = vi.spyOn(tracker, 'track')
|
||||||
vi.mocked(publish).mockReturnValue({
|
|
||||||
emitter: mockEmitter,
|
|
||||||
})
|
|
||||||
|
|
||||||
const thunk = makeThunk(mockRequest)
|
|
||||||
const statuses: Map<string, any> = new Map<string, any>()
|
const statuses: Map<string, any> = new Map<string, any>()
|
||||||
|
const thunk = makeThunk(mockRequest)
|
||||||
|
|
||||||
// Subscribe to status updates
|
// Subscribe to status updates
|
||||||
thunk.status.subscribe(status => {
|
thunk.status.subscribe(status => {
|
||||||
@@ -233,55 +126,19 @@ describe("thunkWorker", async () => {
|
|||||||
// Wait for initial async operations
|
// Wait for initial async operations
|
||||||
await vi.runAllTimersAsync()
|
await vi.runAllTimersAsync()
|
||||||
|
|
||||||
// Simulate publish status updates
|
expect(statuses.get(LOCAL_RELAY_URL)).toEqual({
|
||||||
mockEmitter.emit("*", PublishStatus.Pending, "relay1", "Connecting...")
|
|
||||||
|
|
||||||
await vi.runAllTimersAsync()
|
|
||||||
|
|
||||||
expect(statuses.get("relay1")).toEqual({
|
|
||||||
status: PublishStatus.Pending,
|
|
||||||
message: "Connecting...",
|
|
||||||
})
|
|
||||||
|
|
||||||
mockEmitter.emit("*", PublishStatus.Success, "relay1", "Published")
|
|
||||||
|
|
||||||
await vi.runAllTimersAsync()
|
|
||||||
|
|
||||||
expect(statuses.get("relay1")).toEqual({
|
|
||||||
status: PublishStatus.Success,
|
status: PublishStatus.Success,
|
||||||
message: "Published",
|
message: "",
|
||||||
})
|
})
|
||||||
|
|
||||||
// Verify tracker was called on success
|
// Verify tracker was called on success
|
||||||
expect(tracker.track).toHaveBeenCalledWith(thunk.event.id, "relay1")
|
expect(track).toHaveBeenCalledWith(thunk.event.id, LOCAL_RELAY_URL)
|
||||||
|
|
||||||
// Verify all relays complete resolves the result
|
|
||||||
mockEmitter.emit("*", PublishStatus.Success, "relay2", "Published")
|
|
||||||
|
|
||||||
await vi.runAllTimersAsync()
|
await vi.runAllTimersAsync()
|
||||||
|
|
||||||
const finalStatus = await thunk.result
|
const finalStatus = await thunk.result
|
||||||
expect(finalStatus).toEqual({
|
expect(finalStatus).toEqual({
|
||||||
relay1: {status: PublishStatus.Success, message: "Published"},
|
[LOCAL_RELAY_URL]: {status: PublishStatus.Success, message: ""},
|
||||||
relay2: {status: PublishStatus.Success, message: "Published"},
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should handle publish failures", async () => {
|
|
||||||
const mockSigner = {
|
|
||||||
sign: vi.fn().mockRejectedValue("Signing failed"),
|
|
||||||
}
|
|
||||||
|
|
||||||
vi.mocked(sessionModule.getSigner).mockReturnValue(mockSigner)
|
|
||||||
|
|
||||||
const thunk = makeThunk(mockRequest)
|
|
||||||
|
|
||||||
thunkWorker.push(thunk)
|
|
||||||
|
|
||||||
await vi.runAllTimersAsync()
|
|
||||||
|
|
||||||
expect(mockSigner.sign).toHaveBeenCalled()
|
|
||||||
|
|
||||||
// in case of failure, the worker will just stop its task, event is not removed
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export type ThunkRequest = {
|
|||||||
event: ThunkEvent
|
event: ThunkEvent
|
||||||
relays: string[]
|
relays: string[]
|
||||||
delay?: number
|
delay?: number
|
||||||
|
context?: AdapterContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ThunkStatus = {
|
export type ThunkStatus = {
|
||||||
@@ -221,7 +222,11 @@ thunkWorker.addGlobalHandler((thunk: Thunk) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Send it off
|
// Send it off
|
||||||
const pub = new MultiPublish({event: signedEvent, relays: thunk.request.relays})
|
const pub = new MultiPublish({
|
||||||
|
event: signedEvent,
|
||||||
|
relays: thunk.request.relays,
|
||||||
|
context: thunk.request.context,
|
||||||
|
})
|
||||||
|
|
||||||
// Copy the signature over since we had deferred it
|
// Copy the signature over since we had deferred it
|
||||||
const savedEvent = repository.getEvent(signedEvent.id) as SignedEvent
|
const savedEvent = repository.getEvent(signedEvent.id) as SignedEvent
|
||||||
|
|||||||
@@ -1,30 +1,12 @@
|
|||||||
import { describe, expect, it, vi, beforeEach, afterEach } from "vitest"
|
import { describe, expect, it, vi, beforeEach, afterEach } from "vitest"
|
||||||
import { EventEmitter } from "events"
|
import { EventEmitter } from "events"
|
||||||
import { Unicast, Multicast, PublishEvent, PublishStatus, unicast, multicast } from "../src/publish"
|
import { SinglePublish, MultiPublish, PublishEvent, PublishStatus, } from "../src/publish"
|
||||||
import { AbstractAdapter, AdapterEvent } from "../src/adapter"
|
import { AbstractAdapter, AdapterEvent, MockAdapter } from "../src/adapter"
|
||||||
import { ClientMessageType, RelayMessage } from "../src/message"
|
import { ClientMessageType, RelayMessage } from "../src/message"
|
||||||
import { SignedEvent, makeEvent } from "@welshman/util"
|
import { SignedEvent, makeEvent } from "@welshman/util"
|
||||||
import { Nip01Signer } from '@welshman/signer'
|
import { Nip01Signer } from '@welshman/signer'
|
||||||
|
|
||||||
class MockAdapter extends AbstractAdapter {
|
describe("SinglePublish", () => {
|
||||||
constructor(readonly url: string, readonly send) {
|
|
||||||
super()
|
|
||||||
}
|
|
||||||
|
|
||||||
get sockets() {
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
|
|
||||||
get urls() {
|
|
||||||
return [this.url]
|
|
||||||
}
|
|
||||||
|
|
||||||
receive = (message: RelayMessage) => {
|
|
||||||
this.emit(AdapterEvent.Receive, message, this.url)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
describe("Unicast", () => {
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.useFakeTimers()
|
vi.useFakeTimers()
|
||||||
})
|
})
|
||||||
@@ -39,7 +21,7 @@ describe("Unicast", () => {
|
|||||||
const signer = Nip01Signer.ephemeral()
|
const signer = Nip01Signer.ephemeral()
|
||||||
const event = await signer.sign(makeEvent(1))
|
const event = await signer.sign(makeEvent(1))
|
||||||
|
|
||||||
const pub = unicast({
|
const pub = new SinglePublish({
|
||||||
relay: '1',
|
relay: '1',
|
||||||
context: {getAdapter: () => adapter},
|
context: {getAdapter: () => adapter},
|
||||||
event,
|
event,
|
||||||
@@ -72,7 +54,7 @@ describe("Unicast", () => {
|
|||||||
const signer = Nip01Signer.ephemeral()
|
const signer = Nip01Signer.ephemeral()
|
||||||
const event = await signer.sign(makeEvent(1))
|
const event = await signer.sign(makeEvent(1))
|
||||||
|
|
||||||
const pub = unicast({
|
const pub = new SinglePublish({
|
||||||
relay: '1',
|
relay: '1',
|
||||||
context: {getAdapter: () => adapter},
|
context: {getAdapter: () => adapter},
|
||||||
event,
|
event,
|
||||||
@@ -105,7 +87,7 @@ describe("Unicast", () => {
|
|||||||
const signer = Nip01Signer.ephemeral()
|
const signer = Nip01Signer.ephemeral()
|
||||||
const event = await signer.sign(makeEvent(1))
|
const event = await signer.sign(makeEvent(1))
|
||||||
|
|
||||||
const pub = unicast({
|
const pub = new SinglePublish({
|
||||||
relay: '1',
|
relay: '1',
|
||||||
context: {getAdapter: () => adapter},
|
context: {getAdapter: () => adapter},
|
||||||
event,
|
event,
|
||||||
@@ -139,7 +121,7 @@ describe("Unicast", () => {
|
|||||||
const signer = Nip01Signer.ephemeral()
|
const signer = Nip01Signer.ephemeral()
|
||||||
const event = await signer.sign(makeEvent(1))
|
const event = await signer.sign(makeEvent(1))
|
||||||
|
|
||||||
const pub = unicast({
|
const pub = new SinglePublish({
|
||||||
relay: '1',
|
relay: '1',
|
||||||
context: {getAdapter: () => adapter},
|
context: {getAdapter: () => adapter},
|
||||||
event,
|
event,
|
||||||
@@ -170,7 +152,7 @@ describe("Unicast", () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("Multicast", () => {
|
describe("MultiPublish", () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.useFakeTimers()
|
vi.useFakeTimers()
|
||||||
})
|
})
|
||||||
@@ -189,7 +171,7 @@ describe("Multicast", () => {
|
|||||||
const signer = Nip01Signer.ephemeral()
|
const signer = Nip01Signer.ephemeral()
|
||||||
const event = await signer.sign(makeEvent(1))
|
const event = await signer.sign(makeEvent(1))
|
||||||
|
|
||||||
const pub = multicast({
|
const pub = new MultiPublish({
|
||||||
event,
|
event,
|
||||||
relays: ['1', '2', '3'],
|
relays: ['1', '2', '3'],
|
||||||
context: {
|
context: {
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import { describe, expect, it, vi, beforeEach, afterEach } from "vitest"
|
|
||||||
import { Socket, SocketEvent } from "../src/socket"
|
|
||||||
import { Relay, LOCAL_RELAY_URL, isRelayUrl } from "@welshman/util"
|
|
||||||
import { AdapterEvent, SocketAdapter, LocalAdapter, getAdapter } from "../src/adapter"
|
|
||||||
import { Pool } from "../src/pool"
|
|
||||||
import { ClientMessage, RelayMessage } from "../src/message"
|
|
||||||
import EventEmitter from "events"
|
import EventEmitter from "events"
|
||||||
|
import { describe, expect, it, vi, beforeEach, afterEach } from "vitest"
|
||||||
|
import { isRelayUrl } from "@welshman/util"
|
||||||
|
import { LocalRelay, LOCAL_RELAY_URL } from "@welshman/relay"
|
||||||
|
import { AdapterEvent, SocketAdapter, LocalAdapter, getAdapter } from "../src/adapter"
|
||||||
|
import { ClientMessage, RelayMessage } from "../src/message"
|
||||||
|
import { Socket, SocketEvent } from "../src/socket"
|
||||||
|
import { Pool } from "../src/pool"
|
||||||
|
|
||||||
vi.mock('isomorphic-ws', () => {
|
vi.mock('isomorphic-ws', () => {
|
||||||
const WebSocket = vi.fn(function () {
|
const WebSocket = vi.fn(function () {
|
||||||
@@ -69,7 +70,7 @@ describe("SocketAdapter", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe("LocalAdapter", () => {
|
describe("LocalAdapter", () => {
|
||||||
let relay: Relay & EventEmitter
|
let relay: LocalRelay & EventEmitter
|
||||||
let adapter: LocalAdapter
|
let adapter: LocalAdapter
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@@ -78,7 +79,7 @@ describe("LocalAdapter", () => {
|
|||||||
send: vi.fn(),
|
send: vi.fn(),
|
||||||
removeAllListeners: vi.fn()
|
removeAllListeners: vi.fn()
|
||||||
})
|
})
|
||||||
relay = mockRelay as unknown as Relay & EventEmitter
|
relay = mockRelay as unknown as LocalRelay & EventEmitter
|
||||||
adapter = new LocalAdapter(relay)
|
adapter = new LocalAdapter(relay)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -119,11 +120,11 @@ describe("LocalAdapter", () => {
|
|||||||
|
|
||||||
describe("getAdapter", () => {
|
describe("getAdapter", () => {
|
||||||
let pool: Pool
|
let pool: Pool
|
||||||
let relay: Relay
|
let relay: LocalRelay
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
pool = new Pool()
|
pool = new Pool()
|
||||||
relay = new Relay()
|
relay = new LocalRelay()
|
||||||
pool.get = vi.fn().mockReturnValue(new Socket("wss://test.relay"))
|
pool.get = vi.fn().mockReturnValue(new Socket("wss://test.relay"))
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -143,20 +144,6 @@ describe("getAdapter", () => {
|
|||||||
expect(adapter).toBeInstanceOf(SocketAdapter)
|
expect(adapter).toBeInstanceOf(SocketAdapter)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should throw error for invalid relay URL", () => {
|
|
||||||
expect(() => getAdapter("invalid-url", {})).toThrow("Invalid relay url invalid-url")
|
|
||||||
})
|
|
||||||
|
|
||||||
it("should throw error for local relay URL without relay context", () => {
|
|
||||||
const url = LOCAL_RELAY_URL
|
|
||||||
expect(() => getAdapter(url, {})).toThrow(`Unable to get local relay for ${url}`)
|
|
||||||
})
|
|
||||||
|
|
||||||
it("should throw error for remote relay URL without pool context", () => {
|
|
||||||
const url = "wss://test.relay"
|
|
||||||
expect(() => getAdapter(url, {})).toThrow(`Unable to get socket for ${url}`)
|
|
||||||
})
|
|
||||||
|
|
||||||
it("should use custom adapter if provided", () => {
|
it("should use custom adapter if provided", () => {
|
||||||
const customAdapter = new SocketAdapter(new Socket("wss://test.relay"))
|
const customAdapter = new SocketAdapter(new Socket("wss://test.relay"))
|
||||||
const getCustomAdapter = vi.fn().mockReturnValue(customAdapter)
|
const getCustomAdapter = vi.fn().mockReturnValue(customAdapter)
|
||||||
|
|||||||
@@ -2,28 +2,10 @@ import { describe, expect, it, vi, beforeEach, afterEach } from "vitest"
|
|||||||
import { Nip01Signer } from '@welshman/signer'
|
import { Nip01Signer } from '@welshman/signer'
|
||||||
import { LOCAL_RELAY_URL, makeEvent } from '@welshman/util'
|
import { LOCAL_RELAY_URL, makeEvent } from '@welshman/util'
|
||||||
import { ClientMessageType, RelayMessage } from "../src/message"
|
import { ClientMessageType, RelayMessage } from "../src/message"
|
||||||
import { AdapterContext, AbstractAdapter, AdapterEvent } from "../src/adapter"
|
import { AdapterContext, AbstractAdapter, AdapterEvent, MockAdapter } from "../src/adapter"
|
||||||
import { unireq, multireq, RequestEvent } from "../src/request"
|
import { SingleRequest, MultiRequest, RequestEvent } from "../src/request"
|
||||||
import { Tracker } from "../src/tracker"
|
import { Tracker } from "../src/tracker"
|
||||||
|
|
||||||
class MockAdapter extends AbstractAdapter {
|
|
||||||
constructor(readonly url: string, readonly send) {
|
|
||||||
super()
|
|
||||||
}
|
|
||||||
|
|
||||||
get sockets() {
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
|
|
||||||
get urls() {
|
|
||||||
return [this.url]
|
|
||||||
}
|
|
||||||
|
|
||||||
receive = (message: RelayMessage) => {
|
|
||||||
this.emit(AdapterEvent.Receive, message, this.url)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
describe("Unireq", () => {
|
describe("Unireq", () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.useFakeTimers()
|
vi.useFakeTimers()
|
||||||
@@ -36,7 +18,7 @@ describe("Unireq", () => {
|
|||||||
it("everything basically works", async () => {
|
it("everything basically works", async () => {
|
||||||
const sendSpy = vi.fn()
|
const sendSpy = vi.fn()
|
||||||
const adapter = new MockAdapter('1', sendSpy)
|
const adapter = new MockAdapter('1', sendSpy)
|
||||||
const req = unireq({
|
const req = new SingleRequest({
|
||||||
relay: 'whatever',
|
relay: 'whatever',
|
||||||
filter: {kinds: [1]},
|
filter: {kinds: [1]},
|
||||||
context: {getAdapter: () => adapter},
|
context: {getAdapter: () => adapter},
|
||||||
@@ -100,7 +82,7 @@ describe("Multireq", () => {
|
|||||||
const adapter1 = new MockAdapter('1', send1Spy)
|
const adapter1 = new MockAdapter('1', send1Spy)
|
||||||
const send2Spy = vi.fn()
|
const send2Spy = vi.fn()
|
||||||
const adapter2 = new MockAdapter('2', send2Spy)
|
const adapter2 = new MockAdapter('2', send2Spy)
|
||||||
const req = multireq({
|
const req = new MultiRequest({
|
||||||
autoClose: true,
|
autoClose: true,
|
||||||
relays: ['1', '2'],
|
relays: ['1', '2'],
|
||||||
filter: {kinds: [1]},
|
filter: {kinds: [1]},
|
||||||
|
|||||||
@@ -78,16 +78,25 @@ export class LocalAdapter extends AbstractAdapter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class EmptyAdapter extends AbstractAdapter {
|
export class MockAdapter extends AbstractAdapter {
|
||||||
|
constructor(
|
||||||
|
readonly url: string,
|
||||||
|
readonly send: (message: ClientMessage) => void,
|
||||||
|
) {
|
||||||
|
super()
|
||||||
|
}
|
||||||
|
|
||||||
get sockets() {
|
get sockets() {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
get urls() {
|
get urls() {
|
||||||
return []
|
return [this.url]
|
||||||
}
|
}
|
||||||
|
|
||||||
send(message: ClientMessage) {}
|
receive = (message: RelayMessage) => {
|
||||||
|
this.emit(AdapterEvent.Receive, message, this.url)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type AdapterContext = {
|
export type AdapterContext = {
|
||||||
|
|||||||
@@ -205,9 +205,7 @@ export const socketPolicyReopenActive = (socket: Socket) => {
|
|||||||
|
|
||||||
// If the socket closed and we have no error, reopen it but don't flap
|
// If the socket closed and we have no error, reopen it but don't flap
|
||||||
if (newStatus === SocketStatus.Closed && pending.size) {
|
if (newStatus === SocketStatus.Closed && pending.size) {
|
||||||
console.log("1")
|
|
||||||
sleep(Math.max(0, 30_000 - (Date.now() - lastOpen))).then(() => {
|
sleep(Math.max(0, 30_000 - (Date.now() - lastOpen))).then(() => {
|
||||||
console.log("2")
|
|
||||||
for (const message of pending.values()) {
|
for (const message of pending.values()) {
|
||||||
socket.send(message)
|
socket.send(message)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user