mirror of https://github.com/ghostfolio/ghostfolio
8 changed files with 389 additions and 76 deletions
@ -0,0 +1,83 @@ |
|||||
|
import { DataSource } from '@prisma/client'; |
||||
|
|
||||
|
import { BenchmarksService } from './benchmarks.service'; |
||||
|
|
||||
|
describe('BenchmarksService', () => { |
||||
|
it('forward-fills non-trading days and uses the live quote for the end date', async () => { |
||||
|
const fridayCloseDate = new Date(2021, 4, 28); |
||||
|
const saturdayDate = new Date(2021, 4, 29); |
||||
|
const sundayDate = new Date(2021, 4, 30); |
||||
|
|
||||
|
const benchmarkService = { |
||||
|
calculateChangeInPercentage: (startValue: number, endValue: number) => { |
||||
|
return endValue / startValue - 1; |
||||
|
} |
||||
|
}; |
||||
|
const exchangeRateDataService = { |
||||
|
getExchangeRatesByCurrency: jest.fn().mockResolvedValue({ |
||||
|
USDUSD: { |
||||
|
'2021-05-29': 1, |
||||
|
'2021-05-30': 1 |
||||
|
} |
||||
|
}) |
||||
|
}; |
||||
|
const marketDataService = { |
||||
|
marketDataItems: jest |
||||
|
.fn() |
||||
|
.mockResolvedValueOnce([]) |
||||
|
.mockResolvedValueOnce([ |
||||
|
{ |
||||
|
date: fridayCloseDate, |
||||
|
marketPrice: 100 |
||||
|
} |
||||
|
]) |
||||
|
}; |
||||
|
const portfolioService = { |
||||
|
getPerformance: jest.fn().mockResolvedValue({ |
||||
|
chart: [{ date: '2021-05-29' }, { date: '2021-05-30' }] |
||||
|
}) |
||||
|
}; |
||||
|
const prismaService = { |
||||
|
symbolProfile: { |
||||
|
findFirst: jest.fn().mockResolvedValue({ currency: 'USD' }) |
||||
|
} |
||||
|
}; |
||||
|
const symbolService = { |
||||
|
get: jest.fn().mockResolvedValue({ marketPrice: 110 }) |
||||
|
}; |
||||
|
const service = new BenchmarksService( |
||||
|
benchmarkService as never, |
||||
|
exchangeRateDataService as never, |
||||
|
marketDataService as never, |
||||
|
portfolioService as never, |
||||
|
prismaService as never, |
||||
|
symbolService as never |
||||
|
); |
||||
|
|
||||
|
const { marketData } = await service.getMarketDataForUser({ |
||||
|
dataSource: DataSource.YAHOO, |
||||
|
dateRange: 'max', |
||||
|
endDate: sundayDate, |
||||
|
impersonationId: undefined, |
||||
|
startDate: saturdayDate, |
||||
|
symbol: 'SPY', |
||||
|
user: { |
||||
|
id: 'user-id', |
||||
|
settings: { settings: { baseCurrency: 'USD' } } |
||||
|
} as never |
||||
|
}); |
||||
|
|
||||
|
expect(marketData).toHaveLength(2); |
||||
|
expect(marketData[0]).toEqual({ date: '2021-05-29', value: 0 }); |
||||
|
expect(marketData[1].date).toBe('2021-05-30'); |
||||
|
expect(marketData[1].value).toBeCloseTo(10); |
||||
|
expect( |
||||
|
exchangeRateDataService.getExchangeRatesByCurrency |
||||
|
).toHaveBeenCalledWith({ |
||||
|
currencies: ['USD'], |
||||
|
endDate: new Date(Date.UTC(2021, 4, 30)), |
||||
|
startDate: new Date(Date.UTC(2021, 4, 29)), |
||||
|
targetCurrency: 'USD' |
||||
|
}); |
||||
|
}); |
||||
|
}); |
||||
@ -0,0 +1,19 @@ |
|||||
|
import { Big } from 'big.js'; |
||||
|
|
||||
|
import { getLatestMarketPriceOnOrBefore } from './portfolio.helper'; |
||||
|
|
||||
|
describe('getLatestMarketPriceOnOrBefore', () => { |
||||
|
it('returns the latest available price without using future values', () => { |
||||
|
expect( |
||||
|
getLatestMarketPriceOnOrBefore({ |
||||
|
dateString: '2026-05-31', |
||||
|
marketSymbolMap: { |
||||
|
'2026-06-01': { SPY: new Big(103) }, |
||||
|
'2026-05-29': { SPY: new Big(101) }, |
||||
|
'2026-05-28': { SPY: new Big(100) } |
||||
|
}, |
||||
|
symbol: 'SPY' |
||||
|
}) |
||||
|
).toEqual(new Big(101)); |
||||
|
}); |
||||
|
}); |
||||
Loading…
Reference in new issue