1234567891011121314151617import {IKeyringPair} from '@polkadot/types/types';18import {ApiPromise} from '@polkadot/api';19import chai from 'chai';20import chaiAsPromised from 'chai-as-promised';21import {default as usingApi} from './substrate/substrate-api';22import {23 approveExpectFail,24 approveExpectSuccess,25 createCollectionExpectSuccess,26 createItemExpectSuccess,27 destroyCollectionExpectSuccess,28 setCollectionLimitsExpectSuccess,29 transferExpectSuccess,30 addCollectionAdminExpectSuccess,31 adminApproveFromExpectFail,32 getCreatedCollectionCount,33 transferFromExpectSuccess,34 transferFromExpectFail,35 requirePallets,36 Pallets,37} from './util/helpers';3839chai.use(chaiAsPromised);4041describe('Integration Test approve(spender, collection_id, item_id, amount):', () => {42 let alice: IKeyringPair;43 let bob: IKeyringPair;44 let charlie: IKeyringPair;4546 before(async () => {47 await usingApi(async (api, privateKeyWrapper) => {48 alice = privateKeyWrapper('//Alice');49 bob = privateKeyWrapper('//Bob');50 charlie = privateKeyWrapper('//Charlie');51 });52 });5354 it('[nft] Execute the extrinsic and check approvedList', async () => {55 const nftCollectionId = await createCollectionExpectSuccess();56 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');57 await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address);58 });5960 it('[fungible] Execute the extrinsic and check approvedList', async () => {61 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});62 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');63 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);64 });6566 it('[refungible] Execute the extrinsic and check approvedList', async function() {67 await requirePallets(this, [Pallets.ReFungible]);6869 const reFungibleCollectionId =70 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});71 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');72 await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address);73 });7475 it('[nft] Remove approval by using 0 amount', async () => {76 const nftCollectionId = await createCollectionExpectSuccess();77 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');78 await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address, 1);79 await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address, 0);80 });8182 it('[fungible] Remove approval by using 0 amount', async () => {83 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});84 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');85 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address, 1);86 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address, 0);87 });8889 it('[refungible] Remove approval by using 0 amount', async function() {90 await requirePallets(this, [Pallets.ReFungible]);9192 const reFungibleCollectionId =93 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});94 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');95 await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address, 1);96 await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address, 0);97 });9899 it('can`t be called by collection owner on non-owned item when OwnerCanTransfer == false', async () => {100 const collectionId = await createCollectionExpectSuccess();101 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', bob.address);102103 await adminApproveFromExpectFail(collectionId, itemId, alice, bob.address, charlie.address);104 });105});106107describe('Normal user can approve other users to transfer:', () => {108 let alice: IKeyringPair;109 let bob: IKeyringPair;110 let charlie: IKeyringPair;111112 before(async () => {113 await usingApi(async (api, privateKeyWrapper) => {114 alice = privateKeyWrapper('//Alice');115 bob = privateKeyWrapper('//Bob');116 charlie = privateKeyWrapper('//Charlie');117 });118 }); 119120 it('NFT', async () => {121 const collectionId = await createCollectionExpectSuccess();122 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', bob.address);123 await approveExpectSuccess(collectionId, itemId, bob, charlie.address);124 });125126 it('Fungible up to an approved amount', async () => {127 const collectionId = await createCollectionExpectSuccess({mode:{type: 'Fungible', decimalPoints: 0}});128 const itemId = await createItemExpectSuccess(alice, collectionId, 'Fungible', bob.address); 129 await approveExpectSuccess(collectionId, itemId, bob, charlie.address);130 });131132 it('ReFungible up to an approved amount', async function() {133 await requirePallets(this, [Pallets.ReFungible]);134135 const collectionId = await createCollectionExpectSuccess({mode:{type: 'ReFungible'}});136 const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', bob.address);137 await approveExpectSuccess(collectionId, itemId, bob, charlie.address);138 });139});140141describe('Approved users can transferFrom up to approved amount:', () => {142 let alice: IKeyringPair;143 let bob: IKeyringPair;144 let charlie: IKeyringPair;145146 before(async () => {147 await usingApi(async (api, privateKeyWrapper) => {148 alice = privateKeyWrapper('//Alice');149 bob = privateKeyWrapper('//Bob');150 charlie = privateKeyWrapper('//Charlie');151 });152 }); 153154 it('NFT', async () => {155 const collectionId = await createCollectionExpectSuccess();156 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', bob.address);157 await approveExpectSuccess(collectionId, itemId, bob, charlie.address);158 await transferFromExpectSuccess(collectionId, itemId, charlie, bob, alice, 1, 'NFT');159 });160161 it('Fungible up to an approved amount', async () => {162 const collectionId = await createCollectionExpectSuccess({mode:{type: 'Fungible', decimalPoints: 0}});163 const itemId = await createItemExpectSuccess(alice, collectionId, 'Fungible', bob.address); 164 await approveExpectSuccess(collectionId, itemId, bob, charlie.address);165 await transferFromExpectSuccess(collectionId, itemId, charlie, bob, alice, 1, 'Fungible');166 });167168 it('ReFungible up to an approved amount', async function() {169 await requirePallets(this, [Pallets.ReFungible]);170171 const collectionId = await createCollectionExpectSuccess({mode:{type: 'ReFungible'}});172 const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', bob.address);173 await approveExpectSuccess(collectionId, itemId, bob, charlie.address);174 await transferFromExpectSuccess(collectionId, itemId, charlie, bob, alice, 1, 'ReFungible');175 });176});177178describe('Approved users cannot use transferFrom to repeat transfers if approved amount was already transferred:', () => {179 let alice: IKeyringPair;180 let bob: IKeyringPair;181 let charlie: IKeyringPair;182183 before(async () => {184 await usingApi(async (api, privateKeyWrapper) => {185 alice = privateKeyWrapper('//Alice');186 bob = privateKeyWrapper('//Bob');187 charlie = privateKeyWrapper('//Charlie');188 });189 }); 190191 it('NFT', async () => {192 const collectionId = await createCollectionExpectSuccess();193 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', bob.address);194 await approveExpectSuccess(collectionId, itemId, bob, charlie.address);195 await transferFromExpectSuccess(collectionId, itemId, charlie, bob, alice, 1, 'NFT');196 await transferFromExpectFail(collectionId, itemId, charlie, bob, alice, 1);197 });198199 it('Fungible up to an approved amount', async () => {200 const collectionId = await createCollectionExpectSuccess({mode:{type: 'Fungible', decimalPoints: 0}});201 const itemId = await createItemExpectSuccess(alice, collectionId, 'Fungible', bob.address); 202 await approveExpectSuccess(collectionId, itemId, bob, charlie.address);203 await transferFromExpectSuccess(collectionId, itemId, charlie, bob, alice, 1, 'Fungible');204 await transferFromExpectFail(collectionId, itemId, charlie, bob, alice, 1);205 });206207 it('ReFungible up to an approved amount', async function() {208 await requirePallets(this, [Pallets.ReFungible]);209210 const collectionId = await createCollectionExpectSuccess({mode:{type: 'ReFungible'}});211 const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', bob.address);212 await approveExpectSuccess(collectionId, itemId, bob, charlie.address);213 await transferFromExpectSuccess(collectionId, itemId, charlie, bob, alice, 1, 'ReFungible');214 await transferFromExpectFail(collectionId, itemId, charlie, bob, alice, 1);215 });216});217218describe('Approved amount decreases by the transferred amount.:', () => {219 let alice: IKeyringPair;220 let bob: IKeyringPair;221 let charlie: IKeyringPair;222 let dave: IKeyringPair;223224 before(async () => {225 await usingApi(async (api, privateKeyWrapper) => {226 alice = privateKeyWrapper('//Alice');227 bob = privateKeyWrapper('//Bob');228 charlie = privateKeyWrapper('//Charlie');229 dave = privateKeyWrapper('//Dave');230 });231 }); 232233 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 () => {234 const collectionId = await createCollectionExpectSuccess({mode:{type: 'Fungible', decimalPoints: 0}});235 const itemId = await createItemExpectSuccess(alice, collectionId, 'Fungible', alice.address); 236 await approveExpectSuccess(collectionId, itemId, alice, bob.address, 10);237 await transferFromExpectSuccess(collectionId, itemId, bob, alice, charlie, 2, 'Fungible');238 await transferFromExpectSuccess(collectionId, itemId, bob, alice, dave, 8, 'Fungible');239 });240});241242describe('User may clear the approvals to approving for 0 amount:', () => {243 let alice: IKeyringPair;244 let bob: IKeyringPair;245 let charlie: IKeyringPair;246247 before(async () => {248 await usingApi(async (api, privateKeyWrapper) => {249 alice = privateKeyWrapper('//Alice');250 bob = privateKeyWrapper('//Bob');251 charlie = privateKeyWrapper('//Charlie');252 });253 });254255 it('NFT', async () => {256 const collectionId = await createCollectionExpectSuccess();257 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT');258 await approveExpectSuccess(collectionId, itemId, alice, bob.address, 1);259 await approveExpectSuccess(collectionId, itemId, alice, bob.address, 0);260 await transferFromExpectFail(collectionId, itemId, bob, bob, charlie, 1);261 });262263 it('Fungible', async () => {264 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});265 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');266 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address, 1);267 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address, 0);268 await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, bob, charlie, 1);269 });270271 it('ReFungible', async function() {272 await requirePallets(this, [Pallets.ReFungible]);273274 const reFungibleCollectionId =275 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});276 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');277 await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address, 1);278 await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address, 0);279 await transferFromExpectFail(reFungibleCollectionId, newReFungibleTokenId, bob, bob, charlie, 1);280 });281});282283describe('User cannot approve for the amount greater than they own:', () => {284 let alice: IKeyringPair;285 let bob: IKeyringPair;286 let charlie: IKeyringPair;287288 before(async () => {289 await usingApi(async (api, privateKeyWrapper) => {290 alice = privateKeyWrapper('//Alice');291 bob = privateKeyWrapper('//Bob');292 charlie = privateKeyWrapper('//Charlie');293 });294 });295296 it('1 for NFT', async () => {297 const collectionId = await createCollectionExpectSuccess();298 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', bob.address);299 await approveExpectFail(collectionId, itemId, bob, charlie, 2);300 });301302 it('Fungible', async () => {303 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});304 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');305 await approveExpectFail(fungibleCollectionId, newFungibleTokenId, bob, charlie, 11);306 });307308 it('ReFungible', async function() {309 await requirePallets(this, [Pallets.ReFungible]);310311 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});312 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');313 await approveExpectFail(reFungibleCollectionId, newReFungibleTokenId, bob, charlie, 101);314 });315});316317describe('Administrator and collection owner do not need approval in order to execute TransferFrom (with owner_can_transfer_flag = true):', () => {318 let alice: IKeyringPair;319 let bob: IKeyringPair;320 let charlie: IKeyringPair;321 let dave: IKeyringPair;322323 before(async () => {324 await usingApi(async (api, privateKeyWrapper) => {325 alice = privateKeyWrapper('//Alice');326 bob = privateKeyWrapper('//Bob');327 charlie = privateKeyWrapper('//Charlie');328 dave = privateKeyWrapper('//Dave');329 });330 }); 331332 it('NFT', async () => {333 const collectionId = await createCollectionExpectSuccess();334 await setCollectionLimitsExpectSuccess(alice, collectionId, {ownerCanTransfer: true});335 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', charlie.address);336 await transferFromExpectSuccess(collectionId, itemId, alice, charlie, dave, 1, 'NFT');337 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);338 await transferFromExpectSuccess(collectionId, itemId, bob, dave, alice, 1, 'NFT');339 });340341 it('Fungible up to an approved amount', async () => {342 const collectionId = await createCollectionExpectSuccess({mode:{type: 'Fungible', decimalPoints: 0}});343 await setCollectionLimitsExpectSuccess(alice, collectionId, {ownerCanTransfer: true});344 const itemId = await createItemExpectSuccess(alice, collectionId, 'Fungible', charlie.address); 345 await transferFromExpectSuccess(collectionId, itemId, alice, charlie, dave, 1, 'Fungible');346 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);347 await transferFromExpectSuccess(collectionId, itemId, bob, dave, alice, 1, 'Fungible');348 });349350 it('ReFungible up to an approved amount', async function() {351 await requirePallets(this, [Pallets.ReFungible]);352353 const collectionId = await createCollectionExpectSuccess({mode:{type: 'ReFungible'}});354 await setCollectionLimitsExpectSuccess(alice, collectionId, {ownerCanTransfer: true});355 const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', charlie.address);356 await transferFromExpectSuccess(collectionId, itemId, alice, charlie, dave, 1, 'ReFungible');357 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);358 await transferFromExpectSuccess(collectionId, itemId, bob, dave, alice, 1, 'ReFungible');359 });360});361362describe('Repeated approvals add up', () => {363 let alice: IKeyringPair;364 let bob: IKeyringPair;365 let charlie: IKeyringPair;366 let dave: IKeyringPair;367368 before(async () => {369 await usingApi(async (api, privateKeyWrapper) => {370 alice = privateKeyWrapper('//Alice');371 bob = privateKeyWrapper('//Bob');372 charlie = privateKeyWrapper('//Charlie');373 dave = privateKeyWrapper('//Dave');374 });375 }); 376377 it.skip('Owned 10, approval 1: 1, approval 2: 1, resulting approved value: 2. Fungible', async () => {378 const collectionId = await createCollectionExpectSuccess({mode:{type: 'Fungible', decimalPoints: 0}});379 await createItemExpectSuccess(alice, collectionId, 'Fungible', alice.address);380 await approveExpectSuccess(collectionId, 0, alice, bob.address, 1);381 await approveExpectSuccess(collectionId, 0, alice, charlie.address, 1);382 383 384 385 });386387 it.skip('Owned 10, approval 1: 1, approval 2: 1, resulting approved value: 2. ReFungible', async () => {388 const collectionId = await createCollectionExpectSuccess({mode:{type: 'ReFungible'}});389 const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', alice.address);390 await approveExpectSuccess(collectionId, itemId, alice, bob.address, 1);391 await approveExpectSuccess(collectionId, itemId, alice, charlie.address, 1);392 393 394 395 });396397 398 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 () => {399 const collectionId = await createCollectionExpectSuccess({mode:{type: 'Fungible', decimalPoints: 0}});400 await createItemExpectSuccess(alice, collectionId, 'Fungible', dave.address);401 await approveExpectSuccess(collectionId, 0, dave, bob.address, 5);402 await approveExpectFail(collectionId, 0, dave, charlie, 6);403 });404405 406 it.skip('Cannot approve for more than total users amount (owned: 100, approval 1: 50 - should succeed, approval 2: 51 - should fail). ReFungible', async () => {407 const collectionId = await createCollectionExpectSuccess({mode:{type: 'ReFungible'}});408 const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', dave.address);409 await approveExpectSuccess(collectionId, itemId, dave, bob.address, 50);410 await approveExpectFail(collectionId, itemId, dave, charlie, 51);411 });412});413414describe('Integration Test approve(spender, collection_id, item_id, amount) with collection admin permissions:', () => {415 let alice: IKeyringPair;416 let bob: IKeyringPair;417 let charlie: IKeyringPair;418419 before(async () => {420 await usingApi(async (api, privateKeyWrapper) => {421 alice = privateKeyWrapper('//Alice');422 bob = privateKeyWrapper('//Bob');423 charlie = privateKeyWrapper('//Charlie');424 });425 });426427 it('can be called by collection admin on non-owned item', async () => {428 const collectionId = await createCollectionExpectSuccess();429 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);430431 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);432 await adminApproveFromExpectFail(collectionId, itemId, bob, alice.address, charlie.address);433 });434});435436describe('Negative Integration Test approve(spender, collection_id, item_id, amount):', () => {437 let alice: IKeyringPair;438 let bob: IKeyringPair;439 let charlie: IKeyringPair;440441 before(async () => {442 await usingApi(async (api, privateKeyWrapper) => {443 alice = privateKeyWrapper('//Alice');444 bob = privateKeyWrapper('//Bob');445 charlie = privateKeyWrapper('//Charlie');446 });447 });448449 it('[nft] Approve for a collection that does not exist', async () => {450 await usingApi(async (api: ApiPromise) => {451 const nftCollectionCount = await getCreatedCollectionCount(api);452 await approveExpectFail(nftCollectionCount + 1, 1, alice, bob);453 });454 });455456 it('[fungible] Approve for a collection that does not exist', async () => {457 await usingApi(async (api: ApiPromise) => {458 const fungibleCollectionCount = await getCreatedCollectionCount(api);459 await approveExpectFail(fungibleCollectionCount + 1, 0, alice, bob);460 });461 });462463 it('[refungible] Approve for a collection that does not exist', async function() {464 await requirePallets(this, [Pallets.ReFungible]);465466 await usingApi(async (api: ApiPromise) => {467 const reFungibleCollectionCount = await getCreatedCollectionCount(api);468 await approveExpectFail(reFungibleCollectionCount + 1, 1, alice, bob);469 });470 });471472 it('[nft] Approve for a collection that was destroyed', async () => {473 const nftCollectionId = await createCollectionExpectSuccess();474 await destroyCollectionExpectSuccess(nftCollectionId);475 await approveExpectFail(nftCollectionId, 1, alice, bob);476 });477478 it('Approve for a collection that was destroyed', async () => {479 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});480 await destroyCollectionExpectSuccess(fungibleCollectionId);481 await approveExpectFail(fungibleCollectionId, 0, alice, bob);482 });483484 it('[refungible] Approve for a collection that was destroyed', async function() {485 await requirePallets(this, [Pallets.ReFungible]);486487 const reFungibleCollectionId =488 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});489 await destroyCollectionExpectSuccess(reFungibleCollectionId);490 await approveExpectFail(reFungibleCollectionId, 1, alice, bob);491 });492493 it('[nft] Approve transfer of a token that does not exist', async () => {494 const nftCollectionId = await createCollectionExpectSuccess();495 await approveExpectFail(nftCollectionId, 2, alice, bob);496 });497498 it('[refungible] Approve transfer of a token that does not exist', async function() {499 await requirePallets(this, [Pallets.ReFungible]);500501 const reFungibleCollectionId =502 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});503 await approveExpectFail(reFungibleCollectionId, 2, alice, bob);504 });505506 it('[nft] Approve using the address that does not own the approved token', async () => {507 const nftCollectionId = await createCollectionExpectSuccess();508 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');509 await approveExpectFail(nftCollectionId, newNftTokenId, bob, alice);510 });511512 it('[fungible] Approve using the address that does not own the approved token', async () => {513 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});514 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');515 await approveExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice);516 });517518 it('[refungible] Approve using the address that does not own the approved token', async function() {519 await requirePallets(this, [Pallets.ReFungible]);520521 const reFungibleCollectionId =522 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});523 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');524 await approveExpectFail(reFungibleCollectionId, newReFungibleTokenId, bob, alice);525 });526527 it('should fail if approved more ReFungibles than owned', async function() {528 await requirePallets(this, [Pallets.ReFungible]);529530 const nftCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});531 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'ReFungible');532 await transferExpectSuccess(nftCollectionId, newNftTokenId, alice, bob, 100, 'ReFungible');533 await approveExpectSuccess(nftCollectionId, newNftTokenId, bob, alice.address, 100);534 await approveExpectFail(nftCollectionId, newNftTokenId, bob, alice, 101);535 });536537 it('should fail if approved more Fungibles than owned', async () => {538 const nftCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});539 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'Fungible');540 await transferExpectSuccess(nftCollectionId, newNftTokenId, alice, bob, 10, 'Fungible');541 await approveExpectSuccess(nftCollectionId, newNftTokenId, bob, alice.address, 10);542 await approveExpectFail(nftCollectionId, newNftTokenId, bob, alice, 11);543 });544545 it('fails when called by collection owner on non-owned item when OwnerCanTransfer == false', async () => {546 const collectionId = await createCollectionExpectSuccess();547 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', bob.address);548 await setCollectionLimitsExpectSuccess(alice, collectionId, {ownerCanTransfer: false});549550 await approveExpectFail(collectionId, itemId, alice, charlie);551 });552});