273 lines
7.0 KiB
TypeScript
273 lines
7.0 KiB
TypeScript
import {ctx} from "@welshman/lib"
|
|
import {FOLLOWS, MUTES, PINS} from "@welshman/util"
|
|
import {afterEach, beforeEach, describe, expect, it, vi} from "vitest"
|
|
import {follow, mute, pin, unfollow, unmute, unpin} from "../src/commands"
|
|
import * as thunkModule from "../src/thunk"
|
|
import {thunkWorker} from "../src/thunk"
|
|
import {repository} from "../src/core"
|
|
|
|
vi.mock(import("@welshman/lib"), async importOriginal => ({
|
|
...(await importOriginal()),
|
|
ctx: {
|
|
app: {
|
|
router: {
|
|
FromUser: vi.fn().mockReturnValue({
|
|
getUrls: vi.fn().mockReturnValue(["relay1", "relay2"]),
|
|
}),
|
|
},
|
|
},
|
|
net: {
|
|
getExecutor: vi.fn(),
|
|
optimizeSubscriptions: vi.fn().mockReturnValue([]),
|
|
},
|
|
},
|
|
}))
|
|
|
|
vi.mock(import("../src/session"), async importOriginal => ({
|
|
...(await importOriginal()),
|
|
nip44EncryptToSelf: vi.fn().mockImplementation(text => `encrypted:${text}`),
|
|
pubkey: {
|
|
get: () => "ee".repeat(32),
|
|
subscribe: run => {
|
|
run("ee".repeat(32))
|
|
return () => null
|
|
},
|
|
},
|
|
}))
|
|
|
|
describe("commands", () => {
|
|
const pubkey1 = "aa".repeat(32)
|
|
const pubkey2 = "bb".repeat(32)
|
|
|
|
const event1 = "ee".repeat(32)
|
|
const event2 = "ff".repeat(32)
|
|
|
|
beforeEach(async () => {
|
|
vi.useFakeTimers()
|
|
vi.setSystemTime(new Date())
|
|
vi.resetModules()
|
|
vi.clearAllMocks()
|
|
|
|
repository.load([])
|
|
})
|
|
|
|
afterEach(() => {
|
|
vi.clearAllTimers()
|
|
vi.useRealTimers()
|
|
|
|
thunkWorker.clear()
|
|
thunkWorker.pause()
|
|
thunkWorker.resume()
|
|
})
|
|
|
|
describe("follow commands", () => {
|
|
it("should create new follows list if none exists", async () => {
|
|
const publishThunkSpy = vi.spyOn(thunkModule, "publishThunk")
|
|
await follow(["p", pubkey1])
|
|
await vi.runAllTimersAsync()
|
|
|
|
expect(publishThunkSpy).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
event: expect.objectContaining({
|
|
kind: FOLLOWS,
|
|
tags: expect.arrayContaining([["p", pubkey1]]),
|
|
}),
|
|
relays: ["relay1", "relay2"],
|
|
}),
|
|
)
|
|
})
|
|
|
|
it("should use existing follows list if available", async () => {
|
|
const publishThunkSpy = vi.spyOn(thunkModule, "publishThunk")
|
|
|
|
await follow(["p", pubkey1])
|
|
|
|
await vi.runAllTimersAsync()
|
|
|
|
await follow(["p", pubkey2])
|
|
|
|
await vi.runAllTimersAsync()
|
|
|
|
expect(publishThunkSpy).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
event: expect.objectContaining({
|
|
kind: FOLLOWS,
|
|
tags: expect.arrayContaining([
|
|
["p", pubkey1],
|
|
["p", pubkey2],
|
|
]),
|
|
}),
|
|
relays: ["relay1", "relay2"],
|
|
}),
|
|
)
|
|
})
|
|
|
|
it("should handle unfollow command", async () => {
|
|
const publishThunkSpy = vi.spyOn(thunkModule, "publishThunk")
|
|
|
|
await follow(["p", pubkey1])
|
|
|
|
await vi.runAllTimersAsync()
|
|
|
|
await unfollow(pubkey1)
|
|
|
|
expect(publishThunkSpy).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
event: expect.objectContaining({
|
|
kind: FOLLOWS,
|
|
tags: expect.arrayContaining([]),
|
|
}),
|
|
relays: ["relay1", "relay2"],
|
|
}),
|
|
)
|
|
})
|
|
})
|
|
|
|
describe("mute commands", () => {
|
|
it("should create new mutes list if none exists", async () => {
|
|
const publishThunkSpy = vi.spyOn(thunkModule, "publishThunk")
|
|
|
|
await mute(["p", pubkey1])
|
|
|
|
await vi.runAllTimersAsync()
|
|
|
|
expect(publishThunkSpy).toHaveBeenCalledWith({
|
|
event: expect.objectContaining({
|
|
kind: MUTES,
|
|
tags: expect.arrayContaining([["p", pubkey1]]),
|
|
}),
|
|
relays: ["relay1", "relay2"],
|
|
})
|
|
})
|
|
|
|
it.skip("should use existing mutes list if available", async () => {
|
|
const publishThunkSpy = vi.spyOn(thunkModule, "publishThunk")
|
|
|
|
await mute(["p", pubkey1])
|
|
|
|
await vi.runAllTimersAsync()
|
|
|
|
await mute(["p", pubkey2])
|
|
|
|
await vi.runAllTimersAsync()
|
|
|
|
expect(publishThunkSpy).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
event: expect.objectContaining({
|
|
kind: MUTES,
|
|
tags: expect.arrayContaining([
|
|
["p", pubkey1],
|
|
["p", pubkey2],
|
|
]),
|
|
}),
|
|
relays: ["relay1", "relay2"],
|
|
}),
|
|
)
|
|
})
|
|
|
|
it("should handle unmute command", async () => {
|
|
const publishThunkSpy = vi.spyOn(thunkModule, "publishThunk")
|
|
|
|
await mute(["p", pubkey1])
|
|
|
|
await vi.runAllTimersAsync()
|
|
|
|
await unmute("pubkey1")
|
|
|
|
expect(publishThunkSpy).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
event: expect.objectContaining({
|
|
kind: MUTES,
|
|
tags: expect.arrayContaining([]),
|
|
}),
|
|
relays: ["relay1", "relay2"],
|
|
}),
|
|
)
|
|
})
|
|
})
|
|
|
|
describe("pin commands", () => {
|
|
it("should create new pins list if none exists", async () => {
|
|
const publishThunkSpy = vi.spyOn(thunkModule, "publishThunk")
|
|
await pin(["e", event1])
|
|
|
|
await vi.runAllTimersAsync()
|
|
|
|
expect(publishThunkSpy).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
event: expect.objectContaining({
|
|
kind: PINS,
|
|
tags: expect.arrayContaining([["e", event1]]),
|
|
}),
|
|
relays: ["relay1", "relay2"],
|
|
}),
|
|
)
|
|
})
|
|
|
|
it.skip("should use existing pins list if available", async () => {
|
|
const publishThunkSpy = vi.spyOn(thunkModule, "publishThunk")
|
|
|
|
await pin(["e", event1])
|
|
|
|
await vi.runAllTimersAsync()
|
|
|
|
await pin(["e", event2])
|
|
|
|
await vi.runAllTimersAsync()
|
|
|
|
expect(publishThunkSpy).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
event: expect.objectContaining({
|
|
kind: PINS,
|
|
tags: expect.arrayContaining([
|
|
["e", event1],
|
|
["e", event2],
|
|
]),
|
|
}),
|
|
relays: ["relay1", "relay2"],
|
|
}),
|
|
)
|
|
})
|
|
|
|
it("should handle unpin command", async () => {
|
|
const publishThunkSpy = vi.spyOn(thunkModule, "publishThunk")
|
|
|
|
await pin(["e", event1])
|
|
|
|
await vi.runAllTimersAsync()
|
|
|
|
await unpin("event1")
|
|
|
|
expect(publishThunkSpy).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
event: expect.objectContaining({
|
|
kind: PINS,
|
|
tags: expect.arrayContaining([]),
|
|
}),
|
|
relays: ["relay1", "relay2"],
|
|
}),
|
|
)
|
|
})
|
|
})
|
|
|
|
describe("relay selection", () => {
|
|
it("should use correct relays from router", async () => {
|
|
const publishThunkSpy = vi.spyOn(thunkModule, "publishThunk")
|
|
const mockGetUrls = vi.fn().mockReturnValue(["relay3", "relay4"])
|
|
vi.mocked(ctx.app.router.FromUser).mockReturnValue({
|
|
getUrls: mockGetUrls,
|
|
})
|
|
|
|
await follow(["p", pubkey1])
|
|
|
|
expect(ctx.app.router.FromUser).toHaveBeenCalled()
|
|
expect(mockGetUrls).toHaveBeenCalled()
|
|
expect(publishThunkSpy).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
relays: ["relay3", "relay4"],
|
|
}),
|
|
)
|
|
})
|
|
})
|
|
})
|