You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

210 lines
5.8 KiB

import { ImportService } from './import.service';
describe('ImportService', () => {
let importService: ImportService;
let exchangeRateDataServiceMock: { toCurrencyAtDate: jest.Mock };
let dataProviderServiceMock: {
getDataSourceForImport: jest.Mock;
getDataSources: jest.Mock;
getAssetProfiles: jest.Mock;
};
let orderServiceMock: { getOrders: jest.Mock };
let accountServiceMock: { getAccounts: jest.Mock };
let tagServiceMock: { getTagsForUser: jest.Mock };
let configurationServiceMock: { get: jest.Mock };
beforeEach(() => {
exchangeRateDataServiceMock = {
toCurrencyAtDate: jest.fn()
};
dataProviderServiceMock = {
getDataSourceForImport: jest.fn().mockReturnValue('YAHOO'),
getDataSources: jest.fn().mockResolvedValue(['MANUAL', 'YAHOO']),
getAssetProfiles: jest.fn()
};
orderServiceMock = {
getOrders: jest.fn().mockResolvedValue({ activities: [], count: 0 })
};
accountServiceMock = {
getAccounts: jest.fn().mockResolvedValue([])
};
tagServiceMock = {
getTagsForUser: jest.fn().mockResolvedValue([])
};
configurationServiceMock = {
get: jest.fn().mockImplementation((key: string) => {
if (key === 'ENABLE_FEATURE_SUBSCRIPTION') {
return false;
}
if (key === 'MAX_ACTIVITIES_TO_IMPORT') {
return Number.MAX_SAFE_INTEGER;
}
return undefined;
})
};
importService = new ImportService(
accountServiceMock as any,
null,
configurationServiceMock as any,
null,
dataProviderServiceMock as any,
exchangeRateDataServiceMock as any,
null,
orderServiceMock as any,
null,
null,
null,
tagServiceMock as any
);
});
describe('import', () => {
it('should include valueInBaseCurrency for a dry-run FEE activity', async () => {
const expectedValueInBaseCurrency = 15;
exchangeRateDataServiceMock.toCurrencyAtDate.mockResolvedValue(
expectedValueInBaseCurrency
);
const activities = await importService.import({
isDryRun: true,
maxActivitiesToImport: Number.MAX_SAFE_INTEGER,
accountsWithBalancesDto: [],
activitiesDto: [
{
currency: 'USD',
dataSource: 'MANUAL',
date: '2024-01-15T00:00:00.000Z',
fee: 0,
quantity: 1,
symbol: 'Account Opening Fee',
type: 'FEE',
unitPrice: 15
} as any
],
assetProfilesWithMarketDataDto: [],
tagsDto: [],
user: {
id: 'test-user-id',
settings: { settings: { baseCurrency: 'USD' } }
} as any
});
expect(activities).toHaveLength(1);
expect(activities[0].valueInBaseCurrency).toBe(
expectedValueInBaseCurrency
);
expect(activities[0].value).toBe(15);
expect(exchangeRateDataServiceMock.toCurrencyAtDate).toHaveBeenCalledWith(
15,
'USD',
'USD',
expect.any(Date)
);
});
it('should convert valueInBaseCurrency using the correct currencies', async () => {
exchangeRateDataServiceMock.toCurrencyAtDate.mockResolvedValue(1350.5);
dataProviderServiceMock.getAssetProfiles.mockResolvedValue({
MSFT: {
currency: 'USD',
dataSource: 'YAHOO',
name: 'Microsoft Corporation',
symbol: 'MSFT'
}
});
const activities = await importService.import({
isDryRun: true,
maxActivitiesToImport: Number.MAX_SAFE_INTEGER,
accountsWithBalancesDto: [],
activitiesDto: [
{
currency: 'USD',
dataSource: 'YAHOO',
date: '2024-01-15T00:00:00.000Z',
fee: 19,
quantity: 5,
symbol: 'MSFT',
type: 'BUY',
unitPrice: 298.58
} as any
],
assetProfilesWithMarketDataDto: [],
tagsDto: [],
user: {
id: 'test-user-id',
settings: { settings: { baseCurrency: 'EUR' } }
} as any
});
expect(activities).toHaveLength(1);
expect(activities[0].valueInBaseCurrency).toBe(1350.5);
expect(activities[0].value).toBeCloseTo(1492.9);
expect(exchangeRateDataServiceMock.toCurrencyAtDate).toHaveBeenCalledWith(
expect.closeTo(1492.9),
'USD',
'EUR',
expect.any(Date)
);
});
it('should fall back to asset profile currency when activity currency is not set', async () => {
exchangeRateDataServiceMock.toCurrencyAtDate.mockResolvedValue(450);
dataProviderServiceMock.getAssetProfiles.mockResolvedValue({
AAPL: {
currency: 'EUR',
dataSource: 'YAHOO',
name: 'Apple Inc.',
symbol: 'AAPL'
}
});
const activities = await importService.import({
isDryRun: true,
maxActivitiesToImport: Number.MAX_SAFE_INTEGER,
accountsWithBalancesDto: [],
activitiesDto: [
{
currency: undefined,
dataSource: 'YAHOO',
date: '2024-06-01T00:00:00.000Z',
fee: 0,
quantity: 2,
symbol: 'AAPL',
type: 'BUY',
unitPrice: 250
} as any
],
assetProfilesWithMarketDataDto: [],
tagsDto: [],
user: {
id: 'test-user-id',
settings: { settings: { baseCurrency: 'CHF' } }
} as any
});
expect(activities).toHaveLength(1);
expect(activities[0].valueInBaseCurrency).toBe(450);
// Should fall back to asset profile currency (EUR) when activity currency is undefined
expect(exchangeRateDataServiceMock.toCurrencyAtDate).toHaveBeenCalledWith(
500,
'EUR',
'CHF',
expect.any(Date)
);
});
});
});