Co-authored-by: Thomas Kaul <4159106+dtslvr@users.noreply.github.com>pull/270/head
parent
e255b76053
commit
a91f6c783e
@ -0,0 +1,201 @@
|
|||||||
|
import { DateQuery } from '@ghostfolio/api/app/portfolio/interfaces/date-query.interface';
|
||||||
|
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data.service';
|
||||||
|
import { MarketDataService } from '@ghostfolio/api/services/market-data.service';
|
||||||
|
import { MarketData } from '@prisma/client';
|
||||||
|
import { Big } from 'big.js';
|
||||||
|
import { addDays, endOfDay, isBefore } from 'date-fns';
|
||||||
|
|
||||||
|
jest.mock('@ghostfolio/api/services/market-data.service', () => {
|
||||||
|
return {
|
||||||
|
MarketDataService: jest.fn().mockImplementation(() => {
|
||||||
|
return {
|
||||||
|
getRange: ({
|
||||||
|
dateQuery,
|
||||||
|
symbols
|
||||||
|
}: {
|
||||||
|
dateQuery: DateQuery;
|
||||||
|
symbols: string[];
|
||||||
|
}) => {
|
||||||
|
const exchangeRateMap = {
|
||||||
|
USDEUR: 1,
|
||||||
|
USDCHF: 2,
|
||||||
|
USDUSD: 0
|
||||||
|
};
|
||||||
|
const result = [];
|
||||||
|
let j = 1;
|
||||||
|
for (
|
||||||
|
let i = dateQuery.gte;
|
||||||
|
isBefore(i, dateQuery.lt);
|
||||||
|
i = addDays(i, 1)
|
||||||
|
) {
|
||||||
|
const marketPrice = j++;
|
||||||
|
for (const symbol of symbols) {
|
||||||
|
result.push({
|
||||||
|
createdAt: i,
|
||||||
|
date: i,
|
||||||
|
id: '8fa48fde-f397-4b0d-adbc-fb940e830e6d',
|
||||||
|
marketPrice: marketPrice * exchangeRateMap[symbol] + 1,
|
||||||
|
symbol: symbol
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Promise.resolve<MarketData[]>(result);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('ExchangeRateDataService', () => {
|
||||||
|
let exchangeRateDataService: ExchangeRateDataService;
|
||||||
|
let marketDataService: MarketDataService;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
marketDataService = new MarketDataService(null);
|
||||||
|
exchangeRateDataService = new ExchangeRateDataService(
|
||||||
|
null,
|
||||||
|
marketDataService,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getExchangeRates', () => {
|
||||||
|
it('source and destination USD', async () => {
|
||||||
|
const startDate = new Date(2021, 0, 1);
|
||||||
|
const exchangeRates = await exchangeRateDataService.getExchangeRates({
|
||||||
|
dateQuery: {
|
||||||
|
gte: startDate,
|
||||||
|
lt: endOfDay(startDate)
|
||||||
|
},
|
||||||
|
sourceCurrencies: ['USD'],
|
||||||
|
destinationCurrency: 'USD'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(exchangeRates).toEqual([
|
||||||
|
{
|
||||||
|
date: startDate,
|
||||||
|
exchangeRates: {
|
||||||
|
USD: new Big(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('source USD and destination CHF', async () => {
|
||||||
|
const startDate = new Date(2021, 0, 1);
|
||||||
|
const exchangeRates = await exchangeRateDataService.getExchangeRates({
|
||||||
|
dateQuery: {
|
||||||
|
gte: startDate,
|
||||||
|
lt: endOfDay(startDate)
|
||||||
|
},
|
||||||
|
sourceCurrencies: ['USD'],
|
||||||
|
destinationCurrency: 'CHF'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(exchangeRates).toEqual([
|
||||||
|
{
|
||||||
|
date: startDate,
|
||||||
|
exchangeRates: {
|
||||||
|
USD: new Big(3)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('source CHF and destination USD', async () => {
|
||||||
|
const startDate = new Date(2021, 0, 1);
|
||||||
|
const exchangeRates = await exchangeRateDataService.getExchangeRates({
|
||||||
|
dateQuery: {
|
||||||
|
gte: startDate,
|
||||||
|
lt: endOfDay(startDate)
|
||||||
|
},
|
||||||
|
sourceCurrencies: ['CHF'],
|
||||||
|
destinationCurrency: 'USD'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(exchangeRates).toEqual([
|
||||||
|
{
|
||||||
|
date: startDate,
|
||||||
|
exchangeRates: {
|
||||||
|
CHF: new Big(1).div(3)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('source CHF and destination EUR', async () => {
|
||||||
|
const startDate = new Date(2021, 0, 1);
|
||||||
|
const exchangeRates = await exchangeRateDataService.getExchangeRates({
|
||||||
|
dateQuery: {
|
||||||
|
gte: startDate,
|
||||||
|
lt: endOfDay(startDate)
|
||||||
|
},
|
||||||
|
sourceCurrencies: ['CHF'],
|
||||||
|
destinationCurrency: 'EUR'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(exchangeRates).toEqual([
|
||||||
|
{
|
||||||
|
date: startDate,
|
||||||
|
exchangeRates: {
|
||||||
|
CHF: new Big(2).div(3)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('source CHF,EUR,USD and destination EUR', async () => {
|
||||||
|
const startDate = new Date(2021, 0, 1);
|
||||||
|
const exchangeRates = await exchangeRateDataService.getExchangeRates({
|
||||||
|
dateQuery: {
|
||||||
|
gte: startDate,
|
||||||
|
lt: endOfDay(startDate)
|
||||||
|
},
|
||||||
|
sourceCurrencies: ['CHF', 'USD', 'EUR'],
|
||||||
|
destinationCurrency: 'EUR'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(exchangeRates).toEqual([
|
||||||
|
{
|
||||||
|
date: startDate,
|
||||||
|
exchangeRates: {
|
||||||
|
CHF: new Big(2).div(3),
|
||||||
|
USD: new Big(2),
|
||||||
|
EUR: new Big(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with multiple days', async () => {
|
||||||
|
const startDate = new Date(2021, 0, 1);
|
||||||
|
const exchangeRates = await exchangeRateDataService.getExchangeRates({
|
||||||
|
dateQuery: {
|
||||||
|
gte: startDate,
|
||||||
|
lt: endOfDay(addDays(startDate, 1))
|
||||||
|
},
|
||||||
|
sourceCurrencies: ['CHF', 'USD', 'EUR'],
|
||||||
|
destinationCurrency: 'EUR'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(exchangeRates).toEqual([
|
||||||
|
{
|
||||||
|
date: startDate,
|
||||||
|
exchangeRates: {
|
||||||
|
CHF: new Big(2).div(3),
|
||||||
|
USD: new Big(2),
|
||||||
|
EUR: new Big(1)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: addDays(startDate, 1),
|
||||||
|
exchangeRates: {
|
||||||
|
CHF: new Big(3).div(5),
|
||||||
|
USD: new Big(3),
|
||||||
|
EUR: new Big(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,6 @@
|
|||||||
|
import Big from 'big.js';
|
||||||
|
|
||||||
|
export interface DateBasedExchangeRate {
|
||||||
|
date: Date;
|
||||||
|
exchangeRates: { [currency: string]: Big };
|
||||||
|
}
|
Loading…
Reference in new issue