Browse Source

Add business logic and tests for stock splits

pull/7568/head
Thomas Kaul 2 weeks ago
parent
commit
7e7d7df82b
  1. 12
      apps/api/src/app/activities/activities.service.ts
  2. 17
      apps/api/src/app/endpoints/asset-profiles/asset-profiles.service.spec.ts
  3. 24
      apps/api/src/app/endpoints/asset-profiles/asset-profiles.service.ts

12
apps/api/src/app/activities/activities.service.ts

@ -984,17 +984,13 @@ export class ActivitiesService {
* Returns the id of every user who has an activity for the given asset
* profile, including draft activities and activities of excluded accounts
*/
public async getUserIdsByAssetProfile({
dataSource,
symbol
}: AssetProfileIdentifier): Promise<string[]> {
public async getUserIdsBySymbolProfileId(
symbolProfileId: string
): Promise<string[]> {
const activitiesByUser = await this.prismaService.order.groupBy({
by: ['userId'],
where: {
SymbolProfile: {
dataSource,
symbol
}
symbolProfileId
}
});

17
apps/api/src/app/endpoints/asset-profiles/asset-profiles.service.spec.ts

@ -15,7 +15,7 @@ describe('AssetProfilesService', () => {
let emit: jest.Mock;
let finished: jest.Mock;
let gatherSymbol: jest.Mock;
let getUserIdsByAssetProfile: jest.Mock;
let getUserIdsBySymbolProfileId: jest.Mock;
let upsert: jest.Mock;
beforeEach(() => {
@ -23,11 +23,11 @@ describe('AssetProfilesService', () => {
emit = jest.fn();
finished = jest.fn().mockResolvedValue(undefined);
gatherSymbol = jest.fn().mockResolvedValue([{ finished }]);
getUserIdsByAssetProfile = jest.fn().mockResolvedValue([]);
getUserIdsBySymbolProfileId = jest.fn().mockResolvedValue([]);
upsert = jest.fn();
assetProfilesService = new AssetProfilesService(
{ getUserIdsByAssetProfile } as unknown as ActivitiesService,
{ getUserIdsBySymbolProfileId } as unknown as ActivitiesService,
{
deleteById,
upsert
@ -73,7 +73,7 @@ describe('AssetProfilesService', () => {
it('invalidates portfolio snapshots for users holding the asset', async () => {
upsert.mockResolvedValue({} as AssetProfileSplit);
getUserIdsByAssetProfile.mockResolvedValue(['user-1', 'user-2']);
getUserIdsBySymbolProfileId.mockResolvedValue(['user-1', 'user-2']);
await assetProfilesService.createSplit({
dataSource: DataSource.YAHOO,
@ -85,10 +85,7 @@ describe('AssetProfilesService', () => {
});
await flushPendingPromises();
expect(getUserIdsByAssetProfile).toHaveBeenCalledWith({
dataSource: DataSource.YAHOO,
symbol: 'AAPL'
});
expect(getUserIdsBySymbolProfileId).toHaveBeenCalledWith('profile-id');
expect(emit.mock.calls.map(([, event]) => event.getUserId())).toEqual([
'user-1',
'user-2'
@ -105,7 +102,7 @@ describe('AssetProfilesService', () => {
})
);
upsert.mockResolvedValue({} as AssetProfileSplit);
getUserIdsByAssetProfile.mockResolvedValue(['user-1']);
getUserIdsBySymbolProfileId.mockResolvedValue(['user-1']);
await assetProfilesService.createSplit({
dataSource: DataSource.YAHOO,
@ -148,7 +145,7 @@ describe('AssetProfilesService', () => {
it('deletes an existing split using its profile scope', async () => {
deleteById.mockResolvedValue(true);
getUserIdsByAssetProfile.mockResolvedValue(['user-1']);
getUserIdsBySymbolProfileId.mockResolvedValue(['user-1']);
await expect(
assetProfilesService.deleteSplit({

24
apps/api/src/app/endpoints/asset-profiles/asset-profiles.service.ts

@ -67,7 +67,8 @@ export class AssetProfilesService {
await this.gatherSymbolAndEmitPortfolioChangedEvents({
dataSource,
symbol
symbol,
symbolProfileId
});
return assetProfileSplit;
@ -93,7 +94,8 @@ export class AssetProfilesService {
await this.gatherSymbolAndEmitPortfolioChangedEvents({
dataSource,
symbol
symbol,
symbolProfileId
});
}
@ -438,14 +440,9 @@ export class AssetProfilesService {
return assetProfile;
}
private async emitPortfolioChangedEvents({
dataSource,
symbol
}: AssetProfileIdentifier) {
const userIds = await this.activitiesService.getUserIdsByAssetProfile({
dataSource,
symbol
});
private async emitPortfolioChangedEvents(symbolProfileId: string) {
const userIds =
await this.activitiesService.getUserIdsBySymbolProfileId(symbolProfileId);
for (const userId of userIds) {
this.eventEmitter.emit(
@ -463,8 +460,9 @@ export class AssetProfilesService {
*/
private async gatherSymbolAndEmitPortfolioChangedEvents({
dataSource,
symbol
}: AssetProfileIdentifier) {
symbol,
symbolProfileId
}: { symbolProfileId: string } & AssetProfileIdentifier) {
const jobs = await this.dataGatheringService.gatherSymbol({
dataSource,
symbol
@ -475,7 +473,7 @@ export class AssetProfilesService {
return job.finished();
})
).then(() => {
return this.emitPortfolioChangedEvents({ dataSource, symbol });
return this.emitPortfolioChangedEvents(symbolProfileId);
});
}

Loading…
Cancel
Save