UNPKG

@benshi.ai/js-sdk

Version:

Benshi SDK

213 lines (147 loc) 7.95 kB
import { CurrencyCode } from "../../commonTypes" import CurrencyRepository from "./CurrencyRepository" import * as defaultConversions from "./usd.json" let mockNetworkProxy describe('Currency repository', () => { afterEach(() => { jest.clearAllMocks(); }); beforeEach(() => { jest.useRealTimers() }) it('Should make a network request to get the conversion when it is not cached', async () => { const usd_rate = 1 / defaultConversions.usd[CurrencyCode.IDR.toLowerCase()] const mockNetworkProxy = { get: jest.fn().mockResolvedValue({ date: '2022-06-23', usd: usd_rate }) } const currencyRepository = new CurrencyRepository('/fakeurl', mockNetworkProxy) const conversion = await currencyRepository.convertCurrencyToUSD(CurrencyCode.IDR) expect(conversion).toEqual({ usd: usd_rate }) }) it('Should not make a new network request when the cached value has less than an hour', async () => { const usd_rate = 1 / defaultConversions.usd[CurrencyCode.IDR.toLowerCase()] const mockNetworkProxy = { get: jest.fn().mockResolvedValue({ date: '2022-06-23', usd: usd_rate }) } const senderSpy = jest.spyOn(mockNetworkProxy, 'get') const currencyRepository = new CurrencyRepository('/fakeurl', mockNetworkProxy) jest .useFakeTimers() .setSystemTime(new Date('2020-01-10 10:30').getTime()); await currencyRepository.convertCurrencyToUSD(CurrencyCode.IDR) jest.setSystemTime(new Date('2020-01-10 10:33').getTime()); await currencyRepository.convertCurrencyToUSD(CurrencyCode.IDR) expect(senderSpy).toBeCalledTimes(1) }) it('Should make a new network request when the cached value has more than an hour', async () => { const usd_rate = 1 / defaultConversions.usd[CurrencyCode.IDR.toLowerCase()] const mockNetworkProxy = { get: jest.fn().mockResolvedValue({ date: '2022-06-23', usd: usd_rate }) } const senderSpy = jest.spyOn(mockNetworkProxy, 'get') const currencyRepository = new CurrencyRepository('/fakeurl', mockNetworkProxy) jest .useFakeTimers() .setSystemTime(new Date('2020-01-10 10:30').getTime()); await currencyRepository.convertCurrencyToUSD(CurrencyCode.IDR) jest.setSystemTime(new Date('2020-01-10 11:33').getTime()); await currencyRepository.convertCurrencyToUSD(CurrencyCode.IDR) expect(senderSpy).toBeCalledTimes(2) senderSpy.mockClear() }) it('Should use a default value when then network request returns a non-number value', async () => { const USD_RATE_VALUE_FROM_JSON_FILE = 1 / defaultConversions.usd[CurrencyCode.EUR.toLowerCase()] const mockNetworkProxy = { get: jest.fn().mockResolvedValue({ date: '2020-01-10', usd: null }) } const currencyRepository = new CurrencyRepository('/fakeurl', mockNetworkProxy) const conversion = await currencyRepository.convertCurrencyToUSD(CurrencyCode.EUR) expect(conversion.usd).toEqual(USD_RATE_VALUE_FROM_JSON_FILE) }) it('Should not make a network request when the source currency is USD', async () => { const mockNetworkProxy = { get: jest.fn().mockResolvedValue({ date: '2020-01-10', usd: 2 }) } const senderSpy = jest.spyOn(mockNetworkProxy, 'get') const currencyRepository = new CurrencyRepository('/fakeurl', mockNetworkProxy) await currencyRepository.convertCurrencyToUSD(CurrencyCode.USD) expect(senderSpy).toBeCalledTimes(0) }) it('Should return a hardcoded conversion when source currency is USD', async () => { const mockNetworkProxy = { get: jest.fn().mockResolvedValue({ date: '2020-01-10', usd: 2 }) } const currencyRepository = new CurrencyRepository('/fakeurl', mockNetworkProxy) const conversion = await currencyRepository.convertCurrencyToUSD(CurrencyCode.USD) expect(conversion).toEqual({ usd: 1 }) }) it('Should reuse a cached value', async () => { const mockNetworkProxy = { get: jest.fn().mockResolvedValue({ date: '2020-01-10', usd: 2 }) } const senderSpy = jest.spyOn(mockNetworkProxy, 'get') jest .useFakeTimers() .setSystemTime(new Date('2020-01-10').getTime()); const currencyRepository = new CurrencyRepository('/fakeurl', mockNetworkProxy) const conversion = await currencyRepository.convertCurrencyToUSD(CurrencyCode.EUR) const conversion2 = await currencyRepository.convertCurrencyToUSD(CurrencyCode.EUR) const conversion3 = await currencyRepository.convertCurrencyToUSD(CurrencyCode.EUR) expect(senderSpy).toBeCalledTimes(1) }) it('Should do not reuse a cached value when the day has changed', async () => { const mockNetworkProxy = { get: jest.fn().mockResolvedValue({ date: '2020-01-10', usd: 2 }) } const senderSpy = jest.spyOn(mockNetworkProxy, 'get') jest .useFakeTimers() .setSystemTime(new Date('2020-01-10').getTime()); const currencyRepository = new CurrencyRepository('/fakeurl', mockNetworkProxy) const conversion = await currencyRepository.convertCurrencyToUSD(CurrencyCode.EUR) const conversion2 = await currencyRepository.convertCurrencyToUSD(CurrencyCode.EUR) const conversion3 = await currencyRepository.convertCurrencyToUSD(CurrencyCode.EUR) jest .useFakeTimers() .setSystemTime(new Date('2020-01-11').getTime()); const conversion4 = await currencyRepository.convertCurrencyToUSD(CurrencyCode.EUR) expect(senderSpy).toBeCalledTimes(2) }) it('Should return a default value when the network request fails', async () => { const USD_RATE_VALUE_FROM_JSON_FILE = 1 / defaultConversions.usd[CurrencyCode.IDR.toLowerCase()] let mockNetworkProxy = { get: jest.fn().mockRejectedValue(new Error('Async error')) } const currencyRepository = new CurrencyRepository('/fakeurl', mockNetworkProxy) const conversion = await currencyRepository.convertCurrencyToUSD(CurrencyCode.IDR) expect(conversion.usd).toEqual(USD_RATE_VALUE_FROM_JSON_FILE) }) it('Should wait for a previous request to return the converstion - to save network requests', async () => { const mockNetworkProxy2 = { get: jest.fn().mockImplementation(() => { return new Promise(resolve => setTimeout( () => resolve({ date: '2020-01-10', usd: 2 }) , 100) ) }) } const senderSpy = jest.spyOn(mockNetworkProxy2, 'get') const currencyRepository = new CurrencyRepository('/fakeurl', mockNetworkProxy2) currencyRepository.convertCurrencyToUSD(CurrencyCode.IDR) const conversion = await currencyRepository.convertCurrencyToUSD(CurrencyCode.IDR) expect(senderSpy).toBeCalledTimes(1) expect(conversion.usd).toEqual(2) }) it('Should resolved correctly a second request for a different currency, when are triggered concurrently', async () => { const mockNetworkProxy = { get: jest.fn() .mockResolvedValueOnce({ date: '2022-06-23', usd: 4 }) .mockResolvedValueOnce({ date: '2022-06-23', usd: 5 }) } const currencyRepository = new CurrencyRepository('/fakeurl', mockNetworkProxy) currencyRepository.convertCurrencyToUSD(CurrencyCode.IDR) const conversion = await currencyRepository.convertCurrencyToUSD(CurrencyCode.EUR) expect(conversion).toEqual({ usd: 5 }) }) })