mirror of https://github.com/ghostfolio/ghostfolio
committed by
GitHub
3 changed files with 177 additions and 20 deletions
@ -0,0 +1,93 @@ |
|||
import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service'; |
|||
import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service'; |
|||
import { parseDate } from '@ghostfolio/common/helper'; |
|||
|
|||
import { DataSource } from '@prisma/client'; |
|||
import { eachDayOfInterval } from 'date-fns'; |
|||
import ms from 'ms'; |
|||
|
|||
import { ExchangeRateDataService } from './exchange-rate-data.service'; |
|||
|
|||
describe('ExchangeRateDataService', () => { |
|||
let exchangeRateDataService: ExchangeRateDataService; |
|||
let getRange: jest.Mock; |
|||
|
|||
beforeEach(() => { |
|||
getRange = jest.fn().mockResolvedValue([ |
|||
{ date: parseDate('2026-01-02'), marketPrice: 0.9 }, |
|||
{ date: parseDate('2026-01-05'), marketPrice: 0.8 } |
|||
]); |
|||
|
|||
exchangeRateDataService = new ExchangeRateDataService( |
|||
{ |
|||
getDataSourceForExchangeRates: () => { |
|||
return DataSource.YAHOO; |
|||
} |
|||
} as unknown as DataProviderService, |
|||
{ getRange } as unknown as MarketDataService, |
|||
null, |
|||
null |
|||
); |
|||
}); |
|||
|
|||
afterEach(() => { |
|||
jest.restoreAllMocks(); |
|||
}); |
|||
|
|||
describe('toCurrencyAtDate', () => { |
|||
it('loads the market data of a currency pair once for all dates', async () => { |
|||
const dates = eachDayOfInterval({ |
|||
end: parseDate('2026-01-05'), |
|||
start: parseDate('2026-01-02') |
|||
}); |
|||
|
|||
await Promise.all( |
|||
dates.map((date) => { |
|||
return exchangeRateDataService.toCurrencyAtDate( |
|||
100, |
|||
'USD', |
|||
'EUR', |
|||
date |
|||
); |
|||
}) |
|||
); |
|||
|
|||
expect(getRange).toHaveBeenCalledTimes(1); |
|||
}); |
|||
|
|||
it('converts with the market price of the date', async () => { |
|||
await expect( |
|||
exchangeRateDataService.toCurrencyAtDate( |
|||
100, |
|||
'USD', |
|||
'EUR', |
|||
parseDate('2026-01-05') |
|||
) |
|||
).resolves.toBeCloseTo(80); |
|||
}); |
|||
|
|||
it('returns undefined for a date without market data', async () => { |
|||
await expect( |
|||
exchangeRateDataService.toCurrencyAtDate( |
|||
100, |
|||
'USD', |
|||
'EUR', |
|||
parseDate('2026-01-03') |
|||
) |
|||
).resolves.toBeUndefined(); |
|||
}); |
|||
|
|||
it('reloads the market data after a minute', async () => { |
|||
const now = Date.now(); |
|||
const date = parseDate('2026-01-02'); |
|||
|
|||
await exchangeRateDataService.toCurrencyAtDate(100, 'USD', 'EUR', date); |
|||
|
|||
jest.spyOn(Date, 'now').mockReturnValue(now + ms('2 minutes')); |
|||
|
|||
await exchangeRateDataService.toCurrencyAtDate(100, 'USD', 'EUR', date); |
|||
|
|||
expect(getRange).toHaveBeenCalledTimes(2); |
|||
}); |
|||
}); |
|||
}); |
|||
Loading…
Reference in new issue