import { COMPANIES_CACHE_KEY, COMPANIES_CACHE_TTL_MS, IStorageLike, readCachedCompanies, writeCachedCompanies } from './companiesCache'; import { ICompany } from './models/ICompany'; class MemoryStorage implements IStorageLike { public readonly data = new Map(); // eslint-disable-next-line @rushstack/no-new-null public getItem(key: string): string | null { return this.data.has(key) ? (this.data.get(key) as string) : null; } public setItem(key: string, value: string): void { this.data.set(key, value); } public removeItem(key: string): void { this.data.delete(key); } } const COMPANIES: ICompany[] = [ { Id: '9de064a4-44c8-88ef-11ec-8284930fad96', Name: 'ТОО TANSU Construction', Bin: '021040005165' }, { Id: '0a1b2c3d-0000-4000-8000-000000000002', Name: 'ТОО TANSU Строй' } ]; const NOW = 1_800_000_000_000; describe('кэш справочника компаний', () => { it('в пустом хранилище кэша нет', () => { expect(readCachedCompanies(new MemoryStorage(), NOW)).toBeUndefined(); }); it('записанное читается обратно, пока не прошло 4 часа', () => { const storage = new MemoryStorage(); writeCachedCompanies(storage, COMPANIES, NOW); expect(readCachedCompanies(storage, NOW + 1000)).toEqual(COMPANIES); expect(readCachedCompanies(storage, NOW + COMPANIES_CACHE_TTL_MS - 1)).toEqual(COMPANIES); }); it('через 4 часа кэш устаревает и удаляется', () => { const storage = new MemoryStorage(); writeCachedCompanies(storage, COMPANIES, NOW); expect(readCachedCompanies(storage, NOW + COMPANIES_CACHE_TTL_MS)).toBeUndefined(); expect(storage.data.has(COMPANIES_CACHE_KEY)).toBe(false); }); it('срок — ровно 4 часа', () => { expect(COMPANIES_CACHE_TTL_MS).toBe(14_400_000); }); it('запись из будущего (часы переведены назад) не доверяется', () => { const storage = new MemoryStorage(); writeCachedCompanies(storage, COMPANIES, NOW + 60_000); expect(readCachedCompanies(storage, NOW)).toBeUndefined(); }); it('битый JSON и неожиданная форма — как отсутствующий кэш', () => { const broken = new MemoryStorage(); broken.setItem(COMPANIES_CACHE_KEY, '{не json'); expect(readCachedCompanies(broken, NOW)).toBeUndefined(); expect(broken.data.has(COMPANIES_CACHE_KEY)).toBe(false); const wrongShape = new MemoryStorage(); wrongShape.setItem(COMPANIES_CACHE_KEY, JSON.stringify({ savedAt: NOW, items: [{ Id: 1 }] })); expect(readCachedCompanies(wrongShape, NOW)).toBeUndefined(); }); it('недоступное хранилище не ломает ни чтение, ни запись', () => { const throwing: IStorageLike = { getItem: () => { throw new Error('запрещено'); }, setItem: () => { throw new Error('переполнено'); }, removeItem: () => { throw new Error('запрещено'); } }; expect(readCachedCompanies(throwing, NOW)).toBeUndefined(); expect(() => writeCachedCompanies(throwing, COMPANIES, NOW)).not.toThrow(); }); });