generated from PolymeshAssociation/typescript-boilerplate
-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #37 from PolymathNetwork/feat/MSDK-55-st-modify-ma…
…ke-divisible Feat/msdk 55 st modify make divisible
- Loading branch information
Showing
16 changed files
with
301 additions
and
74 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,4 +7,5 @@ npm-package/ | |
coverage/ | ||
test.ts | ||
sandbox.ts | ||
docs/ | ||
docs/ | ||
tsconfig.dev.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
/* eslint-disable */ | ||
const fs = require('fs'); | ||
const path = require('path'); | ||
const rimraf = require('rimraf'); | ||
|
||
const configFile = path.resolve(__dirname, '../tsconfig.json'); | ||
const configDevFile = path.resolve(__dirname, '../tsconfig.dev.json'); | ||
|
||
rimraf.sync(configDevFile); | ||
|
||
let rawdata = fs.readFileSync(configFile); | ||
let tsConfigJson = JSON.parse(rawdata); | ||
|
||
tsConfigJson.compilerOptions.rootDir = '.'; | ||
|
||
let tsConfigDev = JSON.stringify({ | ||
compilerOptions: tsConfigJson.compilerOptions, | ||
}); | ||
|
||
fs.writeFileSync(configDevFile, tsConfigDev); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
import { Ticker } from 'polymesh-types/types'; | ||
import sinon from 'sinon'; | ||
|
||
import { SecurityToken } from '~/api/entities'; | ||
import { Params, prepareModifyToken } from '~/api/procedures/modifyToken'; | ||
import { Context } from '~/context'; | ||
import { entityMockUtils, polkadotMockUtils, procedureMockUtils } from '~/testUtils/mocks'; | ||
import { Mocked } from '~/testUtils/types'; | ||
import * as utilsModule from '~/utils'; | ||
|
||
jest.mock( | ||
'~/api/entities/SecurityToken', | ||
require('~/testUtils/mocks/entities').mockSecurityTokenModule('~/api/entities/SecurityToken') | ||
); | ||
|
||
describe('modifyToken procedure', () => { | ||
let mockContext: Mocked<Context>; | ||
let stringToTickerStub: sinon.SinonStub<[string, Context], Ticker>; | ||
let ticker: string; | ||
let rawTicker: Ticker; | ||
let procedureResult: SecurityToken; | ||
|
||
beforeAll(() => { | ||
polkadotMockUtils.initMocks(); | ||
procedureMockUtils.initMocks(); | ||
entityMockUtils.initMocks(); | ||
stringToTickerStub = sinon.stub(utilsModule, 'stringToTicker'); | ||
ticker = 'someTicker'; | ||
rawTicker = polkadotMockUtils.createMockTicker(ticker); | ||
procedureResult = entityMockUtils.getSecurityTokenInstance(); | ||
}); | ||
|
||
let addTransactionStub: sinon.SinonStub; | ||
|
||
beforeEach(() => { | ||
addTransactionStub = procedureMockUtils.getAddTransactionStub().returns([procedureResult]); | ||
mockContext = polkadotMockUtils.getContextInstance(); | ||
stringToTickerStub.withArgs(ticker, mockContext).returns(rawTicker); | ||
}); | ||
|
||
afterEach(() => { | ||
entityMockUtils.reset(); | ||
procedureMockUtils.reset(); | ||
polkadotMockUtils.reset(); | ||
}); | ||
|
||
afterAll(() => { | ||
entityMockUtils.cleanup(); | ||
procedureMockUtils.cleanup(); | ||
polkadotMockUtils.cleanup(); | ||
}); | ||
|
||
test('should throw an error if the user has not passed any arguments', () => { | ||
const proc = procedureMockUtils.getInstance<Params, SecurityToken>(); | ||
proc.context = mockContext; | ||
|
||
return expect(prepareModifyToken.call(proc, ({} as unknown) as Params)).rejects.toThrow( | ||
'Nothing to modify' | ||
); | ||
}); | ||
|
||
test('should throw an error if the user is not the owner of the token', () => { | ||
entityMockUtils.getSecurityTokenDetailsStub({ | ||
owner: entityMockUtils.getIdentityInstance({ did: 'someOtherDid' }), | ||
}); | ||
|
||
const proc = procedureMockUtils.getInstance<Params, SecurityToken>(); | ||
proc.context = mockContext; | ||
|
||
return expect( | ||
prepareModifyToken.call(proc, { | ||
ticker, | ||
makeDivisible: true, | ||
}) | ||
).rejects.toThrow( | ||
'You must be the owner of the Security Token to modify any of its properties' | ||
); | ||
}); | ||
|
||
test('should throw an error if makeDivisible is set to true and the security token is already divisible', () => { | ||
entityMockUtils.getSecurityTokenDetailsStub({ | ||
isDivisible: true, | ||
}); | ||
|
||
const proc = procedureMockUtils.getInstance<Params, SecurityToken>(); | ||
proc.context = mockContext; | ||
|
||
return expect( | ||
prepareModifyToken.call(proc, { | ||
ticker, | ||
makeDivisible: true, | ||
}) | ||
).rejects.toThrow('The Security Token is already divisible'); | ||
}); | ||
|
||
test('should throw an error if makeDivisible is set to false', () => { | ||
const proc = procedureMockUtils.getInstance<Params, SecurityToken>(); | ||
proc.context = mockContext; | ||
|
||
return expect( | ||
prepareModifyToken.call(proc, { | ||
ticker, | ||
makeDivisible: (false as unknown) as true, | ||
}) | ||
).rejects.toThrow('You cannot make the token indivisible'); | ||
}); | ||
|
||
test('should add a make divisible transaction to the queue', async () => { | ||
const proc = procedureMockUtils.getInstance<Params, SecurityToken>(); | ||
proc.context = mockContext; | ||
|
||
const transaction = polkadotMockUtils.createTxStub('asset', 'makeDivisible'); | ||
|
||
const result = await prepareModifyToken.call(proc, { | ||
ticker, | ||
makeDivisible: true, | ||
}); | ||
|
||
sinon.assert.calledWith(addTransactionStub, transaction, sinon.match({}), rawTicker); | ||
|
||
expect(result.ticker).toBe(procedureResult.ticker); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
export { reserveTicker, ReserveTickerParams } from './reserveTicker'; | ||
export { modifyToken, ModifyTokenParams } from './modifyToken'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import { SecurityToken } from '~/api/entities'; | ||
import { PolymeshError, Procedure } from '~/base'; | ||
import { ErrorCode } from '~/types'; | ||
import { stringToTicker } from '~/utils'; | ||
|
||
export type ModifyTokenParams = | ||
| { makeDivisible?: true; name: string } | ||
| { makeDivisible: true; name?: string }; | ||
|
||
export type Params = { ticker: string } & ModifyTokenParams; | ||
|
||
/** | ||
* @hidden | ||
*/ | ||
export async function prepareModifyToken( | ||
this: Procedure<Params, SecurityToken>, | ||
args: Params | ||
): Promise<SecurityToken> { | ||
const { | ||
context: { | ||
polymeshApi: { tx }, | ||
}, | ||
context, | ||
} = this; | ||
const { ticker, makeDivisible } = args; | ||
|
||
if (makeDivisible === undefined) { | ||
throw new PolymeshError({ | ||
code: ErrorCode.ValidationError, | ||
message: 'Nothing to modify', | ||
}); | ||
} | ||
|
||
const rawTicker = stringToTicker(ticker, context); | ||
|
||
const securityToken = new SecurityToken({ ticker }, context); | ||
|
||
const { isDivisible, owner } = await securityToken.details(); | ||
|
||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
if (owner.did !== context.currentIdentity!.did) { | ||
throw new PolymeshError({ | ||
code: ErrorCode.ValidationError, | ||
message: 'You must be the owner of the Security Token to modify any of its properties', | ||
}); | ||
} | ||
|
||
if (makeDivisible) { | ||
if (isDivisible) { | ||
throw new PolymeshError({ | ||
code: ErrorCode.ValidationError, | ||
message: 'The Security Token is already divisible', | ||
}); | ||
} | ||
|
||
this.addTransaction(tx.asset.makeDivisible, {}, rawTicker); | ||
} else { | ||
/* istanbul ignore else: it does not apply to our business logic. this line will be remove in future task */ | ||
if (makeDivisible === false) { | ||
throw new PolymeshError({ | ||
code: ErrorCode.ValidationError, | ||
message: 'You cannot make the token indivisible', | ||
}); | ||
} | ||
} | ||
|
||
return securityToken; | ||
} | ||
|
||
export const modifyToken = new Procedure(prepareModifyToken); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.