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