Skip to content

Commit

Permalink
feat: venue exists
Browse files Browse the repository at this point in the history
  • Loading branch information
shuffledex committed Dec 24, 2020
1 parent 7a8ba49 commit 6f4007b
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 1 deletion.
53 changes: 53 additions & 0 deletions src/api/entities/Venue/__tests__/index.ts
Expand Up @@ -60,11 +60,50 @@ describe('Venue class', () => {
});
});

describe('method: exists', () => {
afterAll(() => {
sinon.restore();
});

test('should return whether if the venue exists or not', async () => {
const owner = 'someDid';

entityMockUtils.configureMocks({ identityOptions: { did: owner } });
sinon
.stub(utilsConversionModule, 'numberToU64')
.withArgs(id, context)
.returns(rawId);

dsMockUtils
.createQueryStub('settlement', 'venueInfo')
.withArgs(rawId)
.resolves(dsMockUtils.createMockOption());

const result = await venue.exists();

expect(result).toEqual(false);
});
});

describe('method: details', () => {
afterAll(() => {
sinon.restore();
});

test("should throw an error if the venue doesn't exist", async () => {
dsMockUtils
.createQueryStub('settlement', 'venueInfo')
.resolves(dsMockUtils.createMockOption());

entityMockUtils.configureMocks({
numberedPortfolioOptions: {
exists: false,
},
});

return expect(venue.details()).rejects.toThrow("The Venue doesn't exist");
});

test('should return the Venue details', async () => {
const description = 'someDescription';
const type = VenueType.Other;
Expand Down Expand Up @@ -106,6 +145,20 @@ describe('Venue class', () => {
sinon.restore();
});

test("should throw an error if the venue doesn't exist", async () => {
dsMockUtils
.createQueryStub('settlement', 'venueInfo')
.resolves(dsMockUtils.createMockOption());

entityMockUtils.configureMocks({
numberedPortfolioOptions: {
exists: false,
},
});

return expect(venue.getPendingInstructions()).rejects.toThrow("The Venue doesn't exist");
});

test("should return the Venue's pending instructions", async () => {
const description = 'someDescription';
const type = VenueType.Other;
Expand Down
40 changes: 39 additions & 1 deletion src/api/entities/Venue/index.ts
Expand Up @@ -8,8 +8,9 @@ import {
Entity,
Identity,
Instruction,
PolymeshError,
} from '~/internal';
import { InstructionStatus } from '~/types';
import { ErrorCode, InstructionStatus } from '~/types';
import { ProcedureMethod } from '~/types/internal';
import {
identityIdToString,
Expand Down Expand Up @@ -61,6 +62,25 @@ export class Venue extends Entity<UniqueIdentifiers> {
);
}

/**
* Retrieve if the venue still exists
*/
public async exists(): Promise<boolean> {
const {
context: {
polymeshApi: {
query: { settlement },
},
},
id,
context,
} = this;

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

return !venueInfo.isEmpty;
}

/**
* Retrieve information specific to this venue
*/
Expand All @@ -75,6 +95,15 @@ export class Venue extends Entity<UniqueIdentifiers> {
context,
} = this;

const exists = await this.exists();

if (!exists) {
throw new PolymeshError({
code: ErrorCode.ValidationError,
message: "The Venue doesn't exist",
});
}

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

const { creator, details, venue_type: type } = venueInfo.unwrap();
Expand All @@ -100,6 +129,15 @@ export class Venue extends Entity<UniqueIdentifiers> {
context,
} = this;

const exists = await this.exists();

if (!exists) {
throw new PolymeshError({
code: ErrorCode.ValidationError,
message: "The Venue doesn't exist",
});
}

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

const { instructions: rawInstructions } = venueInfo.unwrap();
Expand Down
40 changes: 40 additions & 0 deletions src/api/procedures/__tests__/addInstruction.ts
Expand Up @@ -25,6 +25,11 @@ import { PolymeshTx } from '~/types/internal';
import * as utilsConversionModule from '~/utils/conversion';
import * as utilsInternalModule from '~/utils/internal';

jest.mock(
'~/api/entities/Venue',
require('~/testUtils/mocks/entities').mockVenueModule('~/api/entities/Venue')
);

describe('addInstruction procedure', () => {
let mockContext: Mocked<Context>;
let portfolioIdToMeshPortfolioIdStub: sinon.SinonStub;
Expand Down Expand Up @@ -231,6 +236,11 @@ describe('addInstruction procedure', () => {

test('should throw an error if the end block is in the past', async () => {
dsMockUtils.configureMocks({ contextOptions: { latestBlock: new BigNumber(1000) } });
entityMockUtils.configureMocks({
venueOptions: {
exists: true,
},
});
const proc = procedureMockUtils.getInstance<Params, Instruction>(mockContext);

let error;
Expand All @@ -246,6 +256,11 @@ describe('addInstruction procedure', () => {

test('should add an add and authorize instruction transaction to the queue', async () => {
dsMockUtils.configureMocks({ contextOptions: { did: fromDid } });
entityMockUtils.configureMocks({
venueOptions: {
exists: true,
},
});
getCustodianStub.onCall(1).returns({ did: fromDid });
const proc = procedureMockUtils.getInstance<Params, Instruction>(mockContext);

Expand All @@ -268,6 +283,11 @@ describe('addInstruction procedure', () => {

test('should add an add instruction transaction to the queue', async () => {
dsMockUtils.configureMocks({ contextOptions: { did: fromDid } });
entityMockUtils.configureMocks({
venueOptions: {
exists: true,
},
});
getCustodianStub.onCall(0).returns({ did: toDid });
const proc = procedureMockUtils.getInstance<Params, Instruction>(mockContext);

Expand All @@ -294,6 +314,26 @@ describe('addInstruction procedure', () => {
expect(result).toBe(instruction);
});

test("should throw an error if the venue doesn't exist", async () => {
entityMockUtils.configureMocks({
venueOptions: {
exists: false,
},
});

const proc = procedureMockUtils.getInstance<Params, Instruction>(mockContext);

let error;

try {
await prepareAddInstruction.call(proc, { ...args, legs: [] });
} catch (err) {
error = err;
}

expect(error.message).toBe("The Venue doesn't exist");
});

describe('getAuthorization', () => {
test('should return the appropriate roles and permissions', async () => {
const proc = procedureMockUtils.getInstance<Params, Instruction>(mockContext);
Expand Down
13 changes: 13 additions & 0 deletions src/api/procedures/addInstruction.ts
Expand Up @@ -5,6 +5,7 @@ import BigNumber from 'bignumber.js';
import P from 'bluebird';
import { PortfolioId, Ticker, TxTag, TxTags } from 'polymesh-types/types';

import { Venue } from '~/api/entities/Venue';
import { assertPortfolioExists } from '~/api/procedures/utils';
import {
Context,
Expand Down Expand Up @@ -76,6 +77,18 @@ export async function prepareAddInstruction(
} = this;
const { legs, venueId, endBlock, validFrom } = args;

const venue = new Venue({ id: venueId }, context);
const exists = await venue.exists();

console.log(exists);

if (!exists) {
throw new PolymeshError({
code: ErrorCode.ValidationError,
message: "The Venue doesn't exist",
});
}

if (!legs.length) {
throw new PolymeshError({
code: ErrorCode.ValidationError,
Expand Down
5 changes: 5 additions & 0 deletions src/testUtils/mocks/entities.ts
Expand Up @@ -130,6 +130,7 @@ interface CurrentAccountOptions extends AccountOptions {
interface VenueOptions {
id?: BigNumber;
details?: Partial<VenueDetails>;
exists?: boolean;
}

interface NumberedPortfolioOptions {
Expand Down Expand Up @@ -193,6 +194,7 @@ let currentAccountGetIdentityStub: SinonStub;
let currentAccountGetTransactionHistoryStub: SinonStub;
let tickerReservationDetailsStub: SinonStub;
let venueDetailsStub: SinonStub;
let venueExistsStub: SinonStub;
let instructionDetailsStub: SinonStub;
let instructionGetLegsStub: SinonStub;
let numberedPortfolioIsOwnedByStub: SinonStub;
Expand Down Expand Up @@ -443,6 +445,7 @@ const defaultVenueOptions: VenueOptions = {
type: VenueType.Distribution,
description: 'someDescription',
},
exists: true,
};
let venueOptions = defaultVenueOptions;
const defaultNumberedPortfolioOptions: NumberedPortfolioOptions = {
Expand Down Expand Up @@ -542,6 +545,7 @@ function configureVenue(opts: VenueOptions): void {
const venue = ({
id: opts.id,
details: venueDetailsStub.resolves(details),
exists: venueExistsStub.resolves(opts.exists),
} as unknown) as MockVenue;

Object.assign(mockInstanceContainer.venue, venue);
Expand All @@ -559,6 +563,7 @@ function configureVenue(opts: VenueOptions): void {
function initVenue(opts?: VenueOptions): void {
venueConstructorStub = sinon.stub();
venueDetailsStub = sinon.stub();
venueExistsStub = sinon.stub();

venueOptions = { ...defaultVenueOptions, ...opts };

Expand Down

0 comments on commit 6f4007b

Please sign in to comment.