@benshi.ai/js-sdk
Version:
Benshi SDK
213 lines (147 loc) • 7.95 kB
text/typescript
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 })
})
})