Skip to content

Commit 265e819

Browse files
fix: validation service isBeneficiary
Signed-off-by: Axel Loupias <[email protected]>
1 parent 1d59131 commit 265e819

File tree

12 files changed

+516
-20
lines changed

12 files changed

+516
-20
lines changed

packages/ats/sdk/src/app/service/validation/ValidationService.ts

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,8 @@ import { IsExternallyGrantedQuery } from '@query/security/externalKycLists/isExt
269269
import { GetTokenBySaltQuery } from '@query/factory/trex/getTokenBySalt/GetTokenBySaltQuery';
270270
import { InvalidTrexTokenSalt } from '@domain/context/factory/error/InvalidTrexTokenSalt';
271271
import { IsBeneficiaryQuery } from '@query/security/beneficiary/isBeneficiary/IsBeneficiaryQuery';
272+
import { AccountIsNotBeneficiary } from '@domain/context/security/error/operations/AccountIsNotBeneficiary';
273+
import { AccountIsBeneficiary } from '@domain/context/security/error/operations/AccountIsBeneficiary';
272274

273275
@singleton()
274276
export default class ValidationService extends Service {
@@ -766,15 +768,36 @@ export default class ValidationService extends Service {
766768
return kycResult.payload === kycStatus;
767769
}
768770

769-
async isBeneficiary(
771+
async checkIsBeneficiary(
770772
securityId: string,
771773
beneficiary: string,
772774
): Promise<boolean> {
773775
this.queryBus = Injectable.resolve<QueryBus>(QueryBus);
774-
return (
776+
const res = (
777+
await this.queryBus.execute(
778+
new IsBeneficiaryQuery(securityId, beneficiary),
779+
)
780+
).payload;
781+
if (!res) {
782+
throw new AccountIsNotBeneficiary(securityId, beneficiary);
783+
}
784+
785+
return res;
786+
}
787+
async checkIsNotBeneficiary(
788+
securityId: string,
789+
beneficiary: string,
790+
): Promise<boolean> {
791+
this.queryBus = Injectable.resolve<QueryBus>(QueryBus);
792+
const res = (
775793
await this.queryBus.execute(
776794
new IsBeneficiaryQuery(securityId, beneficiary),
777795
)
778796
).payload;
797+
if (res) {
798+
throw new AccountIsBeneficiary(securityId, beneficiary);
799+
}
800+
801+
return !res;
779802
}
780803
}

packages/ats/sdk/src/app/service/validation/ValidationService.unit.test.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,9 @@ import { OperationNotAllowed } from '@domain/context/security/error/operations/O
273273
import { KycStatus } from '@domain/context/kyc/Kyc';
274274
import { IsInternalKycActivatedQuery } from '@query/security/kyc/isInternalKycActivated/IsInternalKycActivatedQuery';
275275
import { IsExternallyGrantedQuery } from '@query/security/externalKycLists/isExternallyGranted/IsExternallyGrantedQuery';
276+
import { IsBeneficiaryQuery } from '@query/security/beneficiary/isBeneficiary/IsBeneficiaryQuery';
277+
import { AccountIsNotBeneficiary } from '@domain/context/security/error/operations/AccountIsNotBeneficiary';
278+
import { AccountIsBeneficiary } from '@domain/context/security/error/operations/AccountIsBeneficiary';
276279

277280
describe('ValidationService', () => {
278281
let service: ValidationService;
@@ -1313,4 +1316,48 @@ describe('ValidationService', () => {
13131316
).rejects.toThrow(OperationNotAllowed);
13141317
});
13151318
});
1319+
1320+
describe('checkIsBeneficiary', () => {
1321+
it('should resolve successfully when address is a beneficiary', async () => {
1322+
queryBusMock.execute.mockResolvedValueOnce({ payload: true });
1323+
const res = await service.checkIsBeneficiary(
1324+
securityId.value,
1325+
targetId.value,
1326+
);
1327+
1328+
expect(res).toBe(true);
1329+
expect(queryBusMock.execute).toHaveBeenCalledWith(
1330+
new IsBeneficiaryQuery(securityId.value, targetId.value),
1331+
);
1332+
});
1333+
1334+
it('should throw AccountIsNotBeneficiary when security is not issuable', async () => {
1335+
queryBusMock.execute.mockResolvedValueOnce({ payload: false });
1336+
await expect(
1337+
service.checkIsBeneficiary(securityId.value, targetId.value),
1338+
).rejects.toThrow(AccountIsNotBeneficiary);
1339+
});
1340+
});
1341+
1342+
describe('checkIsNotBeneficiary', () => {
1343+
it('should resolve successfully when address is not a beneficiary', async () => {
1344+
queryBusMock.execute.mockResolvedValueOnce({ payload: false });
1345+
const res = await service.checkIsNotBeneficiary(
1346+
securityId.value,
1347+
targetId.value,
1348+
);
1349+
1350+
expect(res).toBe(true);
1351+
expect(queryBusMock.execute).toHaveBeenCalledWith(
1352+
new IsBeneficiaryQuery(securityId.value, targetId.value),
1353+
);
1354+
});
1355+
1356+
it('should throw AccountIsBeneficiary when security is not issuable', async () => {
1357+
queryBusMock.execute.mockResolvedValueOnce({ payload: true });
1358+
await expect(
1359+
service.checkIsNotBeneficiary(securityId.value, targetId.value),
1360+
).rejects.toThrow(AccountIsBeneficiary);
1361+
});
1362+
});
13161363
});

packages/ats/sdk/src/app/usecase/command/security/beneficiaries/addBeneficiary/AddBeneficiaryCommandHandler.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -222,9 +222,10 @@ export class AddBeneficiaryCommandHandler
222222
securityId,
223223
);
224224

225-
if (await this.validationService.isBeneficiary(securityId, beneficiary)) {
226-
throw new Error('The address is already a beneficiary');
227-
}
225+
await this.validationService.checkIsNotBeneficiary(
226+
securityId,
227+
beneficiary,
228+
);
228229

229230
const res = await handler.addBeneficiary(
230231
securityEvmAddress,

packages/ats/sdk/src/app/usecase/command/security/beneficiaries/addBeneficiary/AddBeneficiaryCommandHandler.unit.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ describe('AddBeneficiaryCommandHandler', () => {
254254
accountServiceMock.getCurrentAccount.mockReturnValue(account);
255255
validationServiceMock.checkPause.mockResolvedValue(undefined);
256256
validationServiceMock.checkRole.mockResolvedValue(undefined);
257-
validationServiceMock.isBeneficiary.mockResolvedValue(false);
257+
validationServiceMock.checkIsNotBeneficiary.mockResolvedValue(true);
258258
transactionServiceMock.getHandler().addBeneficiary.mockResolvedValue({
259259
id: transactionId,
260260
});

packages/ats/sdk/src/app/usecase/command/security/beneficiaries/removeBeneficiary/RemoveBeneficiaryCommandHandler.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -222,11 +222,8 @@ export class RemoveBeneficiaryCommandHandler
222222
securityId,
223223
);
224224

225-
if (
226-
!(await this.validationService.isBeneficiary(securityId, beneficiary))
227-
) {
228-
throw new Error('The address is not a beneficiary');
229-
}
225+
await this.validationService.checkIsBeneficiary(securityId, beneficiary);
226+
230227
const res = await handler.removeBeneficiary(
231228
securityEvmAddress,
232229
beneficiaryEvmAddress,

packages/ats/sdk/src/app/usecase/command/security/beneficiaries/removeBeneficiary/RemoveBeneficiaryCommandHandler.unit.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ describe('RemoveBeneficiaryCommandHandler', () => {
254254
accountServiceMock.getCurrentAccount.mockReturnValue(account);
255255
validationServiceMock.checkPause.mockResolvedValue(undefined);
256256
validationServiceMock.checkRole.mockResolvedValue(undefined);
257-
validationServiceMock.isBeneficiary.mockResolvedValue(true);
257+
validationServiceMock.checkIsBeneficiary.mockResolvedValue(true);
258258
transactionServiceMock.getHandler().removeBeneficiary.mockResolvedValue({
259259
id: transactionId,
260260
});

packages/ats/sdk/src/app/usecase/command/security/beneficiaries/updateBeneficiaryData/UpdateBeneficiaryDataCommandHandler.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -222,11 +222,8 @@ export class UpdateBeneficiaryDataCommandHandler
222222
securityId,
223223
);
224224

225-
if (
226-
!(await this.validationService.isBeneficiary(securityId, beneficiary))
227-
) {
228-
throw new Error('The address is not a beneficiary');
229-
}
225+
await this.validationService.checkIsBeneficiary(securityId, beneficiary);
226+
230227
const res = await handler.updateBeneficiaryData(
231228
securityEvmAddress,
232229
beneficiaryEvmAddress,

packages/ats/sdk/src/app/usecase/command/security/beneficiaries/updateBeneficiaryData/UpdateBeneficiaryDataCommandHandler.unit.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ describe('UpdateBeneficiaryDataCommandHandler', () => {
254254
accountServiceMock.getCurrentAccount.mockReturnValue(account);
255255
validationServiceMock.checkPause.mockResolvedValue(undefined);
256256
validationServiceMock.checkRole.mockResolvedValue(undefined);
257-
validationServiceMock.isBeneficiary.mockResolvedValue(true);
257+
validationServiceMock.checkIsBeneficiary.mockResolvedValue(true);
258258
transactionServiceMock
259259
.getHandler()
260260
.updateBeneficiaryData.mockResolvedValue({

packages/ats/sdk/src/core/error/BaseError.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,8 @@ export enum ErrorCode {
279279
InvalidKycStatus = '20041',
280280
WalletRecovered = '20042',
281281
AddressNotVerified = '20043',
282+
AccountIsBeneficiary = '20044',
283+
AccountIsNotBeneficiary = '20045',
282284

283285
// Error codes for System Errors (Prefix: 3XXXX)
284286
ContractNotFound = '30002',

0 commit comments

Comments
 (0)