@@ -2,6 +2,15 @@ import { createClient } from 'redis';
22
33const redisClient = createClient ( { url : process . env . REDIS_URL || 'redis://localhost:6379' } ) ;
44
5+ interface RedisStreamMessage {
6+ id : string ;
7+ message : Record < string , string > ;
8+ }
9+ interface RedisStreamResult {
10+ name : string ;
11+ messages : RedisStreamMessage [ ] ;
12+ }
13+
514test ( 'Redis client connects successfully' , async ( ) => {
615 await redisClient . connect ( ) ;
716 expect ( redisClient . isOpen ) . toBe ( true ) ;
@@ -35,3 +44,74 @@ test('multiple connect calls', async () => {
3544 expect ( client . isOpen ) . toBe ( true ) ;
3645 await client . quit ( ) ;
3746} ) ;
47+
48+ test ( 'write to stream and read back' , async ( ) => {
49+ const client = createClient ( { url : process . env . REDIS_URL || 'redis://localhost:6379' } ) ;
50+ await client . connect ( ) ;
51+
52+ const streamKey = 'test-stream' ;
53+ await client . del ( streamKey ) ;
54+ const messageId = await client . xAdd ( streamKey , '*' , { field1 : 'value1' } ) ;
55+
56+ const result = ( await client . xRead ( { key : streamKey , id : '0-0' } , { COUNT : 1 , BLOCK : 2000 } ) ) as
57+ | RedisStreamResult [ ]
58+ | null ;
59+ expect ( result ) . not . toBeNull ( ) ;
60+ expect ( result ) . toBeDefined ( ) ;
61+
62+ const [ stream ] = result ! ;
63+ expect ( stream ) . toBeDefined ( ) ;
64+ expect ( stream ?. messages . length ) . toBe ( 1 ) ;
65+ const [ message ] = stream ! . messages ;
66+ expect ( message ! . id ) . toBe ( messageId ) ;
67+ expect ( message ! . message ) . toEqual ( { field1 : 'value1' } ) ;
68+
69+ await client . quit ( ) ;
70+ } ) ;
71+
72+ test ( 'quit while reading from stream' , async ( ) => {
73+ const client = createClient ( { url : process . env . REDIS_URL || 'redis://localhost:6379' } ) ;
74+ await client . connect ( ) ;
75+
76+ const streamKey = 'test-stream-quit' ;
77+
78+ const readPromise = client . xRead ( { key : streamKey , id : '$' } , { BLOCK : 0 } ) ;
79+
80+ // Wait a moment to ensure xRead is blocking
81+ await new Promise ( ( resolve ) => {
82+ setTimeout ( resolve , 500 ) ;
83+ } ) ;
84+
85+ client . destroy ( ) ;
86+
87+ await expect ( readPromise ) . rejects . toThrow ( ) ;
88+ } ) ;
89+
90+ it ( 'expire sets TTL on stream' , async ( ) => {
91+ const client = createClient ( { url : process . env . REDIS_URL || 'redis://localhost:6379' } ) ;
92+ await client . connect ( ) ;
93+
94+ const streamKey = 'test-stream-expire' ;
95+ await client . del ( streamKey ) ;
96+ await client . xAdd ( streamKey , '*' , { field1 : 'value1' } ) ;
97+
98+ const expireResult = await client . expire ( streamKey , 1 ) ; // 1 second
99+ expect ( expireResult ) . toBe ( 1 ) ; // 1 means the key existed and TTL was set
100+
101+ const ttl1 = await client . ttl ( streamKey ) ;
102+ expect ( ttl1 ) . toBeLessThanOrEqual ( 1 ) ;
103+ expect ( ttl1 ) . toBeGreaterThan ( 0 ) ;
104+
105+ const existsBeforeTimeout = await client . exists ( streamKey ) ;
106+ expect ( existsBeforeTimeout ) . toBe ( 1 ) ; // Key should exist before timeout
107+
108+ // Wait for 1.1 seconds
109+ await new Promise ( ( resolve ) => {
110+ setTimeout ( resolve , 1100 ) ;
111+ } ) ;
112+
113+ const existsAfterTimeout = await client . exists ( streamKey ) ;
114+ expect ( existsAfterTimeout ) . toBe ( 0 ) ; // Key should have expired
115+
116+ await client . quit ( ) ;
117+ } ) ;
0 commit comments