Skip to content

Commit 176f76b

Browse files
test: increase event-message-handler edge-path coverage
1 parent 32ac52e commit 176f76b

1 file changed

Lines changed: 140 additions & 2 deletions

File tree

test/unit/handlers/event-message-handler.spec.ts

Lines changed: 140 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { identifyEvent, signEvent } from '../../../src/utils/event'
1313
import { IncomingEventMessage, MessageType } from '../../../src/@types/messages'
1414
import { CacheAdmissionState } from '../../../src/constants/caching'
1515
import { Event } from '../../../src/@types/event'
16-
import { EventKinds } from '../../../src/constants/base'
16+
import { EventKinds, EventExpirationTimeMetadataKey, EventTags } from '../../../src/constants/base'
1717
import { EventMessageHandler } from '../../../src/handlers/event-message-handler'
1818
import { IUserRepository } from '../../../src/@types/repositories'
1919
import { IWebSocketAdapter } from '../../../src/@types/adapters'
@@ -172,6 +172,23 @@ describe('EventMessageHandler', () => {
172172
expect(strategyFactoryStub).not.to.have.been.called
173173
})
174174

175+
it('rejects event if NIP-05 verification is required', async () => {
176+
canAcceptEventStub.returns(undefined)
177+
isEventValidStub.resolves(undefined)
178+
isUserAdmitted.resolves(undefined)
179+
sandbox.stub(EventMessageHandler.prototype, 'checkNip05Verification' as any).resolves('blocked: NIP-05 verification required')
180+
181+
await handler.handleMessage(message)
182+
183+
expect(onMessageSpy).to.have.been.calledOnceWithExactly([
184+
MessageType.OK,
185+
event.id,
186+
false,
187+
'blocked: NIP-05 verification required',
188+
])
189+
expect(strategyFactoryStub).not.to.have.been.called
190+
})
191+
175192
it('rejects event if it is expired', async () => {
176193
isEventValidStub.resolves(undefined)
177194

@@ -280,6 +297,14 @@ describe('EventMessageHandler', () => {
280297
})
281298

282299
describe('createdAt', () => {
300+
it('returns undefined if event pubkey equals relay public key', () => {
301+
sandbox.stub(EventMessageHandler.prototype, 'getRelayPublicKey' as any).returns(event.pubkey)
302+
eventLimits.createdAt.maxPositiveDelta = 1
303+
event.created_at += 999
304+
305+
expect((handler as any).canAcceptEvent(event)).to.be.undefined
306+
})
307+
283308
describe('maxPositiveDelta', () => {
284309
it('returns undefined if maxPositiveDelta is zero', () => {
285310
eventLimits.createdAt.maxPositiveDelta = 0
@@ -616,6 +641,22 @@ describe('EventMessageHandler', () => {
616641
}
617642
})
618643

644+
it('returns reason if request to vanish relay tag does not match relay URL', async () => {
645+
const privkey = '0000000000000000000000000000000000000000000000000000000000000001'
646+
const unsignedEvent = await identifyEvent({
647+
pubkey: '79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798',
648+
created_at: 1700000000,
649+
kind: EventKinds.REQUEST_TO_VANISH,
650+
tags: [[EventTags.Relay, 'wss://another-relay.example']],
651+
content: '',
652+
})
653+
const vanishEvent = await signEvent(privkey)(unsignedEvent)
654+
655+
return expect((handler as any).isEventValid(vanishEvent)).to.eventually.equal(
656+
'invalid: request to vanish relay tag invalid',
657+
)
658+
})
659+
619660
it('returns undefined if event is valid', () => {
620661
return expect((handler as any).isEventValid(event)).to.eventually.be.undefined
621662
})
@@ -683,6 +724,36 @@ describe('EventMessageHandler', () => {
683724
})
684725
})
685726

727+
describe('isBlockedByRequestToVanish', () => {
728+
beforeEach(() => {
729+
handler = new EventMessageHandler(
730+
{} as any,
731+
() => null,
732+
{} as any,
733+
userRepository,
734+
() =>
735+
({
736+
info: { relay_url: 'relay_url' },
737+
}) as any,
738+
{} as any,
739+
{ hasKey: async () => false, setKey: async () => true } as any,
740+
() => ({ hit: async () => false }),
741+
)
742+
})
743+
744+
it('returns undefined for request to vanish events', async () => {
745+
event.kind = EventKinds.REQUEST_TO_VANISH
746+
747+
return expect((handler as any).isBlockedByRequestToVanish(event)).to.eventually.be.undefined
748+
})
749+
750+
it("returns undefined if event pubkey equals relay's own public key", async () => {
751+
sandbox.stub(EventMessageHandler.prototype, 'getRelayPublicKey' as any).returns(event.pubkey)
752+
753+
return expect((handler as any).isBlockedByRequestToVanish(event)).to.eventually.be.undefined
754+
})
755+
})
756+
686757
describe('isRateLimited', () => {
687758
let eventLimits: EventLimits
688759
let settings: Settings
@@ -743,6 +814,21 @@ describe('EventMessageHandler', () => {
743814
return expect((handler as any).isRateLimited(event)).to.eventually.be.false
744815
})
745816

817+
it("fulfills with false if event pubkey equals relay's own public key", async () => {
818+
sandbox.stub(EventMessageHandler.prototype, 'getRelayPublicKey' as any).returns(event.pubkey)
819+
eventLimits.rateLimits = [
820+
{
821+
period: 60000,
822+
rate: 1,
823+
},
824+
]
825+
826+
const actualResult = await (handler as any).isRateLimited(event)
827+
828+
expect(actualResult).to.be.false
829+
expect(rateLimiterHitStub).not.to.have.been.called
830+
})
831+
746832
it('skips rate limiter if IP is whitelisted', async () => {
747833
eventLimits.rateLimits = [
748834
{
@@ -1098,6 +1184,17 @@ describe('EventMessageHandler', () => {
10981184
})
10991185

11001186
describe('caching', () => {
1187+
it('falls back to repository lookup when cache read fails', async () => {
1188+
cacheStub.getKey.rejects(new Error('cache unavailable'))
1189+
settings.limits.event.pubkey.minBalance = 100n
1190+
userRepositoryFindByPubkeyStub.resolves({ isAdmitted: true, balance: 150n })
1191+
1192+
await expect((handler as any).isUserAdmitted(event)).to.eventually.be.undefined
1193+
1194+
expect(userRepositoryFindByPubkeyStub).to.have.been.calledOnceWithExactly(event.pubkey)
1195+
expect(cacheStub.setKey).to.have.been.calledWith(`${event.pubkey}:is-admitted`, CacheAdmissionState.ADMITTED, 300)
1196+
})
1197+
11011198
it('fulfills with undefined and uses cache hit for admitted user without hitting DB', async () => {
11021199
cacheStub.getKey.resolves(CacheAdmissionState.ADMITTED)
11031200

@@ -1341,6 +1438,35 @@ describe('EventMessageHandler', () => {
13411438
})
13421439
})
13431440

1441+
describe('addExpirationMetadata', () => {
1442+
beforeEach(() => {
1443+
handler = new EventMessageHandler(
1444+
{} as any,
1445+
() => null,
1446+
{} as any,
1447+
userRepository,
1448+
() =>
1449+
({
1450+
info: { relay_url: 'relay_url' },
1451+
}) as any,
1452+
{} as any,
1453+
{ hasKey: async () => false, setKey: async () => true } as any,
1454+
() => ({ hit: async () => false }),
1455+
)
1456+
})
1457+
1458+
it('adds expiration metadata when expiration tag is present', () => {
1459+
const expiringEvent: Event = {
1460+
...event,
1461+
tags: [[EventTags.Expiration, '1665547000']],
1462+
}
1463+
1464+
const enriched = (handler as any).addExpirationMetadata(expiringEvent)
1465+
1466+
expect((enriched as any)[EventExpirationTimeMetadataKey]).to.equal(1665547000)
1467+
})
1468+
})
1469+
13441470
describe('processNip05Metadata', () => {
13451471
let settings: Settings
13461472
let nip05VerificationRepository: any
@@ -1422,6 +1548,18 @@ describe('EventMessageHandler', () => {
14221548
expect(verifyStub).not.to.have.been.called
14231549
})
14241550

1551+
it('ignores delete errors when kind-0 has no nip05 in content', async () => {
1552+
nip05VerificationRepository.deleteByPubkey.rejects(new Error('db down'))
1553+
event.kind = EventKinds.SET_METADATA
1554+
event.content = JSON.stringify({ name: 'alice' })
1555+
1556+
;(handler as any).processNip05Metadata(event)
1557+
await new Promise((resolve) => setTimeout(resolve, 10))
1558+
1559+
expect(nip05VerificationRepository.deleteByPubkey).to.have.been.calledOnceWithExactly(event.pubkey)
1560+
expect(verifyStub).not.to.have.been.called
1561+
})
1562+
14251563
it('does nothing when nip05 identifier is unparseable', async () => {
14261564
event.kind = EventKinds.SET_METADATA
14271565
event.content = JSON.stringify({ nip05: 'invalid-no-at-sign' })
@@ -1969,4 +2107,4 @@ describe('EventMessageHandler', () => {
19692107
expect(nip05VerificationRepository.upsert).to.have.been.calledOnce
19702108
})
19712109
})
1972-
})
2110+
})

0 commit comments

Comments
 (0)