Fix some tests

This commit is contained in:
Jon Staab
2025-03-31 14:06:52 -07:00
parent 1524d128e3
commit 8bc336ae5d
8 changed files with 69 additions and 251 deletions
-2
View File
@@ -206,8 +206,6 @@ describe("tags", () => {
// a[0] should be the address of the replaceable event
expect(a[0][1]).toBe(getAddress(replaceableEvent))
console.log(result)
})
})
+27 -170
View File
@@ -1,10 +1,13 @@
import {now} from "@welshman/lib"
import {publish, PublishStatus} from "@welshman/net"
import {NOTE} from "@welshman/util"
import {publish, PublishStatus, MockAdapter} from "@welshman/net"
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 {afterEach, beforeEach, describe, expect, it, vi} from "vitest"
import {repository, tracker} from "../src/core"
import * as sessionModule from "../src/session"
import {addSession, dropSession} from "../src/session"
import {
abortThunk,
makeThunk,
@@ -16,100 +19,31 @@ import {
walkThunks,
} from "../src/thunk"
// Mock dependencies
vi.mock("@welshman/net", () => ({
publish: vi.fn().mockReturnValue({emitter: {on: vi.fn()}}),
PublishStatus: {
Pending: "pending",
Success: "success",
Failure: "failure",
Timeout: "timeout",
Aborted: "aborted",
},
}))
const secret = makeSecret()
vi.mock("../src/session", () => ({
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 pubkey = getPubkey(secret)
const mockRequest = {
event: mockEvent,
relays: ["relay1", "relay2"],
event: prepEvent({...makeEvent(NOTE), pubkey}),
relays: [LOCAL_RELAY_URL],
}
describe("thunk", () => {
beforeEach(() => {
vi.useFakeTimers()
vi.clearAllMocks()
addSession({method: 'nip01', secret, pubkey})
})
afterEach(() => {
vi.useRealTimers()
vi.resetModules()
vi.clearAllMocks()
thunkWorker.clear()
thunkWorker.pause() // clear timeout
thunkWorker.pause()
thunkWorker.resume()
})
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")
})
dropSession(pubkey)
})
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", () => {
const thunk1 = makeThunk(mockRequest)
const thunk2 = makeThunk(mockRequest)
@@ -135,18 +69,21 @@ describe("thunk", () => {
describe("publishThunk", () => {
it("should create and publish a thunk", async () => {
const publishSpy = vi.spyOn(repository, 'publish')
const result = publishThunk(mockRequest)
expect(repository.publish).toHaveBeenCalled()
expect(publishSpy).toHaveBeenCalled()
expect(result).toHaveProperty("event")
expect(result).toHaveProperty("request")
})
it("should handle abort", () => {
const removeEventSpy = vi.spyOn(repository, 'removeEvent')
const thunk = publishThunk(mockRequest)
thunk.controller.abort()
expect(repository.removeEvent).toHaveBeenCalledWith(thunk.event.id)
expect(removeEventSpy).toHaveBeenCalledWith(thunk.event.id)
})
})
@@ -163,62 +100,18 @@ describe("thunk", () => {
describe("abortThunk", () => {
it("should abort a thunk and clean up", () => {
const thunk = makeThunk(mockRequest)
abortThunk(thunk)
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 () => {
// Create mock emitter
const mockEmitter = new EventEmitter()
vi.mocked(publish).mockReturnValue({
emitter: mockEmitter,
})
const thunk = makeThunk(mockRequest)
const send = vi.fn()
const track = vi.spyOn(tracker, 'track')
const statuses: Map<string, any> = new Map<string, any>()
const thunk = makeThunk(mockRequest)
// Subscribe to status updates
thunk.status.subscribe(status => {
@@ -233,55 +126,19 @@ describe("thunkWorker", async () => {
// Wait for initial async operations
await vi.runAllTimersAsync()
// Simulate publish status updates
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({
expect(statuses.get(LOCAL_RELAY_URL)).toEqual({
status: PublishStatus.Success,
message: "Published",
message: "",
})
// Verify tracker was called on success
expect(tracker.track).toHaveBeenCalledWith(thunk.event.id, "relay1")
// Verify all relays complete resolves the result
mockEmitter.emit("*", PublishStatus.Success, "relay2", "Published")
expect(track).toHaveBeenCalledWith(thunk.event.id, LOCAL_RELAY_URL)
await vi.runAllTimersAsync()
const finalStatus = await thunk.result
expect(finalStatus).toEqual({
relay1: {status: PublishStatus.Success, message: "Published"},
relay2: {status: PublishStatus.Success, message: "Published"},
[LOCAL_RELAY_URL]: {status: PublishStatus.Success, message: ""},
})
})
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
})
})
+6 -1
View File
@@ -26,6 +26,7 @@ export type ThunkRequest = {
event: ThunkEvent
relays: string[]
delay?: number
context?: AdapterContext,
}
export type ThunkStatus = {
@@ -221,7 +222,11 @@ thunkWorker.addGlobalHandler((thunk: Thunk) => {
}
// 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
const savedEvent = repository.getEvent(signedEvent.id) as SignedEvent