diff --git a/src/api/procedures/__tests__/reserveTicker.ts b/src/api/procedures/__tests__/reserveTicker.ts index f746acf884..e092f1778c 100644 --- a/src/api/procedures/__tests__/reserveTicker.ts +++ b/src/api/procedures/__tests__/reserveTicker.ts @@ -173,47 +173,48 @@ describe('reserveTicker procedure', () => { ); }); - test('should throw an error if extendPeriod property is set to true and the token has already been launched', async () => { - const expiryDate = null; + test('should throw an error if extendPeriod property is set to true and the ticker has not reserved or the reservation has expired', async () => { + const expiryDate = new Date(2019, 1, 1); mockTickerReservation.mock('details', { ownerDid: 'someDid', expiryDate, + status: TickerReservationStatus.Free, }); const proc = mockProcedure.getMockInstance(); proc.context = mockContext; return expect(prepareReserveTicker.call(proc, { ...args, extendPeriod: true })).rejects.toThrow( - 'Ticker has already been launched' + 'Ticker not reserved or the reservation has expired' ); }); - test('should throw an error if extendPeriod property is set to true and the ticker has not reserved or the reservation has expired', async () => { - const expiryDate = new Date(2019, 1, 1); + test("should throw an error if extendPeriod property is set to true and the signing account doesn't have enough balance", () => { + const expiryDate = new Date(new Date().getTime() + 1000); mockTickerReservation.mock('details', { ownerDid: 'someDid', expiryDate, - status: TickerReservationStatus.Free, }); + mockFactory.createQueryStub('asset', 'tickerRegistrationFee', createMockBalance(600000000)); const proc = mockProcedure.getMockInstance(); proc.context = mockContext; return expect(prepareReserveTicker.call(proc, { ...args, extendPeriod: true })).rejects.toThrow( - 'Ticker not reserved or the reservation has expired' + 'Not enough POLY balance to pay for ticker period extension' ); }); - test("should throw an error if extendPeriod property is set to true and the signing account doesn't have enough balance", () => { + test('should throw an error if extendPeriod property is set to true and the signing account is not the ticker owner', () => { const expiryDate = new Date(new Date().getTime() + 1000); mockTickerReservation.mock('details', { - ownerDid: 'someDid', + ownerDid: 'anotherDid', expiryDate, + status: TickerReservationStatus.Reserved, }); - mockFactory.createQueryStub('asset', 'tickerRegistrationFee', createMockBalance(600000000)); const proc = mockProcedure.getMockInstance(); proc.context = mockContext; return expect(prepareReserveTicker.call(proc, { ...args, extendPeriod: true })).rejects.toThrow( - 'Not enough POLY balance to pay for ticker period extension' + 'You must be the owner of the ticker to extend its registration period' ); }); diff --git a/src/api/procedures/reserveTicker.ts b/src/api/procedures/reserveTicker.ts index dc6f548c02..bea1f4d28c 100644 --- a/src/api/procedures/reserveTicker.ts +++ b/src/api/procedures/reserveTicker.ts @@ -50,7 +50,7 @@ export async function prepareReserveTicker( rawFee, balance, { max_ticker_length: rawMaxTickerLength }, - { expiryDate, status }, + { ownerDid, expiryDate, status }, ] = await Promise.all([ query.asset.tickerRegistrationFee(), context.accountBalance(), @@ -58,15 +58,15 @@ export async function prepareReserveTicker( reservation.details(), ]); - if (!extendPeriod) { - if (status === TickerReservationStatus.TokenCreated) { - throw new PolymeshError({ - code: ErrorCode.ValidationError, - message: `A Security Token with ticker "${ticker} already exists`, - }); - } + if (status === TickerReservationStatus.TokenCreated) { + throw new PolymeshError({ + code: ErrorCode.ValidationError, + message: `A Security Token with ticker "${ticker} already exists`, + }); + } - if (status === TickerReservationStatus.Reserved) { + if (status === TickerReservationStatus.Reserved) { + if (!extendPeriod) { const isPermanent = expiryDate === null; throw new PolymeshError({ @@ -75,8 +75,15 @@ export async function prepareReserveTicker( !isPermanent ? '' : 'not ' }expire${!isPermanent ? ` at ${expiryDate}` : ''}`, }); + } else if (ownerDid !== context.currentIdentity?.did) { + throw new PolymeshError({ + code: ErrorCode.ValidationError, + message: 'You must be the owner of the ticker to extend its registration period', + }); } + } + if (!extendPeriod) { const maxTickerLength = rawMaxTickerLength.toNumber(); if (ticker.length > maxTickerLength) { @@ -86,13 +93,6 @@ export async function prepareReserveTicker( }); } } else { - if (expiryDate === null) { - throw new PolymeshError({ - code: ErrorCode.ValidationError, - message: 'Ticker has already been launched', - }); - } - if (status === TickerReservationStatus.Free) { throw new PolymeshError({ code: ErrorCode.ValidationError, diff --git a/src/testUtils/mocks/PolkadotMockFactory.ts b/src/testUtils/mocks/PolkadotMockFactory.ts index a4b6448e72..121fa16054 100644 --- a/src/testUtils/mocks/PolkadotMockFactory.ts +++ b/src/testUtils/mocks/PolkadotMockFactory.ts @@ -223,7 +223,7 @@ export class PolkadotMockFactory { */ private initContext(opts: ContextOptions): void { const currentIdentity = opts.withSeed - ? { getIdentityBalance: sinon.stub().resolves(opts.balance) } + ? { getIdentityBalance: sinon.stub().resolves(opts.balance), did: 'someDid' } : undefined; const currentPair = opts.withSeed ? ({