Skip to content

Commit f8eee76

Browse files
committed
chore: Add cache manager functions and tests
1 parent 62a3cc3 commit f8eee76

File tree

1 file changed

+136
-0
lines changed

1 file changed

+136
-0
lines changed

tests/index.test.ts

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
import 'reflect-metadata'; // eslint-disable-line import/no-unassigned-import
2+
import {
3+
expect, describe, it, afterEach,
4+
mock,
5+
} from 'bun:test';
6+
import cacheManager, {type Cache} from 'cache-manager';
7+
import {redisStore} from 'cache-manager-redis-store';
8+
import {
9+
cache, cacheMeta, cacheFunction, initializeCache, ensureCacheInitialized,
10+
} from '../src/index';
11+
12+
mock(cacheManager.caching, function_ => ({
13+
async caching(config) {
14+
return mockCacheManagerInstance;
15+
},
16+
}));
17+
mock(redisStore, () => jest.fn());
18+
19+
const mockCacheManagerInstance: Partial<Cache> = {
20+
get: mock(async () => null),
21+
set: mock(async () => undefined),
22+
};
23+
24+
describe('Cache Manager Functions', () => {
25+
afterEach(() => {
26+
mockCacheManagerInstance.get.mockClear();
27+
mockCacheManagerInstance.set.mockClear();
28+
});
29+
30+
describe('initializeCache', () => {
31+
it('should initialize cache with given config', async () => {
32+
await initializeCache({host: 'localhost', port: 6379, ttl: 100});
33+
34+
expect(cacheManager.caching).toHaveBeenCalledWith({
35+
store: redisStore,
36+
host: 'localhost',
37+
port: 6379,
38+
password: undefined,
39+
ttl: 100,
40+
});
41+
});
42+
});
43+
44+
describe('ensureCacheInitialized', () => {
45+
it('should initialize cache if not already initialized', async () => {
46+
await ensureCacheInitialized({ttl: 200});
47+
48+
expect(cacheManager.caching).toHaveBeenCalled();
49+
});
50+
51+
it('should not initialize cache if already initialized', async () => {
52+
await initializeCache({ttl: 200});
53+
await ensureCacheInitialized({ttl: 200});
54+
55+
expect(cacheManager.caching).toHaveBeenCalledTimes(1);
56+
});
57+
});
58+
59+
describe('cacheMeta', () => {
60+
it('should define cache metadata correctly', async () => {
61+
const target = {};
62+
const propertyKey = 'testFunction';
63+
64+
await cacheMeta({ttl: 300, keySelector: 'key.path'})(target, propertyKey);
65+
66+
expect(Reflect.getMetadata('cacheKeySelector', target, propertyKey)).toEqual('key.path');
67+
expect(Reflect.getMetadata('cacheTtl', target, propertyKey)).toEqual(300);
68+
});
69+
});
70+
71+
describe('cache', () => {
72+
it('should cache the result of the decorated function', async () => {
73+
const target = {};
74+
const propertyKey = 'cachedMethod';
75+
const originalMethod = mock(async () => 'result');
76+
const descriptor = {
77+
value: originalMethod,
78+
};
79+
80+
cache({ttl: 400, keySelector: 'id'})(target, propertyKey, descriptor);
81+
82+
mockCacheManagerInstance.get.mockResolvedValueOnce(null);
83+
84+
const result = await descriptor.value.apply({}, [{id: 1}]);
85+
86+
expect(originalMethod).toHaveBeenCalledWith({id: 1});
87+
expect(mockCacheManagerInstance.set).toHaveBeenCalledWith(expect.any(String), 'result', 400);
88+
expect(result).toEqual('result');
89+
});
90+
91+
it('should return cached result if available', async () => {
92+
const target = {};
93+
const propertyKey = 'cachedMethod';
94+
const originalMethod = mock(async () => 'should not be called');
95+
const descriptor = {
96+
value: originalMethod,
97+
};
98+
99+
cache({ttl: 400, keySelector: 'id'})(target, propertyKey, descriptor);
100+
101+
mockCacheManagerInstance.get.mockResolvedValueOnce('cachedResult');
102+
103+
const result = await descriptor.value.apply({}, [{id: 1}]);
104+
105+
expect(originalMethod).not.toHaveBeenCalled();
106+
expect(result).toEqual('cachedResult');
107+
});
108+
});
109+
110+
describe('cacheFunction', () => {
111+
it('should cache the result of the function', async () => {
112+
const function_ = mock(async () => 'computedValue');
113+
const wrappedFunction = cacheFunction(function_, {ttl: 500, keySelector: 'name'});
114+
115+
mockCacheManagerInstance.get.mockResolvedValueOnce(null);
116+
117+
const result = await wrappedFunction({name: 'test'});
118+
119+
expect(function_).toHaveBeenCalledWith({name: 'test'});
120+
expect(mockCacheManagerInstance.set).toHaveBeenCalledWith(expect.any(String), 'computedValue', 500);
121+
expect(result).toEqual('computedValue');
122+
});
123+
124+
it('should return cached result if available', async () => {
125+
const function_ = mock(async () => 'should not be called');
126+
const wrappedFunction = cacheFunction(function_, {ttl: 500, keySelector: 'name'});
127+
128+
mockCacheManagerInstance.get.mockResolvedValueOnce('cachedValue');
129+
130+
const result = await wrappedFunction({name: 'test'});
131+
132+
expect(function_).not.toHaveBeenCalled();
133+
expect(result).toEqual('cachedValue');
134+
});
135+
});
136+
});

0 commit comments

Comments
 (0)