diff --git a/src/subdomains/generic/user/models/account-merge/__tests__/account-merge.service.spec.ts b/src/subdomains/generic/user/models/account-merge/__tests__/account-merge.service.spec.ts index 95918133c4..91ffe0c3cf 100644 --- a/src/subdomains/generic/user/models/account-merge/__tests__/account-merge.service.spec.ts +++ b/src/subdomains/generic/user/models/account-merge/__tests__/account-merge.service.spec.ts @@ -1,4 +1,5 @@ import { ConfigService } from 'src/config/config'; +import { Util } from 'src/shared/utils/util'; import { KycLogService } from 'src/subdomains/generic/kyc/services/kyc-log.service'; import { NotificationService } from 'src/subdomains/supporting/notification/services/notification.service'; import { UserData } from '../../user-data/user-data.entity'; @@ -13,6 +14,7 @@ describe('AccountMergeService', () => { let accountMergeRepo: jest.Mocked>; let notificationService: jest.Mocked>; let kycLogService: jest.Mocked>; + let userDataService: jest.Mocked>; const buildUserData = (id: number, mail?: string): UserData => { const userData = Object.assign(new UserData(), { id, mail, firstname: `user${id}` }); @@ -25,15 +27,16 @@ describe('AccountMergeService', () => { }); beforeEach(() => { - accountMergeRepo = { findOneBy: jest.fn(), save: jest.fn() }; + accountMergeRepo = { findOneBy: jest.fn(), save: jest.fn(), findOne: jest.fn(), update: jest.fn() }; notificationService = { sendMail: jest.fn() }; kycLogService = { createMergeLog: jest.fn() }; + userDataService = { mergeUserData: jest.fn() }; service = new AccountMergeService( accountMergeRepo as unknown as AccountMergeRepository, notificationService as unknown as NotificationService, kycLogService as unknown as KycLogService, - {} as unknown as UserDataService, + userDataService as unknown as UserDataService, ); }); @@ -111,4 +114,30 @@ describe('AccountMergeService', () => { expect((mail.input as { userData: UserData }).userData).toBe(slave); }); }); + + describe('executeMerge', () => { + const buildRequest = (master: UserData, slave: UserData): AccountMerge => + Object.assign(new AccountMerge(), { + id: 20, + code: 'code-20', + master, + slave, + isCompleted: false, + expiration: Util.daysAfter(30), + }); + + it('merges with notifyUser=true so the master is notified about the confirmed merge', async () => { + // master is the account with an ident document; the slave's mailbox confirmed the merge. + // Without notifyUser=true the master (the account being merged into) would never be told. + const master = buildUserData(1, 'master@test.com'); + const slave = buildUserData(2, 'slave@test.com'); + Object.assign(master, { identDocumentId: 'DOC-1' }); + accountMergeRepo.findOne.mockResolvedValue(buildRequest(master, slave)); + + await service.executeMerge('code-20'); + + expect(userDataService.mergeUserData).toHaveBeenCalledTimes(1); + expect(userDataService.mergeUserData).toHaveBeenCalledWith(master.id, slave.id, slave.mail, true); + }); + }); }); diff --git a/src/subdomains/generic/user/models/account-merge/account-merge.service.ts b/src/subdomains/generic/user/models/account-merge/account-merge.service.ts index 564dee8db4..6ce691de55 100644 --- a/src/subdomains/generic/user/models/account-merge/account-merge.service.ts +++ b/src/subdomains/generic/user/models/account-merge/account-merge.service.ts @@ -132,7 +132,10 @@ export class AccountMergeService { await this.accountMergeRepo.update(...request.startProcessing()); try { - await this.userDataService.mergeUserData(master.id, slave.id, request.slave.mail); + // notifyUser: a merge confirmed via the e-mailed code is the one path an outside party can + // trigger (IDENT_DOCUMENT merges mail the code to the slave, not the master), so the master + // must be told its account gained an address/mail — same as the AML and admin merge callers. + await this.userDataService.mergeUserData(master.id, slave.id, request.slave.mail, true); } catch (e) { // clear the processing marker so a failed merge does not leave the client stuck on a // never-ending waiting state (isProcessing would otherwise stay true until expiration)