Skip to content

Commit

Permalink
feat(instruction): add support for portfolios in get/modify auths
Browse files Browse the repository at this point in the history
  • Loading branch information
monitz87 committed Nov 5, 2020
1 parent 088b63f commit 26dd0d5
Show file tree
Hide file tree
Showing 9 changed files with 307 additions and 108 deletions.
24 changes: 16 additions & 8 deletions src/Claims.ts
Expand Up @@ -84,10 +84,10 @@ export class Claims {
includeExpired?: boolean;
size?: number;
start?: number;
} = { includeExpired: true }
} = {}
): Promise<ResultSet<ClaimData>> {
const { context } = this;
const { target, includeExpired, size, start } = opts;
const { target, includeExpired = true, size, start } = opts;

const did = await getDid(target, context);

Expand Down Expand Up @@ -124,11 +124,19 @@ export class Claims {
includeExpired?: boolean;
size?: number;
start?: number;
} = { includeExpired: true }
} = {}
): Promise<ResultSet<IdentityWithClaims>> {
const { context } = this;

const { targets, trustedClaimIssuers, scope, claimTypes, includeExpired, size, start } = opts;
const {
targets,
trustedClaimIssuers,
scope,
claimTypes,
includeExpired = true,
size,
start,
} = opts;

const result = await context.queryMiddleware<Ensured<Query, 'didsWithClaims'>>(
didsWithClaims({
Expand Down Expand Up @@ -214,10 +222,10 @@ export class Claims {
includeExpired?: boolean;
size?: number;
start?: number;
} = { includeExpired: true }
} = {}
): Promise<ResultSet<ClaimData>> {
const { context } = this;
const { target, includeExpired, size, start } = opts;
const { target, includeExpired = true, size, start } = opts;

const did = await getDid(target, context);

Expand Down Expand Up @@ -249,11 +257,11 @@ export class Claims {
includeExpired?: boolean;
size?: number;
start?: number;
} = { includeExpired: true }
} = {}
): Promise<ResultSet<IdentityWithClaims>> {
const { context } = this;

const { target, trustedClaimIssuers, scope, includeExpired, size, start } = opts;
const { target, trustedClaimIssuers, scope, includeExpired = true, size, start } = opts;

const did = await getDid(target, context);

Expand Down
34 changes: 26 additions & 8 deletions src/api/entities/CurrentIdentity.ts
@@ -1,4 +1,6 @@
import { u64 } from '@polkadot/types';
import P from 'bluebird';
import { chunk, flatten, uniqBy } from 'lodash';
import { Instruction as MeshInstruction } from 'polymesh-types/types';

import { Identity, Instruction, Venue } from '~/api/entities';
Expand All @@ -11,7 +13,9 @@ import {
} from '~/api/procedures';
import { TransactionQueue } from '~/base';
import { SecondaryKey, Signer, SubCallback, UnsubCallback } from '~/types';
import { PortfolioId } from '~/types/internal';
import { portfolioIdToMeshPortfolioId, u64ToBigNumber } from '~/utils';
import { MAX_CONCURRENT_REQUESTS } from '~/utils/constants';

/**
* Represents the Identity associated to the current [[Account]]
Expand Down Expand Up @@ -74,20 +78,34 @@ export class CurrentIdentity extends Identity {
},
},
did,
portfolios,
context,
} = this;

const auths = await settlement.userAuths.entries(
portfolioIdToMeshPortfolioId({ did }, context)
);
const [, ...numberedPortfolios] = await portfolios.getPortfolios();

const instructionIds = auths.map(([key]) => key.args[1] as u64);
const portfolioIds: PortfolioId[] = [
{ did },
...numberedPortfolios.map(({ id: number }) => ({ did, number })),
];

const meshInstructions = await settlement.instructionDetails.multi<MeshInstruction>(
instructionIds
);
const portfolioIdChunks = chunk(portfolioIds, MAX_CONCURRENT_REQUESTS);

return meshInstructions
const chunkedInstructions = await P.mapSeries(portfolioIdChunks, async portfolioIdChunk => {
const auths = await P.map(portfolioIdChunk, portfolioId =>
settlement.userAuths.entries(portfolioIdToMeshPortfolioId(portfolioId, context))
);

const instructionIds = uniqBy(
flatten(auths).map(([key]) => key.args[1] as u64),
id => id.toNumber()
);
return settlement.instructionDetails.multi<MeshInstruction>(instructionIds);
});

const rawInstructions = flatten(chunkedInstructions);

return rawInstructions
.filter(({ status }) => status.isPending)
.map(({ instruction_id: id }) => new Instruction({ id: u64ToBigNumber(id) }, context));
}
Expand Down
154 changes: 118 additions & 36 deletions src/api/entities/__tests__/CurrentIdentity.ts
Expand Up @@ -7,6 +7,7 @@ import { Context, TransactionQueue } from '~/base';
import { dsMockUtils, entityMockUtils } from '~/testUtils/mocks';
import { SecondaryKey, SubCallback, VenueType } from '~/types';
import { tuple } from '~/types/utils';
import * as utilsModule from '~/utils';

describe('CurrentIdentity class', () => {
let context: Context;
Expand Down Expand Up @@ -141,67 +142,148 @@ describe('CurrentIdentity class', () => {
const id1 = new BigNumber(1);
const id2 = new BigNumber(2);
const id3 = new BigNumber(3);
const id4 = new BigNumber(4);
const id5 = new BigNumber(5);

const did = 'someDid';
const identity = new CurrentIdentity({ did }, context);

const numberedPortfolioId = new BigNumber(1);

identity.portfolios.getPortfolios = sinon
.stub()
.resolves([{ owner: { did } }, { owner: { did }, id: numberedPortfolioId }]);

const rawPortfolio = dsMockUtils.createMockPortfolioId({
did: dsMockUtils.createMockIdentityId(did),
kind: dsMockUtils.createMockPortfolioKind('Default'),
});
dsMockUtils.createQueryStub('settlement', 'userAuths', {
entries: [

const rawNumberedPortfolio = dsMockUtils.createMockPortfolioId({
did: dsMockUtils.createMockIdentityId(did),
kind: dsMockUtils.createMockPortfolioKind({
User: dsMockUtils.createMockU64(numberedPortfolioId.toNumber()),
}),
});

const portfolioIdToMeshPortfolioIdStub = sinon.stub(
utilsModule,
'portfolioIdToMeshPortfolioId'
);

portfolioIdToMeshPortfolioIdStub.withArgs({ did }, context).returns(rawPortfolio);
portfolioIdToMeshPortfolioIdStub
.withArgs({ did, number: numberedPortfolioId }, context)
.returns(rawNumberedPortfolio);

const userAuthsStub = dsMockUtils.createQueryStub('settlement', 'userAuths');

const rawId1 = dsMockUtils.createMockU64(id1.toNumber());
const rawId2 = dsMockUtils.createMockU64(id2.toNumber());
const rawId3 = dsMockUtils.createMockU64(id3.toNumber());
const rawId4 = dsMockUtils.createMockU64(id4.toNumber());
const rawId5 = dsMockUtils.createMockU64(id5.toNumber());

const entriesStub = sinon.stub();
entriesStub
.withArgs(rawPortfolio)
.resolves([
tuple(
[rawPortfolio, dsMockUtils.createMockU64(id1.toNumber())],
{ args: [rawPortfolio, rawId1] },
dsMockUtils.createMockAuthorizationStatus('Pending')
),
tuple(
[rawPortfolio, dsMockUtils.createMockU64(id2.toNumber())],
{ args: [rawPortfolio, rawId2] },
dsMockUtils.createMockAuthorizationStatus('Pending')
),
tuple(
[rawPortfolio, dsMockUtils.createMockU64(id3.toNumber())],
{ args: [rawPortfolio, rawId3] },
dsMockUtils.createMockAuthorizationStatus('Pending')
),
],
});
]);

entriesStub
.withArgs(rawNumberedPortfolio)
.resolves([
tuple(
{ args: [rawNumberedPortfolio, rawId2] },
dsMockUtils.createMockAuthorizationStatus('Pending')
),
tuple(
{ args: [rawNumberedPortfolio, rawId4] },
dsMockUtils.createMockAuthorizationStatus('Pending')
),
tuple(
{ args: [rawNumberedPortfolio, rawId5] },
dsMockUtils.createMockAuthorizationStatus('Pending')
),
]);

userAuthsStub.entries = entriesStub;

/* eslint-disable @typescript-eslint/camelcase */
dsMockUtils.createQueryStub('settlement', 'instructionDetails', {
multi: [
dsMockUtils.createMockInstruction({
instruction_id: dsMockUtils.createMockU64(id1.toNumber()),
venue_id: dsMockUtils.createMockU64(),
status: dsMockUtils.createMockInstructionStatus('Pending'),
settlement_type: dsMockUtils.createMockSettlementType('SettleOnAuthorization'),
created_at: dsMockUtils.createMockOption(),
valid_from: dsMockUtils.createMockOption(),
}),
dsMockUtils.createMockInstruction({
instruction_id: dsMockUtils.createMockU64(id2.toNumber()),
venue_id: dsMockUtils.createMockU64(),
status: dsMockUtils.createMockInstructionStatus('Pending'),
settlement_type: dsMockUtils.createMockSettlementType('SettleOnAuthorization'),
created_at: dsMockUtils.createMockOption(),
valid_from: dsMockUtils.createMockOption(),
}),
dsMockUtils.createMockInstruction({
instruction_id: dsMockUtils.createMockU64(id3.toNumber()),
venue_id: dsMockUtils.createMockU64(),
status: dsMockUtils.createMockInstructionStatus('Unknown'),
settlement_type: dsMockUtils.createMockSettlementType('SettleOnAuthorization'),
created_at: dsMockUtils.createMockOption(),
valid_from: dsMockUtils.createMockOption(),
}),
],
});
const instructionDetailsStub = dsMockUtils.createQueryStub(
'settlement',
'instructionDetails',
{
multi: [],
}
);

const multiStub = sinon.stub();

multiStub.withArgs([rawId1, rawId2, rawId3, rawId4, rawId5]).resolves([
dsMockUtils.createMockInstruction({
instruction_id: dsMockUtils.createMockU64(id1.toNumber()),
venue_id: dsMockUtils.createMockU64(),
status: dsMockUtils.createMockInstructionStatus('Pending'),
settlement_type: dsMockUtils.createMockSettlementType('SettleOnAuthorization'),
created_at: dsMockUtils.createMockOption(),
valid_from: dsMockUtils.createMockOption(),
}),
dsMockUtils.createMockInstruction({
instruction_id: dsMockUtils.createMockU64(id2.toNumber()),
venue_id: dsMockUtils.createMockU64(),
status: dsMockUtils.createMockInstructionStatus('Pending'),
settlement_type: dsMockUtils.createMockSettlementType('SettleOnAuthorization'),
created_at: dsMockUtils.createMockOption(),
valid_from: dsMockUtils.createMockOption(),
}),
dsMockUtils.createMockInstruction({
instruction_id: dsMockUtils.createMockU64(id3.toNumber()),
venue_id: dsMockUtils.createMockU64(),
status: dsMockUtils.createMockInstructionStatus('Unknown'),
settlement_type: dsMockUtils.createMockSettlementType('SettleOnAuthorization'),
created_at: dsMockUtils.createMockOption(),
valid_from: dsMockUtils.createMockOption(),
}),
dsMockUtils.createMockInstruction({
instruction_id: dsMockUtils.createMockU64(id4.toNumber()),
venue_id: dsMockUtils.createMockU64(),
status: dsMockUtils.createMockInstructionStatus('Pending'),
settlement_type: dsMockUtils.createMockSettlementType('SettleOnAuthorization'),
created_at: dsMockUtils.createMockOption(),
valid_from: dsMockUtils.createMockOption(),
}),
dsMockUtils.createMockInstruction({
instruction_id: dsMockUtils.createMockU64(id5.toNumber()),
venue_id: dsMockUtils.createMockU64(),
status: dsMockUtils.createMockInstructionStatus('Unknown'),
settlement_type: dsMockUtils.createMockSettlementType('SettleOnAuthorization'),
created_at: dsMockUtils.createMockOption(),
valid_from: dsMockUtils.createMockOption(),
}),
]);

instructionDetailsStub.multi = multiStub;
/* eslint-enable @typescript-eslint/camelcase */

const result = await identity.getPendingInstructions();

expect(result.length).toBe(2);
expect(result.length).toBe(3);
expect(result[0].id).toEqual(id1);
expect(result[1].id).toEqual(id2);
expect(result[2].id).toEqual(id4);
});
});
});

0 comments on commit 26dd0d5

Please sign in to comment.