@@ -3,6 +3,7 @@ import chai from 'chai'
33import chaiAsPromised from 'chai-as-promised'
44import EventEmitter from 'events'
55import Sinon from 'sinon'
6+ import sinonChai from 'sinon-chai'
67
78import { IAbortable , IMessageHandler } from '../../../src/@types/message-handlers'
89import { MessageType , SubscribeMessage } from '../../../src/@types/messages'
@@ -14,17 +15,22 @@ import { PassThrough } from 'stream'
1415import { SubscribeMessageHandler } from '../../../src/handlers/subscribe-message-handler'
1516import { WebSocketAdapterEvent } from '../../../src/constants/adapter'
1617
18+ chai . use ( sinonChai )
1719chai . use ( chaiAsPromised )
1820const { expect } = chai
1921
20- const toDbEvent = ( event : Event ) => ( {
22+ const toDbEvent = (
23+ event : Event ,
24+ metadata : { expires_at ?: number , deleted_at ?: Date | null } = { } ,
25+ ) => ( {
2126 event_id : Buffer . from ( event . id , 'hex' ) ,
2227 event_kind : event . kind ,
2328 event_pubkey : Buffer . from ( event . pubkey , 'hex' ) ,
2429 event_created_at : event . created_at ,
2530 event_content : event . content ,
2631 event_tags : event . tags ,
2732 event_signature : Buffer . from ( event . sig , 'hex' ) ,
33+ ...metadata ,
2834} )
2935
3036describe ( 'SubscribeMessageHandler' , ( ) => {
@@ -112,11 +118,13 @@ describe('SubscribeMessageHandler', () => {
112118
113119 describe ( '#fetchAndSend' , ( ) => {
114120 let event : Event
121+ let clock : Sinon . SinonFakeTimers
115122 let webSocketOnMessageStub : Sinon . SinonStub
116123 let webSocketOnSubscribeStub : Sinon . SinonStub
117124 let isClientSubscribedToEventStub : Sinon . SinonStub
118125
119126 beforeEach ( ( ) => {
127+ clock = sandbox . useFakeTimers ( 1665546189000 )
120128 event = {
121129 'id' : 'b1601d26958e6508b7b9df0af609c652346c09392b6534d93aead9819a51b4ef' ,
122130 'pubkey' : '22e804d26ed16b68db5259e78449e96dab5d464c8f470bda3eb1a70467f2c793' ,
@@ -165,6 +173,53 @@ describe('SubscribeMessageHandler', () => {
165173 )
166174 } )
167175
176+ it ( 'does not send expired events' , async ( ) => {
177+ isClientSubscribedToEventStub . returns ( always ( true ) )
178+
179+ const now = Math . floor ( clock . now / 1000 )
180+ const promise = ( handler as any ) . fetchAndSend ( subscriptionId , filters )
181+
182+ const expiredEvent : Event = {
183+ ...event ,
184+ tags : [ [ 'expiration' , String ( now - 1 ) ] as any ] ,
185+ }
186+
187+ stream . write ( toDbEvent ( expiredEvent ) )
188+ stream . end ( )
189+
190+ await promise
191+
192+ expect ( eventRepositoryFindByFiltersStub ) . to . have . been . calledOnceWithExactly ( filters )
193+ expect ( webSocketOnMessageStub ) . to . have . been . calledOnceWithExactly (
194+ [ 'EOSE' , subscriptionId ] ,
195+ )
196+ } )
197+
198+ it ( 'sends event if expiration is in the future' , async ( ) => {
199+ isClientSubscribedToEventStub . returns ( always ( true ) )
200+
201+ const now = Math . floor ( clock . now / 1000 )
202+ const promise = ( handler as any ) . fetchAndSend ( subscriptionId , filters )
203+
204+ const eventWithFutureExpiration : Event = {
205+ ...event ,
206+ tags : [ [ 'expiration' , String ( now + 60 ) ] as any ] ,
207+ }
208+
209+ stream . write ( toDbEvent ( eventWithFutureExpiration ) )
210+ stream . end ( )
211+
212+ await promise
213+
214+ expect ( eventRepositoryFindByFiltersStub ) . to . have . been . calledOnceWithExactly ( filters )
215+ expect ( webSocketOnMessageStub ) . to . have . been . calledWithExactly (
216+ [ 'EVENT' , subscriptionId , eventWithFutureExpiration ] ,
217+ )
218+ expect ( webSocketOnMessageStub ) . to . have . been . calledWithExactly (
219+ [ 'EOSE' , subscriptionId ] ,
220+ )
221+ } )
222+
168223 it ( 'sends EOSE' , async ( ) => {
169224 const promise = ( handler as any ) . fetchAndSend ( subscriptionId , filters )
170225
0 commit comments