git.delta.rocks / unique-network / refs/commits / 012b227bf9e4

difftreelog

source

tests/src/approve.test.ts22.6 KiBsourcehistory
1//2// This file is subject to the terms and conditions defined in3// file 'LICENSE', which is part of this source code package.4//5import {IKeyringPair} from '@polkadot/types/types';6import {ApiPromise} from '@polkadot/api';7import chai from 'chai';8import chaiAsPromised from 'chai-as-promised';9import privateKey from './substrate/privateKey';10import {default as usingApi} from './substrate/substrate-api';11import {12  approveExpectFail,13  approveExpectSuccess,14  createCollectionExpectSuccess,15  createItemExpectSuccess,16  destroyCollectionExpectSuccess,17  setCollectionLimitsExpectSuccess,18  transferExpectSuccess,19  addCollectionAdminExpectSuccess,20  adminApproveFromExpectSuccess,21  transferFromExpectSuccess,22  transferFromExpectFail,23} from './util/helpers';2425chai.use(chaiAsPromised);26const expect = chai.expect;2728describe('Integration Test approve(spender, collection_id, item_id, amount):', () => {29  let Alice: IKeyringPair;30  let Bob: IKeyringPair;31  let Charlie: IKeyringPair;3233  before(async () => {34    await usingApi(async () => {35      Alice = privateKey('//Alice');36      Bob = privateKey('//Bob');37      Charlie = privateKey('//Charlie');38    });39  });4041  it('Execute the extrinsic and check approvedList', async () => {42    const nftCollectionId = await createCollectionExpectSuccess();43    // nft44    const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');45    await approveExpectSuccess(nftCollectionId, newNftTokenId, Alice, Bob.address);46    // fungible47    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});48    const newFungibleTokenId = await createItemExpectSuccess(Alice, fungibleCollectionId, 'Fungible');49    await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, Alice, Bob.address);50    // reFungible51    const reFungibleCollectionId =52      await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});53    const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');54    await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, Alice, Bob.address);55  });5657  it('Remove approval by using 0 amount', async () => {58    const nftCollectionId = await createCollectionExpectSuccess();59    // nft60    const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');61    await approveExpectSuccess(nftCollectionId, newNftTokenId, Alice, Bob.address, 1);62    await approveExpectSuccess(nftCollectionId, newNftTokenId, Alice, Bob.address, 0);63    // fungible64    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});65    const newFungibleTokenId = await createItemExpectSuccess(Alice, fungibleCollectionId, 'Fungible');66    await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, Alice, Bob.address, 1);67    await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, Alice, Bob.address, 0);68    // reFungible69    const reFungibleCollectionId =70      await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});71    const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');72    await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, Alice, Bob.address, 1);73    await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, Alice, Bob.address, 0);74  });7576  it('can be called by collection owner on non-owned item when OwnerCanTransfer == true', async () => {77    const collectionId = await createCollectionExpectSuccess();78    const itemId = await createItemExpectSuccess(Alice, collectionId, 'NFT', Bob.address);7980    await adminApproveFromExpectSuccess(collectionId, itemId, Alice, Bob.address, Charlie.address);81  });82});8384describe('Normal user can approve other users to transfer:', () => {85  let Alice: IKeyringPair;86  let Bob: IKeyringPair;87  let Charlie: IKeyringPair;8889  before(async () => {90    await usingApi(async () => {91      Alice = privateKey('//Alice');92      Bob = privateKey('//Bob');93      Charlie = privateKey('//Charlie');94    });95  });  9697  it('NFT', async () => {98    const collectionId = await createCollectionExpectSuccess();99    const itemId = await createItemExpectSuccess(Alice, collectionId, 'NFT', Bob.address);100    await approveExpectSuccess(collectionId, itemId, Bob, Charlie.address);101  });102103  it('Fungible up to an approved amount', async () => {104    const collectionId = await createCollectionExpectSuccess({ mode:{ type: 'Fungible', decimalPoints: 0 }});105    const itemId = await createItemExpectSuccess(Alice, collectionId, 'Fungible', Bob.address); 106    await approveExpectSuccess(collectionId, itemId, Bob, Charlie.address);107  });108109  it('ReFungible up to an approved amount', async () => {110    const collectionId = await createCollectionExpectSuccess({ mode:{ type: 'ReFungible' } });111    const itemId = await createItemExpectSuccess(Alice, collectionId, 'ReFungible', Bob.address);112    await approveExpectSuccess(collectionId, itemId, Bob, Charlie.address);113  });114});115116describe('Approved users can transferFrom up to approved amount:', () => {117  let Alice: IKeyringPair;118  let Bob: IKeyringPair;119  let Charlie: IKeyringPair;120121  before(async () => {122    await usingApi(async () => {123      Alice = privateKey('//Alice');124      Bob = privateKey('//Bob');125      Charlie = privateKey('//Charlie');126    });127  });  128129  it('NFT', async () => {130    const collectionId = await createCollectionExpectSuccess();131    const itemId = await createItemExpectSuccess(Alice, collectionId, 'NFT', Bob.address);132    await approveExpectSuccess(collectionId, itemId, Bob, Charlie.address);133    await transferFromExpectSuccess(collectionId, itemId, Charlie, Bob, Alice, 1, 'NFT');134  });135136  it('Fungible up to an approved amount', async () => {137    const collectionId = await createCollectionExpectSuccess({ mode:{ type: 'Fungible', decimalPoints: 0 }});138    const itemId = await createItemExpectSuccess(Alice, collectionId, 'Fungible', Bob.address); 139    await approveExpectSuccess(collectionId, itemId, Bob, Charlie.address);140    await transferFromExpectSuccess(collectionId, itemId, Charlie, Bob, Alice, 1, 'Fungible');141  });142143  it('ReFungible up to an approved amount', async () => {144    const collectionId = await createCollectionExpectSuccess({ mode:{ type: 'ReFungible' } });145    const itemId = await createItemExpectSuccess(Alice, collectionId, 'ReFungible', Bob.address);146    await approveExpectSuccess(collectionId, itemId, Bob, Charlie.address);147    await transferFromExpectSuccess(collectionId, itemId, Charlie, Bob, Alice, 1, 'ReFungible');148  });149});150151describe('Approved users cannot use transferFrom to repeat transfers if approved amount was already transferred:', () => {152  let Alice: IKeyringPair;153  let Bob: IKeyringPair;154  let Charlie: IKeyringPair;155156  before(async () => {157    await usingApi(async () => {158      Alice = privateKey('//Alice');159      Bob = privateKey('//Bob');160      Charlie = privateKey('//Charlie');161    });162  });  163164  it('NFT', async () => {165    const collectionId = await createCollectionExpectSuccess();166    const itemId = await createItemExpectSuccess(Alice, collectionId, 'NFT', Bob.address);167    await approveExpectSuccess(collectionId, itemId, Bob, Charlie.address);168    await transferFromExpectSuccess(collectionId, itemId, Charlie, Bob, Alice, 1, 'NFT');169    await transferFromExpectFail(collectionId, itemId, Charlie, Bob, Alice, 1);170  });171172  it('Fungible up to an approved amount', async () => {173    const collectionId = await createCollectionExpectSuccess({ mode:{ type: 'Fungible', decimalPoints: 0 }});174    const itemId = await createItemExpectSuccess(Alice, collectionId, 'Fungible', Bob.address); 175    await approveExpectSuccess(collectionId, itemId, Bob, Charlie.address);176    await transferFromExpectSuccess(collectionId, itemId, Charlie, Bob, Alice, 1, 'Fungible');177    await transferFromExpectFail(collectionId, itemId, Charlie, Bob, Alice, 1);178  });179180  it('ReFungible up to an approved amount', async () => {181    const collectionId = await createCollectionExpectSuccess({ mode:{ type: 'ReFungible' } });182    const itemId = await createItemExpectSuccess(Alice, collectionId, 'ReFungible', Bob.address);183    await approveExpectSuccess(collectionId, itemId, Bob, Charlie.address);184    await transferFromExpectSuccess(collectionId, itemId, Charlie, Bob, Alice, 1, 'ReFungible');185    await transferFromExpectFail(collectionId, itemId, Charlie, Bob, Alice, 1);186  });187});188189describe('Approved amount decreases by the transferred amount.:', () => {190  let Alice: IKeyringPair;191  let Bob: IKeyringPair;192  let Charlie: IKeyringPair;193  let Dave: IKeyringPair;194195  before(async () => {196    await usingApi(async () => {197      Alice = privateKey('//Alice');198      Bob = privateKey('//Bob');199      Charlie = privateKey('//Charlie');200      Dave = privateKey('//Dave');201    });202  });  203204  it('If a user B is approved to transfer 10 Fungible tokens from user A, they can transfer 2 tokens to user C, which will result in decreasing approval from 10 to 8. Then user B can transfer 8 tokens to user D.', async () => {205    const collectionId = await createCollectionExpectSuccess({ mode:{ type: 'Fungible', decimalPoints: 0 }});206    const itemId = await createItemExpectSuccess(Alice, collectionId, 'Fungible', Alice.address); 207    await approveExpectSuccess(collectionId, itemId, Alice, Bob.address, 10);208    await transferFromExpectSuccess(collectionId, itemId, Bob, Alice, Charlie, 2, 'Fungible');209    await transferFromExpectSuccess(collectionId, itemId, Bob, Alice, Dave, 8, 'Fungible');210  });211});212213describe('User may clear the approvals to approving for 0 amount:', () => {214  let Alice: IKeyringPair;215  let Bob: IKeyringPair;216  let Charlie: IKeyringPair;217218  before(async () => {219    await usingApi(async () => {220      Alice = privateKey('//Alice');221      Bob = privateKey('//Bob');222      Charlie = privateKey('//Charlie');223    });224  });225226  it('NFT', async () => {227    const collectionId = await createCollectionExpectSuccess();228    const itemId = await createItemExpectSuccess(Alice, collectionId, 'NFT');229    await approveExpectSuccess(collectionId, itemId, Alice, Bob.address, 1);230    await approveExpectSuccess(collectionId, itemId, Alice, Bob.address, 0);231    await transferFromExpectFail(collectionId, itemId, Bob, Bob, Charlie, 1);232  });233234  it('Fungible', async () => {235    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});236    const newFungibleTokenId = await createItemExpectSuccess(Alice, fungibleCollectionId, 'Fungible');237    await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, Alice, Bob.address, 1);238    await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, Alice, Bob.address, 0);239    await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, Bob, Bob, Charlie, 1);240  });241242  it('ReFungible', async () => {243    const reFungibleCollectionId =244      await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});245    const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');246    await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, Alice, Bob.address, 1);247    await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, Alice, Bob.address, 0);248    await transferFromExpectFail(reFungibleCollectionId, newReFungibleTokenId, Bob, Bob, Charlie, 1);249  });250});251252describe('User cannot approve for the amount greater than they own:', () => {253  let Alice: IKeyringPair;254  let Bob: IKeyringPair;255  let Charlie: IKeyringPair;256257  before(async () => {258    await usingApi(async () => {259      Alice = privateKey('//Alice');260      Bob = privateKey('//Bob');261      Charlie = privateKey('//Charlie');262    });263  });264265  it('1 for NFT', async () => {266    const collectionId = await createCollectionExpectSuccess();267    const itemId = await createItemExpectSuccess(Alice, collectionId, 'NFT', Bob.address);268    await approveExpectFail(collectionId, itemId, Bob, Charlie, 2);269  });270271  it('Fungible', async () => {272    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});273    const newFungibleTokenId = await createItemExpectSuccess(Alice, fungibleCollectionId, 'Fungible');274    await approveExpectFail(fungibleCollectionId, newFungibleTokenId, Bob, Charlie, 11);275  });276277  it('ReFungible', async () => {278    const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});279    const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');280    await approveExpectFail(reFungibleCollectionId, newReFungibleTokenId, Bob, Charlie, 101);281  });282});283284describe('Administrator and collection owner do not need approval in order to execute TransferFrom:', () => {285  let Alice: IKeyringPair;286  let Bob: IKeyringPair;287  let Charlie: IKeyringPair;288  let Dave: IKeyringPair;289290  before(async () => {291    await usingApi(async () => {292      Alice = privateKey('//Alice');293      Bob = privateKey('//Bob');294      Charlie = privateKey('//Charlie');295      Dave = privateKey('//Dave');296    });297  });  298299  it('NFT', async () => {300    const collectionId = await createCollectionExpectSuccess();301    const itemId = await createItemExpectSuccess(Alice, collectionId, 'NFT', Charlie.address);302    await transferFromExpectSuccess(collectionId, itemId, Alice, Charlie, Dave, 1, 'NFT');303    await addCollectionAdminExpectSuccess(Alice, collectionId, Bob.address);304    await transferFromExpectSuccess(collectionId, itemId, Bob, Dave, Alice, 1, 'NFT');305  });306307  it('Fungible up to an approved amount', async () => {308    const collectionId = await createCollectionExpectSuccess({ mode:{ type: 'Fungible', decimalPoints: 0 }});309    const itemId = await createItemExpectSuccess(Alice, collectionId, 'Fungible', Charlie.address); 310    await transferFromExpectSuccess(collectionId, itemId, Alice, Charlie, Dave, 1, 'Fungible');311    await addCollectionAdminExpectSuccess(Alice, collectionId, Bob.address);312    await transferFromExpectSuccess(collectionId, itemId, Bob, Dave, Alice, 1, 'Fungible');313  });314315  it('ReFungible up to an approved amount', async () => {316    const collectionId = await createCollectionExpectSuccess({ mode:{ type: 'ReFungible' } });317    const itemId = await createItemExpectSuccess(Alice, collectionId, 'ReFungible', Charlie.address);318    await transferFromExpectSuccess(collectionId, itemId, Alice, Charlie, Dave, 1, 'ReFungible');319    await addCollectionAdminExpectSuccess(Alice, collectionId, Bob.address);320    await transferFromExpectSuccess(collectionId, itemId, Bob, Dave, Alice, 1, 'ReFungible');321  });322});323324describe('Repeated approvals add up', () => {325  let Alice: IKeyringPair;326  let Bob: IKeyringPair;327  let Charlie: IKeyringPair;328  let Dave: IKeyringPair;329330  before(async () => {331    await usingApi(async () => {332      Alice = privateKey('//Alice');333      Bob = privateKey('//Bob');334      Charlie = privateKey('//Charlie');335      Dave = privateKey('//Dave');336    });337  });  338339  it.skip('Owned 10, approval 1: 1, approval 2: 1, resulting approved value: 2. Fungible', async () => {340    const collectionId = await createCollectionExpectSuccess({ mode:{ type: 'Fungible', decimalPoints: 0 }});341    await createItemExpectSuccess(Alice, collectionId, 'Fungible', Alice.address);342    await approveExpectSuccess(collectionId, 0, Alice, Bob.address, 1);343    await approveExpectSuccess(collectionId, 0, Alice, Charlie.address, 1);344    // const allowances1 = await getAllowance(collectionId, 0, Alice.address, Bob.address);345    // const allowances2 = await getAllowance(collectionId, 0, Alice.address, Charlie.address);346    // expect(allowances1 + allowances2).to.be.eq(BigInt(2));347  });348349  it.skip('Owned 10, approval 1: 1, approval 2: 1, resulting approved value: 2. ReFungible', async () => {350    const collectionId = await createCollectionExpectSuccess({ mode:{ type: 'ReFungible' } });351    const itemId = await createItemExpectSuccess(Alice, collectionId, 'ReFungible', Alice.address);352    await approveExpectSuccess(collectionId, itemId, Alice, Bob.address, 1);353    await approveExpectSuccess(collectionId, itemId, Alice, Charlie.address, 1);354    // const allowances1 = await getAllowance(collectionId, itemId, Alice.address, Bob.address);355    // const allowances2 = await getAllowance(collectionId, itemId, Alice.address, Charlie.address);356    // expect(allowances1 + allowances2).to.be.eq(BigInt(2));357  });358359  // Canceled by changing approve logic360  it.skip('Cannot approve for more than total user`s amount (owned: 10, approval 1: 5 - should succeed, approval 2: 6 - should fail). Fungible', async () => {361    const collectionId = await createCollectionExpectSuccess({ mode:{ type: 'Fungible', decimalPoints: 0 }});362    await createItemExpectSuccess(Alice, collectionId, 'Fungible', Dave.address);363    await approveExpectSuccess(collectionId, 0, Dave, Bob.address, 5);364    await approveExpectFail(collectionId, 0, Dave, Charlie, 6);365  });366367  // Canceled by changing approve logic368  it.skip('Cannot approve for more than total users amount (owned: 100, approval 1: 50 - should succeed, approval 2: 51 - should fail). ReFungible', async () => {369    const collectionId = await createCollectionExpectSuccess({ mode:{ type: 'ReFungible' } });370    const itemId = await createItemExpectSuccess(Alice, collectionId, 'ReFungible', Dave.address);371    await approveExpectSuccess(collectionId, itemId, Dave, Bob.address, 50);372    await approveExpectFail(collectionId, itemId, Dave, Charlie, 51);373  });374});375376describe('Integration Test approve(spender, collection_id, item_id, amount) with collection admin permissions:', () => {377  let Alice: IKeyringPair;378  let Bob: IKeyringPair;379  let Charlie: IKeyringPair;380381  before(async () => {382    await usingApi(async () => {383      Alice = privateKey('//Alice');384      Bob = privateKey('//Bob');385      Charlie = privateKey('//Charlie');386    });387  });388389  it('can be called by collection admin on non-owned item', async () => {390    const collectionId = await createCollectionExpectSuccess();391    const itemId = await createItemExpectSuccess(Alice, collectionId, 'NFT', Alice.address);392393    await addCollectionAdminExpectSuccess(Alice, collectionId, Bob.address);394    await adminApproveFromExpectSuccess(collectionId, itemId, Bob, Alice.address, Charlie.address);395  });396});397398describe('Negative Integration Test approve(spender, collection_id, item_id, amount):', () => {399  let Alice: IKeyringPair;400  let Bob: IKeyringPair;401  let Charlie: IKeyringPair;402403  before(async () => {404    await usingApi(async () => {405      Alice = privateKey('//Alice');406      Bob = privateKey('//Bob');407      Charlie = privateKey('//Charlie');408    });409  });410411  it('Approve for a collection that does not exist', async () => {412    await usingApi(async (api: ApiPromise) => {413      // nft414      const nftCollectionCount = (await api.query.common.createdCollectionCount()).toNumber();415      await approveExpectFail(nftCollectionCount + 1, 1, Alice, Bob);416      // fungible417      const fungibleCollectionCount = (await api.query.common.createdCollectionCount()).toNumber();418      await approveExpectFail(fungibleCollectionCount + 1, 0, Alice, Bob);419      // reFungible420      const reFungibleCollectionCount = (await api.query.common.createdCollectionCount()).toNumber();421      await approveExpectFail(reFungibleCollectionCount + 1, 1, Alice, Bob);422    });423  });424425  it('Approve for a collection that was destroyed', async () => {426    // nft427    const nftCollectionId = await createCollectionExpectSuccess();428    await destroyCollectionExpectSuccess(nftCollectionId);429    await approveExpectFail(nftCollectionId, 1, Alice, Bob);430    // fungible431    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});432    await destroyCollectionExpectSuccess(fungibleCollectionId);433    await approveExpectFail(fungibleCollectionId, 0, Alice, Bob);434    // reFungible435    const reFungibleCollectionId =436      await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});437    await destroyCollectionExpectSuccess(reFungibleCollectionId);438    await approveExpectFail(reFungibleCollectionId, 1, Alice, Bob);439  });440441  it('Approve transfer of a token that does not exist', async () => {442    // nft443    const nftCollectionId = await createCollectionExpectSuccess();444    await approveExpectFail(nftCollectionId, 2, Alice, Bob);445    // reFungible446    const reFungibleCollectionId =447      await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});448    await approveExpectFail(reFungibleCollectionId, 2, Alice, Bob);449  });450451  it('Approve using the address that does not own the approved token', async () => {452    const nftCollectionId = await createCollectionExpectSuccess();453    // nft454    const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');455    await approveExpectFail(nftCollectionId, newNftTokenId, Bob, Alice);456    // fungible457    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});458    const newFungibleTokenId = await createItemExpectSuccess(Alice, fungibleCollectionId, 'Fungible');459    await approveExpectFail(fungibleCollectionId, newFungibleTokenId, Bob, Alice);460    // reFungible461    const reFungibleCollectionId =462      await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});463    const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');464    await approveExpectFail(reFungibleCollectionId, newReFungibleTokenId, Bob, Alice);465  });466467  it('should fail if approved more ReFungibles than owned', async () => {468    const nftCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});469    const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'ReFungible');470    await transferExpectSuccess(nftCollectionId, newNftTokenId, Alice, Bob, 100, 'ReFungible');471    await approveExpectSuccess(nftCollectionId, newNftTokenId, Bob, Alice.address, 100);472    await approveExpectFail(nftCollectionId, newNftTokenId, Bob, Alice, 101);473  });474475  it('should fail if approved more Fungibles than owned', async () => {476    const nftCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});477    const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'Fungible');478    await transferExpectSuccess(nftCollectionId, newNftTokenId, Alice, Bob, 10, 'Fungible');479    await approveExpectSuccess(nftCollectionId, newNftTokenId, Bob, Alice.address, 10);480    await approveExpectFail(nftCollectionId, newNftTokenId, Bob, Alice, 11);481  });482483  it('fails when called by collection owner on non-owned item when OwnerCanTransfer == false', async () => {484    const collectionId = await createCollectionExpectSuccess();485    const itemId = await createItemExpectSuccess(Alice, collectionId, 'NFT', Bob.address);486    await setCollectionLimitsExpectSuccess(Alice, collectionId, {ownerCanTransfer: false});487488    await approveExpectFail(collectionId, itemId, Alice, Charlie);489  });490});