Skip to content

Commit

Permalink
feat: getAuthorizationStatuses method
Browse files Browse the repository at this point in the history
  • Loading branch information
shuffledex committed Oct 9, 2020
1 parent 53fc558 commit e7e7483
Show file tree
Hide file tree
Showing 6 changed files with 173 additions and 2 deletions.
49 changes: 48 additions & 1 deletion src/api/entities/Instruction/__tests__/index.ts
@@ -1,12 +1,17 @@
import { u64 } from '@polkadot/types';
import BigNumber from 'bignumber.js';
import {
AuthorizationStatus as MeshAuthorizationStatus,
PortfolioId as MeshPortfolioId,
} from 'polymesh-types/types';
import sinon from 'sinon';

import { Entity, Instruction } from '~/api/entities';
import { Identity } from '~/api/entities/Identity';
import { Context } from '~/base';
import { dsMockUtils, entityMockUtils } from '~/testUtils/mocks';
import { Mocked } from '~/testUtils/types';
import { InstructionStatus, InstructionType } from '~/types';
import { AuthorizationStatus, InstructionStatus, InstructionType } from '~/types';
import { tuple } from '~/types/utils';
import * as utilsModule from '~/utils';

Expand Down Expand Up @@ -128,6 +133,48 @@ describe('Instruction class', () => {
});
});

describe('method: getAuthorizationStatuses', () => {
const did = 'someDid';
const status = AuthorizationStatus.Authorized;
let rawStorageKey: [u64, MeshPortfolioId][];
let authsReceivedEntries: [[u64, MeshPortfolioId], MeshAuthorizationStatus][];

afterAll(() => {
sinon.restore();
});

beforeAll(() => {
rawStorageKey = [
tuple(
dsMockUtils.createMockU64(),
dsMockUtils.createMockPortfolioId({
did: dsMockUtils.createMockIdentityId(did),
kind: dsMockUtils.createMockPortfolioKind('Default'),
})
),
];
authsReceivedEntries = rawStorageKey.map(([instructionId, portfolioId]) =>
tuple(
[instructionId, portfolioId],
dsMockUtils.createMockAuthorizationStatus(AuthorizationStatus.Authorized)
)
);
dsMockUtils.createQueryStub('settlement', 'authsReceived', {
entries: [authsReceivedEntries[0]],
});
sinon.stub(utilsModule, 'identityIdToString').returns(did);
sinon.stub(utilsModule, 'meshAuthorizationStatusToAuthorizationStatus').returns(status);
});

test('should return a list of Authorization Statuses', async () => {
const result = await instruction.getAuthorizationStatuses();

expect(result).toHaveLength(1);
expect(result[0].identity).toEqual(new Identity({ did }, context));
expect(result[0].authorizarionStatus).toEqual(status);
});
});

describe('method: getLegs', () => {
afterAll(() => {
sinon.restore();
Expand Down
38 changes: 37 additions & 1 deletion src/api/entities/Instruction/index.ts
@@ -1,18 +1,25 @@
import BigNumber from 'bignumber.js';
import { PortfolioId as MeshPortfolioId } from 'polymesh-types/types';

import { Entity, Identity, SecurityToken } from '~/api/entities';
import { Context } from '~/base';
import {
balanceToBigNumber,
identityIdToString,
meshAuthorizationStatusToAuthorizationStatus,
meshInstructionStatusToInstructionStatus,
momentToDate,
numberToU64,
tickerToString,
u32ToBigNumber,
} from '~/utils';

import { InstructionDetails, InstructionType, Leg } from './types';
import {
AuthorizerWithAuthorizationStatus,
InstructionDetails,
InstructionType,
Leg,
} from './types';

export interface UniqueIdentifiers {
id: BigNumber;
Expand Down Expand Up @@ -89,6 +96,35 @@ export class Instruction extends Entity<UniqueIdentifiers> {
};
}

/**
* Retrieve all authorization statuses with authorizer identity of this Instruction
*/
public async getAuthorizationStatuses(): Promise<AuthorizerWithAuthorizationStatus[]> {
const {
context: {
polymeshApi: {
query: { settlement },
},
},
id,
context,
} = this;

const entries = await settlement.authsReceived.entries(numberToU64(id, context));

const authorizerWithAuthorizationStatus: AuthorizerWithAuthorizationStatus[] = [];

entries.forEach(([key, meshAuthorizationStatus]) => {
const { did } = key.args[1] as MeshPortfolioId;
authorizerWithAuthorizationStatus.push({
identity: new Identity({ did: identityIdToString(did) }, context),
authorizarionStatus: meshAuthorizationStatusToAuthorizationStatus(meshAuthorizationStatus),
});
});

return authorizerWithAuthorizationStatus;
}

/**
* Retrieve all legs of this Instruction
*/
Expand Down
12 changes: 12 additions & 0 deletions src/api/entities/Instruction/types.ts
Expand Up @@ -35,3 +35,15 @@ export interface Leg {
amount: BigNumber;
token: SecurityToken;
}

export enum AuthorizationStatus {
Unknown = 'Unknown',
Pending = 'Pending',
Authorized = 'Authorized',
Rejected = 'Rejected',
}

export interface AuthorizerWithAuthorizationStatus {
identity: Identity;
authorizarionStatus: AuthorizationStatus;
}
11 changes: 11 additions & 0 deletions src/testUtils/mocks/dataSources.ts
Expand Up @@ -38,6 +38,7 @@ import {
AuthIdentifier,
Authorization,
AuthorizationData,
AuthorizationStatus as MeshAuthorizationStatus,
AuthorizationType as MeshAuthorizationType,
CanTransferResult,
CddId,
Expand Down Expand Up @@ -1527,6 +1528,16 @@ export const createMockPermission = (
return createMockEnum(permission) as Permission;
};

/**
* @hidden
* NOTE: `isEmpty` will be set to true if no value is passed
*/
export const createMockAuthorizationStatus = (
authorizationStatus: 'Authorized' | 'Pending' | 'Rejected' | 'Unknown'
): MeshAuthorizationStatus => {
return createMockEnum(authorizationStatus) as MeshAuthorizationStatus;
};

/**
* @hidden
* NOTE: `isEmpty` will be set to true if no value is passed
Expand Down
42 changes: 42 additions & 0 deletions src/utils/__tests__/index.ts
Expand Up @@ -41,6 +41,7 @@ import { CallIdEnum, ClaimTypeEnum, ModuleIdEnum } from '~/middleware/types';
import { dsMockUtils, entityMockUtils } from '~/testUtils/mocks';
import {
Authorization,
AuthorizationStatus,
AuthorizationType,
Claim,
ClaimType,
Expand Down Expand Up @@ -100,6 +101,7 @@ import {
isIsinValid,
isLeiValid,
keyToAddress,
meshAuthorizationStatusToAuthorizationStatus,
meshClaimToClaim,
meshInstructionStatusToInstructionStatus,
meshPermissionToPermission,
Expand Down Expand Up @@ -2536,6 +2538,46 @@ describe('permissionToMeshPermission and meshPermissionToPermission', () => {
});
});

describe('meshAuthorizationStatusToAuthorizationStatus', () => {
beforeAll(() => {
dsMockUtils.initMocks();
});

afterEach(() => {
dsMockUtils.reset();
});

afterAll(() => {
dsMockUtils.cleanup();
});

test('meshAuthorizationStatusToAuthorizationStatus should convert a polkadot AuthorizationStatus object to a AuthorizationStatus', () => {
let fakeResult = AuthorizationStatus.Authorized;
let permission = dsMockUtils.createMockAuthorizationStatus(fakeResult);

let result = meshAuthorizationStatusToAuthorizationStatus(permission);
expect(result).toEqual(fakeResult);

fakeResult = AuthorizationStatus.Pending;
permission = dsMockUtils.createMockAuthorizationStatus(fakeResult);

result = meshAuthorizationStatusToAuthorizationStatus(permission);
expect(result).toEqual(fakeResult);

fakeResult = AuthorizationStatus.Rejected;
permission = dsMockUtils.createMockAuthorizationStatus(fakeResult);

result = meshAuthorizationStatusToAuthorizationStatus(permission);
expect(result).toEqual(fakeResult);

fakeResult = AuthorizationStatus.Unknown;
permission = dsMockUtils.createMockAuthorizationStatus(fakeResult);

result = meshAuthorizationStatusToAuthorizationStatus(permission);
expect(result).toEqual(fakeResult);
});
});

describe('authorizationTypeToMeshAuthorizationType', () => {
beforeAll(() => {
dsMockUtils.initMocks();
Expand Down
23 changes: 23 additions & 0 deletions src/utils/index.ts
Expand Up @@ -33,6 +33,7 @@ import {
AssetType,
AuthIdentifier,
AuthorizationData,
AuthorizationStatus as MeshAuthorizationStatus,
AuthorizationType as MeshAuthorizationType,
CanTransferResult,
CddId,
Expand Down Expand Up @@ -77,6 +78,7 @@ import {
} from '~/middleware/types';
import {
Authorization,
AuthorizationStatus,
AuthorizationType,
Claim,
ClaimType,
Expand Down Expand Up @@ -431,6 +433,27 @@ export function meshPermissionToPermission(permission: MeshPermission): Permissi
return Permission.SpendFunds;
}

/**
* @hidden
*/
export function meshAuthorizationStatusToAuthorizationStatus(
authorizationStatus: MeshAuthorizationStatus
): AuthorizationStatus {
if (authorizationStatus.isPending) {
return AuthorizationStatus.Pending;
}

if (authorizationStatus.isRejected) {
return AuthorizationStatus.Rejected;
}

if (authorizationStatus.isUnknown) {
return AuthorizationStatus.Unknown;
}

return AuthorizationStatus.Authorized;
}

/**
* @hidden
*/
Expand Down

0 comments on commit e7e7483

Please sign in to comment.