Skip to content

Commit 06bd24e

Browse files
authored
Merge pull request #2470 from ai16z-demirix/tests/redis-adapter
test: adding test configuration and tests for redis adapter
2 parents 7100fe7 + 4f99207 commit 06bd24e

File tree

3 files changed

+196
-2
lines changed

3 files changed

+196
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2+
import { RedisClient } from '../src';
3+
import { type UUID, elizaLogger } from '@elizaos/core';
4+
import Redis from 'ioredis';
5+
6+
// Mock ioredis
7+
vi.mock('ioredis', () => {
8+
const MockRedis = vi.fn(() => ({
9+
on: vi.fn(),
10+
get: vi.fn(),
11+
set: vi.fn(),
12+
del: vi.fn(),
13+
quit: vi.fn()
14+
}));
15+
return { default: MockRedis };
16+
});
17+
18+
// Mock elizaLogger
19+
vi.mock('@elizaos/core', async () => {
20+
const actual = await vi.importActual('@elizaos/core');
21+
return {
22+
...actual as any,
23+
elizaLogger: {
24+
success: vi.fn(),
25+
error: vi.fn()
26+
}
27+
};
28+
});
29+
30+
describe('RedisClient', () => {
31+
let client: RedisClient;
32+
let mockRedis: any;
33+
34+
beforeEach(() => {
35+
vi.clearAllMocks();
36+
client = new RedisClient('redis://localhost:6379');
37+
// Get the instance created by the constructor
38+
mockRedis = (Redis as unknown as ReturnType<typeof vi.fn>).mock.results[0].value;
39+
});
40+
41+
afterEach(() => {
42+
vi.clearAllMocks();
43+
});
44+
45+
describe('constructor', () => {
46+
it('should set up event handlers', () => {
47+
expect(mockRedis.on).toHaveBeenCalledWith('connect', expect.any(Function));
48+
expect(mockRedis.on).toHaveBeenCalledWith('error', expect.any(Function));
49+
});
50+
51+
it('should log success on connect', () => {
52+
const connectHandler = mockRedis.on.mock.calls.find(call => call[0] === 'connect')[1];
53+
connectHandler();
54+
expect(elizaLogger.success).toHaveBeenCalledWith('Connected to Redis');
55+
});
56+
57+
it('should log error on error event', () => {
58+
const error = new Error('Redis connection error');
59+
const errorHandler = mockRedis.on.mock.calls.find(call => call[0] === 'error')[1];
60+
errorHandler(error);
61+
expect(elizaLogger.error).toHaveBeenCalledWith('Redis error:', error);
62+
});
63+
});
64+
65+
describe('getCache', () => {
66+
const agentId = 'test-agent' as UUID;
67+
const key = 'test-key';
68+
const expectedRedisKey = `${agentId}:${key}`;
69+
70+
it('should return cached value when it exists', async () => {
71+
const cachedValue = 'cached-data';
72+
mockRedis.get.mockResolvedValueOnce(cachedValue);
73+
74+
const result = await client.getCache({ agentId, key });
75+
76+
expect(mockRedis.get).toHaveBeenCalledWith(expectedRedisKey);
77+
expect(result).toBe(cachedValue);
78+
});
79+
80+
it('should return undefined when key does not exist', async () => {
81+
mockRedis.get.mockResolvedValueOnce(null);
82+
83+
const result = await client.getCache({ agentId, key });
84+
85+
expect(mockRedis.get).toHaveBeenCalledWith(expectedRedisKey);
86+
expect(result).toBeUndefined();
87+
});
88+
89+
it('should handle errors and return undefined', async () => {
90+
const error = new Error('Redis error');
91+
mockRedis.get.mockRejectedValueOnce(error);
92+
93+
const result = await client.getCache({ agentId, key });
94+
95+
expect(mockRedis.get).toHaveBeenCalledWith(expectedRedisKey);
96+
expect(elizaLogger.error).toHaveBeenCalledWith('Error getting cache:', error);
97+
expect(result).toBeUndefined();
98+
});
99+
});
100+
101+
describe('setCache', () => {
102+
const agentId = 'test-agent' as UUID;
103+
const key = 'test-key';
104+
const value = 'test-value';
105+
const expectedRedisKey = `${agentId}:${key}`;
106+
107+
it('should successfully set cache value', async () => {
108+
mockRedis.set.mockResolvedValueOnce('OK');
109+
110+
const result = await client.setCache({ agentId, key, value });
111+
112+
expect(mockRedis.set).toHaveBeenCalledWith(expectedRedisKey, value);
113+
expect(result).toBe(true);
114+
});
115+
116+
it('should handle errors and return false', async () => {
117+
const error = new Error('Redis error');
118+
mockRedis.set.mockRejectedValueOnce(error);
119+
120+
const result = await client.setCache({ agentId, key, value });
121+
122+
expect(mockRedis.set).toHaveBeenCalledWith(expectedRedisKey, value);
123+
expect(elizaLogger.error).toHaveBeenCalledWith('Error setting cache:', error);
124+
expect(result).toBe(false);
125+
});
126+
});
127+
128+
describe('deleteCache', () => {
129+
const agentId = 'test-agent' as UUID;
130+
const key = 'test-key';
131+
const expectedRedisKey = `${agentId}:${key}`;
132+
133+
it('should successfully delete cache when key exists', async () => {
134+
mockRedis.del.mockResolvedValueOnce(1);
135+
136+
const result = await client.deleteCache({ agentId, key });
137+
138+
expect(mockRedis.del).toHaveBeenCalledWith(expectedRedisKey);
139+
expect(result).toBe(true);
140+
});
141+
142+
it('should return false when key does not exist', async () => {
143+
mockRedis.del.mockResolvedValueOnce(0);
144+
145+
const result = await client.deleteCache({ agentId, key });
146+
147+
expect(mockRedis.del).toHaveBeenCalledWith(expectedRedisKey);
148+
expect(result).toBe(false);
149+
});
150+
151+
it('should handle errors and return false', async () => {
152+
const error = new Error('Redis error');
153+
mockRedis.del.mockRejectedValueOnce(error);
154+
155+
const result = await client.deleteCache({ agentId, key });
156+
157+
expect(mockRedis.del).toHaveBeenCalledWith(expectedRedisKey);
158+
expect(elizaLogger.error).toHaveBeenCalledWith('Error deleting cache:', error);
159+
expect(result).toBe(false);
160+
});
161+
});
162+
163+
describe('disconnect', () => {
164+
it('should successfully disconnect from Redis', async () => {
165+
mockRedis.quit.mockResolvedValueOnce('OK');
166+
167+
await client.disconnect();
168+
169+
expect(mockRedis.quit).toHaveBeenCalled();
170+
expect(elizaLogger.success).toHaveBeenCalledWith('Disconnected from Redis');
171+
});
172+
173+
it('should handle disconnect errors', async () => {
174+
const error = new Error('Redis disconnect error');
175+
mockRedis.quit.mockRejectedValueOnce(error);
176+
177+
await client.disconnect();
178+
179+
expect(mockRedis.quit).toHaveBeenCalled();
180+
expect(elizaLogger.error).toHaveBeenCalledWith('Error disconnecting from Redis:', error);
181+
});
182+
});
183+
});

packages/adapter-redis/package.json

+5-2
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,15 @@
2424
},
2525
"devDependencies": {
2626
"@types/ioredis": "^5.0.0",
27-
"tsup": "8.3.5"
27+
"tsup": "8.3.5",
28+
"vitest": "^3.0.2"
2829
},
2930
"scripts": {
3031
"build": "tsup --format esm --dts",
3132
"dev": "tsup --format esm --dts --watch",
32-
"lint": "eslint --fix --cache ."
33+
"lint": "eslint --fix --cache .",
34+
"test": "vitest run",
35+
"test:watch": "vitest"
3336
},
3437
"peerDependencies": {
3538
"whatwg-url": "7.1.0"
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { defineConfig } from 'vitest/config';
2+
3+
export default defineConfig({
4+
test: {
5+
globals: true,
6+
environment: 'node',
7+
},
8+
});

0 commit comments

Comments
 (0)