UNPKG

semantic-ds-toolkit

Version:

Performance-first semantic layer for modern data stacks - Stable Column Anchors & intelligent inference

63 lines 2.95 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const fx_cache_1 = require("../../src/operators/fx-cache"); describe('Operators: FXCache with Redis-like client', () => { const realFetch = global.fetch; beforeEach(() => { global.fetch = jest.fn(async (_url) => ({ ok: true, status: 200, json: async () => ({ rates: { EUR: 0.91, USD: 1 } }) })); }); afterEach(() => { global.fetch = realFetch; }); it('writes entries to Redis (setEx) with TTL and reads back after clearCache', async () => { const store = new Map(); const redisStub = { get: jest.fn(async (key) => store.get(key) ?? null), setEx: jest.fn(async (key, _ttl, value) => { store.set(key, value); return 'OK'; }), expire: jest.fn(async () => 'OK') }; const fx = new fx_cache_1.FXCache(1000, { enableRedis: true, redisClient: redisStub, dataSources: ['ecb'] }); // First fetch should go to network and write to Redis const first = await fx.getExchangeRate('USD', 'EUR', { mode: fx_cache_1.OfflineMode.NETWORK_FIRST }); expect(['ecb', 'fed', 'fallback']).toContain(first.source); expect(redisStub.setEx).toHaveBeenCalled(); // ttlSeconds should be floor(ttlMs/1000) = 1 for (const call of redisStub.setEx.mock.calls) { expect(call[1]).toBe(1); } // Clear in-memory cache and ensure we can read from Redis fx.clearCache(); const second = await fx.getExchangeRate('USD', 'EUR', { mode: fx_cache_1.OfflineMode.CACHE_FIRST }); expect(second.source).toBe('cache'); expect(second.stale).toBe(false); expect(redisStub.get).toHaveBeenCalled(); }); it('uses set+expire path when setEx is unavailable', async () => { const store = new Map(); const redisStub = { get: jest.fn(async (key) => store.get(key) ?? null), set: jest.fn(async (key, value) => { store.set(key, value); return 'OK'; }), expire: jest.fn(async (_key, _ttl) => 'OK') }; const fx = new fx_cache_1.FXCache(2500, { enableRedis: true, redisClient: redisStub, dataSources: ['ecb'] }); const first = await fx.getExchangeRate('USD', 'EUR'); expect(['ecb', 'fed', 'fallback']).toContain(first.source); expect(redisStub.set).toHaveBeenCalledTimes(2); expect(redisStub.expire).toHaveBeenCalledTimes(2); // ttlSeconds should be floor(2500/1000) = 2 for (const call of redisStub.expire.mock.calls) { expect(call[1]).toBe(2); } fx.clearCache(); const second = await fx.getExchangeRate('USD', 'EUR', { mode: fx_cache_1.OfflineMode.CACHE_FIRST }); expect(second.source).toBe('cache'); }); }); //# sourceMappingURL=fx-cache-redis.test.js.map