Skip to content

Commit

Permalink
feat: freeze and unfreeze sto
Browse files Browse the repository at this point in the history
  • Loading branch information
shuffledex committed Feb 3, 2021
1 parent 2efab01 commit e2f167a
Show file tree
Hide file tree
Showing 5 changed files with 352 additions and 2 deletions.
45 changes: 44 additions & 1 deletion src/api/entities/Sto/__tests__/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import BigNumber from 'bignumber.js';
import sinon from 'sinon';
import sinon, { SinonStub } from 'sinon';

import { Params } from '~/api/procedures/toggleFreezeSto';
import {
cancelSto,
Context,
Expand All @@ -9,6 +10,7 @@ import {
Identity,
SecurityToken,
Sto,
toggleFreezeSto,
TransactionQueue,
Venue,
} from '~/internal';
Expand Down Expand Up @@ -37,10 +39,15 @@ jest.mock(

describe('Sto class', () => {
let context: Context;
let prepareToggleFreezeStoStub: SinonStub<
[Params, Context],
Promise<TransactionQueue<Sto, unknown[][]>>
>;

beforeAll(() => {
dsMockUtils.initMocks();
entityMockUtils.initMocks();
prepareToggleFreezeStoStub = sinon.stub(toggleFreezeSto, 'prepare');
});

beforeEach(() => {
Expand Down Expand Up @@ -203,4 +210,40 @@ describe('Sto class', () => {
expect(queue).toBe(expectedQueue);
});
});

describe('method: freeze', () => {
test('should prepare the procedure and return the resulting transaction queue', async () => {
const ticker = 'SOMETICKER';
const id = new BigNumber(1);
const sto = new Sto({ id, ticker }, context);

const expectedQueue = ('someQueue' as unknown) as TransactionQueue<Sto>;

prepareToggleFreezeStoStub
.withArgs({ ticker, id, freeze: true }, context)
.resolves(expectedQueue);

const queue = await sto.freeze();

expect(queue).toBe(expectedQueue);
});
});

describe('method: unfreeze', () => {
test('should prepare the procedure and return the resulting transaction queue', async () => {
const ticker = 'SOMETICKER';
const id = new BigNumber(1);
const sto = new Sto({ id, ticker }, context);

const expectedQueue = ('someQueue' as unknown) as TransactionQueue<Sto>;

prepareToggleFreezeStoStub
.withArgs({ ticker, id, freeze: false }, context)
.resolves(expectedQueue);

const queue = await sto.unfreeze();

expect(queue).toBe(expectedQueue);
});
});
});
27 changes: 26 additions & 1 deletion src/api/entities/Sto/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import { Option } from '@polkadot/types';
import BigNumber from 'bignumber.js';

import { cancelSto, CancelStoParams, Context, Entity, PolymeshError } from '~/internal';
import {
cancelSto,
CancelStoParams,
Context,
Entity,
PolymeshError,
toggleFreezeSto,
} from '~/internal';
import { Fundraiser } from '~/polkadot/polymesh/types';
import { ErrorCode, StoDetails, SubCallback, UnsubCallback } from '~/types';
import { ProcedureMethod } from '~/types/internal';
Expand Down Expand Up @@ -49,6 +56,14 @@ export class Sto extends Entity<UniqueIdentifiers> {
this.ticker = ticker;

this.close = createProcedureMethod(args => [cancelSto, { ticker, ...args }], context);
this.freeze = createProcedureMethod(
() => [toggleFreezeSto, { ticker, id, freeze: true }],
context
);
this.unfreeze = createProcedureMethod(
() => [toggleFreezeSto, { ticker, id, freeze: false }],
context
);
}

/**
Expand Down Expand Up @@ -101,4 +116,14 @@ export class Sto extends Entity<UniqueIdentifiers> {
* Close the STO
*/
public close: ProcedureMethod<CancelStoParams, void>;

/**
* Freezes the STO
*/
public freeze: ProcedureMethod<void, Sto>;

/**
* Unfreeze the STO
*/
public unfreeze: ProcedureMethod<void, Sto>;
}
187 changes: 187 additions & 0 deletions src/api/procedures/__tests__/toggleFreezeSto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
import { u64 } from '@polkadot/types';
import BigNumber from 'bignumber.js';
import { Ticker, TxTags } from 'polymesh-types/types';
import sinon from 'sinon';

import { getAuthorization, Params, prepareToggleFreezeSto } from '~/api/procedures/toggleFreezeSto';
import { Context, Sto } from '~/internal';
import { dsMockUtils, entityMockUtils, procedureMockUtils } from '~/testUtils/mocks';
import { Mocked } from '~/testUtils/types';
import { RoleType, StoStatus } from '~/types';
import * as utilsConversionModule from '~/utils/conversion';

jest.mock(
'~/api/entities/SecurityToken',
require('~/testUtils/mocks/entities').mockSecurityTokenModule('~/api/entities/SecurityToken')
);
jest.mock(
'~/api/entities/Sto',
require('~/testUtils/mocks/entities').mockStoModule('~/api/entities/Sto')
);

describe('toggleFreezeSto procedure', () => {
let mockContext: Mocked<Context>;
let stringToTickerStub: sinon.SinonStub<[string, Context], Ticker>;
let numberToU64Stub: sinon.SinonStub<[number | BigNumber, Context], u64>;
let ticker: string;
let rawTicker: Ticker;
let id: BigNumber;
let rawId: u64;
let sto: Sto;

beforeAll(() => {
dsMockUtils.initMocks();
procedureMockUtils.initMocks();
entityMockUtils.initMocks();
stringToTickerStub = sinon.stub(utilsConversionModule, 'stringToTicker');
numberToU64Stub = sinon.stub(utilsConversionModule, 'numberToU64');
ticker = 'tickerFrozen';
id = new BigNumber(1);
rawTicker = dsMockUtils.createMockTicker(ticker);
rawId = dsMockUtils.createMockU64(id.toNumber());
sto = new Sto({ ticker, id }, mockContext);
});

let addTransactionStub: sinon.SinonStub;

beforeEach(() => {
addTransactionStub = procedureMockUtils.getAddTransactionStub();
mockContext = dsMockUtils.getContextInstance();
stringToTickerStub.withArgs(ticker, mockContext).returns(rawTicker);
numberToU64Stub.withArgs(id, mockContext).returns(rawId);
});

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

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

test('should throw an error if freeze is set to true and the STO is already frozen', () => {
entityMockUtils.configureMocks({
stoOptions: {
details: {
status: StoStatus.Frozen,
},
},
});

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

return expect(
prepareToggleFreezeSto.call(proc, {
ticker,
id,
freeze: true,
})
).rejects.toThrow('The STO is already frozen');
});

test('should throw an error if freeze is set to false and the STO status is live or close', () => {
const proc = procedureMockUtils.getInstance<Params, Sto>(mockContext);

entityMockUtils.configureMocks({
stoOptions: {
details: {
status: StoStatus.Live,
},
},
});

expect(
prepareToggleFreezeSto.call(proc, {
ticker,
id,
freeze: false,
})
).rejects.toThrow('The STO is already unfrozen');

entityMockUtils.configureMocks({
stoOptions: {
details: {
status: StoStatus.Closed,
},
},
});

expect(
prepareToggleFreezeSto.call(proc, {
ticker,
id,
freeze: false,
})
).rejects.toThrow('The STO is already closed');
});

test('should add a freeze transaction to the queue', async () => {
const proc = procedureMockUtils.getInstance<Params, Sto>(mockContext);

const transaction = dsMockUtils.createTxStub('sto', 'freezeFundraiser');

const result = await prepareToggleFreezeSto.call(proc, {
ticker,
id,
freeze: true,
});

sinon.assert.calledWith(addTransactionStub, transaction, {}, rawTicker, rawId);

expect(sto.ticker).toBe(result.ticker);
});

test('should add a unfreeze transaction to the queue', async () => {
entityMockUtils.configureMocks({
securityTokenOptions: {
isFrozen: true,
},
});

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

const transaction = dsMockUtils.createTxStub('sto', 'unfreezeFundraiser');

const result = await prepareToggleFreezeSto.call(proc, {
ticker,
id,
freeze: false,
});

sinon.assert.calledWith(addTransactionStub, transaction, {}, rawTicker, rawId);

expect(sto.ticker).toBe(result.ticker);
});

describe('getAuthorization', () => {
test('should return the appropriate roles and permissions', () => {
const proc = procedureMockUtils.getInstance<Params, Sto>(mockContext);
const boundFunc = getAuthorization.bind(proc);

const token = entityMockUtils.getSecurityTokenInstance({ ticker });
const identityRoles = [{ type: RoleType.TokenPia, ticker }];

expect(boundFunc({ ticker, id, freeze: true })).toEqual({
identityRoles,
signerPermissions: {
transactions: [TxTags.sto.FreezeFundraiser],
tokens: [token],
portfolios: [],
},
});

expect(boundFunc({ ticker, id, freeze: false })).toEqual({
identityRoles,
signerPermissions: {
transactions: [TxTags.sto.UnfreezeFundraiser],
tokens: [token],
portfolios: [],
},
});
});
});
});

0 comments on commit e2f167a

Please sign in to comment.