git.delta.rocks / unique-network / refs/commits / f54ae82ec2a7

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  getCreatedCollectionCount,22  transferFromExpectSuccess,23  transferFromExpectFail,24} from './util/helpers';2526chai.use(chaiAsPromised);27const expect = chai.expect;2829describe('Integration Test approve(spender, collection_id, item_id, amount):', () => {30  let alice: IKeyringPair;31  let bob: IKeyringPair;32  let charlie: IKeyringPair;3334  before(async () => {35    await usingApi(async () => {36      alice = privateKey('//Alice');37      bob = privateKey('//Bob');38      charlie = privateKey('//Charlie');39    });40  });4142  it('Execute the extrinsic and check approvedList', async () => {43    const nftCollectionId = await createCollectionExpectSuccess();44    // nft45    const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');46    await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address);47    // fungible48    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});49    const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');50    await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);51    // reFungible52    const reFungibleCollectionId =53      await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});54    const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');55    await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address);56  });5758  it('Remove approval by using 0 amount', async () => {59    const nftCollectionId = await createCollectionExpectSuccess();60    // nft61    const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');62    await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address, 1);63    await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address, 0);64    // fungible65    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});66    const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');67    await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address, 1);68    await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address, 0);69    // reFungible70    const reFungibleCollectionId =71      await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});72    const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');73    await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address, 1);74    await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address, 0);75  });7677  it('can be called by collection owner on non-owned item when OwnerCanTransfer == true', async () => {78    const collectionId = await createCollectionExpectSuccess();79    const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', bob.address);8081    await adminApproveFromExpectSuccess(collectionId, itemId, alice, bob.address, charlie.address);82  });83});8485describe('Normal user can approve other users to transfer:', () => {86  let alice: IKeyringPair;87  let bob: IKeyringPair;88  let charlie: IKeyringPair;8990  before(async () => {91    await usingApi(async () => {92      alice = privateKey('//Alice');93      bob = privateKey('//Bob');94      charlie = privateKey('//Charlie');95    });96  });  9798  it('NFT', async () => {99    const collectionId = await createCollectionExpectSuccess();100    const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', bob.address);101    await approveExpectSuccess(collectionId, itemId, bob, charlie.address);102  });103104  it('Fungible up to an approved amount', async () => {105    const collectionId = await createCollectionExpectSuccess({ mode:{ type: 'Fungible', decimalPoints: 0 }});106    const itemId = await createItemExpectSuccess(alice, collectionId, 'Fungible', bob.address); 107    await approveExpectSuccess(collectionId, itemId, bob, charlie.address);108  });109110  it('ReFungible up to an approved amount', async () => {111    const collectionId = await createCollectionExpectSuccess({ mode:{ type: 'ReFungible' } });112    const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', bob.address);113    await approveExpectSuccess(collectionId, itemId, bob, charlie.address);114  });115});116117describe('Approved users can transferFrom up to approved amount:', () => {118  let alice: IKeyringPair;119  let bob: IKeyringPair;120  let charlie: IKeyringPair;121122  before(async () => {123    await usingApi(async () => {124      alice = privateKey('//Alice');125      bob = privateKey('//Bob');126      charlie = privateKey('//Charlie');127    });128  });  129130  it('NFT', async () => {131    const collectionId = await createCollectionExpectSuccess();132    const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', bob.address);133    await approveExpectSuccess(collectionId, itemId, bob, charlie.address);134    await transferFromExpectSuccess(collectionId, itemId, charlie, bob, alice, 1, 'NFT');135  });136137  it('Fungible up to an approved amount', async () => {138    const collectionId = await createCollectionExpectSuccess({ mode:{ type: 'Fungible', decimalPoints: 0 }});139    const itemId = await createItemExpectSuccess(alice, collectionId, 'Fungible', bob.address); 140    await approveExpectSuccess(collectionId, itemId, bob, charlie.address);141    await transferFromExpectSuccess(collectionId, itemId, charlie, bob, alice, 1, 'Fungible');142  });143144  it('ReFungible up to an approved amount', async () => {145    const collectionId = await createCollectionExpectSuccess({ mode:{ type: 'ReFungible' } });146    const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', bob.address);147    await approveExpectSuccess(collectionId, itemId, bob, charlie.address);148    await transferFromExpectSuccess(collectionId, itemId, charlie, bob, alice, 1, 'ReFungible');149  });150});151152describe('Approved users cannot use transferFrom to repeat transfers if approved amount was already transferred:', () => {153  let alice: IKeyringPair;154  let bob: IKeyringPair;155  let charlie: IKeyringPair;156157  before(async () => {158    await usingApi(async () => {159      alice = privateKey('//Alice');160      bob = privateKey('//Bob');161      charlie = privateKey('//Charlie');162    });163  });  164165  it('NFT', async () => {166    const collectionId = await createCollectionExpectSuccess();167    const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', bob.address);168    await approveExpectSuccess(collectionId, itemId, bob, charlie.address);169    await transferFromExpectSuccess(collectionId, itemId, charlie, bob, alice, 1, 'NFT');170    await transferFromExpectFail(collectionId, itemId, charlie, bob, alice, 1);171  });172173  it('Fungible up to an approved amount', async () => {174    const collectionId = await createCollectionExpectSuccess({ mode:{ type: 'Fungible', decimalPoints: 0 }});175    const itemId = await createItemExpectSuccess(alice, collectionId, 'Fungible', bob.address); 176    await approveExpectSuccess(collectionId, itemId, bob, charlie.address);177    await transferFromExpectSuccess(collectionId, itemId, charlie, bob, alice, 1, 'Fungible');178    await transferFromExpectFail(collectionId, itemId, charlie, bob, alice, 1);179  });180181  it('ReFungible up to an approved amount', async () => {182    const collectionId = await createCollectionExpectSuccess({ mode:{ type: 'ReFungible' } });183    const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', bob.address);184    await approveExpectSuccess(collectionId, itemId, bob, charlie.address);185    await transferFromExpectSuccess(collectionId, itemId, charlie, bob, alice, 1, 'ReFungible');186    await transferFromExpectFail(collectionId, itemId, charlie, bob, alice, 1);187  });188});189190describe('Approved amount decreases by the transferred amount.:', () => {191  let alice: IKeyringPair;192  let bob: IKeyringPair;193  let charlie: IKeyringPair;194  let dave: IKeyringPair;195196  before(async () => {197    await usingApi(async () => {198      alice = privateKey('//Alice');199      bob = privateKey('//Bob');200      charlie = privateKey('//Charlie');201      dave = privateKey('//Dave');202    });203  });  204205  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 () => {206    const collectionId = await createCollectionExpectSuccess({ mode:{ type: 'Fungible', decimalPoints: 0 }});207    const itemId = await createItemExpectSuccess(alice, collectionId, 'Fungible', alice.address); 208    await approveExpectSuccess(collectionId, itemId, alice, bob.address, 10);209    await transferFromExpectSuccess(collectionId, itemId, bob, alice, charlie, 2, 'Fungible');210    await transferFromExpectSuccess(collectionId, itemId, bob, alice, dave, 8, 'Fungible');211  });212});213214describe('User may clear the approvals to approving for 0 amount:', () => {215  let alice: IKeyringPair;216  let bob: IKeyringPair;217  let charlie: IKeyringPair;218219  before(async () => {220    await usingApi(async () => {221      alice = privateKey('//Alice');222      bob = privateKey('//Bob');223      charlie = privateKey('//Charlie');224    });225  });226227  it('NFT', async () => {228    const collectionId = await createCollectionExpectSuccess();229    const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT');230    await approveExpectSuccess(collectionId, itemId, alice, bob.address, 1);231    await approveExpectSuccess(collectionId, itemId, alice, bob.address, 0);232    await transferFromExpectFail(collectionId, itemId, bob, bob, charlie, 1);233  });234235  it('Fungible', async () => {236    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});237    const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');238    await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address, 1);239    await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address, 0);240    await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, bob, charlie, 1);241  });242243  it('ReFungible', async () => {244    const reFungibleCollectionId =245      await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});246    const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');247    await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address, 1);248    await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address, 0);249    await transferFromExpectFail(reFungibleCollectionId, newReFungibleTokenId, bob, bob, charlie, 1);250  });251});252253describe('User cannot approve for the amount greater than they own:', () => {254  let alice: IKeyringPair;255  let bob: IKeyringPair;256  let charlie: IKeyringPair;257258  before(async () => {259    await usingApi(async () => {260      alice = privateKey('//Alice');261      bob = privateKey('//Bob');262      charlie = privateKey('//Charlie');263    });264  });265266  it('1 for NFT', async () => {267    const collectionId = await createCollectionExpectSuccess();268    const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', bob.address);269    await approveExpectFail(collectionId, itemId, bob, charlie, 2);270  });271272  it('Fungible', async () => {273    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});274    const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');275    await approveExpectFail(fungibleCollectionId, newFungibleTokenId, bob, charlie, 11);276  });277278  it('ReFungible', async () => {279    const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});280    const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');281    await approveExpectFail(reFungibleCollectionId, newReFungibleTokenId, bob, charlie, 101);282  });283});284285describe('Administrator and collection owner do not need approval in order to execute TransferFrom:', () => {286  let alice: IKeyringPair;287  let bob: IKeyringPair;288  let charlie: IKeyringPair;289  let dave: IKeyringPair;290291  before(async () => {292    await usingApi(async () => {293      alice = privateKey('//Alice');294      bob = privateKey('//Bob');295      charlie = privateKey('//Charlie');296      dave = privateKey('//Dave');297    });298  });  299300  it('NFT', async () => {301    const collectionId = await createCollectionExpectSuccess();302    const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', charlie.address);303    await transferFromExpectSuccess(collectionId, itemId, alice, charlie, dave, 1, 'NFT');304    await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);305    await transferFromExpectSuccess(collectionId, itemId, bob, dave, alice, 1, 'NFT');306  });307308  it('Fungible up to an approved amount', async () => {309    const collectionId = await createCollectionExpectSuccess({ mode:{ type: 'Fungible', decimalPoints: 0 }});310    const itemId = await createItemExpectSuccess(alice, collectionId, 'Fungible', charlie.address); 311    await transferFromExpectSuccess(collectionId, itemId, alice, charlie, dave, 1, 'Fungible');312    await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);313    await transferFromExpectSuccess(collectionId, itemId, bob, dave, alice, 1, 'Fungible');314  });315316  it('ReFungible up to an approved amount', async () => {317    const collectionId = await createCollectionExpectSuccess({ mode:{ type: 'ReFungible' } });318    const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', charlie.address);319    await transferFromExpectSuccess(collectionId, itemId, alice, charlie, dave, 1, 'ReFungible');320    await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);321    await transferFromExpectSuccess(collectionId, itemId, bob, dave, alice, 1, 'ReFungible');322  });323});324325describe('Repeated approvals add up', () => {326  let alice: IKeyringPair;327  let bob: IKeyringPair;328  let charlie: IKeyringPair;329  let dave: IKeyringPair;330331  before(async () => {332    await usingApi(async () => {333      alice = privateKey('//Alice');334      bob = privateKey('//Bob');335      charlie = privateKey('//Charlie');336      dave = privateKey('//Dave');337    });338  });  339340  it.skip('Owned 10, approval 1: 1, approval 2: 1, resulting approved value: 2. Fungible', async () => {341    const collectionId = await createCollectionExpectSuccess({ mode:{ type: 'Fungible', decimalPoints: 0 }});342    await createItemExpectSuccess(alice, collectionId, 'Fungible', alice.address);343    await approveExpectSuccess(collectionId, 0, alice, bob.address, 1);344    await approveExpectSuccess(collectionId, 0, alice, charlie.address, 1);345    // const allowances1 = await getAllowance(collectionId, 0, Alice.address, Bob.address);346    // const allowances2 = await getAllowance(collectionId, 0, Alice.address, Charlie.address);347    // expect(allowances1 + allowances2).to.be.eq(BigInt(2));348  });349350  it.skip('Owned 10, approval 1: 1, approval 2: 1, resulting approved value: 2. ReFungible', async () => {351    const collectionId = await createCollectionExpectSuccess({ mode:{ type: 'ReFungible' } });352    const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', alice.address);353    await approveExpectSuccess(collectionId, itemId, alice, bob.address, 1);354    await approveExpectSuccess(collectionId, itemId, alice, charlie.address, 1);355    // const allowances1 = await getAllowance(collectionId, itemId, Alice.address, Bob.address);356    // const allowances2 = await getAllowance(collectionId, itemId, Alice.address, Charlie.address);357    // expect(allowances1 + allowances2).to.be.eq(BigInt(2));358  });359360  // Canceled by changing approve logic361  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 () => {362    const collectionId = await createCollectionExpectSuccess({ mode:{ type: 'Fungible', decimalPoints: 0 }});363    await createItemExpectSuccess(alice, collectionId, 'Fungible', dave.address);364    await approveExpectSuccess(collectionId, 0, dave, bob.address, 5);365    await approveExpectFail(collectionId, 0, dave, charlie, 6);366  });367368  // Canceled by changing approve logic369  it.skip('Cannot approve for more than total users amount (owned: 100, approval 1: 50 - should succeed, approval 2: 51 - should fail). ReFungible', async () => {370    const collectionId = await createCollectionExpectSuccess({ mode:{ type: 'ReFungible' } });371    const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', dave.address);372    await approveExpectSuccess(collectionId, itemId, dave, bob.address, 50);373    await approveExpectFail(collectionId, itemId, dave, charlie, 51);374  });375});376377describe('Integration Test approve(spender, collection_id, item_id, amount) with collection admin permissions:', () => {378  let alice: IKeyringPair;379  let bob: IKeyringPair;380  let charlie: IKeyringPair;381382  before(async () => {383    await usingApi(async () => {384      alice = privateKey('//Alice');385      bob = privateKey('//Bob');386      charlie = privateKey('//Charlie');387    });388  });389390  it('can be called by collection admin on non-owned item', async () => {391    const collectionId = await createCollectionExpectSuccess();392    const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);393394    await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);395    await adminApproveFromExpectSuccess(collectionId, itemId, bob, alice.address, charlie.address);396  });397});398399describe('Negative Integration Test approve(spender, collection_id, item_id, amount):', () => {400  let alice: IKeyringPair;401  let bob: IKeyringPair;402  let charlie: IKeyringPair;403404  before(async () => {405    await usingApi(async () => {406      alice = privateKey('//Alice');407      bob = privateKey('//Bob');408      charlie = privateKey('//Charlie');409    });410  });411412  it('Approve for a collection that does not exist', async () => {413    await usingApi(async (api: ApiPromise) => {414      // nft415      const nftCollectionCount = await getCreatedCollectionCount(api);416      await approveExpectFail(nftCollectionCount + 1, 1, alice, bob);417      // fungible418      const fungibleCollectionCount = await getCreatedCollectionCount(api);419      await approveExpectFail(fungibleCollectionCount + 1, 0, alice, bob);420      // reFungible421      const reFungibleCollectionCount = await getCreatedCollectionCount(api);422      await approveExpectFail(reFungibleCollectionCount + 1, 1, alice, bob);423    });424  });425426  it('Approve for a collection that was destroyed', async () => {427    // nft428    const nftCollectionId = await createCollectionExpectSuccess();429    await destroyCollectionExpectSuccess(nftCollectionId);430    await approveExpectFail(nftCollectionId, 1, alice, bob);431    // fungible432    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});433    await destroyCollectionExpectSuccess(fungibleCollectionId);434    await approveExpectFail(fungibleCollectionId, 0, alice, bob);435    // reFungible436    const reFungibleCollectionId =437      await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});438    await destroyCollectionExpectSuccess(reFungibleCollectionId);439    await approveExpectFail(reFungibleCollectionId, 1, alice, bob);440  });441442  it('Approve transfer of a token that does not exist', async () => {443    // nft444    const nftCollectionId = await createCollectionExpectSuccess();445    await approveExpectFail(nftCollectionId, 2, alice, bob);446    // reFungible447    const reFungibleCollectionId =448      await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});449    await approveExpectFail(reFungibleCollectionId, 2, alice, bob);450  });451452  it('Approve using the address that does not own the approved token', async () => {453    const nftCollectionId = await createCollectionExpectSuccess();454    // nft455    const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');456    await approveExpectFail(nftCollectionId, newNftTokenId, bob, alice);457    // fungible458    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});459    const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');460    await approveExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice);461    // reFungible462    const reFungibleCollectionId =463      await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});464    const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');465    await approveExpectFail(reFungibleCollectionId, newReFungibleTokenId, bob, alice);466  });467468  it('should fail if approved more ReFungibles than owned', async () => {469    const nftCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});470    const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'ReFungible');471    await transferExpectSuccess(nftCollectionId, newNftTokenId, alice, bob, 100, 'ReFungible');472    await approveExpectSuccess(nftCollectionId, newNftTokenId, bob, alice.address, 100);473    await approveExpectFail(nftCollectionId, newNftTokenId, bob, alice, 101);474  });475476  it('should fail if approved more Fungibles than owned', async () => {477    const nftCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});478    const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'Fungible');479    await transferExpectSuccess(nftCollectionId, newNftTokenId, alice, bob, 10, 'Fungible');480    await approveExpectSuccess(nftCollectionId, newNftTokenId, bob, alice.address, 10);481    await approveExpectFail(nftCollectionId, newNftTokenId, bob, alice, 11);482  });483484  it('fails when called by collection owner on non-owned item when OwnerCanTransfer == false', async () => {485    const collectionId = await createCollectionExpectSuccess();486    const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', bob.address);487    await setCollectionLimitsExpectSuccess(alice, collectionId, {ownerCanTransfer: false});488489    await approveExpectFail(collectionId, itemId, alice, charlie);490  });491});