git.delta.rocks / unique-network / refs/commits / 4e00e0c4cd4e

difftreelog

source

tests/src/approve.test.ts22.5 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);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 getCreatedCollectionCount(api);415      await approveExpectFail(nftCollectionCount + 1, 1, alice, bob);416      // fungible417      const fungibleCollectionCount = await getCreatedCollectionCount(api);418      await approveExpectFail(fungibleCollectionCount + 1, 0, alice, bob);419      // reFungible420      const reFungibleCollectionCount = await getCreatedCollectionCount(api);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});