From a5bd6fad4f0f209f332ccd056bfd7e609171d354 Mon Sep 17 00:00:00 2001 From: Fahrrader Date: Fri, 07 Oct 2022 17:47:35 +0000 Subject: [PATCH] tests(rmrk+outdated): refactor old helpers and rmrk to get rid of warnings --- --- a/tests/src/deprecated-helpers/helpers.ts +++ b/tests/src/deprecated-helpers/helpers.ts @@ -463,7 +463,7 @@ } export async function createCollectionExpectSuccess(params: Partial = {}): Promise { - const {name, description, mode, tokenPrefix} = {...defaultCreateCollectionParams, ...params}; + const {name, description, tokenPrefix} = {...defaultCreateCollectionParams, ...params}; let collectionId = 0; await usingApi(async (api, privateKeyWrapper) => { @@ -763,7 +763,7 @@ } export async function confirmSponsorshipByKeyExpectSuccess(collectionId: number, sender: IKeyringPair) { - await usingApi(async (api, privateKeyWrapper) => { + await usingApi(async (api) => { // Run the transaction const tx = api.tx.unique.confirmSponsorship(collectionId); @@ -1764,11 +1764,11 @@ return (await api.rpc.unique.collectionById(collectionId)).unwrap(); } -export const describe_xcm = ( +/*export const describe_xcm = ( process.env.RUN_XCM_TESTS ? describe : describe.skip -); +);*/ export async function waitNewBlocks(blocksCount = 1): Promise { await usingApi(async (api) => { --- /dev/null +++ b/tests/src/rmrk/acceptNft.seqtest.ts @@ -0,0 +1,108 @@ +import {expect} from 'chai'; +import {getApiConnection} from '../substrate/substrate-api'; +import { + createCollection, + mintNft, + sendNft, + acceptNft, +} from './util/tx'; +import {NftIdTuple} from './util/fetch'; +import {isNftChildOfAnother, expectTxFailure} from './util/helpers'; +import {requirePallets, Pallets} from '../deprecated-helpers/helpers'; + +describe('integration test: accept NFT', () => { + let api: any; + before(async function() { + api = await getApiConnection(); + await requirePallets(this, [Pallets.RmrkCore]); + }); + + + const alice = '//Alice'; + const bob = '//Bob'; + + const createTestCollection = async (issuerUri: string) => { + return await createCollection( + api, + issuerUri, + 'accept-metadata', + null, + 'acpt', + ); + }; + + it('accept NFT', async () => { + const ownerAlice = alice; + const ownerBob = bob; + + const aliceCollectionId = await createTestCollection(alice); + const bobCollectionId = await createTestCollection(bob); + + const parentNftId = await mintNft(api, alice, ownerAlice, aliceCollectionId, 'parent-nft-metadata'); + const childNftId = await mintNft(api, bob, ownerBob, bobCollectionId, 'child-nft-metadata'); + + const newOwnerNFT: NftIdTuple = [aliceCollectionId, parentNftId]; + + await sendNft(api, 'pending', ownerBob, bobCollectionId, childNftId, newOwnerNFT); + await acceptNft(api, alice, bobCollectionId, childNftId, newOwnerNFT); + + const isChild = await isNftChildOfAnother(api, bobCollectionId, childNftId, newOwnerNFT); + expect(isChild).to.be.true; + }); + + it('[negative] unable to accept NFT by a not-an-owner', async () => { + const ownerAlice = alice; + const ownerBob = bob; + + const aliceCollectionId = await createTestCollection(alice); + const bobCollectionId = await createTestCollection(bob); + + const parentNftId = await mintNft(api, alice, ownerAlice, aliceCollectionId, 'parent-nft-metadata'); + const childNftId = await mintNft(api, bob, ownerBob, bobCollectionId, 'child-nft-metadata'); + + const newOwnerNFT: NftIdTuple = [aliceCollectionId, parentNftId]; + + await sendNft(api, 'pending', ownerBob, bobCollectionId, childNftId, newOwnerNFT); + const tx = acceptNft(api, bob, bobCollectionId, childNftId, newOwnerNFT); + + await expectTxFailure(/rmrkCore\.NoPermission/, tx); + }); + + it('[negative] unable to accept non-existing NFT', async () => { + const collectionId = 0; + const maxNftId = 0xFFFFFFFF; + + const owner = alice; + const aliceCollectionId = await createTestCollection(alice); + + const parentNftId = await mintNft(api, alice, owner, aliceCollectionId, 'parent-nft-metadata'); + + const newOwnerNFT: NftIdTuple = [aliceCollectionId, parentNftId]; + + const tx = acceptNft(api, alice, collectionId, maxNftId, newOwnerNFT); + + await expectTxFailure(/rmrkCore\.NoAvailableNftId/, tx); + }); + + it('[negative] unable to accept NFT which is not sent', async () => { + const ownerAlice = alice; + const ownerBob = bob; + + const aliceCollectionId = await createTestCollection(alice); + const bobCollectionId = await createTestCollection(bob); + + const parentNftId = await mintNft(api, alice, ownerAlice, aliceCollectionId, 'parent-nft-metadata'); + const childNftId = await mintNft(api, bob, ownerBob, bobCollectionId, 'child-nft-metadata'); + + const newOwnerNFT: NftIdTuple = [aliceCollectionId, parentNftId]; + + const tx = acceptNft(api, alice, bobCollectionId, childNftId, newOwnerNFT); + + await expectTxFailure(/rmrkCore\.NoPermission/, tx); + + const isChild = await isNftChildOfAnother(api, bobCollectionId, childNftId, newOwnerNFT); + expect(isChild).to.be.false; + }); + + after(() => { api.disconnect(); }); +}); --- a/tests/src/rmrk/acceptNft.test.ts +++ /dev/null @@ -1,108 +0,0 @@ -import {expect} from 'chai'; -import {getApiConnection} from '../substrate/substrate-api'; -import { - createCollection, - mintNft, - sendNft, - acceptNft, -} from './util/tx'; -import {NftIdTuple} from './util/fetch'; -import {isNftChildOfAnother, expectTxFailure} from './util/helpers'; -import {requirePallets, Pallets} from '../deprecated-helpers/helpers'; - -describe('integration test: accept NFT', () => { - let api: any; - before(async function() { - api = await getApiConnection(); - await requirePallets(this, [Pallets.RmrkCore]); - }); - - - const alice = '//Alice'; - const bob = '//Bob'; - - const createTestCollection = async (issuerUri: string) => { - return await createCollection( - api, - issuerUri, - 'accept-metadata', - null, - 'acpt', - ); - }; - - it('accept NFT', async () => { - const ownerAlice = alice; - const ownerBob = bob; - - const aliceCollectionId = await createTestCollection(alice); - const bobCollectionId = await createTestCollection(bob); - - const parentNftId = await mintNft(api, alice, ownerAlice, aliceCollectionId, 'parent-nft-metadata'); - const childNftId = await mintNft(api, bob, ownerBob, bobCollectionId, 'child-nft-metadata'); - - const newOwnerNFT: NftIdTuple = [aliceCollectionId, parentNftId]; - - await sendNft(api, 'pending', ownerBob, bobCollectionId, childNftId, newOwnerNFT); - await acceptNft(api, alice, bobCollectionId, childNftId, newOwnerNFT); - - const isChild = await isNftChildOfAnother(api, bobCollectionId, childNftId, newOwnerNFT); - expect(isChild).to.be.true; - }); - - it('[negative] unable to accept NFT by a not-an-owner', async () => { - const ownerAlice = alice; - const ownerBob = bob; - - const aliceCollectionId = await createTestCollection(alice); - const bobCollectionId = await createTestCollection(bob); - - const parentNftId = await mintNft(api, alice, ownerAlice, aliceCollectionId, 'parent-nft-metadata'); - const childNftId = await mintNft(api, bob, ownerBob, bobCollectionId, 'child-nft-metadata'); - - const newOwnerNFT: NftIdTuple = [aliceCollectionId, parentNftId]; - - await sendNft(api, 'pending', ownerBob, bobCollectionId, childNftId, newOwnerNFT); - const tx = acceptNft(api, bob, bobCollectionId, childNftId, newOwnerNFT); - - await expectTxFailure(/rmrkCore\.NoPermission/, tx); - }); - - it('[negative] unable to accept non-existing NFT', async () => { - const collectionId = 0; - const maxNftId = 0xFFFFFFFF; - - const owner = alice; - const aliceCollectionId = await createTestCollection(alice); - - const parentNftId = await mintNft(api, alice, owner, aliceCollectionId, 'parent-nft-metadata'); - - const newOwnerNFT: NftIdTuple = [aliceCollectionId, parentNftId]; - - const tx = acceptNft(api, alice, collectionId, maxNftId, newOwnerNFT); - - await expectTxFailure(/rmrkCore\.NoAvailableNftId/, tx); - }); - - it('[negative] unable to accept NFT which is not sent', async () => { - const ownerAlice = alice; - const ownerBob = bob; - - const aliceCollectionId = await createTestCollection(alice); - const bobCollectionId = await createTestCollection(bob); - - const parentNftId = await mintNft(api, alice, ownerAlice, aliceCollectionId, 'parent-nft-metadata'); - const childNftId = await mintNft(api, bob, ownerBob, bobCollectionId, 'child-nft-metadata'); - - const newOwnerNFT: NftIdTuple = [aliceCollectionId, parentNftId]; - - const tx = acceptNft(api, alice, bobCollectionId, childNftId, newOwnerNFT); - - await expectTxFailure(/rmrkCore\.NoPermission/, tx); - - const isChild = await isNftChildOfAnother(api, bobCollectionId, childNftId, newOwnerNFT); - expect(isChild).to.be.false; - }); - - after(() => { api.disconnect(); }); -}); --- /dev/null +++ b/tests/src/rmrk/addResource.seqtest.ts @@ -0,0 +1,438 @@ +import {expect} from 'chai'; +import {getApiConnection} from '../substrate/substrate-api'; +import {NftIdTuple} from './util/fetch'; +import {expectTxFailure, getResourceById} from './util/helpers'; +import { + addNftBasicResource, + acceptNftResource, + createCollection, + mintNft, + sendNft, + addNftSlotResource, + addNftComposableResource, +} from './util/tx'; +import {RmrkTraitsResourceResourceInfo as ResourceInfo} from '@polkadot/types/lookup'; +import {requirePallets, Pallets} from '../deprecated-helpers/helpers'; + +describe('integration test: add NFT resource', () => { + const alice = '//Alice'; + const bob = '//Bob'; + const src = 'test-res-src'; + const metadata = 'test-res-metadata'; + const license = 'test-res-license'; + const thumb = 'test-res-thumb'; + + const nonexistentId = 99999; + + let api: any; + before(async function() { + api = await getApiConnection(); + await requirePallets(this, [Pallets.RmrkCore]); + }); + + it('add resource', async () => { + const collectionIdAlice = await createCollection( + api, + alice, + 'test-metadata', + null, + 'test-symbol', + ); + + const nftAlice = await mintNft( + api, + alice, + alice, + collectionIdAlice, + 'nft-metadata', + ); + + await addNftBasicResource( + api, + alice, + 'added', + collectionIdAlice, + nftAlice, + src, + metadata, + license, + thumb, + ); + }); + + it('add a resource to the nested NFT', async () => { + const collectionIdAlice = await createCollection( + api, + alice, + 'test-metadata', + null, + 'test-symbol', + ); + + const parentNftId = await mintNft(api, alice, alice, collectionIdAlice, 'parent-nft-metadata'); + const childNftId = await mintNft(api, alice, alice, collectionIdAlice, 'child-nft-metadata'); + + const newOwnerNFT: NftIdTuple = [collectionIdAlice, parentNftId]; + + await sendNft(api, 'sent', alice, collectionIdAlice, childNftId, newOwnerNFT); + + await addNftBasicResource( + api, + alice, + 'added', + collectionIdAlice, + childNftId, + src, + metadata, + license, + thumb, + ); + }); + + it('add multiple resources', async () => { + const collectionIdAlice = await createCollection( + api, + alice, + 'test-metadata', + null, + 'test-symbol', + ); + + const nftAlice = await mintNft( + api, + alice, + alice, + collectionIdAlice, + 'nft-metadata', + ); + + const baseId = 42; + const slotId = 10; + const parts = [0, 5, 2]; + + const resourcesInfo = []; + const resourceNum = 4; + + const checkResource = async (resource: ResourceInfo, resType: string, expectedId: number, expected: { + src: string, + metadata: string, + license: string, + thumb: string + }) => { + + // FIXME A workaround. It seems it is a PolkadotJS bug. + // All of the following are `false`. + // + // console.log('>>> basic:', resource.resource.isBasic); + // console.log('>>> composable:', resource.resource.isComposable); + // console.log('>>> slot:', resource.resource.isSlot); + const resourceJson = (resource.resource.toHuman() as any)[resType]; + + expect(resource.id.toNumber(), 'Error: Invalid resource Id') + .to.be.eq(expectedId); + + expect(resourceJson.src, 'Error: Invalid resource src') + .to.be.eq(expected.src); + expect(resourceJson.metadata, 'Error: Invalid resource metadata') + .to.be.eq(expected.metadata); + expect(resourceJson.license, 'Error: Invalid resource license') + .to.be.eq(expected.license); + expect(resourceJson.thumb, 'Error: Invalid resource thumb') + .to.be.eq(expected.thumb); + }; + + for (let i = 0; i < resourceNum; i++) { + resourcesInfo.push({ + src: src + 'r-' + i, + metadata: metadata + 'r-' + i, + license: license + 'r-' + i, + thumb: thumb + 'r-' + i, + }); + } + + const firstBasicResourceId = await addNftBasicResource( + api, + alice, + 'added', + collectionIdAlice, + nftAlice, + resourcesInfo[0].src, + resourcesInfo[0].metadata, + resourcesInfo[0].license, + resourcesInfo[0].thumb, + ); + + const secondBasicResourceId = await addNftBasicResource( + api, + alice, + 'added', + collectionIdAlice, + nftAlice, + resourcesInfo[1].src, + resourcesInfo[1].metadata, + resourcesInfo[1].license, + resourcesInfo[1].thumb, + ); + + const composableResourceId = await addNftComposableResource( + api, + alice, + 'added', + collectionIdAlice, + nftAlice, + parts, + baseId, + resourcesInfo[2].src, + resourcesInfo[2].metadata, + resourcesInfo[2].license, + resourcesInfo[2].thumb, + ); + + const slotResourceId = await addNftSlotResource( + api, + alice, + 'added', + collectionIdAlice, + nftAlice, + baseId, + slotId, + resourcesInfo[3].src, + resourcesInfo[3].metadata, + resourcesInfo[3].license, + resourcesInfo[3].thumb, + ); + + const firstResource = await getResourceById(api, collectionIdAlice, nftAlice, firstBasicResourceId); + await checkResource(firstResource, 'Basic', firstBasicResourceId, resourcesInfo[0]); + + const secondResource = await getResourceById(api, collectionIdAlice, nftAlice, secondBasicResourceId); + await checkResource(secondResource, 'Basic', secondBasicResourceId, resourcesInfo[1]); + + const composableResource = await getResourceById(api, collectionIdAlice, nftAlice, composableResourceId); + await checkResource(composableResource, 'Composable', composableResourceId, resourcesInfo[2]); + + const slotResource = await getResourceById(api, collectionIdAlice, nftAlice, slotResourceId); + await checkResource(slotResource, 'Slot', slotResourceId, resourcesInfo[3]); + }); + + it('[negative]: unable to add a resource to the non-existing NFT', async () => { + const collectionIdAlice = await createCollection( + api, + alice, + 'test-metadata', + null, + 'test-symbol', + ); + + const tx = addNftBasicResource( + api, + alice, + 'added', + collectionIdAlice, + nonexistentId, + src, + metadata, + license, + thumb, + ); + + await expectTxFailure(/rmrkCore\.NoAvailableNftId/, tx); + }); + + it('[negative]: unable to add a resource by a not-an-owner user', async () => { + const collectionIdAlice = await createCollection( + api, + alice, + 'test-metadata', + null, + 'test-symbol', + ); + + const nftAlice = await mintNft( + api, + alice, + alice, + collectionIdAlice, + 'nft-metadata', + ); + + const tx = addNftBasicResource( + api, + bob, + 'added', + collectionIdAlice, + nftAlice, + src, + metadata, + license, + thumb, + ); + + await expectTxFailure(/rmrkCore\.NoPermission/, tx); + }); + + it('[negative]: unable to add a resource to the nested NFT if it isnt root owned by the caller', async () => { + const collectionIdAlice = await createCollection( + api, + alice, + 'test-metadata', + null, + 'test-symbol', + ); + + const parentNftId = await mintNft(api, alice, alice, collectionIdAlice, 'parent-nft-metadata'); + const childNftId = await mintNft(api, alice, alice, collectionIdAlice, 'child-nft-metadata'); + + const newOwnerNFT: NftIdTuple = [collectionIdAlice, parentNftId]; + + await sendNft(api, 'sent', alice, collectionIdAlice, childNftId, newOwnerNFT); + + const tx = addNftBasicResource( + api, + bob, + 'added', + collectionIdAlice, + childNftId, + src, + metadata, + license, + thumb, + ); + + await expectTxFailure(/rmrkCore\.NoPermission/, tx); + }); + + it('accept resource', async () => { + const collectionIdBob = await createCollection( + api, + bob, + 'test-metadata', + null, + 'test-symbol', + ); + + const nftAlice = await mintNft( + api, + bob, + alice, + collectionIdBob, + 'nft-metadata', + ); + + const resourceId = await addNftBasicResource( + api, + bob, + 'pending', + collectionIdBob, + nftAlice, + src, + metadata, + license, + thumb, + ); + + await acceptNftResource(api, alice, collectionIdBob, nftAlice, resourceId); + }); + + it('[negative]: unable to accept a non-existing resource', async () => { + const collectionIdBob = await createCollection( + api, + bob, + 'test-metadata', + null, + 'test-symbol', + ); + + const nftAlice = await mintNft( + api, + bob, + alice, + collectionIdBob, + 'nft-metadata', + ); + + const tx = acceptNftResource(api, alice, collectionIdBob, nftAlice, nonexistentId); + await expectTxFailure(/rmrkCore\.ResourceDoesntExist/, tx); + }); + + it('[negative]: unable to accept a resource by a not-an-NFT-owner user', async () => { + const collectionIdBob = await createCollection( + api, + bob, + 'test-metadata', + null, + 'test-symbol', + ); + + const nftAlice = await mintNft( + api, + bob, + alice, + collectionIdBob, + 'nft-metadata', + ); + + const resourceId = await addNftBasicResource( + api, + bob, + 'pending', + collectionIdBob, + nftAlice, + src, + metadata, + license, + thumb, + ); + + const tx = acceptNftResource(api, bob, collectionIdBob, nftAlice, resourceId); + + await expectTxFailure(/rmrkCore\.NoPermission/, tx); + }); + + it('[negative]: unable to accept a resource to a non-target NFT', async () => { + const collectionIdBob = await createCollection( + api, + bob, + 'test-metadata', + null, + 'test-symbol', + ); + + const nftAlice = await mintNft( + api, + bob, + alice, + collectionIdBob, + 'nft-metadata', + ); + + const wrongNft = await mintNft( + api, + bob, + alice, + collectionIdBob, + 'nft-metadata', + ); + + const resourceId = await addNftBasicResource( + api, + bob, + 'pending', + collectionIdBob, + nftAlice, + src, + metadata, + license, + thumb, + ); + + const tx = acceptNftResource(api, bob, collectionIdBob, wrongNft, resourceId); + + await expectTxFailure(/rmrkCore\.ResourceDoesntExist/, tx); + }); + + + after(() => { + api.disconnect(); + }); +}); --- a/tests/src/rmrk/addResource.test.ts +++ /dev/null @@ -1,438 +0,0 @@ -import {expect} from 'chai'; -import {getApiConnection} from '../substrate/substrate-api'; -import {NftIdTuple} from './util/fetch'; -import {expectTxFailure, getResourceById} from './util/helpers'; -import { - addNftBasicResource, - acceptNftResource, - createCollection, - mintNft, - sendNft, - addNftSlotResource, - addNftComposableResource, -} from './util/tx'; -import {RmrkTraitsResourceResourceInfo as ResourceInfo} from '@polkadot/types/lookup'; -import {requirePallets, Pallets} from '../deprecated-helpers/helpers'; - -describe('integration test: add NFT resource', () => { - const Alice = '//Alice'; - const Bob = '//Bob'; - const src = 'test-res-src'; - const metadata = 'test-res-metadata'; - const license = 'test-res-license'; - const thumb = 'test-res-thumb'; - - const nonexistentId = 99999; - - let api: any; - before(async function() { - api = await getApiConnection(); - await requirePallets(this, [Pallets.RmrkCore]); - }); - - it('add resource', async () => { - const collectionIdAlice = await createCollection( - api, - Alice, - 'test-metadata', - null, - 'test-symbol', - ); - - const nftAlice = await mintNft( - api, - Alice, - Alice, - collectionIdAlice, - 'nft-metadata', - ); - - await addNftBasicResource( - api, - Alice, - 'added', - collectionIdAlice, - nftAlice, - src, - metadata, - license, - thumb, - ); - }); - - it('add a resource to the nested NFT', async () => { - const collectionIdAlice = await createCollection( - api, - Alice, - 'test-metadata', - null, - 'test-symbol', - ); - - const parentNftId = await mintNft(api, Alice, Alice, collectionIdAlice, 'parent-nft-metadata'); - const childNftId = await mintNft(api, Alice, Alice, collectionIdAlice, 'child-nft-metadata'); - - const newOwnerNFT: NftIdTuple = [collectionIdAlice, parentNftId]; - - await sendNft(api, 'sent', Alice, collectionIdAlice, childNftId, newOwnerNFT); - - await addNftBasicResource( - api, - Alice, - 'added', - collectionIdAlice, - childNftId, - src, - metadata, - license, - thumb, - ); - }); - - it('add multiple resources', async () => { - const collectionIdAlice = await createCollection( - api, - Alice, - 'test-metadata', - null, - 'test-symbol', - ); - - const nftAlice = await mintNft( - api, - Alice, - Alice, - collectionIdAlice, - 'nft-metadata', - ); - - const baseId = 42; - const slotId = 10; - const parts = [0, 5, 2]; - - const resourcesInfo = []; - const resourceNum = 4; - - const checkResource = async (resource: ResourceInfo, resType: string, expectedId: number, expected: { - src: string, - metadata: string, - license: string, - thumb: string - }) => { - - // FIXME A workaround. It seems it is a PolkadotJS bug. - // All of the following are `false`. - // - // console.log('>>> basic:', resource.resource.isBasic); - // console.log('>>> composable:', resource.resource.isComposable); - // console.log('>>> slot:', resource.resource.isSlot); - const resourceJson = (resource.resource.toHuman() as any)[resType]; - - expect(resource.id.toNumber(), 'Error: Invalid resource Id') - .to.be.eq(expectedId); - - expect(resourceJson.src, 'Error: Invalid resource src') - .to.be.eq(expected.src); - expect(resourceJson.metadata, 'Error: Invalid resource metadata') - .to.be.eq(expected.metadata); - expect(resourceJson.license, 'Error: Invalid resource license') - .to.be.eq(expected.license); - expect(resourceJson.thumb, 'Error: Invalid resource thumb') - .to.be.eq(expected.thumb); - }; - - for (let i = 0; i < resourceNum; i++) { - resourcesInfo.push({ - src: src + 'r-' + i, - metadata: metadata + 'r-' + i, - license: license + 'r-' + i, - thumb: thumb + 'r-' + i, - }); - } - - const firstBasicResourceId = await addNftBasicResource( - api, - Alice, - 'added', - collectionIdAlice, - nftAlice, - resourcesInfo[0].src, - resourcesInfo[0].metadata, - resourcesInfo[0].license, - resourcesInfo[0].thumb, - ); - - const secondBasicResourceId = await addNftBasicResource( - api, - Alice, - 'added', - collectionIdAlice, - nftAlice, - resourcesInfo[1].src, - resourcesInfo[1].metadata, - resourcesInfo[1].license, - resourcesInfo[1].thumb, - ); - - const composableResourceId = await addNftComposableResource( - api, - Alice, - 'added', - collectionIdAlice, - nftAlice, - parts, - baseId, - resourcesInfo[2].src, - resourcesInfo[2].metadata, - resourcesInfo[2].license, - resourcesInfo[2].thumb, - ); - - const slotResourceId = await addNftSlotResource( - api, - Alice, - 'added', - collectionIdAlice, - nftAlice, - baseId, - slotId, - resourcesInfo[3].src, - resourcesInfo[3].metadata, - resourcesInfo[3].license, - resourcesInfo[3].thumb, - ); - - const firstResource = await getResourceById(api, collectionIdAlice, nftAlice, firstBasicResourceId); - await checkResource(firstResource, 'Basic', firstBasicResourceId, resourcesInfo[0]); - - const secondResource = await getResourceById(api, collectionIdAlice, nftAlice, secondBasicResourceId); - await checkResource(secondResource, 'Basic', secondBasicResourceId, resourcesInfo[1]); - - const composableResource = await getResourceById(api, collectionIdAlice, nftAlice, composableResourceId); - await checkResource(composableResource, 'Composable', composableResourceId, resourcesInfo[2]); - - const slotResource = await getResourceById(api, collectionIdAlice, nftAlice, slotResourceId); - await checkResource(slotResource, 'Slot', slotResourceId, resourcesInfo[3]); - }); - - it('[negative]: unable to add a resource to the non-existing NFT', async () => { - const collectionIdAlice = await createCollection( - api, - Alice, - 'test-metadata', - null, - 'test-symbol', - ); - - const tx = addNftBasicResource( - api, - Alice, - 'added', - collectionIdAlice, - nonexistentId, - src, - metadata, - license, - thumb, - ); - - await expectTxFailure(/rmrkCore\.NoAvailableNftId/, tx); - }); - - it('[negative]: unable to add a resource by a not-an-owner user', async () => { - const collectionIdAlice = await createCollection( - api, - Alice, - 'test-metadata', - null, - 'test-symbol', - ); - - const nftAlice = await mintNft( - api, - Alice, - Alice, - collectionIdAlice, - 'nft-metadata', - ); - - const tx = addNftBasicResource( - api, - Bob, - 'added', - collectionIdAlice, - nftAlice, - src, - metadata, - license, - thumb, - ); - - await expectTxFailure(/rmrkCore\.NoPermission/, tx); - }); - - it('[negative]: unable to add a resource to the nested NFT if it isnt root owned by the caller', async () => { - const collectionIdAlice = await createCollection( - api, - Alice, - 'test-metadata', - null, - 'test-symbol', - ); - - const parentNftId = await mintNft(api, Alice, Alice, collectionIdAlice, 'parent-nft-metadata'); - const childNftId = await mintNft(api, Alice, Alice, collectionIdAlice, 'child-nft-metadata'); - - const newOwnerNFT: NftIdTuple = [collectionIdAlice, parentNftId]; - - await sendNft(api, 'sent', Alice, collectionIdAlice, childNftId, newOwnerNFT); - - const tx = addNftBasicResource( - api, - Bob, - 'added', - collectionIdAlice, - childNftId, - src, - metadata, - license, - thumb, - ); - - await expectTxFailure(/rmrkCore\.NoPermission/, tx); - }); - - it('accept resource', async () => { - const collectionIdBob = await createCollection( - api, - Bob, - 'test-metadata', - null, - 'test-symbol', - ); - - const nftAlice = await mintNft( - api, - Bob, - Alice, - collectionIdBob, - 'nft-metadata', - ); - - const resourceId = await addNftBasicResource( - api, - Bob, - 'pending', - collectionIdBob, - nftAlice, - src, - metadata, - license, - thumb, - ); - - await acceptNftResource(api, Alice, collectionIdBob, nftAlice, resourceId); - }); - - it('[negative]: unable to accept a non-existing resource', async () => { - const collectionIdBob = await createCollection( - api, - Bob, - 'test-metadata', - null, - 'test-symbol', - ); - - const nftAlice = await mintNft( - api, - Bob, - Alice, - collectionIdBob, - 'nft-metadata', - ); - - const tx = acceptNftResource(api, Alice, collectionIdBob, nftAlice, nonexistentId); - await expectTxFailure(/rmrkCore\.ResourceDoesntExist/, tx); - }); - - it('[negative]: unable to accept a resource by a not-an-NFT-owner user', async () => { - const collectionIdBob = await createCollection( - api, - Bob, - 'test-metadata', - null, - 'test-symbol', - ); - - const nftAlice = await mintNft( - api, - Bob, - Alice, - collectionIdBob, - 'nft-metadata', - ); - - const resourceId = await addNftBasicResource( - api, - Bob, - 'pending', - collectionIdBob, - nftAlice, - src, - metadata, - license, - thumb, - ); - - const tx = acceptNftResource(api, Bob, collectionIdBob, nftAlice, resourceId); - - await expectTxFailure(/rmrkCore\.NoPermission/, tx); - }); - - it('[negative]: unable to accept a resource to a non-target NFT', async () => { - const collectionIdBob = await createCollection( - api, - Bob, - 'test-metadata', - null, - 'test-symbol', - ); - - const nftAlice = await mintNft( - api, - Bob, - Alice, - collectionIdBob, - 'nft-metadata', - ); - - const wrongNft = await mintNft( - api, - Bob, - Alice, - collectionIdBob, - 'nft-metadata', - ); - - const resourceId = await addNftBasicResource( - api, - Bob, - 'pending', - collectionIdBob, - nftAlice, - src, - metadata, - license, - thumb, - ); - - const tx = acceptNftResource(api, Bob, collectionIdBob, wrongNft, resourceId); - - await expectTxFailure(/rmrkCore\.ResourceDoesntExist/, tx); - }); - - - after(() => { - api.disconnect(); - }); -}); --- /dev/null +++ b/tests/src/rmrk/addTheme.seqtest.ts @@ -0,0 +1,130 @@ +import {expect} from 'chai'; +import {getApiConnection} from '../substrate/substrate-api'; +import {createBase, addTheme} from './util/tx'; +import {expectTxFailure} from './util/helpers'; +import {getThemeNames} from './util/fetch'; +import {requirePallets, Pallets} from '../deprecated-helpers/helpers'; + +describe('integration test: add Theme to Base', () => { + let api: any; + before(async function() { + api = await getApiConnection(); + await requirePallets(this, [Pallets.RmrkEquip]); + }); + + const alice = '//Alice'; + const bob = '//Bob'; + + it('add default theme', async () => { + const baseId = await createBase(api, alice, 'default-themed-base', 'DTBase', []); + await addTheme(api, alice, baseId, { + name: 'default', + properties: [ + { + key: 'some-key', + value: 'some-key-value', + }, + { + key: 'another-key', + value: 'another-key-value', + }, + ], + }); + }); + + it('add default theme and a custom one', async () => { + const baseId = await createBase(api, alice, '2-themed-base', '2TBase', []); + await addTheme(api, alice, baseId, { + name: 'default', + properties: [ + { + key: 'default-key', + value: 'default-key-value', + }, + ], + }); + await addTheme(api, alice, baseId, { + name: 'custom-theme', + properties: [ + { + key: 'custom-key-0', + value: 'custom-key-value-0', + }, + { + key: 'custom-key-1', + value: 'custom-key-value-1', + }, + ], + }); + }); + + it('fetch filtered theme keys', async () => { + const baseId = await createBase(api, alice, '2-themed-base', '2TBase', []); + await addTheme(api, alice, baseId, { + name: 'default', + properties: [ + { + key: 'first-key', + value: 'first-key-value', + }, + { + key: 'second-key', + value: 'second-key-value', + }, + ], + }, ['second-key']); + }); + + it('fetch theme names', async() => { + const baseId = await createBase(api, alice, '3-themed-base', '3TBase', []); + const names = [ + 'default', + 'first-theme', + 'second-theme', + ]; + + for (let i = 0; i < names.length; i++) { + await addTheme(api, alice, baseId, {name: names[i], properties: [{key: 'dummy', value: 'dummy'}]}); + } + + const fetchedNames = await getThemeNames(api, baseId); + + for (let i = 0; i < names.length; i++) { + const isFound = fetchedNames.find((name) => name === names[i]) !== undefined; + + expect(isFound, 'Error: invalid theme names').to.be.true; + } + }); + + it('[negative] unable to add theme to non-existing base', async () => { + const maxBaseId = 0xFFFFFFFF; + const tx = addTheme(api, alice, maxBaseId, { + name: 'default', + properties: [], + }); + + await expectTxFailure(/rmrkEquip\.BaseDoesntExist/, tx); + }); + + it('[negative] unable to add custom theme if no default theme', async () => { + const baseId = await createBase(api, alice, 'no-default-themed-base', 'NDTBase', []); + const tx = addTheme(api, alice, baseId, { + name: 'custom-theme', + properties: [], + }); + + await expectTxFailure(/rmrkEquip\.NeedsDefaultThemeFirst/, tx); + }); + + it('[negative] unable to add theme by a not-an-owner', async () => { + const baseId = await createBase(api, alice, 'no-default-themed-base', 'NDTBase', []); + const tx = addTheme(api, bob, baseId, { + name: 'default', + properties: [], + }); + + await expectTxFailure(/rmrkEquip\.PermissionError/, tx); + }); + + after(() => { api.disconnect(); }); +}); --- a/tests/src/rmrk/addTheme.test.ts +++ /dev/null @@ -1,130 +0,0 @@ -import {expect} from 'chai'; -import {getApiConnection} from '../substrate/substrate-api'; -import {createBase, addTheme} from './util/tx'; -import {expectTxFailure} from './util/helpers'; -import {getThemeNames} from './util/fetch'; -import {requirePallets, Pallets} from '../deprecated-helpers/helpers'; - -describe('integration test: add Theme to Base', () => { - let api: any; - before(async function() { - api = await getApiConnection(); - await requirePallets(this, [Pallets.RmrkEquip]); - }); - - const alice = '//Alice'; - const bob = '//Bob'; - - it('add default theme', async () => { - const baseId = await createBase(api, alice, 'default-themed-base', 'DTBase', []); - await addTheme(api, alice, baseId, { - name: 'default', - properties: [ - { - key: 'some-key', - value: 'some-key-value', - }, - { - key: 'another-key', - value: 'another-key-value', - }, - ], - }); - }); - - it('add default theme and a custom one', async () => { - const baseId = await createBase(api, alice, '2-themed-base', '2TBase', []); - await addTheme(api, alice, baseId, { - name: 'default', - properties: [ - { - key: 'default-key', - value: 'default-key-value', - }, - ], - }); - await addTheme(api, alice, baseId, { - name: 'custom-theme', - properties: [ - { - key: 'custom-key-0', - value: 'custom-key-value-0', - }, - { - key: 'custom-key-1', - value: 'custom-key-value-1', - }, - ], - }); - }); - - it('fetch filtered theme keys', async () => { - const baseId = await createBase(api, alice, '2-themed-base', '2TBase', []); - await addTheme(api, alice, baseId, { - name: 'default', - properties: [ - { - key: 'first-key', - value: 'first-key-value', - }, - { - key: 'second-key', - value: 'second-key-value', - }, - ], - }, ['second-key']); - }); - - it('fetch theme names', async() => { - const baseId = await createBase(api, alice, '3-themed-base', '3TBase', []); - const names = [ - 'default', - 'first-theme', - 'second-theme', - ]; - - for (let i = 0; i < names.length; i++) { - await addTheme(api, alice, baseId, {name: names[i], properties: [{key: 'dummy', value: 'dummy'}]}); - } - - const fetchedNames = await getThemeNames(api, baseId); - - for (let i = 0; i < names.length; i++) { - const isFound = fetchedNames.find((name) => name === names[i]) !== undefined; - - expect(isFound, 'Error: invalid theme names').to.be.true; - } - }); - - it('[negative] unable to add theme to non-existing base', async () => { - const maxBaseId = 0xFFFFFFFF; - const tx = addTheme(api, alice, maxBaseId, { - name: 'default', - properties: [], - }); - - await expectTxFailure(/rmrkEquip\.BaseDoesntExist/, tx); - }); - - it('[negative] unable to add custom theme if no default theme', async () => { - const baseId = await createBase(api, alice, 'no-default-themed-base', 'NDTBase', []); - const tx = addTheme(api, alice, baseId, { - name: 'custom-theme', - properties: [], - }); - - await expectTxFailure(/rmrkEquip\.NeedsDefaultThemeFirst/, tx); - }); - - it('[negative] unable to add theme by a not-an-owner', async () => { - const baseId = await createBase(api, alice, 'no-default-themed-base', 'NDTBase', []); - const tx = addTheme(api, bob, baseId, { - name: 'default', - properties: [], - }); - - await expectTxFailure(/rmrkEquip\.PermissionError/, tx); - }); - - after(() => { api.disconnect(); }); -}); --- /dev/null +++ b/tests/src/rmrk/burnNft.seqtest.ts @@ -0,0 +1,173 @@ +import {getApiConnection} from '../substrate/substrate-api'; +import {expectTxFailure} from './util/helpers'; +import {NftIdTuple, getChildren} from './util/fetch'; +import {burnNft, createCollection, sendNft, mintNft} from './util/tx'; + +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +import {requirePallets, Pallets} from '../deprecated-helpers/helpers'; + +chai.use(chaiAsPromised); +const expect = chai.expect; + +describe('integration test: burn nft', () => { + const alice = '//Alice'; + const bob = '//Bob'; + + let api: any; + before(async function() { + api = await getApiConnection(); + await requirePallets(this, [Pallets.RmrkCore]); + }); + + + it('burn nft', async () => { + await createCollection( + api, + alice, + 'test-metadata', + null, + 'test-symbol', + ).then(async (collectionId) => { + const nftId = await mintNft( + api, + alice, + alice, + collectionId, + 'nft-metadata', + ); + await burnNft(api, alice, collectionId, nftId); + }); + }); + + it('burn nft with children', async () => { + const collectionId = await createCollection( + api, + alice, + 'test-metadata', + null, + 'test-symbol', + ); + + const parentNftId = await mintNft( + api, + alice, + alice, + collectionId, + 'nft-metadata', + ); + + const childNftId = await mintNft( + api, + alice, + alice, + collectionId, + 'nft-metadata', + ); + + const newOwnerNFT: NftIdTuple = [collectionId, parentNftId]; + + await sendNft(api, 'sent', alice, collectionId, childNftId, newOwnerNFT); + + const childrenBefore = await getChildren(api, collectionId, parentNftId); + expect(childrenBefore.length === 1, 'Error: parent NFT should have children') + .to.be.true; + + const child = childrenBefore[0]; + expect(child.collectionId.eq(collectionId), 'Error: invalid child collection Id') + .to.be.true; + + expect(child.nftId.eq(childNftId), 'Error: invalid child NFT Id') + .to.be.true; + + await burnNft(api, alice, collectionId, parentNftId); + + const childrenAfter = await getChildren(api, collectionId, parentNftId); + + expect(childrenAfter.length === 0, 'Error: children should be burned').to.be.true; + }); + + it('burn child nft', async () => { + const collectionId = await createCollection( + api, + alice, + 'test-metadata', + null, + 'test-symbol', + ); + + const parentNftId = await mintNft( + api, + alice, + alice, + collectionId, + 'nft-metadata', + ); + + const childNftId = await mintNft( + api, + alice, + alice, + collectionId, + 'nft-metadata', + ); + + const newOwnerNFT: NftIdTuple = [collectionId, parentNftId]; + + await sendNft(api, 'sent', alice, collectionId, childNftId, newOwnerNFT); + + const childrenBefore = await getChildren(api, collectionId, parentNftId); + expect(childrenBefore.length === 1, 'Error: parent NFT should have children') + .to.be.true; + + const child = childrenBefore[0]; + expect(child.collectionId.eq(collectionId), 'Error: invalid child collection Id') + .to.be.true; + + expect(child.nftId.eq(childNftId), 'Error: invalid child NFT Id') + .to.be.true; + + await burnNft(api, alice, collectionId, childNftId); + + const childrenAfter = await getChildren(api, collectionId, parentNftId); + + expect(childrenAfter.length === 0, 'Error: children should be burned').to.be.true; + }); + + it('[negative] burn non-existing NFT', async () => { + await createCollection( + api, + alice, + 'test-metadata', + null, + 'test-symbol', + ).then(async (collectionId) => { + const tx = burnNft(api, alice, collectionId, 99999); + await expectTxFailure(/rmrkCore\.NoAvailableNftId/, tx); + }); + }); + + it('[negative] burn not an owner NFT user', async () => { + await createCollection( + api, + alice, + 'test-metadata', + null, + 'test-symbol', + ).then(async (collectionId) => { + const nftId = await mintNft( + api, + alice, + alice, + collectionId, + 'nft-metadata', + ); + const tx = burnNft(api, bob, collectionId, nftId); + await expectTxFailure(/rmrkCore\.NoPermission/, tx); + }); + }); + + after(() => { + api.disconnect(); + }); +}); --- a/tests/src/rmrk/burnNft.test.ts +++ /dev/null @@ -1,173 +0,0 @@ -import {getApiConnection} from '../substrate/substrate-api'; -import {expectTxFailure} from './util/helpers'; -import {NftIdTuple, getChildren} from './util/fetch'; -import {burnNft, createCollection, sendNft, mintNft} from './util/tx'; - -import chai from 'chai'; -import chaiAsPromised from 'chai-as-promised'; -import {requirePallets, Pallets} from '../deprecated-helpers/helpers'; - -chai.use(chaiAsPromised); -const expect = chai.expect; - -describe('integration test: burn nft', () => { - const Alice = '//Alice'; - const Bob = '//Bob'; - - let api: any; - before(async function() { - api = await getApiConnection(); - await requirePallets(this, [Pallets.RmrkCore]); - }); - - - it('burn nft', async () => { - await createCollection( - api, - Alice, - 'test-metadata', - null, - 'test-symbol', - ).then(async (collectionId) => { - const nftId = await mintNft( - api, - Alice, - Alice, - collectionId, - 'nft-metadata', - ); - await burnNft(api, Alice, collectionId, nftId); - }); - }); - - it('burn nft with children', async () => { - const collectionId = await createCollection( - api, - Alice, - 'test-metadata', - null, - 'test-symbol', - ); - - const parentNftId = await mintNft( - api, - Alice, - Alice, - collectionId, - 'nft-metadata', - ); - - const childNftId = await mintNft( - api, - Alice, - Alice, - collectionId, - 'nft-metadata', - ); - - const newOwnerNFT: NftIdTuple = [collectionId, parentNftId]; - - await sendNft(api, 'sent', Alice, collectionId, childNftId, newOwnerNFT); - - const childrenBefore = await getChildren(api, collectionId, parentNftId); - expect(childrenBefore.length === 1, 'Error: parent NFT should have children') - .to.be.true; - - const child = childrenBefore[0]; - expect(child.collectionId.eq(collectionId), 'Error: invalid child collection Id') - .to.be.true; - - expect(child.nftId.eq(childNftId), 'Error: invalid child NFT Id') - .to.be.true; - - await burnNft(api, Alice, collectionId, parentNftId); - - const childrenAfter = await getChildren(api, collectionId, parentNftId); - - expect(childrenAfter.length === 0, 'Error: children should be burned').to.be.true; - }); - - it('burn child nft', async () => { - const collectionId = await createCollection( - api, - Alice, - 'test-metadata', - null, - 'test-symbol', - ); - - const parentNftId = await mintNft( - api, - Alice, - Alice, - collectionId, - 'nft-metadata', - ); - - const childNftId = await mintNft( - api, - Alice, - Alice, - collectionId, - 'nft-metadata', - ); - - const newOwnerNFT: NftIdTuple = [collectionId, parentNftId]; - - await sendNft(api, 'sent', Alice, collectionId, childNftId, newOwnerNFT); - - const childrenBefore = await getChildren(api, collectionId, parentNftId); - expect(childrenBefore.length === 1, 'Error: parent NFT should have children') - .to.be.true; - - const child = childrenBefore[0]; - expect(child.collectionId.eq(collectionId), 'Error: invalid child collection Id') - .to.be.true; - - expect(child.nftId.eq(childNftId), 'Error: invalid child NFT Id') - .to.be.true; - - await burnNft(api, Alice, collectionId, childNftId); - - const childrenAfter = await getChildren(api, collectionId, parentNftId); - - expect(childrenAfter.length === 0, 'Error: children should be burned').to.be.true; - }); - - it('[negative] burn non-existing NFT', async () => { - await createCollection( - api, - Alice, - 'test-metadata', - null, - 'test-symbol', - ).then(async (collectionId) => { - const tx = burnNft(api, Alice, collectionId, 99999); - await expectTxFailure(/rmrkCore\.NoAvailableNftId/, tx); - }); - }); - - it('[negative] burn not an owner NFT user', async () => { - await createCollection( - api, - Alice, - 'test-metadata', - null, - 'test-symbol', - ).then(async (collectionId) => { - const nftId = await mintNft( - api, - Alice, - Alice, - collectionId, - 'nft-metadata', - ); - const tx = burnNft(api, Bob, collectionId, nftId); - await expectTxFailure(/rmrkCore\.NoPermission/, tx); - }); - }); - - after(() => { - api.disconnect(); - }); -}); --- /dev/null +++ b/tests/src/rmrk/changeCollectionIssuer.seqtest.ts @@ -0,0 +1,56 @@ +import {getApiConnection} from '../substrate/substrate-api'; +import {requirePallets, Pallets} from '../deprecated-helpers/helpers'; +import {expectTxFailure} from './util/helpers'; +import { + changeIssuer, + createCollection, +} from './util/tx'; + +describe('integration test: collection issuer', () => { + const alice = '//Alice'; + const bob = '//Bob'; + + let api: any; + before(async function() { + api = await getApiConnection(); + await requirePallets(this, [Pallets.RmrkCore]); + }); + + + + it('change collection issuer', async () => { + await createCollection( + api, + alice, + 'test-metadata', + null, + 'test-symbol', + ).then(async (collectionId) => { + await changeIssuer(api, alice, collectionId, bob); + }); + }); + + it('[negative] change not an owner NFT collection issuer', async () => { + await createCollection(api, bob, 'test-metadata', null, 'test-symbol').then(async (collectionId) => { + const tx = changeIssuer(api, alice, collectionId, bob); + await expectTxFailure(/rmrkCore\.NoPermission/, tx); + }); + }); + + it('[negative] change non-existigit NFT collection issuer', async () => { + await createCollection( + api, + alice, + 'test-metadata', + null, + 'test-symbol', + ).then(async () => { + const tx = changeIssuer(api, alice, 99999, bob); + await expectTxFailure(/rmrkCore\.CollectionUnknown/, tx); + }); + }); + + after(() => { + api.disconnect(); + }); +}); --- a/tests/src/rmrk/changeCollectionIssuer.test.ts +++ /dev/null @@ -1,56 +0,0 @@ -import {getApiConnection} from '../substrate/substrate-api'; -import {requirePallets, Pallets} from '../deprecated-helpers/helpers'; -import {expectTxFailure} from './util/helpers'; -import { - changeIssuer, - createCollection, -} from './util/tx'; - -describe('integration test: collection issuer', () => { - const Alice = '//Alice'; - const Bob = '//Bob'; - - let api: any; - before(async function() { - api = await getApiConnection(); - await requirePallets(this, [Pallets.RmrkCore]); - }); - - - - it('change collection issuer', async () => { - await createCollection( - api, - Alice, - 'test-metadata', - null, - 'test-symbol', - ).then(async (collectionId) => { - await changeIssuer(api, Alice, collectionId, Bob); - }); - }); - - it('[negative] change not an owner NFT collection issuer', async () => { - await createCollection(api, Bob, 'test-metadata', null, 'test-symbol').then(async (collectionId) => { - const tx = changeIssuer(api, Alice, collectionId, Bob); - await expectTxFailure(/rmrkCore\.NoPermission/, tx); - }); - }); - - it('[negative] change non-existigit NFT collection issuer', async () => { - await createCollection( - api, - Alice, - 'test-metadata', - null, - 'test-symbol', - ).then(async () => { - const tx = changeIssuer(api, Alice, 99999, Bob); - await expectTxFailure(/rmrkCore\.CollectionUnknown/, tx); - }); - }); - - after(() => { - api.disconnect(); - }); -}); --- /dev/null +++ b/tests/src/rmrk/createBase.seqtest.ts @@ -0,0 +1,88 @@ +import {getApiConnection} from '../substrate/substrate-api'; +import {requirePallets, Pallets} from '../deprecated-helpers/helpers'; +import {createCollection, createBase} from './util/tx'; + +describe('integration test: create new Base', () => { + let api: any; + before(async function() { + api = await getApiConnection(); + await requirePallets(this, [Pallets.RmrkCore, Pallets.RmrkEquip]); + }); + + const alice = '//Alice'; + + it('create empty Base', async () => { + await createBase(api, alice, 'empty-base-type', 'EBase', []); + }); + + it('create Base with fixed part', async () => { + await createBase(api, alice, 'fixedpart-base-type', 'FPBase', [ + { + 'FixedPart': { + id: 42, + z: 0, + src: 'some-fixed-url', + }, + }, + ]); + }); + + it('create Base with slot part (no collection)', async () => { + await createBase(api, alice, 'slotpart-base-type', 'SPBase', [ + { + 'SlotPart': { + id: 112, + equippable: 'Empty', + z: 0, + src: 'some-fallback-slot-url', + }, + }, + ]); + }); + + it('create Base with slot part (any collection)', async () => { + await createBase(api, alice, 'slotpartany-base-type', 'SPABase', [ + { + 'SlotPart': { + id: 222, + equippable: 'All', + z: 1, + src: 'some-fallback-slot-url', + }, + }, + ]); + }); + + it('create Base with slot part (custom collections)', async () => { + const firstCollectionId = await createCollection( + api, + alice, + 'first-collection-meta', + null, + 'first-collection', + ); + + const secondCollectionId = await createCollection( + api, + alice, + 'first-collection-meta', + null, + 'first-collection', + ); + + await createBase(api, alice, 'slotpartcustom-base-type', 'SPCBase', [ + { + 'SlotPart': { + id: 1024, + equippable: { + 'Custom': [firstCollectionId, secondCollectionId], + }, + z: 2, + src: 'some-fallback-slot-url', + }, + }, + ]); + }); + + after(() => { api.disconnect(); }); +}); --- a/tests/src/rmrk/createBase.test.ts +++ /dev/null @@ -1,88 +0,0 @@ -import {getApiConnection} from '../substrate/substrate-api'; -import {requirePallets, Pallets} from '../deprecated-helpers/helpers'; -import {createCollection, createBase} from './util/tx'; - -describe('integration test: create new Base', () => { - let api: any; - before(async function() { - api = await getApiConnection(); - await requirePallets(this, [Pallets.RmrkCore, Pallets.RmrkEquip]); - }); - - const alice = '//Alice'; - - it('create empty Base', async () => { - await createBase(api, alice, 'empty-base-type', 'EBase', []); - }); - - it('create Base with fixed part', async () => { - await createBase(api, alice, 'fixedpart-base-type', 'FPBase', [ - { - 'FixedPart': { - id: 42, - z: 0, - src: 'some-fixed-url', - }, - }, - ]); - }); - - it('create Base with slot part (no collection)', async () => { - await createBase(api, alice, 'slotpart-base-type', 'SPBase', [ - { - 'SlotPart': { - id: 112, - equippable: 'Empty', - z: 0, - src: 'some-fallback-slot-url', - }, - }, - ]); - }); - - it('create Base with slot part (any collection)', async () => { - await createBase(api, alice, 'slotpartany-base-type', 'SPABase', [ - { - 'SlotPart': { - id: 222, - equippable: 'All', - z: 1, - src: 'some-fallback-slot-url', - }, - }, - ]); - }); - - it('create Base with slot part (custom collections)', async () => { - const firstCollectionId = await createCollection( - api, - alice, - 'first-collection-meta', - null, - 'first-collection', - ); - - const secondCollectionId = await createCollection( - api, - alice, - 'first-collection-meta', - null, - 'first-collection', - ); - - await createBase(api, alice, 'slotpartcustom-base-type', 'SPCBase', [ - { - 'SlotPart': { - id: 1024, - equippable: { - 'Custom': [firstCollectionId, secondCollectionId], - }, - z: 2, - src: 'some-fallback-slot-url', - }, - }, - ]); - }); - - after(() => { api.disconnect(); }); -}); --- /dev/null +++ b/tests/src/rmrk/createCollection.seqtest.ts @@ -0,0 +1,25 @@ +import {getApiConnection} from '../substrate/substrate-api'; +import {requirePallets, Pallets} from '../deprecated-helpers/helpers'; +import {createCollection} from './util/tx'; + +describe('Integration test: create new collection', () => { + let api: any; + before(async function () { + api = await getApiConnection(); + await requirePallets(this, [Pallets.RmrkCore]); + }); + + + + const alice = '//Alice'; + + it('create NFT collection', async () => { + await createCollection(api, alice, 'test-metadata', 42, 'test-symbol'); + }); + + it('create NFT collection without token limit', async () => { + await createCollection(api, alice, 'no-limit-metadata', null, 'no-limit-symbol'); + }); + + after(() => { api.disconnect(); }); +}); --- a/tests/src/rmrk/createCollection.test.ts +++ /dev/null @@ -1,25 +0,0 @@ -import {getApiConnection} from '../substrate/substrate-api'; -import {requirePallets, Pallets} from '../deprecated-helpers/helpers'; -import {createCollection} from './util/tx'; - -describe('Integration test: create new collection', () => { - let api: any; - before(async function () { - api = await getApiConnection(); - await requirePallets(this, [Pallets.RmrkCore]); - }); - - - - const alice = '//Alice'; - - it('create NFT collection', async () => { - await createCollection(api, alice, 'test-metadata', 42, 'test-symbol'); - }); - - it('create NFT collection without token limit', async () => { - await createCollection(api, alice, 'no-limit-metadata', null, 'no-limit-symbol'); - }); - - after(() => { api.disconnect(); }); -}); --- /dev/null +++ b/tests/src/rmrk/deleteCollection.seqtest.ts @@ -0,0 +1,49 @@ +import {getApiConnection} from '../substrate/substrate-api'; +import {requirePallets, Pallets} from '../deprecated-helpers/helpers'; +import {expectTxFailure} from './util/helpers'; +import {createCollection, deleteCollection} from './util/tx'; + +describe('integration test: delete collection', () => { + let api: any; + before(async function () { + api = await getApiConnection(); + await requirePallets(this, [Pallets.RmrkCore]); + }); + + const alice = '//Alice'; + const bob = '//Bob'; + + it('delete NFT collection', async () => { + await createCollection( + api, + alice, + 'test-metadata', + null, + 'test-symbol', + ).then(async (collectionId) => { + await deleteCollection(api, alice, collectionId.toString()); + }); + }); + + it('[negative] delete non-existing NFT collection', async () => { + const tx = deleteCollection(api, alice, '99999'); + await expectTxFailure(/rmrkCore\.CollectionUnknown/, tx); + }); + + it('[negative] delete not an owner NFT collection', async () => { + await createCollection( + api, + alice, + 'test-metadata', + null, + 'test-symbol', + ).then(async (collectionId) => { + const tx = deleteCollection(api, bob, collectionId.toString()); + await expectTxFailure(/rmrkCore.NoPermission/, tx); + }); + }); + + after(() => { + api.disconnect(); + }); +}); --- a/tests/src/rmrk/deleteCollection.test.ts +++ /dev/null @@ -1,49 +0,0 @@ -import {getApiConnection} from '../substrate/substrate-api'; -import {requirePallets, Pallets} from '../deprecated-helpers/helpers'; -import {expectTxFailure} from './util/helpers'; -import {createCollection, deleteCollection} from './util/tx'; - -describe('integration test: delete collection', () => { - let api: any; - before(async function () { - api = await getApiConnection(); - await requirePallets(this, [Pallets.RmrkCore]); - }); - - const Alice = '//Alice'; - const Bob = '//Bob'; - - it('delete NFT collection', async () => { - await createCollection( - api, - Alice, - 'test-metadata', - null, - 'test-symbol', - ).then(async (collectionId) => { - await deleteCollection(api, Alice, collectionId.toString()); - }); - }); - - it('[negative] delete non-existing NFT collection', async () => { - const tx = deleteCollection(api, Alice, '99999'); - await expectTxFailure(/rmrkCore\.CollectionUnknown/, tx); - }); - - it('[negative] delete not an owner NFT collection', async () => { - await createCollection( - api, - Alice, - 'test-metadata', - null, - 'test-symbol', - ).then(async (collectionId) => { - const tx = deleteCollection(api, Bob, collectionId.toString()); - await expectTxFailure(/rmrkCore.NoPermission/, tx); - }); - }); - - after(() => { - api.disconnect(); - }); -}); --- /dev/null +++ b/tests/src/rmrk/equipNft.seqtest.ts @@ -0,0 +1,343 @@ +import {ApiPromise} from '@polkadot/api'; +import {expect} from 'chai'; +import {getApiConnection} from '../substrate/substrate-api'; +import {requirePallets, Pallets} from '../deprecated-helpers/helpers'; +import {getNft, NftIdTuple} from './util/fetch'; +import {expectTxFailure} from './util/helpers'; +import { + addNftComposableResource, + addNftSlotResource, + createBase, + createCollection, + equipNft, + mintNft, + sendNft, + unequipNft, +} from './util/tx'; + +const alice = '//Alice'; +const bob = '//Bob'; + +const composableParts: number[] = [5, 2, 7]; +const composableSrc = 'test-cmp-src'; +const composableMetadata = 'test-cmp-metadata'; +const composableLicense = 'test-comp-license'; +const composableThumb = 'test-comp-thumb'; + +const slotSrc = 'test-slot-src'; +const slotLicense = 'test-slot-license'; +const slotMetadata = 'test-slot-metadata'; +const slotThumb = 'test-slot-thumb'; + +const slotId = 1; + +async function createTestCollection(api: ApiPromise): Promise { + return createCollection( + api, + alice, + 'test-metadata', + null, + 'test-symbol', + ); +} + +async function mintTestNft(api: ApiPromise, collectionId: number): Promise { + return await mintNft( + api, + alice, + alice, + collectionId, + 'nft-metadata', + ); +} + +async function mintChildNft(api: ApiPromise, collectionId: number, parentNftId: number): Promise { + const nftChildId = await mintTestNft(api, collectionId); + + const parentNFT: NftIdTuple = [collectionId, parentNftId]; + + await sendNft(api, 'sent', alice, collectionId, nftChildId, parentNFT); + + return nftChildId; +} + +async function createTestBase(api: ApiPromise): Promise { + return createBase(api, alice, 'test-base', 'DTBase', [ + { + SlotPart: { + id: slotId, + equippable: 'All', + z: 1, + src: slotSrc, + }, + }, + ]); +} + +async function addTestComposable(api: ApiPromise, collectionId: number, nftId: number, baseId: number) { + await addNftComposableResource( + api, + alice, + 'added', + collectionId, + nftId, + composableParts, + baseId, + composableSrc, + composableMetadata, + composableLicense, + composableThumb, + ); +} + +async function addTestSlot(api: ApiPromise, collectionId: number, nftId: number, baseId: number, slotId: number): Promise { + return await addNftSlotResource( + api, + alice, + 'added', + collectionId, + nftId, + baseId, + slotId, + slotSrc, + slotMetadata, + slotLicense, + slotThumb, + ); +} + +async function checkEquipStatus( + api: ApiPromise, + expectedStatus: 'equipped' | 'unequipped', + collectionId: number, + nftId: number, +) { + const itemNftDataOpt = await getNft(api, collectionId, nftId); + expect(itemNftDataOpt.isSome, 'Error: unable to fetch item NFT data'); + + const itemNftData = itemNftDataOpt.unwrap(); + expect(itemNftData.equipped.isTrue, `Error: item NFT should be ${expectedStatus}`) + .to.be.equal(expectedStatus === 'equipped'); +} + +describe.skip('integration test: Equip NFT', () => { + + let api: any; + + before(async function () { + api = await getApiConnection(); + await requirePallets(this, [Pallets.RmrkCore, Pallets.RmrkEquip]); + }); + + it('equip nft', async () => { + const collectionId = await createTestCollection(api); + const nftParentId = await mintTestNft(api, collectionId); + const nftChildId = await mintChildNft(api, collectionId, nftParentId); + + const baseId = await createTestBase(api); + + await addTestComposable(api, collectionId, nftParentId, baseId); + const resourceId = await addTestSlot(api, collectionId, nftChildId, baseId, slotId); + + const equipperNFT: NftIdTuple = [collectionId, nftParentId]; + const itemNFT: NftIdTuple = [collectionId, nftChildId]; + + await equipNft(api, alice, itemNFT, equipperNFT, resourceId, baseId, slotId); + + await checkEquipStatus(api, 'equipped', collectionId, nftChildId); + }); + + it('unequip nft', async () => { + const collectionId = await createTestCollection(api); + const nftParentId = await mintTestNft(api, collectionId); + const nftChildId = await mintChildNft(api, collectionId, nftParentId); + + const baseId = await createTestBase(api); + + await addTestComposable(api, collectionId, nftParentId, baseId); + const resourceId = await addTestSlot(api, collectionId, nftChildId, baseId, slotId); + + const equipperNFT: NftIdTuple = [collectionId, nftParentId]; + const itemNFT: NftIdTuple = [collectionId, nftChildId]; + + await equipNft(api, alice, itemNFT, equipperNFT, resourceId, baseId, slotId); + + await checkEquipStatus(api, 'equipped', collectionId, nftChildId); + + await unequipNft(api, alice, itemNFT, equipperNFT, resourceId, baseId, slotId); + await checkEquipStatus(api, 'unequipped', collectionId, nftChildId); + }); + + it('[negative] equip NFT onto non-existing NFT', async () => { + const collectionId = await createTestCollection(api); + + const nftChildId = await mintNft( + api, + alice, + alice, + collectionId, + 'nft-metadata', + ); + + const itemNFT: NftIdTuple = [collectionId, nftChildId]; + const invalidEquipperNFT: NftIdTuple = [collectionId, 9999999]; + + const baseId = 0; + const resourceId = 0; + + const tx = equipNft(api, alice, itemNFT, invalidEquipperNFT, resourceId, baseId, slotId); + await expectTxFailure(/rmrkCore\.NoAvailableNftId/, tx); + }); + + it('[negative] equip non-existing NFT', async () => { + const collectionId = await createTestCollection(api); + const nftParentId = await mintNft( + api, + alice, + alice, + collectionId, + 'nft-metadata', + ); + + const baseId = await createTestBase(api); + + await addTestComposable(api, collectionId, nftParentId, baseId); + + const equipperNFT: NftIdTuple = [collectionId, nftParentId]; + const invalidItemNFT: NftIdTuple = [collectionId, 99999999]; + + const resourceId = 0; + + const tx = equipNft(api, alice, invalidItemNFT, equipperNFT, resourceId, baseId, slotId); + await expectTxFailure(/rmrkCore\.NoAvailableNftId/, tx); + }); + + it('[negative] equip NFT by a not-an-owner user', async () => { + const collectionId = await createTestCollection(api); + const nftParentId = await mintTestNft(api, collectionId); + const nftChildId = await mintChildNft(api, collectionId, nftParentId); + + const baseId = await createTestBase(api); + + await addTestComposable(api, collectionId, nftParentId, baseId); + + const equipperNFT: NftIdTuple = [collectionId, nftParentId]; + const itemNFT: NftIdTuple = [collectionId, nftChildId]; + + const resourceId = await addTestSlot(api, collectionId, nftChildId, baseId, slotId); + + const tx = equipNft(api, bob, itemNFT, equipperNFT, resourceId, baseId, slotId); + await expectTxFailure(/rmrkEquip\.PermissionError/, tx); + }); + + it('[negative] unable to equip NFT onto indirect parent NFT', async () => { + const collectionId = await createTestCollection(api); + const nftParentId = await mintTestNft(api, collectionId); + const nftChildId = await mintChildNft(api, collectionId, nftParentId); + const nftGrandchildId = await mintChildNft(api, collectionId, nftChildId); + + const baseId = await createTestBase(api); + + await addTestComposable(api, collectionId, nftParentId, baseId); + const resourceId = await addTestSlot(api, collectionId, nftGrandchildId, baseId, slotId); + + const equipperNFT: NftIdTuple = [collectionId, nftParentId]; + const itemNFT: NftIdTuple = [collectionId, nftGrandchildId]; + + const tx = equipNft(api, alice, itemNFT, equipperNFT, resourceId, baseId, slotId); + await expectTxFailure(/rmrkEquip\.MustBeDirectParent/, tx); + }); + + it('[negative] unable to equip NFT onto parent NFT with another base', async () => { + const collectionId = await createTestCollection(api); + const nftParentId = await mintTestNft(api, collectionId); + const nftChildId = await mintChildNft(api, collectionId, nftParentId); + + const baseId = await createTestBase(api); + + await addTestComposable(api, collectionId, nftParentId, baseId); + const resourceId = await addTestSlot(api, collectionId, nftChildId, baseId, slotId); + + const equipperNFT: NftIdTuple = [collectionId, nftParentId]; + const itemNFT: NftIdTuple = [collectionId, nftChildId]; + + const invalidBaseId = 99999; + + const tx = equipNft(api, alice, itemNFT, equipperNFT, resourceId, invalidBaseId, slotId); + await expectTxFailure(/rmrkEquip\.NoResourceForThisBaseFoundOnNft/, tx); + }); + + it('[negative] unable to equip NFT into slot with another id', async () => { + const collectionId = await createTestCollection(api); + const nftParentId = await mintTestNft(api, collectionId); + const nftChildId = await mintChildNft(api, collectionId, nftParentId); + + const baseId = await createTestBase(api); + + await addTestComposable(api, collectionId, nftParentId, baseId); + const resourceId = await addTestSlot(api, collectionId, nftChildId, baseId, slotId); + + const equipperNFT: NftIdTuple = [collectionId, nftParentId]; + const itemNFT: NftIdTuple = [collectionId, nftChildId]; + + const incorrectSlotId = slotId + 1; + const tx = equipNft(api, alice, itemNFT, equipperNFT, resourceId, baseId, incorrectSlotId); + await expectTxFailure(/rmrkEquip\.ItemHasNoResourceToEquipThere/, tx); + }); + + it('[negative] unable to equip NFT with incorrect slot (fixed part)', async () => { + const collectionId = await createTestCollection(api); + const nftParentId = await mintTestNft(api, collectionId); + const nftChildId = await mintChildNft(api, collectionId, nftParentId); + + const baseId = await createBase(api, alice, 'test-base', 'DTBase', [ + { + FixedPart: { + id: slotId, + equippable: 'All', + z: 1, + src: slotSrc, + }, + }, + ]); + + await addTestComposable(api, collectionId, nftParentId, baseId); + const resourceId = await addTestSlot(api, collectionId, nftChildId, baseId, slotId); + + const equipperNFT: NftIdTuple = [collectionId, nftParentId]; + const itemNFT: NftIdTuple = [collectionId, nftChildId]; + + const tx = equipNft(api, alice, itemNFT, equipperNFT, resourceId, baseId, slotId); + await expectTxFailure(/rmrkEquip\.CantEquipFixedPart/, tx); + }); + + it('[negative] unable to equip NFT from a collection that is not allowed by the slot', async () => { + const collectionId = await createTestCollection(api); + const nftParentId = await mintTestNft(api, collectionId); + const nftChildId = await mintChildNft(api, collectionId, nftParentId); + + const baseId = await createBase(api, alice, 'test-base', 'DTBase', [ + { + SlotPart: { + id: 1, + z: 1, + equippable: 'Empty', + src: slotSrc, + }, + }, + ]); + + await addTestComposable(api, collectionId, nftParentId, baseId); + const resourceId = await addTestSlot(api, collectionId, nftChildId, baseId, slotId); + + const equipperNFT: NftIdTuple = [collectionId, nftParentId]; + const itemNFT: NftIdTuple = [collectionId, nftChildId]; + + const tx = equipNft(api, alice, itemNFT, equipperNFT, resourceId, baseId, slotId); + await expectTxFailure(/rmrkEquip\.CollectionNotEquippable/, tx); + }); + + after(() => { + api.disconnect(); + }); +}); --- a/tests/src/rmrk/equipNft.test.ts +++ /dev/null @@ -1,343 +0,0 @@ -import {ApiPromise} from '@polkadot/api'; -import {expect} from 'chai'; -import {getApiConnection} from '../substrate/substrate-api'; -import {requirePallets, Pallets} from '../deprecated-helpers/helpers'; -import {getNft, getParts, NftIdTuple} from './util/fetch'; -import {expectTxFailure} from './util/helpers'; -import { - addNftComposableResource, - addNftSlotResource, - createBase, - createCollection, - equipNft, - mintNft, - sendNft, - unequipNft, -} from './util/tx'; - -const Alice = '//Alice'; -const Bob = '//Bob'; - -const composableParts: number[] = [5, 2, 7]; -const composableSrc = 'test-cmp-src'; -const composableMetadata = 'test-cmp-metadata'; -const composableLicense = 'test-comp-license'; -const composableThumb = 'test-comp-thumb'; - -const slotSrc = 'test-slot-src'; -const slotLicense = 'test-slot-license'; -const slotMetadata = 'test-slot-metadata'; -const slotThumb = 'test-slot-thumb'; - -const slotId = 1; - -async function createTestCollection(api: ApiPromise): Promise { - return createCollection( - api, - Alice, - 'test-metadata', - null, - 'test-symbol', - ); -} - -async function mintTestNft(api: ApiPromise, collectionId: number): Promise { - return await mintNft( - api, - Alice, - Alice, - collectionId, - 'nft-metadata', - ); -} - -async function mintChildNft(api: ApiPromise, collectionId: number, parentNftId: number): Promise { - const nftChildId = await mintTestNft(api, collectionId); - - const parentNFT: NftIdTuple = [collectionId, parentNftId]; - - await sendNft(api, 'sent', Alice, collectionId, nftChildId, parentNFT); - - return nftChildId; -} - -async function createTestBase(api: ApiPromise): Promise { - return createBase(api, Alice, 'test-base', 'DTBase', [ - { - SlotPart: { - id: slotId, - equippable: 'All', - z: 1, - src: slotSrc, - }, - }, - ]); -} - -async function addTestComposable(api: ApiPromise, collectionId: number, nftId: number, baseId: number) { - await addNftComposableResource( - api, - Alice, - 'added', - collectionId, - nftId, - composableParts, - baseId, - composableSrc, - composableMetadata, - composableLicense, - composableThumb, - ); -} - -async function addTestSlot(api: ApiPromise, collectionId: number, nftId: number, baseId: number, slotId: number): Promise { - return await addNftSlotResource( - api, - Alice, - 'added', - collectionId, - nftId, - baseId, - slotId, - slotSrc, - slotMetadata, - slotLicense, - slotThumb, - ); -} - -async function checkEquipStatus( - api: ApiPromise, - expectedStatus: 'equipped' | 'unequipped', - collectionId: number, - nftId: number, -) { - const itemNftDataOpt = await getNft(api, collectionId, nftId); - expect(itemNftDataOpt.isSome, 'Error: unable to fetch item NFT data'); - - const itemNftData = itemNftDataOpt.unwrap(); - expect(itemNftData.equipped.isTrue, `Error: item NFT should be ${expectedStatus}`) - .to.be.equal(expectedStatus === 'equipped'); -} - -describe.skip('integration test: Equip NFT', () => { - - let api: any; - - before(async function () { - api = await getApiConnection(); - await requirePallets(this, [Pallets.RmrkCore, Pallets.RmrkEquip]); - }); - - it('equip nft', async () => { - const collectionId = await createTestCollection(api); - const nftParentId = await mintTestNft(api, collectionId); - const nftChildId = await mintChildNft(api, collectionId, nftParentId); - - const baseId = await createTestBase(api); - - await addTestComposable(api, collectionId, nftParentId, baseId); - const resourceId = await addTestSlot(api, collectionId, nftChildId, baseId, slotId); - - const equipperNFT: NftIdTuple = [collectionId, nftParentId]; - const itemNFT: NftIdTuple = [collectionId, nftChildId]; - - await equipNft(api, Alice, itemNFT, equipperNFT, resourceId, baseId, slotId); - - await checkEquipStatus(api, 'equipped', collectionId, nftChildId); - }); - - it('unequip nft', async () => { - const collectionId = await createTestCollection(api); - const nftParentId = await mintTestNft(api, collectionId); - const nftChildId = await mintChildNft(api, collectionId, nftParentId); - - const baseId = await createTestBase(api); - - await addTestComposable(api, collectionId, nftParentId, baseId); - const resourceId = await addTestSlot(api, collectionId, nftChildId, baseId, slotId); - - const equipperNFT: NftIdTuple = [collectionId, nftParentId]; - const itemNFT: NftIdTuple = [collectionId, nftChildId]; - - await equipNft(api, Alice, itemNFT, equipperNFT, resourceId, baseId, slotId); - - await checkEquipStatus(api, 'equipped', collectionId, nftChildId); - - await unequipNft(api, Alice, itemNFT, equipperNFT, resourceId, baseId, slotId); - await checkEquipStatus(api, 'unequipped', collectionId, nftChildId); - }); - - it('[negative] equip NFT onto non-existing NFT', async () => { - const collectionId = await createTestCollection(api); - - const nftChildId = await mintNft( - api, - Alice, - Alice, - collectionId, - 'nft-metadata', - ); - - const itemNFT: NftIdTuple = [collectionId, nftChildId]; - const invalidEquipperNFT: NftIdTuple = [collectionId, 9999999]; - - const baseId = 0; - const resourceId = 0; - - const tx = equipNft(api, Alice, itemNFT, invalidEquipperNFT, resourceId, baseId, slotId); - await expectTxFailure(/rmrkCore\.NoAvailableNftId/, tx); - }); - - it('[negative] equip non-existing NFT', async () => { - const collectionId = await createTestCollection(api); - const nftParentId = await mintNft( - api, - Alice, - Alice, - collectionId, - 'nft-metadata', - ); - - const baseId = await createTestBase(api); - - await addTestComposable(api, collectionId, nftParentId, baseId); - - const equipperNFT: NftIdTuple = [collectionId, nftParentId]; - const invalidItemNFT: NftIdTuple = [collectionId, 99999999]; - - const resourceId = 0; - - const tx = equipNft(api, Alice, invalidItemNFT, equipperNFT, resourceId, baseId, slotId); - await expectTxFailure(/rmrkCore\.NoAvailableNftId/, tx); - }); - - it('[negative] equip NFT by a not-an-owner user', async () => { - const collectionId = await createTestCollection(api); - const nftParentId = await mintTestNft(api, collectionId); - const nftChildId = await mintChildNft(api, collectionId, nftParentId); - - const baseId = await createTestBase(api); - - await addTestComposable(api, collectionId, nftParentId, baseId); - - const equipperNFT: NftIdTuple = [collectionId, nftParentId]; - const itemNFT: NftIdTuple = [collectionId, nftChildId]; - - const resourceId = await addTestSlot(api, collectionId, nftChildId, baseId, slotId); - - const tx = equipNft(api, Bob, itemNFT, equipperNFT, resourceId, baseId, slotId); - await expectTxFailure(/rmrkEquip\.PermissionError/, tx); - }); - - it('[negative] unable to equip NFT onto indirect parent NFT', async () => { - const collectionId = await createTestCollection(api); - const nftParentId = await mintTestNft(api, collectionId); - const nftChildId = await mintChildNft(api, collectionId, nftParentId); - const nftGrandchildId = await mintChildNft(api, collectionId, nftChildId); - - const baseId = await createTestBase(api); - - await addTestComposable(api, collectionId, nftParentId, baseId); - const resourceId = await addTestSlot(api, collectionId, nftGrandchildId, baseId, slotId); - - const equipperNFT: NftIdTuple = [collectionId, nftParentId]; - const itemNFT: NftIdTuple = [collectionId, nftGrandchildId]; - - const tx = equipNft(api, Alice, itemNFT, equipperNFT, resourceId, baseId, slotId); - await expectTxFailure(/rmrkEquip\.MustBeDirectParent/, tx); - }); - - it('[negative] unable to equip NFT onto parent NFT with another base', async () => { - const collectionId = await createTestCollection(api); - const nftParentId = await mintTestNft(api, collectionId); - const nftChildId = await mintChildNft(api, collectionId, nftParentId); - - const baseId = await createTestBase(api); - - await addTestComposable(api, collectionId, nftParentId, baseId); - const resourceId = await addTestSlot(api, collectionId, nftChildId, baseId, slotId); - - const equipperNFT: NftIdTuple = [collectionId, nftParentId]; - const itemNFT: NftIdTuple = [collectionId, nftChildId]; - - const invalidBaseId = 99999; - - const tx = equipNft(api, Alice, itemNFT, equipperNFT, resourceId, invalidBaseId, slotId); - await expectTxFailure(/rmrkEquip\.NoResourceForThisBaseFoundOnNft/, tx); - }); - - it('[negative] unable to equip NFT into slot with another id', async () => { - const collectionId = await createTestCollection(api); - const nftParentId = await mintTestNft(api, collectionId); - const nftChildId = await mintChildNft(api, collectionId, nftParentId); - - const baseId = await createTestBase(api); - - await addTestComposable(api, collectionId, nftParentId, baseId); - const resourceId = await addTestSlot(api, collectionId, nftChildId, baseId, slotId); - - const equipperNFT: NftIdTuple = [collectionId, nftParentId]; - const itemNFT: NftIdTuple = [collectionId, nftChildId]; - - const incorrectSlotId = slotId + 1; - const tx = equipNft(api, Alice, itemNFT, equipperNFT, resourceId, baseId, incorrectSlotId); - await expectTxFailure(/rmrkEquip\.ItemHasNoResourceToEquipThere/, tx); - }); - - it('[negative] unable to equip NFT with incorrect slot (fixed part)', async () => { - const collectionId = await createTestCollection(api); - const nftParentId = await mintTestNft(api, collectionId); - const nftChildId = await mintChildNft(api, collectionId, nftParentId); - - const baseId = await createBase(api, Alice, 'test-base', 'DTBase', [ - { - FixedPart: { - id: slotId, - equippable: 'All', - z: 1, - src: slotSrc, - }, - }, - ]); - - await addTestComposable(api, collectionId, nftParentId, baseId); - const resourceId = await addTestSlot(api, collectionId, nftChildId, baseId, slotId); - - const equipperNFT: NftIdTuple = [collectionId, nftParentId]; - const itemNFT: NftIdTuple = [collectionId, nftChildId]; - - const tx = equipNft(api, Alice, itemNFT, equipperNFT, resourceId, baseId, slotId); - await expectTxFailure(/rmrkEquip\.CantEquipFixedPart/, tx); - }); - - it('[negative] unable to equip NFT from a collection that is not allowed by the slot', async () => { - const collectionId = await createTestCollection(api); - const nftParentId = await mintTestNft(api, collectionId); - const nftChildId = await mintChildNft(api, collectionId, nftParentId); - - const baseId = await createBase(api, Alice, 'test-base', 'DTBase', [ - { - SlotPart: { - id: 1, - z: 1, - equippable: 'Empty', - src: slotSrc, - }, - }, - ]); - - await addTestComposable(api, collectionId, nftParentId, baseId); - const resourceId = await addTestSlot(api, collectionId, nftChildId, baseId, slotId); - - const equipperNFT: NftIdTuple = [collectionId, nftParentId]; - const itemNFT: NftIdTuple = [collectionId, nftChildId]; - - const tx = equipNft(api, Alice, itemNFT, equipperNFT, resourceId, baseId, slotId); - await expectTxFailure(/rmrkEquip\.CollectionNotEquippable/, tx); - }); - - after(() => { - api.disconnect(); - }); -}); --- /dev/null +++ b/tests/src/rmrk/getOwnedNfts.seqtest.ts @@ -0,0 +1,80 @@ +import {expect} from 'chai'; +import {getApiConnection} from '../substrate/substrate-api'; +import {requirePallets, Pallets} from '../deprecated-helpers/helpers'; +import {getOwnedNfts} from './util/fetch'; +import {mintNft, createCollection} from './util/tx'; + +describe('integration test: get owned NFTs', () => { + let api: any; + + before(async function () { + api = await getApiConnection(); + await requirePallets(this, [Pallets.RmrkCore]); + }); + + + const alice = '//Alice'; + + it('fetch all NFTs owned by a user', async () => { + const owner = alice; + const collectionMetadata = 'aliceCollectionMetadata'; + const collectionMax = null; + const collectionSymbol = 'AliceSym'; + const recipientUri = null; + const royalty = null; + const nftMetadata = 'alice-NFT-metadata'; + + const collectionId = await createCollection( + api, + alice, + collectionMetadata, + collectionMax, + collectionSymbol, + ); + + const nftIds = [ + await mintNft( + api, + alice, + owner, + collectionId, + nftMetadata + '-0', + recipientUri, + royalty, + ), + await mintNft( + api, + alice, + owner, + collectionId, + nftMetadata + '-1', + recipientUri, + royalty, + ), + await mintNft( + api, + alice, + owner, + collectionId, + nftMetadata + '-2', + recipientUri, + royalty, + ), + ]; + + const ownedNfts = await getOwnedNfts(api, alice, collectionId); + + const isFound = (nftId: number) => { + return ownedNfts.find((ownedNftId) => { + return ownedNftId === nftId; + }) !== undefined; + }; + + nftIds.forEach((nftId) => { + expect(isFound(nftId), `NFT ${nftId} should be owned by ${alice}`) + .to.be.true; + }); + }); + + after(() => { api.disconnect(); }); +}); --- a/tests/src/rmrk/getOwnedNfts.test.ts +++ /dev/null @@ -1,80 +0,0 @@ -import {expect} from 'chai'; -import {getApiConnection} from '../substrate/substrate-api'; -import {requirePallets, Pallets} from '../deprecated-helpers/helpers'; -import {getOwnedNfts} from './util/fetch'; -import {mintNft, createCollection} from './util/tx'; - -describe('integration test: get owned NFTs', () => { - let api: any; - - before(async function () { - api = await getApiConnection(); - await requirePallets(this, [Pallets.RmrkCore]); - }); - - - const alice = '//Alice'; - - it('fetch all NFTs owned by a user', async () => { - const owner = alice; - const collectionMetadata = 'aliceCollectionMetadata'; - const collectionMax = null; - const collectionSymbol = 'AliceSym'; - const recipientUri = null; - const royalty = null; - const nftMetadata = 'alice-NFT-metadata'; - - const collectionId = await createCollection( - api, - alice, - collectionMetadata, - collectionMax, - collectionSymbol, - ); - - const nftIds = [ - await mintNft( - api, - alice, - owner, - collectionId, - nftMetadata + '-0', - recipientUri, - royalty, - ), - await mintNft( - api, - alice, - owner, - collectionId, - nftMetadata + '-1', - recipientUri, - royalty, - ), - await mintNft( - api, - alice, - owner, - collectionId, - nftMetadata + '-2', - recipientUri, - royalty, - ), - ]; - - const ownedNfts = await getOwnedNfts(api, alice, collectionId); - - const isFound = (nftId: number) => { - return ownedNfts.find((ownedNftId) => { - return ownedNftId === nftId; - }) !== undefined; - }; - - nftIds.forEach((nftId) => { - expect(isFound(nftId), `NFT ${nftId} should be owned by ${alice}`) - .to.be.true; - }); - }); - - after(() => { api.disconnect(); }); -}); --- /dev/null +++ b/tests/src/rmrk/lockCollection.seqtest.ts @@ -0,0 +1,119 @@ +import {getApiConnection} from '../substrate/substrate-api'; +import {requirePallets, Pallets} from '../deprecated-helpers/helpers'; +import {expectTxFailure} from './util/helpers'; +import {createCollection, lockCollection, mintNft} from './util/tx'; + +describe('integration test: lock collection', () => { + const alice = '//Alice'; + const bob = '//Bob'; + const max = 5; + + let api: any; + before(async function () { + api = await getApiConnection(); + await requirePallets(this, [Pallets.RmrkCore]); + }); + + it('lock collection', async () => { + await createCollection( + api, + alice, + 'test-metadata', + null, + 'test-symbol', + ).then(async (collectionId) => { + await lockCollection(api, alice, collectionId); + }); + }); + + it('[negative] lock non-existing NFT collection', async () => { + const tx = lockCollection(api, alice, 99999); + await expectTxFailure(/rmrkCore\.CollectionUnknown/, tx); + }); + + it('[negative] lock not an owner NFT collection issuer', async () => { + await createCollection( + api, + alice, + 'test-metadata', + null, + 'test-symbol', + ).then(async (collectionId) => { + const tx = lockCollection(api, bob, collectionId); + await expectTxFailure(/rmrkCore\.NoPermission/, tx); + }); + }); + + it('lock collection with minting', async () => { + await createCollection( + api, + alice, + 'test-metadata', + max, + 'test-symbol', + ).then(async (collectionId) => { + for (let i = 0; i < 5; i++) { + await mintNft( + api, + alice, + alice, + collectionId, + 'test-metadata', + null, + null, + ); + } + await lockCollection(api, alice, collectionId, max); + }); + }); + + it('[negative] unable to mint NFT inside a locked collection', async () => { + await createCollection( + api, + alice, + 'test-metadata', + max, + 'test-symbol', + ).then(async (collectionId) => { + await lockCollection(api, alice, collectionId); + const tx = mintNft( + api, + alice, + alice, + collectionId, + 'test-metadata', + null, + null, + ); + await expectTxFailure(/rmrkCore\.CollectionFullOrLocked/, tx); + }); + }); + + it('[negative] unable to mint NFT inside a full collection', async () => { + await createCollection(api, alice, 'test-metadata', 1, 'test-symbol').then(async (collectionId) => { + await mintNft( + api, + alice, + alice, + collectionId, + 'test-metadata', + null, + null, + ); + const tx = mintNft( + api, + alice, + alice, + collectionId, + 'test-metadata', + null, + null, + ); + await expectTxFailure(/rmrkCore\.CollectionFullOrLocked/, tx); + }); + }); + + after(() => { + api.disconnect(); + }); +}); --- a/tests/src/rmrk/lockCollection.test.ts +++ /dev/null @@ -1,119 +0,0 @@ -import {getApiConnection} from '../substrate/substrate-api'; -import {requirePallets, Pallets} from '../deprecated-helpers/helpers'; -import {expectTxFailure} from './util/helpers'; -import {createCollection, lockCollection, mintNft} from './util/tx'; - -describe('integration test: lock collection', () => { - const Alice = '//Alice'; - const Bob = '//Bob'; - const Max = 5; - - let api: any; - before(async function () { - api = await getApiConnection(); - await requirePallets(this, [Pallets.RmrkCore]); - }); - - it('lock collection', async () => { - await createCollection( - api, - Alice, - 'test-metadata', - null, - 'test-symbol', - ).then(async (collectionId) => { - await lockCollection(api, Alice, collectionId); - }); - }); - - it('[negative] lock non-existing NFT collection', async () => { - const tx = lockCollection(api, Alice, 99999); - await expectTxFailure(/rmrkCore\.CollectionUnknown/, tx); - }); - - it('[negative] lock not an owner NFT collection issuer', async () => { - await createCollection( - api, - Alice, - 'test-metadata', - null, - 'test-symbol', - ).then(async (collectionId) => { - const tx = lockCollection(api, Bob, collectionId); - await expectTxFailure(/rmrkCore\.NoPermission/, tx); - }); - }); - - it('lock collection with minting', async () => { - await createCollection( - api, - Alice, - 'test-metadata', - Max, - 'test-symbol', - ).then(async (collectionId) => { - for (let i = 0; i < 5; i++) { - await mintNft( - api, - Alice, - Alice, - collectionId, - 'test-metadata', - null, - null, - ); - } - await lockCollection(api, Alice, collectionId, Max); - }); - }); - - it('[negative] unable to mint NFT inside a locked collection', async () => { - await createCollection( - api, - Alice, - 'test-metadata', - Max, - 'test-symbol', - ).then(async (collectionId) => { - await lockCollection(api, Alice, collectionId); - const tx = mintNft( - api, - Alice, - Alice, - collectionId, - 'test-metadata', - null, - null, - ); - await expectTxFailure(/rmrkCore\.CollectionFullOrLocked/, tx); - }); - }); - - it('[negative] unable to mint NFT inside a full collection', async () => { - await createCollection(api, Alice, 'test-metadata', 1, 'test-symbol').then(async (collectionId) => { - await mintNft( - api, - Alice, - Alice, - collectionId, - 'test-metadata', - null, - null, - ); - const tx = mintNft( - api, - Alice, - Alice, - collectionId, - 'test-metadata', - null, - null, - ); - await expectTxFailure(/rmrkCore\.CollectionFullOrLocked/, tx); - }); - }); - - after(() => { - api.disconnect(); - }); -}); --- /dev/null +++ b/tests/src/rmrk/mintNft.seqtest.ts @@ -0,0 +1,212 @@ +import {expect} from 'chai'; +import {getApiConnection} from '../substrate/substrate-api'; +import {requirePallets, Pallets} from '../deprecated-helpers/helpers'; +import {getNft} from './util/fetch'; +import {expectTxFailure} from './util/helpers'; +import {createCollection, mintNft} from './util/tx'; + +describe('integration test: mint new NFT', () => { + let api: any; + + before(async function () { + api = await getApiConnection(); + await requirePallets(this, [Pallets.RmrkCore]); + }); + + + const alice = '//Alice'; + const bob = '//Bob'; + const maxCollectionId = 0xFFFFFFFF; + const maxNftId = 0xFFFFFFFF; + + it('mint NFT', async () => { + const owner = null; + const collectionMetadata = 'mintingCollectionMetadata'; + const collectionMax = null; + const collectionSymbol = 'MCS'; + const recipientUri = null; + const royalty = null; + const nftMetadata = 'NFT-test-metadata'; + + const collectionId = await createCollection( + api, + alice, + collectionMetadata, + collectionMax, + collectionSymbol, + ); + + await mintNft( + api, + alice, + owner, + collectionId, + nftMetadata, + recipientUri, + royalty, + ); + }); + + it('mint NFT and set another owner', async () => { + const owner = bob; + const collectionMetadata = 'setOwnerCollectionMetadata'; + const collectionMax = null; + const collectionSymbol = 'SOCS'; + const recipientUri = null; + const royalty = null; + const nftMetadata = 'setOwner-NFT-metadata'; + + const collectionId = await createCollection( + api, + alice, + collectionMetadata, + collectionMax, + collectionSymbol, + ); + + await mintNft( + api, + alice, + owner, + collectionId, + nftMetadata, + recipientUri, + royalty, + ); + }); + + it('mint NFT with recipient and roalty', async () => { + const owner = alice; + const collectionMetadata = 'mintingCollectionMetadata'; + const collectionMax = null; + const collectionSymbol = 'MCS'; + const recipientUri = bob; + const royalty = 70000; + const nftMetadata = 'recipient-royalty-NFT-test-metadata'; + + const collectionId = await createCollection( + api, + alice, + collectionMetadata, + collectionMax, + collectionSymbol, + ); + + await mintNft( + api, + alice, + owner, + collectionId, + nftMetadata, + recipientUri, + royalty, + ); + }); + + it('mint NFT with resources', async () => { + const owner = alice; + const collectionMetadata = 'mintingCollectionMetadata'; + const collectionMax = null; + const collectionSymbol = 'MCS'; + const nftMetadata = 'NFT-with-resources-test-metadata'; + const resources = [ + { + basic: { + metadata: 'basic-resource-nft-minting', + }, + }, { + slot: { + metadata: 'slot-resource-nft-minting', + slot: 9, + }, + }, { + composable: { + metadata: 'composable-resource-nft-minting', + parts: [0, 5, 2], + }, + }, { + slot: { + metadata: 'slot-resource-nft-minting-2', + thumb: 'srnm2', + base: 5, + }, + }, + ]; + + const collectionId = await createCollection( + api, + alice, + collectionMetadata, + collectionMax, + collectionSymbol, + ); + + await mintNft( + api, + alice, + owner, + collectionId, + nftMetadata, + null, + null, + true, + resources, + ); + }); + + it('[negative] unable to mint NFT within non-existing collection', async () => { + const owner = alice; + const recipientUri = null; + const royalty = null; + const nftMetadata = 'NFT-test-metadata'; + + const tx = mintNft( + api, + alice, + owner, + maxCollectionId, + nftMetadata, + recipientUri, + royalty, + ); + + await expectTxFailure(/rmrkCore\.CollectionUnknown/, tx); + }); + + it("[negative] unable to mint NFT by a user that isn't the owner of the collection", async () => { + const owner = alice; + const collectionMetadata = 'mintingCollectionMetadata'; + const collectionMax = null; + const collectionSymbol = 'MCS'; + const recipientUri = null; + const royalty = null; + const nftMetadata = 'NFT-test-metadata'; + + const collectionId = await createCollection( + api, + alice, + collectionMetadata, + collectionMax, + collectionSymbol, + ); + + const tx = mintNft( + api, + bob, + owner, + collectionId, + nftMetadata, + recipientUri, + royalty, + ); + + await expectTxFailure(/rmrkCore\.NoPermission/, tx); + }); + + it('[negative] unable to fetch non-existing NFT', async () => { + const nft = await getNft(api, maxCollectionId, maxNftId); + expect(nft.isSome).to.be.false; + }); + + after(() => { api.disconnect(); }); +}); --- a/tests/src/rmrk/mintNft.test.ts +++ /dev/null @@ -1,212 +0,0 @@ -import {expect} from 'chai'; -import {getApiConnection} from '../substrate/substrate-api'; -import {requirePallets, Pallets} from '../deprecated-helpers/helpers'; -import {getNft} from './util/fetch'; -import {expectTxFailure} from './util/helpers'; -import {createCollection, mintNft} from './util/tx'; - -describe('integration test: mint new NFT', () => { - let api: any; - - before(async function () { - api = await getApiConnection(); - await requirePallets(this, [Pallets.RmrkCore]); - }); - - - const alice = '//Alice'; - const bob = '//Bob'; - const maxCollectionId = 0xFFFFFFFF; - const maxNftId = 0xFFFFFFFF; - - it('mint NFT', async () => { - const owner = null; - const collectionMetadata = 'mintingCollectionMetadata'; - const collectionMax = null; - const collectionSymbol = 'MCS'; - const recipientUri = null; - const royalty = null; - const nftMetadata = 'NFT-test-metadata'; - - const collectionId = await createCollection( - api, - alice, - collectionMetadata, - collectionMax, - collectionSymbol, - ); - - await mintNft( - api, - alice, - owner, - collectionId, - nftMetadata, - recipientUri, - royalty, - ); - }); - - it('mint NFT and set another owner', async () => { - const owner = bob; - const collectionMetadata = 'setOwnerCollectionMetadata'; - const collectionMax = null; - const collectionSymbol = 'SOCS'; - const recipientUri = null; - const royalty = null; - const nftMetadata = 'setOwner-NFT-metadata'; - - const collectionId = await createCollection( - api, - alice, - collectionMetadata, - collectionMax, - collectionSymbol, - ); - - await mintNft( - api, - alice, - owner, - collectionId, - nftMetadata, - recipientUri, - royalty, - ); - }); - - it('mint NFT with recipient and roalty', async () => { - const owner = alice; - const collectionMetadata = 'mintingCollectionMetadata'; - const collectionMax = null; - const collectionSymbol = 'MCS'; - const recipientUri = bob; - const royalty = 70000; - const nftMetadata = 'recipient-royalty-NFT-test-metadata'; - - const collectionId = await createCollection( - api, - alice, - collectionMetadata, - collectionMax, - collectionSymbol, - ); - - await mintNft( - api, - alice, - owner, - collectionId, - nftMetadata, - recipientUri, - royalty, - ); - }); - - it('mint NFT with resources', async () => { - const owner = alice; - const collectionMetadata = 'mintingCollectionMetadata'; - const collectionMax = null; - const collectionSymbol = 'MCS'; - const nftMetadata = 'NFT-with-resources-test-metadata'; - const resources = [ - { - basic: { - metadata: 'basic-resource-nft-minting', - }, - }, { - slot: { - metadata: 'slot-resource-nft-minting', - slot: 9, - }, - }, { - composable: { - metadata: 'composable-resource-nft-minting', - parts: [0, 5, 2], - }, - }, { - slot: { - metadata: 'slot-resource-nft-minting-2', - thumb: 'srnm2', - base: 5, - }, - }, - ]; - - const collectionId = await createCollection( - api, - alice, - collectionMetadata, - collectionMax, - collectionSymbol, - ); - - await mintNft( - api, - alice, - owner, - collectionId, - nftMetadata, - null, - null, - true, - resources, - ); - }); - - it('[negative] unable to mint NFT within non-existing collection', async () => { - const owner = alice; - const recipientUri = null; - const royalty = null; - const nftMetadata = 'NFT-test-metadata'; - - const tx = mintNft( - api, - alice, - owner, - maxCollectionId, - nftMetadata, - recipientUri, - royalty, - ); - - await expectTxFailure(/rmrkCore\.CollectionUnknown/, tx); - }); - - it("[negative] unable to mint NFT by a user that isn't the owner of the collection", async () => { - const owner = alice; - const collectionMetadata = 'mintingCollectionMetadata'; - const collectionMax = null; - const collectionSymbol = 'MCS'; - const recipientUri = null; - const royalty = null; - const nftMetadata = 'NFT-test-metadata'; - - const collectionId = await createCollection( - api, - alice, - collectionMetadata, - collectionMax, - collectionSymbol, - ); - - const tx = mintNft( - api, - bob, - owner, - collectionId, - nftMetadata, - recipientUri, - royalty, - ); - - await expectTxFailure(/rmrkCore\.NoPermission/, tx); - }); - - it('[negative] unable to fetch non-existing NFT', async () => { - const nft = await getNft(api, maxCollectionId, maxNftId); - expect(nft.isSome).to.be.false; - }); - - after(() => { api.disconnect(); }); -}); --- /dev/null +++ b/tests/src/rmrk/rejectNft.seqtest.ts @@ -0,0 +1,95 @@ +import {expect} from 'chai'; +import {getApiConnection} from '../substrate/substrate-api'; +import { + createCollection, + mintNft, + sendNft, + rejectNft, +} from './util/tx'; +import {NftIdTuple} from './util/fetch'; +import {isNftChildOfAnother, expectTxFailure} from './util/helpers'; +import {requirePallets, Pallets} from '../deprecated-helpers/helpers'; + +describe('integration test: reject NFT', () => { + let api: any; + before(async function () { + api = await getApiConnection(); + await requirePallets(this, [Pallets.RmrkCore]); + }); + + + + const alice = '//Alice'; + const bob = '//Bob'; + + const createTestCollection = async (issuerUri: string) => { + return await createCollection( + api, + issuerUri, + 'reject-metadata', + null, + 'rjct', + ); + }; + + it('reject NFT', async () => { + const ownerAlice = alice; + const ownerBob = bob; + + const aliceCollectionId = await createTestCollection(alice); + const bobCollectionId = await createTestCollection(bob); + + const parentNftId = await mintNft(api, alice, ownerAlice, aliceCollectionId, 'parent-nft-metadata'); + const childNftId = await mintNft(api, bob, ownerBob, bobCollectionId, 'child-nft-metadata'); + + const newOwnerNFT: NftIdTuple = [aliceCollectionId, parentNftId]; + + await sendNft(api, 'pending', ownerBob, bobCollectionId, childNftId, newOwnerNFT); + await rejectNft(api, alice, bobCollectionId, childNftId); + + const isChild = await isNftChildOfAnother(api, bobCollectionId, childNftId, newOwnerNFT); + expect(isChild, 'Error: rejected NFT is still a child of the target NFT').to.be.false; + }); + + it('[negative] unable to reject NFT by a not-an-owner', async () => { + const ownerAlice = alice; + const ownerBob = bob; + + const aliceCollectionId = await createTestCollection(alice); + const bobCollectionId = await createTestCollection(bob); + + const parentNftId = await mintNft(api, alice, ownerAlice, aliceCollectionId, 'parent-nft-metadata'); + const childNftId = await mintNft(api, bob, ownerBob, bobCollectionId, 'child-nft-metadata'); + + const newOwnerNFT: NftIdTuple = [aliceCollectionId, parentNftId]; + + await sendNft(api, 'pending', ownerBob, bobCollectionId, childNftId, newOwnerNFT); + const tx = rejectNft(api, bob, bobCollectionId, childNftId); + + await expectTxFailure(/rmrkCore\.CannotRejectNonOwnedNft/, tx); + }); + + it('[negative] unable to reject non-existing NFT', async () => { + const maxNftId = 0xFFFFFFFF; + + const collectionId = await createTestCollection(alice); + + const tx = rejectNft(api, alice, collectionId, maxNftId); + + await expectTxFailure(/rmrkCore\.NoAvailableNftId/, tx); + }); + + it('[negative] unable to reject NFT which is not sent', async () => { + const ownerAlice = alice; + + const collectionId = await createTestCollection(alice); + + const nftId = await mintNft(api, alice, ownerAlice, collectionId, 'parent-nft-metadata'); + + const tx = rejectNft(api, alice, collectionId, nftId); + + await expectTxFailure(/rmrkCore\.CannotRejectNonPendingNft/, tx); + }); + + after(() => { api.disconnect(); }); +}); --- a/tests/src/rmrk/rejectNft.test.ts +++ /dev/null @@ -1,95 +0,0 @@ -import {expect} from 'chai'; -import {getApiConnection} from '../substrate/substrate-api'; -import { - createCollection, - mintNft, - sendNft, - rejectNft, -} from './util/tx'; -import {getChildren, NftIdTuple} from './util/fetch'; -import {isNftChildOfAnother, expectTxFailure} from './util/helpers'; -import {requirePallets, Pallets} from '../deprecated-helpers/helpers'; - -describe('integration test: reject NFT', () => { - let api: any; - before(async function () { - api = await getApiConnection(); - await requirePallets(this, [Pallets.RmrkCore]); - }); - - - - const alice = '//Alice'; - const bob = '//Bob'; - - const createTestCollection = async (issuerUri: string) => { - return await createCollection( - api, - issuerUri, - 'reject-metadata', - null, - 'rjct', - ); - }; - - it('reject NFT', async () => { - const ownerAlice = alice; - const ownerBob = bob; - - const aliceCollectionId = await createTestCollection(alice); - const bobCollectionId = await createTestCollection(bob); - - const parentNftId = await mintNft(api, alice, ownerAlice, aliceCollectionId, 'parent-nft-metadata'); - const childNftId = await mintNft(api, bob, ownerBob, bobCollectionId, 'child-nft-metadata'); - - const newOwnerNFT: NftIdTuple = [aliceCollectionId, parentNftId]; - - await sendNft(api, 'pending', ownerBob, bobCollectionId, childNftId, newOwnerNFT); - await rejectNft(api, alice, bobCollectionId, childNftId); - - const isChild = await isNftChildOfAnother(api, bobCollectionId, childNftId, newOwnerNFT); - expect(isChild, 'Error: rejected NFT is still a child of the target NFT').to.be.false; - }); - - it('[negative] unable to reject NFT by a not-an-owner', async () => { - const ownerAlice = alice; - const ownerBob = bob; - - const aliceCollectionId = await createTestCollection(alice); - const bobCollectionId = await createTestCollection(bob); - - const parentNftId = await mintNft(api, alice, ownerAlice, aliceCollectionId, 'parent-nft-metadata'); - const childNftId = await mintNft(api, bob, ownerBob, bobCollectionId, 'child-nft-metadata'); - - const newOwnerNFT: NftIdTuple = [aliceCollectionId, parentNftId]; - - await sendNft(api, 'pending', ownerBob, bobCollectionId, childNftId, newOwnerNFT); - const tx = rejectNft(api, bob, bobCollectionId, childNftId); - - await expectTxFailure(/rmrkCore\.CannotRejectNonOwnedNft/, tx); - }); - - it('[negative] unable to reject non-existing NFT', async () => { - const maxNftId = 0xFFFFFFFF; - - const collectionId = await createTestCollection(alice); - - const tx = rejectNft(api, alice, collectionId, maxNftId); - - await expectTxFailure(/rmrkCore\.NoAvailableNftId/, tx); - }); - - it('[negative] unable to reject NFT which is not sent', async () => { - const ownerAlice = alice; - - const collectionId = await createTestCollection(alice); - - const nftId = await mintNft(api, alice, ownerAlice, collectionId, 'parent-nft-metadata'); - - const tx = rejectNft(api, alice, collectionId, nftId); - - await expectTxFailure(/rmrkCore\.CannotRejectNonPendingNft/, tx); - }); - - after(() => { api.disconnect(); }); -}); --- /dev/null +++ b/tests/src/rmrk/removeResource.seqtest.ts @@ -0,0 +1,343 @@ +import {getApiConnection} from '../substrate/substrate-api'; +import {requirePallets, Pallets} from '../deprecated-helpers/helpers'; +import {NftIdTuple} from './util/fetch'; +import {expectTxFailure} from './util/helpers'; +import { + acceptResourceRemoval, addNftBasicResource, createCollection, mintNft, removeNftResource, sendNft, +} from './util/tx'; + + + + +describe('Integration test: remove nft resource', () => { + let api: any; + before(async function() { + api = await getApiConnection(); + await requirePallets(this, [Pallets.RmrkCore]); + }); + + const alice = '//Alice'; + const bob = '//Bob'; + const src = 'test-basic-src'; + const metadata = 'test-basic-metadata'; + const license = 'test-basic-license'; + const thumb = 'test-basic-thumb'; + + it('deleting a resource directly by the NFT owner', async () => { + const collectionIdAlice = await createCollection( + api, + alice, + 'test-metadata', + null, + 'test-symbol', + ); + + const nftAlice = await mintNft( + api, + alice, + alice, + collectionIdAlice, + 'nft-metadata', + ); + + const resourceId = await addNftBasicResource( + api, + alice, + 'added', + collectionIdAlice, + nftAlice, + src, + metadata, + license, + thumb, + ); + + await removeNftResource(api, 'removed', alice, collectionIdAlice, nftAlice, resourceId); + }); + + it('deleting resources indirectly by the NFT owner', async () => { + const collectionIdAlice = await createCollection( + api, + alice, + 'test-metadata', + null, + 'test-symbol', + ); + + const parentNftId = await mintNft(api, alice, alice, collectionIdAlice, 'parent-nft-metadata'); + const childNftId = await mintNft(api, alice, alice, collectionIdAlice, 'child-nft-metadata'); + + const resourceId = await addNftBasicResource( + api, + alice, + 'added', + collectionIdAlice, + childNftId, + src, + metadata, + license, + thumb, + ); + + const newOwnerNFT: NftIdTuple = [collectionIdAlice, parentNftId]; + + await sendNft(api, 'sent', alice, collectionIdAlice, childNftId, newOwnerNFT); + + await removeNftResource(api, 'removed', alice, collectionIdAlice, childNftId, resourceId); + }); + + it('deleting a resource by the collection owner', async () => { + const collectionIdAlice = await createCollection( + api, + alice, + 'test-metadata', + null, + 'test-symbol', + ); + + const nftBob = await mintNft( + api, + alice, + bob, + collectionIdAlice, + 'nft-metadata', + ); + + const resourceId = await addNftBasicResource( + api, + alice, + 'pending', + collectionIdAlice, + nftBob, + src, + metadata, + license, + thumb, + ); + + await removeNftResource(api, 'pending', alice, collectionIdAlice, nftBob, resourceId); + await acceptResourceRemoval(api, bob, collectionIdAlice, nftBob, resourceId); + }); + + it('deleting a resource in a nested NFT by the collection owner', async () => { + const collectionIdAlice = await createCollection( + api, + alice, + 'test-metadata', + null, + 'test-symbol', + ); + + const parentNftId = await mintNft( + api, + alice, + bob, + collectionIdAlice, + 'parent-nft-metadata', + ); + const childNftId = await mintNft( + api, + alice, + bob, + collectionIdAlice, + 'child-nft-metadata', + ); + + const resourceId = await addNftBasicResource( + api, + alice, + 'pending', + collectionIdAlice, + childNftId, + src, + metadata, + license, + thumb, + ); + + const newOwnerNFT: NftIdTuple = [collectionIdAlice, parentNftId]; + + await sendNft(api, 'sent', bob, collectionIdAlice, childNftId, newOwnerNFT); + + await removeNftResource(api, 'pending', alice, collectionIdAlice, childNftId, resourceId); + await acceptResourceRemoval(api, bob, collectionIdAlice, childNftId, resourceId); + }); + + it('[negative]: can\'t delete a resource in a non-existing collection', async () => { + const collectionIdAlice = await createCollection( + api, + alice, + 'test-metadata', + null, + 'test-symbol', + ); + + const nftAlice = await mintNft( + api, + alice, + alice, + collectionIdAlice, + 'nft-metadata', + ); + + const resourceId = await addNftBasicResource( + api, + alice, + 'added', + collectionIdAlice, + nftAlice, + src, + metadata, + license, + thumb, + ); + + const tx = removeNftResource(api, 'removed', alice, 0xFFFFFFFF, nftAlice, resourceId); + await expectTxFailure(/rmrkCore\.CollectionUnknown/, tx); // FIXME: inappropriate error message (NoAvailableNftId) + }); + + it('[negative]: only collection owner can delete a resource', async () => { + const collectionIdAlice = await createCollection( + api, + alice, + 'test-metadata', + null, + 'test-symbol', + ); + + const nftAlice = await mintNft( + api, + alice, + alice, + collectionIdAlice, + 'nft-metadata', + ); + + const resourceId = await addNftBasicResource( + api, + alice, + 'added', + collectionIdAlice, + nftAlice, + src, + metadata, + license, + thumb, + ); + + const tx = removeNftResource(api, 'removed', bob, collectionIdAlice, nftAlice, resourceId); + await expectTxFailure(/rmrkCore\.NoPermission/, tx); + }); + + it('[negative]: cannot delete a resource that does not exist', async () => { + const collectionIdAlice = await createCollection( + api, + alice, + 'test-metadata', + null, + 'test-symbol', + ); + + const nftAlice = await mintNft( + api, + alice, + alice, + collectionIdAlice, + 'nft-metadata', + ); + + const tx = removeNftResource(api, 'removed', alice, collectionIdAlice, nftAlice, 127); + await expectTxFailure(/rmrkCore\.ResourceDoesntExist/, tx); + }); + + it('[negative]: Cannot accept deleting resource without owner attempt do delete it', async () => { + const collectionIdAlice = await createCollection( + api, + alice, + 'test-metadata', + null, + 'test-symbol', + ); + + const nftBob = await mintNft( + api, + alice, + bob, + collectionIdAlice, + 'nft-metadata', + ); + + const resourceId = await addNftBasicResource( + api, + alice, + 'pending', + collectionIdAlice, + nftBob, + src, + metadata, + license, + thumb, + ); + + const tx = acceptResourceRemoval(api, bob, collectionIdAlice, nftBob, resourceId); + await expectTxFailure(/rmrkCore\.ResourceNotPending/, tx); + }); + + it('[negative]: cannot confirm the deletion of a non-existing resource', async () => { + const collectionIdAlice = await createCollection( + api, + alice, + 'test-metadata', + null, + 'test-symbol', + ); + + const nftBob = await mintNft( + api, + alice, + bob, + collectionIdAlice, + 'nft-metadata', + ); + + const tx = acceptResourceRemoval(api, bob, collectionIdAlice, nftBob, 127); + await expectTxFailure(/rmrkCore\.ResourceDoesntExist/, tx); + }); + + it('[negative]: Non-owner user cannot confirm the deletion of resource', async () => { + const collectionIdAlice = await createCollection( + api, + alice, + 'test-metadata', + null, + 'test-symbol', + ); + + const nftAlice = await mintNft( + api, + alice, + alice, + collectionIdAlice, + 'nft-metadata', + ); + + const resourceId = await addNftBasicResource( + api, + alice, + 'added', + collectionIdAlice, + nftAlice, + src, + metadata, + license, + thumb, + ); + + const tx = acceptResourceRemoval(api, bob, collectionIdAlice, nftAlice, resourceId); + await expectTxFailure(/rmrkCore\.NoPermission/, tx); + }); + + after(() => { + api.disconnect(); + }); +}); --- a/tests/src/rmrk/removeResource.test.ts +++ /dev/null @@ -1,350 +0,0 @@ -import {expect} from 'chai'; -import privateKey from '../substrate/privateKey'; -import {executeTransaction, getApiConnection} from '../substrate/substrate-api'; -import {requirePallets, Pallets} from '../deprecated-helpers/helpers'; -import {getNft, NftIdTuple} from './util/fetch'; -import {expectTxFailure} from './util/helpers'; -import { - acceptNft, acceptResourceRemoval, addNftBasicResource, - createBase, - createCollection, - mintNft, removeNftResource, sendNft, -} from './util/tx'; - - - - -describe('Integration test: remove nft resource', () => { - let api: any; - let ss58Format: string; - before(async function() { - api = await getApiConnection(); - ss58Format = api.registry.getChainProperties()!.toJSON().ss58Format; - await requirePallets(this, [Pallets.RmrkCore]); - }); - - const Alice = '//Alice'; - const Bob = '//Bob'; - const src = 'test-basic-src'; - const metadata = 'test-basic-metadata'; - const license = 'test-basic-license'; - const thumb = 'test-basic-thumb'; - - it('deleting a resource directly by the NFT owner', async () => { - const collectionIdAlice = await createCollection( - api, - Alice, - 'test-metadata', - null, - 'test-symbol', - ); - - const nftAlice = await mintNft( - api, - Alice, - Alice, - collectionIdAlice, - 'nft-metadata', - ); - - const resourceId = await addNftBasicResource( - api, - Alice, - 'added', - collectionIdAlice, - nftAlice, - src, - metadata, - license, - thumb, - ); - - await removeNftResource(api, 'removed', Alice, collectionIdAlice, nftAlice, resourceId); - }); - - it('deleting resources indirectly by the NFT owner', async () => { - const collectionIdAlice = await createCollection( - api, - Alice, - 'test-metadata', - null, - 'test-symbol', - ); - - const parentNftId = await mintNft(api, Alice, Alice, collectionIdAlice, 'parent-nft-metadata'); - const childNftId = await mintNft(api, Alice, Alice, collectionIdAlice, 'child-nft-metadata'); - - const resourceId = await addNftBasicResource( - api, - Alice, - 'added', - collectionIdAlice, - childNftId, - src, - metadata, - license, - thumb, - ); - - const newOwnerNFT: NftIdTuple = [collectionIdAlice, parentNftId]; - - await sendNft(api, 'sent', Alice, collectionIdAlice, childNftId, newOwnerNFT); - - await removeNftResource(api, 'removed', Alice, collectionIdAlice, childNftId, resourceId); - }); - - it('deleting a resource by the collection owner', async () => { - const collectionIdAlice = await createCollection( - api, - Alice, - 'test-metadata', - null, - 'test-symbol', - ); - - const nftBob = await mintNft( - api, - Alice, - Bob, - collectionIdAlice, - 'nft-metadata', - ); - - const resourceId = await addNftBasicResource( - api, - Alice, - 'pending', - collectionIdAlice, - nftBob, - src, - metadata, - license, - thumb, - ); - - await removeNftResource(api, 'pending', Alice, collectionIdAlice, nftBob, resourceId); - await acceptResourceRemoval(api, Bob, collectionIdAlice, nftBob, resourceId); - }); - - it('deleting a resource in a nested NFT by the collection owner', async () => { - const collectionIdAlice = await createCollection( - api, - Alice, - 'test-metadata', - null, - 'test-symbol', - ); - - const parentNftId = await mintNft( - api, - Alice, - Bob, - collectionIdAlice, - 'parent-nft-metadata', - ); - const childNftId = await mintNft( - api, - Alice, - Bob, - collectionIdAlice, - 'child-nft-metadata', - ); - - const resourceId = await addNftBasicResource( - api, - Alice, - 'pending', - collectionIdAlice, - childNftId, - src, - metadata, - license, - thumb, - ); - - const newOwnerNFT: NftIdTuple = [collectionIdAlice, parentNftId]; - - await sendNft(api, 'sent', Bob, collectionIdAlice, childNftId, newOwnerNFT); - - await removeNftResource(api, 'pending', Alice, collectionIdAlice, childNftId, resourceId); - await acceptResourceRemoval(api, Bob, collectionIdAlice, childNftId, resourceId); - }); - - it('[negative]: can\'t delete a resource in a non-existing collection', async () => { - const collectionIdAlice = await createCollection( - api, - Alice, - 'test-metadata', - null, - 'test-symbol', - ); - - const nftAlice = await mintNft( - api, - Alice, - Alice, - collectionIdAlice, - 'nft-metadata', - ); - - const resourceId = await addNftBasicResource( - api, - Alice, - 'added', - collectionIdAlice, - nftAlice, - src, - metadata, - license, - thumb, - ); - - const tx = removeNftResource(api, 'removed', Alice, 0xFFFFFFFF, nftAlice, resourceId); - await expectTxFailure(/rmrkCore\.CollectionUnknown/, tx); // FIXME: inappropriate error message (NoAvailableNftId) - }); - - it('[negative]: only collection owner can delete a resource', async () => { - const collectionIdAlice = await createCollection( - api, - Alice, - 'test-metadata', - null, - 'test-symbol', - ); - - const nftAlice = await mintNft( - api, - Alice, - Alice, - collectionIdAlice, - 'nft-metadata', - ); - - const resourceId = await addNftBasicResource( - api, - Alice, - 'added', - collectionIdAlice, - nftAlice, - src, - metadata, - license, - thumb, - ); - - const tx = removeNftResource(api, 'removed', Bob, collectionIdAlice, nftAlice, resourceId); - await expectTxFailure(/rmrkCore\.NoPermission/, tx); - }); - - it('[negative]: cannot delete a resource that does not exist', async () => { - const collectionIdAlice = await createCollection( - api, - Alice, - 'test-metadata', - null, - 'test-symbol', - ); - - const nftAlice = await mintNft( - api, - Alice, - Alice, - collectionIdAlice, - 'nft-metadata', - ); - - const tx = removeNftResource(api, 'removed', Alice, collectionIdAlice, nftAlice, 127); - await expectTxFailure(/rmrkCore\.ResourceDoesntExist/, tx); - }); - - it('[negative]: Cannot accept deleting resource without owner attempt do delete it', async () => { - const collectionIdAlice = await createCollection( - api, - Alice, - 'test-metadata', - null, - 'test-symbol', - ); - - const nftBob = await mintNft( - api, - Alice, - Bob, - collectionIdAlice, - 'nft-metadata', - ); - - const resourceId = await addNftBasicResource( - api, - Alice, - 'pending', - collectionIdAlice, - nftBob, - src, - metadata, - license, - thumb, - ); - - const tx = acceptResourceRemoval(api, Bob, collectionIdAlice, nftBob, resourceId); - await expectTxFailure(/rmrkCore\.ResourceNotPending/, tx); - }); - - it('[negative]: cannot confirm the deletion of a non-existing resource', async () => { - const collectionIdAlice = await createCollection( - api, - Alice, - 'test-metadata', - null, - 'test-symbol', - ); - - const nftBob = await mintNft( - api, - Alice, - Bob, - collectionIdAlice, - 'nft-metadata', - ); - - const tx = acceptResourceRemoval(api, Bob, collectionIdAlice, nftBob, 127); - await expectTxFailure(/rmrkCore\.ResourceDoesntExist/, tx); - }); - - it('[negative]: Non-owner user cannot confirm the deletion of resource', async () => { - const collectionIdAlice = await createCollection( - api, - Alice, - 'test-metadata', - null, - 'test-symbol', - ); - - const nftAlice = await mintNft( - api, - Alice, - Alice, - collectionIdAlice, - 'nft-metadata', - ); - - const resourceId = await addNftBasicResource( - api, - Alice, - 'added', - collectionIdAlice, - nftAlice, - src, - metadata, - license, - thumb, - ); - - const tx = acceptResourceRemoval(api, Bob, collectionIdAlice, nftAlice, resourceId); - await expectTxFailure(/rmrkCore\.NoPermission/, tx); - }); - - after(() => { - api.disconnect(); - }); -}); --- /dev/null +++ b/tests/src/rmrk/rmrkIsolation.seqtest.ts @@ -0,0 +1,251 @@ +import {expect} from 'chai'; +import usingApi, {executeTransaction} from '../substrate/substrate-api'; +import { + createCollectionExpectSuccess, + createItemExpectSuccess, + getCreateCollectionResult, + getDetailedCollectionInfo, + getGenericResult, + requirePallets, + normalizeAccountId, + Pallets, +} from '../deprecated-helpers/helpers'; +import {IKeyringPair} from '@polkadot/types/types'; +import {ApiPromise} from '@polkadot/api'; +import {it} from 'mocha'; + +let alice: IKeyringPair; +let bob: IKeyringPair; + +async function createRmrkCollection(api: ApiPromise, sender: IKeyringPair): Promise<{uniqueId: number, rmrkId: number}> { + const tx = api.tx.rmrkCore.createCollection('metadata', null, 'symbol'); + const events = await executeTransaction(api, sender, tx); + + const uniqueResult = getCreateCollectionResult(events); + const rmrkResult = getGenericResult(events, 'rmrkCore', 'CollectionCreated', (data) => { + return parseInt(data[1].toString(), 10); + }); + + return { + uniqueId: uniqueResult.collectionId, + rmrkId: rmrkResult.data!, + }; +} + +async function createRmrkNft(api: ApiPromise, sender: IKeyringPair, collectionId: number): Promise { + const tx = api.tx.rmrkCore.mintNft( + sender.address, + collectionId, + sender.address, + null, + 'nft-metadata', + true, + null, + ); + const events = await executeTransaction(api, sender, tx); + const result = getGenericResult(events, 'rmrkCore', 'NftMinted', (data) => { + return parseInt(data[2].toString(), 10); + }); + + return result.data!; +} + +async function isUnique(): Promise { + return usingApi(async api => { + const chain = await api.rpc.system.chain(); + + return chain.eq('UNIQUE'); + }); +} + +describe('RMRK External Integration Test', async () => { + const itRmrk = (await isUnique() ? it : it.skip); + + before(async function() { + await usingApi(async (api, privateKeyWrapper) => { + alice = privateKeyWrapper('//Alice'); + await requirePallets(this, [Pallets.RmrkCore]); + }); + }); + + itRmrk('Creates a new RMRK collection that is mapped to a different ID and is tagged as external', async () => { + await usingApi(async api => { + // throwaway collection to bump last Unique collection ID to test ID mapping + await createCollectionExpectSuccess(); + + const collectionIds = await createRmrkCollection(api, alice); + + expect(collectionIds.rmrkId).to.be.lessThan(collectionIds.uniqueId, 'collection ID mapping'); + + const collection = (await getDetailedCollectionInfo(api, collectionIds.uniqueId))!; + expect(collection.readOnly.toHuman(), 'tagged external').to.be.true; + }); + }); +}); + +describe('Negative Integration Test: External Collections, Internal Ops', async () => { + let uniqueCollectionId: number; + let rmrkCollectionId: number; + let rmrkNftId: number; + + const itRmrk = (await isUnique() ? it : it.skip); + + before(async () => { + await usingApi(async (api, privateKeyWrapper) => { + alice = privateKeyWrapper('//Alice'); + bob = privateKeyWrapper('//Bob'); + + const collectionIds = await createRmrkCollection(api, alice); + uniqueCollectionId = collectionIds.uniqueId; + rmrkCollectionId = collectionIds.rmrkId; + + rmrkNftId = await createRmrkNft(api, alice, rmrkCollectionId); + }); + }); + + itRmrk('[Negative] Forbids Unique operations with an external collection, handled by dispatch_call', async () => { + await usingApi(async api => { + // Collection item creation + + const txCreateItem = api.tx.unique.createItem(uniqueCollectionId, normalizeAccountId(alice), 'NFT'); + await expect(executeTransaction(api, alice, txCreateItem), 'creating item') + .to.be.rejectedWith(/common\.CollectionIsExternal/); + + const txCreateMultipleItems = api.tx.unique.createMultipleItems(uniqueCollectionId, normalizeAccountId(alice), [{NFT: {}}, {NFT: {}}]); + await expect(executeTransaction(api, alice, txCreateMultipleItems), 'creating multiple') + .to.be.rejectedWith(/common\.CollectionIsExternal/); + + const txCreateMultipleItemsEx = api.tx.unique.createMultipleItemsEx(uniqueCollectionId, {NFT: [{}]}); + await expect(executeTransaction(api, alice, txCreateMultipleItemsEx), 'creating multiple ex') + .to.be.rejectedWith(/common\.CollectionIsExternal/); + + // Collection properties + + const txSetCollectionProperties = api.tx.unique.setCollectionProperties(uniqueCollectionId, [{key: 'a', value: '1'}, {key: 'b'}]); + await expect(executeTransaction(api, alice, txSetCollectionProperties), 'setting collection properties') + .to.be.rejectedWith(/common\.CollectionIsExternal/); + + const txDeleteCollectionProperties = api.tx.unique.deleteCollectionProperties(uniqueCollectionId, ['a']); + await expect(executeTransaction(api, alice, txDeleteCollectionProperties), 'deleting collection properties') + .to.be.rejectedWith(/common\.CollectionIsExternal/); + + const txsetTokenPropertyPermissions = api.tx.unique.setTokenPropertyPermissions(uniqueCollectionId, [{key: 'a', permission: {mutable: true}}]); + await expect(executeTransaction(api, alice, txsetTokenPropertyPermissions), 'setting property permissions') + .to.be.rejectedWith(/common\.CollectionIsExternal/); + + // NFT + + const txBurn = api.tx.unique.burnItem(uniqueCollectionId, rmrkNftId, 1); + await expect(executeTransaction(api, alice, txBurn), 'burning').to.be.rejectedWith(/common\.CollectionIsExternal/); + + const txBurnFrom = api.tx.unique.burnFrom(uniqueCollectionId, normalizeAccountId(alice), rmrkNftId, 1); + await expect(executeTransaction(api, alice, txBurnFrom), 'burning-from').to.be.rejectedWith(/common\.CollectionIsExternal/); + + const txTransfer = api.tx.unique.transfer(normalizeAccountId(bob), uniqueCollectionId, rmrkNftId, 1); + await expect(executeTransaction(api, alice, txTransfer), 'transferring').to.be.rejectedWith(/common\.CollectionIsExternal/); + + const txApprove = api.tx.unique.approve(normalizeAccountId(bob), uniqueCollectionId, rmrkNftId, 1); + await expect(executeTransaction(api, alice, txApprove), 'approving').to.be.rejectedWith(/common\.CollectionIsExternal/); + + const txTransferFrom = api.tx.unique.transferFrom(normalizeAccountId(alice), normalizeAccountId(bob), uniqueCollectionId, rmrkNftId, 1); + await expect(executeTransaction(api, alice, txTransferFrom), 'transferring-from').to.be.rejectedWith(/common\.CollectionIsExternal/); + + // NFT properties + + const txSetTokenProperties = api.tx.unique.setTokenProperties(uniqueCollectionId, rmrkNftId, [{key: 'a', value: '2'}]); + await expect(executeTransaction(api, alice, txSetTokenProperties), 'setting token properties') + .to.be.rejectedWith(/common\.CollectionIsExternal/); + + const txDeleteTokenProperties = api.tx.unique.deleteTokenProperties(uniqueCollectionId, rmrkNftId, ['a']); + await expect(executeTransaction(api, alice, txDeleteTokenProperties), 'deleting token properties') + .to.be.rejectedWith(/common\.CollectionIsExternal/); + }); + }); + + itRmrk('[Negative] Forbids Unique collection operations with an external collection', async () => { + await usingApi(async api => { + const txDestroyCollection = api.tx.unique.destroyCollection(uniqueCollectionId); + await expect(executeTransaction(api, alice, txDestroyCollection), 'destroying collection') + .to.be.rejectedWith(/common\.CollectionIsExternal/); + + // Allow list + + const txAddAllowList = api.tx.unique.addToAllowList(uniqueCollectionId, normalizeAccountId(bob)); + await expect(executeTransaction(api, alice, txAddAllowList), 'adding to allow list') + .to.be.rejectedWith(/common\.CollectionIsExternal/); + + const txRemoveAllowList = api.tx.unique.removeFromAllowList(uniqueCollectionId, normalizeAccountId(bob)); + await expect(executeTransaction(api, alice, txRemoveAllowList), 'removing from allowlist') + .to.be.rejectedWith(/common\.CollectionIsExternal/); + + // Owner / Admin / Sponsor + + const txChangeOwner = api.tx.unique.changeCollectionOwner(uniqueCollectionId, bob.address); + await expect(executeTransaction(api, alice, txChangeOwner), 'changing owner') + .to.be.rejectedWith(/common\.CollectionIsExternal/); + + const txAddAdmin = api.tx.unique.addCollectionAdmin(uniqueCollectionId, normalizeAccountId(bob)); + await expect(executeTransaction(api, alice, txAddAdmin), 'adding admin') + .to.be.rejectedWith(/common\.CollectionIsExternal/); + + const txRemoveAdmin = api.tx.unique.removeCollectionAdmin(uniqueCollectionId, normalizeAccountId(bob)); + await expect(executeTransaction(api, alice, txRemoveAdmin), 'removing admin') + .to.be.rejectedWith(/common\.CollectionIsExternal/); + + const txAddCollectionSponsor = api.tx.unique.setCollectionSponsor(uniqueCollectionId, bob.address); + await expect(executeTransaction(api, alice, txAddCollectionSponsor), 'setting sponsor') + .to.be.rejectedWith(/common\.CollectionIsExternal/); + + const txConfirmCollectionSponsor = api.tx.unique.confirmSponsorship(uniqueCollectionId); + await expect(executeTransaction(api, alice, txConfirmCollectionSponsor), 'confirming sponsor') + .to.be.rejectedWith(/common\.CollectionIsExternal/); + + const txRemoveCollectionSponsor = api.tx.unique.removeCollectionSponsor(uniqueCollectionId); + await expect(executeTransaction(api, alice, txRemoveCollectionSponsor), 'removing sponsor') + .to.be.rejectedWith(/common\.CollectionIsExternal/); + + // Limits / permissions / transfers + + const txSetTransfers = api.tx.unique.setTransfersEnabledFlag(uniqueCollectionId, true); + await expect(executeTransaction(api, alice, txSetTransfers), 'setting transfers enabled flag') + .to.be.rejectedWith(/common\.CollectionIsExternal/); + + const txSetLimits = api.tx.unique.setCollectionLimits(uniqueCollectionId, {transfersEnabled: false}); + await expect(executeTransaction(api, alice, txSetLimits), 'setting collection limits') + .to.be.rejectedWith(/common\.CollectionIsExternal/); + + const txSetPermissions = api.tx.unique.setCollectionPermissions(uniqueCollectionId, {access: 'AllowList'}); + await expect(executeTransaction(api, alice, txSetPermissions), 'setting collection permissions') + .to.be.rejectedWith(/common\.CollectionIsExternal/); + }); + }); +}); + +describe('Negative Integration Test: Internal Collections, External Ops', async () => { + let collectionId: number; + let nftId: number; + + const itRmrk = (await isUnique() ? it : it.skip); + + before(async () => { + await usingApi(async (api, privateKeyWrapper) => { + alice = privateKeyWrapper('//Alice'); + bob = privateKeyWrapper('//Bob'); + + collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}}); + nftId = await createItemExpectSuccess(alice, collectionId, 'NFT'); + }); + }); + + itRmrk('[Negative] Forbids RMRK operations with the internal collection and NFT (due to the lack of mapping)', async () => { + await usingApi(async api => { + const txChangeOwner = api.tx.rmrkCore.changeCollectionIssuer(collectionId, bob.address); + await expect(executeTransaction(api, alice, txChangeOwner), 'changing collection issuer') + .to.be.rejectedWith(/rmrkCore\.CollectionUnknown/); + + const maxBurns = 10; + const txBurnItem = api.tx.rmrkCore.burnNft(collectionId, nftId, maxBurns); + await expect(executeTransaction(api, alice, txBurnItem), 'burning NFT').to.be.rejectedWith(/rmrkCore\.CollectionUnknown/); + }); + }); +}); --- a/tests/src/rmrk/rmrkIsolation.test.ts +++ /dev/null @@ -1,251 +0,0 @@ -import {expect} from 'chai'; -import usingApi, {executeTransaction} from '../substrate/substrate-api'; -import { - createCollectionExpectSuccess, - createItemExpectSuccess, - getCreateCollectionResult, - getDetailedCollectionInfo, - getGenericResult, - requirePallets, - normalizeAccountId, - Pallets, -} from '../deprecated-helpers/helpers'; -import {IKeyringPair} from '@polkadot/types/types'; -import {ApiPromise} from '@polkadot/api'; -import {it} from 'mocha'; - -let alice: IKeyringPair; -let bob: IKeyringPair; - -async function createRmrkCollection(api: ApiPromise, sender: IKeyringPair): Promise<{uniqueId: number, rmrkId: number}> { - const tx = api.tx.rmrkCore.createCollection('metadata', null, 'symbol'); - const events = await executeTransaction(api, sender, tx); - - const uniqueResult = getCreateCollectionResult(events); - const rmrkResult = getGenericResult(events, 'rmrkCore', 'CollectionCreated', (data) => { - return parseInt(data[1].toString(), 10); - }); - - return { - uniqueId: uniqueResult.collectionId, - rmrkId: rmrkResult.data!, - }; -} - -async function createRmrkNft(api: ApiPromise, sender: IKeyringPair, collectionId: number): Promise { - const tx = api.tx.rmrkCore.mintNft( - sender.address, - collectionId, - sender.address, - null, - 'nft-metadata', - true, - null, - ); - const events = await executeTransaction(api, sender, tx); - const result = getGenericResult(events, 'rmrkCore', 'NftMinted', (data) => { - return parseInt(data[2].toString(), 10); - }); - - return result.data!; -} - -async function isUnique(): Promise { - return usingApi(async api => { - const chain = await api.rpc.system.chain(); - - return chain.eq('UNIQUE'); - }); -} - -describe('RMRK External Integration Test', async () => { - const it_rmrk = (await isUnique() ? it : it.skip); - - before(async function() { - await usingApi(async (api, privateKeyWrapper) => { - alice = privateKeyWrapper('//Alice'); - await requirePallets(this, [Pallets.RmrkCore]); - }); - }); - - it_rmrk('Creates a new RMRK collection that is mapped to a different ID and is tagged as external', async () => { - await usingApi(async api => { - // throwaway collection to bump last Unique collection ID to test ID mapping - await createCollectionExpectSuccess(); - - const collectionIds = await createRmrkCollection(api, alice); - - expect(collectionIds.rmrkId).to.be.lessThan(collectionIds.uniqueId, 'collection ID mapping'); - - const collection = (await getDetailedCollectionInfo(api, collectionIds.uniqueId))!; - expect(collection.readOnly.toHuman(), 'tagged external').to.be.true; - }); - }); -}); - -describe('Negative Integration Test: External Collections, Internal Ops', async () => { - let uniqueCollectionId: number; - let rmrkCollectionId: number; - let rmrkNftId: number; - - const it_rmrk = (await isUnique() ? it : it.skip); - - before(async () => { - await usingApi(async (api, privateKeyWrapper) => { - alice = privateKeyWrapper('//Alice'); - bob = privateKeyWrapper('//Bob'); - - const collectionIds = await createRmrkCollection(api, alice); - uniqueCollectionId = collectionIds.uniqueId; - rmrkCollectionId = collectionIds.rmrkId; - - rmrkNftId = await createRmrkNft(api, alice, rmrkCollectionId); - }); - }); - - it_rmrk('[Negative] Forbids Unique operations with an external collection, handled by dispatch_call', async () => { - await usingApi(async api => { - // Collection item creation - - const txCreateItem = api.tx.unique.createItem(uniqueCollectionId, normalizeAccountId(alice), 'NFT'); - await expect(executeTransaction(api, alice, txCreateItem), 'creating item') - .to.be.rejectedWith(/common\.CollectionIsExternal/); - - const txCreateMultipleItems = api.tx.unique.createMultipleItems(uniqueCollectionId, normalizeAccountId(alice), [{NFT: {}}, {NFT: {}}]); - await expect(executeTransaction(api, alice, txCreateMultipleItems), 'creating multiple') - .to.be.rejectedWith(/common\.CollectionIsExternal/); - - const txCreateMultipleItemsEx = api.tx.unique.createMultipleItemsEx(uniqueCollectionId, {NFT: [{}]}); - await expect(executeTransaction(api, alice, txCreateMultipleItemsEx), 'creating multiple ex') - .to.be.rejectedWith(/common\.CollectionIsExternal/); - - // Collection properties - - const txSetCollectionProperties = api.tx.unique.setCollectionProperties(uniqueCollectionId, [{key: 'a', value: '1'}, {key: 'b'}]); - await expect(executeTransaction(api, alice, txSetCollectionProperties), 'setting collection properties') - .to.be.rejectedWith(/common\.CollectionIsExternal/); - - const txDeleteCollectionProperties = api.tx.unique.deleteCollectionProperties(uniqueCollectionId, ['a']); - await expect(executeTransaction(api, alice, txDeleteCollectionProperties), 'deleting collection properties') - .to.be.rejectedWith(/common\.CollectionIsExternal/); - - const txsetTokenPropertyPermissions = api.tx.unique.setTokenPropertyPermissions(uniqueCollectionId, [{key: 'a', permission: {mutable: true}}]); - await expect(executeTransaction(api, alice, txsetTokenPropertyPermissions), 'setting property permissions') - .to.be.rejectedWith(/common\.CollectionIsExternal/); - - // NFT - - const txBurn = api.tx.unique.burnItem(uniqueCollectionId, rmrkNftId, 1); - await expect(executeTransaction(api, alice, txBurn), 'burning').to.be.rejectedWith(/common\.CollectionIsExternal/); - - const txBurnFrom = api.tx.unique.burnFrom(uniqueCollectionId, normalizeAccountId(alice), rmrkNftId, 1); - await expect(executeTransaction(api, alice, txBurnFrom), 'burning-from').to.be.rejectedWith(/common\.CollectionIsExternal/); - - const txTransfer = api.tx.unique.transfer(normalizeAccountId(bob), uniqueCollectionId, rmrkNftId, 1); - await expect(executeTransaction(api, alice, txTransfer), 'transferring').to.be.rejectedWith(/common\.CollectionIsExternal/); - - const txApprove = api.tx.unique.approve(normalizeAccountId(bob), uniqueCollectionId, rmrkNftId, 1); - await expect(executeTransaction(api, alice, txApprove), 'approving').to.be.rejectedWith(/common\.CollectionIsExternal/); - - const txTransferFrom = api.tx.unique.transferFrom(normalizeAccountId(alice), normalizeAccountId(bob), uniqueCollectionId, rmrkNftId, 1); - await expect(executeTransaction(api, alice, txTransferFrom), 'transferring-from').to.be.rejectedWith(/common\.CollectionIsExternal/); - - // NFT properties - - const txSetTokenProperties = api.tx.unique.setTokenProperties(uniqueCollectionId, rmrkNftId, [{key: 'a', value: '2'}]); - await expect(executeTransaction(api, alice, txSetTokenProperties), 'setting token properties') - .to.be.rejectedWith(/common\.CollectionIsExternal/); - - const txDeleteTokenProperties = api.tx.unique.deleteTokenProperties(uniqueCollectionId, rmrkNftId, ['a']); - await expect(executeTransaction(api, alice, txDeleteTokenProperties), 'deleting token properties') - .to.be.rejectedWith(/common\.CollectionIsExternal/); - }); - }); - - it_rmrk('[Negative] Forbids Unique collection operations with an external collection', async () => { - await usingApi(async api => { - const txDestroyCollection = api.tx.unique.destroyCollection(uniqueCollectionId); - await expect(executeTransaction(api, alice, txDestroyCollection), 'destroying collection') - .to.be.rejectedWith(/common\.CollectionIsExternal/); - - // Allow list - - const txAddAllowList = api.tx.unique.addToAllowList(uniqueCollectionId, normalizeAccountId(bob)); - await expect(executeTransaction(api, alice, txAddAllowList), 'adding to allow list') - .to.be.rejectedWith(/common\.CollectionIsExternal/); - - const txRemoveAllowList = api.tx.unique.removeFromAllowList(uniqueCollectionId, normalizeAccountId(bob)); - await expect(executeTransaction(api, alice, txRemoveAllowList), 'removing from allowlist') - .to.be.rejectedWith(/common\.CollectionIsExternal/); - - // Owner / Admin / Sponsor - - const txChangeOwner = api.tx.unique.changeCollectionOwner(uniqueCollectionId, bob.address); - await expect(executeTransaction(api, alice, txChangeOwner), 'changing owner') - .to.be.rejectedWith(/common\.CollectionIsExternal/); - - const txAddAdmin = api.tx.unique.addCollectionAdmin(uniqueCollectionId, normalizeAccountId(bob)); - await expect(executeTransaction(api, alice, txAddAdmin), 'adding admin') - .to.be.rejectedWith(/common\.CollectionIsExternal/); - - const txRemoveAdmin = api.tx.unique.removeCollectionAdmin(uniqueCollectionId, normalizeAccountId(bob)); - await expect(executeTransaction(api, alice, txRemoveAdmin), 'removing admin') - .to.be.rejectedWith(/common\.CollectionIsExternal/); - - const txAddCollectionSponsor = api.tx.unique.setCollectionSponsor(uniqueCollectionId, bob.address); - await expect(executeTransaction(api, alice, txAddCollectionSponsor), 'setting sponsor') - .to.be.rejectedWith(/common\.CollectionIsExternal/); - - const txConfirmCollectionSponsor = api.tx.unique.confirmSponsorship(uniqueCollectionId); - await expect(executeTransaction(api, alice, txConfirmCollectionSponsor), 'confirming sponsor') - .to.be.rejectedWith(/common\.CollectionIsExternal/); - - const txRemoveCollectionSponsor = api.tx.unique.removeCollectionSponsor(uniqueCollectionId); - await expect(executeTransaction(api, alice, txRemoveCollectionSponsor), 'removing sponsor') - .to.be.rejectedWith(/common\.CollectionIsExternal/); - - // Limits / permissions / transfers - - const txSetTransfers = api.tx.unique.setTransfersEnabledFlag(uniqueCollectionId, true); - await expect(executeTransaction(api, alice, txSetTransfers), 'setting transfers enabled flag') - .to.be.rejectedWith(/common\.CollectionIsExternal/); - - const txSetLimits = api.tx.unique.setCollectionLimits(uniqueCollectionId, {transfersEnabled: false}); - await expect(executeTransaction(api, alice, txSetLimits), 'setting collection limits') - .to.be.rejectedWith(/common\.CollectionIsExternal/); - - const txSetPermissions = api.tx.unique.setCollectionPermissions(uniqueCollectionId, {access: 'AllowList'}); - await expect(executeTransaction(api, alice, txSetPermissions), 'setting collection permissions') - .to.be.rejectedWith(/common\.CollectionIsExternal/); - }); - }); -}); - -describe('Negative Integration Test: Internal Collections, External Ops', async () => { - let collectionId: number; - let nftId: number; - - const it_rmrk = (await isUnique() ? it : it.skip); - - before(async () => { - await usingApi(async (api, privateKeyWrapper) => { - alice = privateKeyWrapper('//Alice'); - bob = privateKeyWrapper('//Bob'); - - collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}}); - nftId = await createItemExpectSuccess(alice, collectionId, 'NFT'); - }); - }); - - it_rmrk('[Negative] Forbids RMRK operations with the internal collection and NFT (due to the lack of mapping)', async () => { - await usingApi(async api => { - const txChangeOwner = api.tx.rmrkCore.changeCollectionIssuer(collectionId, bob.address); - await expect(executeTransaction(api, alice, txChangeOwner), 'changing collection issuer') - .to.be.rejectedWith(/rmrkCore\.CollectionUnknown/); - - const maxBurns = 10; - const txBurnItem = api.tx.rmrkCore.burnNft(collectionId, nftId, maxBurns); - await expect(executeTransaction(api, alice, txBurnItem), 'burning NFT').to.be.rejectedWith(/rmrkCore\.CollectionUnknown/); - }); - }); -}); --- /dev/null +++ b/tests/src/rmrk/sendNft.seqtest.ts @@ -0,0 +1,256 @@ +import {expect} from 'chai'; +import {getApiConnection} from '../substrate/substrate-api'; +import {createCollection, mintNft, sendNft} from './util/tx'; +import {NftIdTuple} from './util/fetch'; +import {isNftChildOfAnother, expectTxFailure} from './util/helpers'; +import {requirePallets, Pallets} from '../deprecated-helpers/helpers'; + +describe('integration test: send NFT', () => { + let api: any; + before(async function () { + api = await getApiConnection(); + await requirePallets(this, [Pallets.RmrkCore]); + }); + + const maxNftId = 0xFFFFFFFF; + + const alice = '//Alice'; + const bob = '//Bob'; + + const createTestCollection = async (issuerUri: string) => { + return await createCollection( + api, + issuerUri, + 'nft-collection-metadata', + null, + 'nft-collection', + ); + }; + + + it('send NFT to another user', async () => { + const originalOwnerUri = alice; + const newOwnerUri = bob; + + const collectionId = await createTestCollection(alice); + + const nftId = await mintNft(api, alice, originalOwnerUri, collectionId, 'nft-metadata'); + + await sendNft(api, 'sent', originalOwnerUri, collectionId, nftId, newOwnerUri); + }); + + it('[negative] unable to send non-existing NFT', async () => { + const originalOwnerUri = alice; + const newOwnerUri = bob; + + const collectionId = 0; + const tx = sendNft(api, 'sent', originalOwnerUri, collectionId, maxNftId, newOwnerUri); + + await expectTxFailure(/rmrkCore\.NoAvailableNftId/, tx); + }); + + it('[negative] unable to send NFT by a not-an-owner', async () => { + const originalOwnerUri = alice; + const newOwnerUri = bob; + + const collectionId = await createTestCollection(alice); + + const nftId = await mintNft(api, alice, originalOwnerUri, collectionId, 'nft-metadata'); + + const tx = sendNft(api, 'sent', newOwnerUri, collectionId, nftId, newOwnerUri); + await expectTxFailure(/rmrkCore\.NoPermission/, tx); + }); + + it('send NFT to another NFT (same owner)', async () => { + const originalOwnerUri = alice; + + const collectionId = await createTestCollection(alice); + + const parentNftId = await mintNft(api, alice, originalOwnerUri, collectionId, 'parent-nft-metadata'); + const childNftId = await mintNft(api, alice, originalOwnerUri, collectionId, 'child-nft-metadata'); + + const newOwnerNFT: NftIdTuple = [collectionId, parentNftId]; + + await sendNft(api, 'sent', alice, collectionId, childNftId, newOwnerNFT); + + const isChild = await isNftChildOfAnother(api, collectionId, childNftId, newOwnerNFT); + expect(isChild).to.be.true; + }); + + it('[negative] send non-existing NFT to another NFT', async () => { + const originalOwnerUri = alice; + + const collectionId = await createTestCollection(alice); + + const parentNftId = await mintNft(api, alice, originalOwnerUri, collectionId, 'parent-nft-metadata'); + const childNftId = maxNftId; + + const newOwnerNFT: NftIdTuple = [collectionId, parentNftId]; + + const tx = sendNft(api, 'sent', alice, collectionId, childNftId, newOwnerNFT); + + await expectTxFailure(/rmrkCore\.NoAvailableNftId/, tx); + + const isChild = await isNftChildOfAnother(api, collectionId, childNftId, newOwnerNFT); + expect(isChild).to.be.false; + }); + + it('send NFT to another NFT (by not-an-owner)', async () => { + const originalOwnerUri = alice; + + const collectionId = await createTestCollection(alice); + + const author = alice; + const attacker = bob; + + const parentNftId = await mintNft(api, author, originalOwnerUri, collectionId, 'parent-nft-metadata'); + const childNftId = await mintNft(api, author, originalOwnerUri, collectionId, 'child-nft-metadata'); + + const newOwnerNFT: NftIdTuple = [collectionId, parentNftId]; + + const tx = sendNft(api, 'sent', attacker, collectionId, childNftId, newOwnerNFT); + + await expectTxFailure(/rmrkCore\.NoPermission/, tx); + + const isChild = await isNftChildOfAnother(api, collectionId, childNftId, newOwnerNFT); + expect(isChild).to.be.false; + }); + + it('[negative] send NFT to non-existing NFT', async () => { + const originalOwnerUri = alice; + + const collectionId = await createTestCollection(alice); + + const parentNftId = maxNftId; + const childNftId = await mintNft(api, alice, originalOwnerUri, collectionId, 'child-nft-metadata'); + + const newOwnerNFT: NftIdTuple = [collectionId, parentNftId]; + + const tx = sendNft(api, 'sent', alice, collectionId, childNftId, newOwnerNFT); + + await expectTxFailure(/rmrkCore\.NoAvailableNftId/, tx); + + const isChild = await isNftChildOfAnother(api, collectionId, childNftId, newOwnerNFT); + expect(isChild).to.be.false; + }); + + it('send NFT to another NFT owned by another user', async () => { + const ownerAlice = alice; + const ownerBob = bob; + + const aliceCollectionId = await createTestCollection(alice); + const bobCollectionId = await createTestCollection(bob); + + const parentNftId = await mintNft(api, alice, ownerAlice, aliceCollectionId, 'parent-nft-metadata'); + const childNftId = await mintNft(api, bob, ownerBob, bobCollectionId, 'child-nft-metadata'); + + const newOwnerNFT: NftIdTuple = [aliceCollectionId, parentNftId]; + + await sendNft(api, 'pending', bob, bobCollectionId, childNftId, newOwnerNFT); + }); + + it('[negative] unable to send NFT to itself', async () => { + const nftOwner = alice; + const collectionId = await createTestCollection(alice); + + const nftId = await mintNft(api, alice, nftOwner, collectionId, 'ouroboros-nft-metadata'); + + const newOwnerNFT: NftIdTuple = [collectionId, nftId]; + + const tx = sendNft(api, 'sent', alice, collectionId, nftId, newOwnerNFT); + + await expectTxFailure(/rmrkCore\.CannotSendToDescendentOrSelf/, tx); + + const isChild = await isNftChildOfAnother(api, collectionId, nftId, newOwnerNFT); + expect(isChild).to.be.false; + }); + + it('[negative] unable to send NFT to child NFT', async () => { + const originalOwnerUri = alice; + + const collectionId = await createTestCollection(alice); + + const parentNftId = await mintNft(api, alice, originalOwnerUri, collectionId, 'parent-nft-metadata'); + const childNftId = await mintNft(api, alice, originalOwnerUri, collectionId, 'child-nft-metadata'); + + const newOwnerNFT: NftIdTuple = [collectionId, parentNftId]; + + await sendNft(api, 'sent', alice, collectionId, childNftId, newOwnerNFT); + + const isChild = await isNftChildOfAnother(api, collectionId, childNftId, newOwnerNFT); + expect(isChild).to.be.true; + + const descendentOwner: NftIdTuple = [collectionId, childNftId]; + const tx = sendNft(api, 'sent', alice, collectionId, parentNftId, descendentOwner); + + await expectTxFailure(/rmrkCore\.CannotSendToDescendentOrSelf/, tx); + const isOuroboros = await isNftChildOfAnother(api, collectionId, parentNftId, descendentOwner); + expect(isOuroboros).to.be.false; + }); + + it('[negative] unable to send NFT to descendent NFT', async () => { + const originalOwnerUri = alice; + + const collectionId = await createTestCollection(alice); + + const parentNftId = await mintNft(api, alice, originalOwnerUri, collectionId, 'parent-nft-metadata'); + const childNftId = await mintNft(api, alice, originalOwnerUri, collectionId, 'child-nft-metadata'); + const grandsonNftId = await mintNft(api, alice, originalOwnerUri, collectionId, 'grandson-nft-metadata'); + + const ownerParentNFT: NftIdTuple = [collectionId, parentNftId]; + + await sendNft(api, 'sent', alice, collectionId, childNftId, ownerParentNFT); + + const isChild = await isNftChildOfAnother(api, collectionId, childNftId, ownerParentNFT); + expect(isChild).to.be.true; + + const ownerChildNFT: NftIdTuple = [collectionId, childNftId]; + await sendNft(api, 'sent', alice, collectionId, grandsonNftId, ownerChildNFT); + + const isGrandson = await isNftChildOfAnother(api, collectionId, grandsonNftId, ownerChildNFT); + expect(isGrandson).to.be.true; + + const ownerGrandsonNFT: NftIdTuple = [collectionId, grandsonNftId]; + const tx = sendNft(api, 'sent', alice, collectionId, parentNftId, ownerGrandsonNFT); + + await expectTxFailure(/rmrkCore\.CannotSendToDescendentOrSelf/, tx); + const isOuroboros = await isNftChildOfAnother(api, collectionId, parentNftId, ownerGrandsonNFT); + expect(isOuroboros).to.be.false; + }); + + it('send nested NFT to another user', async () => { + const originalOwner = alice; + const newOwner = bob; + + const collectionId = await createTestCollection(alice); + + const parentNftId = await mintNft(api, alice, originalOwner, collectionId, 'parent-nft-metadata'); + const childNftId = await mintNft(api, alice, originalOwner, collectionId, 'child-nft-metadata'); + + const parentNftTuple: NftIdTuple = [collectionId, parentNftId]; + + await sendNft(api, 'sent', originalOwner, collectionId, childNftId, parentNftTuple); + + await sendNft(api, 'sent', originalOwner, collectionId, childNftId, newOwner); + }); + + it('[negative] send nested NFT to another user (by a not-root-owner)', async () => { + const originalOwner = alice; + const newOwner = bob; + + const collectionId = await createTestCollection(alice); + + const parentNftId = await mintNft(api, alice, originalOwner, collectionId, 'parent-nft-metadata'); + const childNftId = await mintNft(api, alice, originalOwner, collectionId, 'child-nft-metadata'); + + const parentNftTuple: NftIdTuple = [collectionId, parentNftId]; + + await sendNft(api, 'sent', originalOwner, collectionId, childNftId, parentNftTuple); + + const tx = sendNft(api, 'sent', newOwner, collectionId, childNftId, newOwner); + + await expectTxFailure(/rmrkCore\.NoPermission/, tx); + }); + + after(() => { api.disconnect(); }); +}); --- a/tests/src/rmrk/sendNft.test.ts +++ /dev/null @@ -1,256 +0,0 @@ -import {expect} from 'chai'; -import {getApiConnection} from '../substrate/substrate-api'; -import {createCollection, mintNft, sendNft} from './util/tx'; -import {NftIdTuple} from './util/fetch'; -import {isNftChildOfAnother, expectTxFailure} from './util/helpers'; -import {requirePallets, Pallets} from '../deprecated-helpers/helpers'; - -describe('integration test: send NFT', () => { - let api: any; - before(async function () { - api = await getApiConnection(); - await requirePallets(this, [Pallets.RmrkCore]); - }); - - const maxNftId = 0xFFFFFFFF; - - const alice = '//Alice'; - const bob = '//Bob'; - - const createTestCollection = async (issuerUri: string) => { - return await createCollection( - api, - issuerUri, - 'nft-collection-metadata', - null, - 'nft-collection', - ); - }; - - - it('send NFT to another user', async () => { - const originalOwnerUri = alice; - const newOwnerUri = bob; - - const collectionId = await createTestCollection(alice); - - const nftId = await mintNft(api, alice, originalOwnerUri, collectionId, 'nft-metadata'); - - await sendNft(api, 'sent', originalOwnerUri, collectionId, nftId, newOwnerUri); - }); - - it('[negative] unable to send non-existing NFT', async () => { - const originalOwnerUri = alice; - const newOwnerUri = bob; - - const collectionId = 0; - const tx = sendNft(api, 'sent', originalOwnerUri, collectionId, maxNftId, newOwnerUri); - - await expectTxFailure(/rmrkCore\.NoAvailableNftId/, tx); - }); - - it('[negative] unable to send NFT by a not-an-owner', async () => { - const originalOwnerUri = alice; - const newOwnerUri = bob; - - const collectionId = await createTestCollection(alice); - - const nftId = await mintNft(api, alice, originalOwnerUri, collectionId, 'nft-metadata'); - - const tx = sendNft(api, 'sent', newOwnerUri, collectionId, nftId, newOwnerUri); - await expectTxFailure(/rmrkCore\.NoPermission/, tx); - }); - - it('send NFT to another NFT (same owner)', async () => { - const originalOwnerUri = alice; - - const collectionId = await createTestCollection(alice); - - const parentNftId = await mintNft(api, alice, originalOwnerUri, collectionId, 'parent-nft-metadata'); - const childNftId = await mintNft(api, alice, originalOwnerUri, collectionId, 'child-nft-metadata'); - - const newOwnerNFT: NftIdTuple = [collectionId, parentNftId]; - - await sendNft(api, 'sent', alice, collectionId, childNftId, newOwnerNFT); - - const isChild = await isNftChildOfAnother(api, collectionId, childNftId, newOwnerNFT); - expect(isChild).to.be.true; - }); - - it('[negative] send non-existing NFT to another NFT', async () => { - const originalOwnerUri = alice; - - const collectionId = await createTestCollection(alice); - - const parentNftId = await mintNft(api, alice, originalOwnerUri, collectionId, 'parent-nft-metadata'); - const childNftId = maxNftId; - - const newOwnerNFT: NftIdTuple = [collectionId, parentNftId]; - - const tx = sendNft(api, 'sent', alice, collectionId, childNftId, newOwnerNFT); - - await expectTxFailure(/rmrkCore\.NoAvailableNftId/, tx); - - const isChild = await isNftChildOfAnother(api, collectionId, childNftId, newOwnerNFT); - expect(isChild).to.be.false; - }); - - it('send NFT to another NFT (by not-an-owner)', async () => { - const originalOwnerUri = alice; - - const collectionId = await createTestCollection(alice); - - const author = alice; - const attacker = bob; - - const parentNftId = await mintNft(api, author, originalOwnerUri, collectionId, 'parent-nft-metadata'); - const childNftId = await mintNft(api, author, originalOwnerUri, collectionId, 'child-nft-metadata'); - - const newOwnerNFT: NftIdTuple = [collectionId, parentNftId]; - - const tx = sendNft(api, 'sent', attacker, collectionId, childNftId, newOwnerNFT); - - await expectTxFailure(/rmrkCore\.NoPermission/, tx); - - const isChild = await isNftChildOfAnother(api, collectionId, childNftId, newOwnerNFT); - expect(isChild).to.be.false; - }); - - it('[negative] send NFT to non-existing NFT', async () => { - const originalOwnerUri = alice; - - const collectionId = await createTestCollection(alice); - - const parentNftId = maxNftId; - const childNftId = await mintNft(api, alice, originalOwnerUri, collectionId, 'child-nft-metadata'); - - const newOwnerNFT: NftIdTuple = [collectionId, parentNftId]; - - const tx = sendNft(api, 'sent', alice, collectionId, childNftId, newOwnerNFT); - - await expectTxFailure(/rmrkCore\.NoAvailableNftId/, tx); - - const isChild = await isNftChildOfAnother(api, collectionId, childNftId, newOwnerNFT); - expect(isChild).to.be.false; - }); - - it('send NFT to another NFT owned by another user', async () => { - const ownerAlice = alice; - const ownerBob = bob; - - const aliceCollectionId = await createTestCollection(alice); - const bobCollectionId = await createTestCollection(bob); - - const parentNftId = await mintNft(api, alice, ownerAlice, aliceCollectionId, 'parent-nft-metadata'); - const childNftId = await mintNft(api, bob, ownerBob, bobCollectionId, 'child-nft-metadata'); - - const newOwnerNFT: NftIdTuple = [aliceCollectionId, parentNftId]; - - await sendNft(api, 'pending', bob, bobCollectionId, childNftId, newOwnerNFT); - }); - - it('[negative] unable to send NFT to itself', async () => { - const nftOwner = alice; - const collectionId = await createTestCollection(alice); - - const nftId = await mintNft(api, alice, nftOwner, collectionId, 'ouroboros-nft-metadata'); - - const newOwnerNFT: NftIdTuple = [collectionId, nftId]; - - const tx = sendNft(api, 'sent', alice, collectionId, nftId, newOwnerNFT); - - await expectTxFailure(/rmrkCore\.CannotSendToDescendentOrSelf/, tx); - - const isChild = await isNftChildOfAnother(api, collectionId, nftId, newOwnerNFT); - expect(isChild).to.be.false; - }); - - it('[negative] unable to send NFT to child NFT', async () => { - const originalOwnerUri = alice; - - const collectionId = await createTestCollection(alice); - - const parentNftId = await mintNft(api, alice, originalOwnerUri, collectionId, 'parent-nft-metadata'); - const childNftId = await mintNft(api, alice, originalOwnerUri, collectionId, 'child-nft-metadata'); - - const newOwnerNFT: NftIdTuple = [collectionId, parentNftId]; - - await sendNft(api, 'sent', alice, collectionId, childNftId, newOwnerNFT); - - const isChild = await isNftChildOfAnother(api, collectionId, childNftId, newOwnerNFT); - expect(isChild).to.be.true; - - const descendentOwner: NftIdTuple = [collectionId, childNftId]; - const tx = sendNft(api, 'sent', alice, collectionId, parentNftId, descendentOwner); - - await expectTxFailure(/rmrkCore\.CannotSendToDescendentOrSelf/, tx); - const isOuroboros = await isNftChildOfAnother(api, collectionId, parentNftId, descendentOwner); - expect(isOuroboros).to.be.false; - }); - - it('[negative] unable to send NFT to descendent NFT', async () => { - const originalOwnerUri = alice; - - const collectionId = await createTestCollection(alice); - - const parentNftId = await mintNft(api, alice, originalOwnerUri, collectionId, 'parent-nft-metadata'); - const childNftId = await mintNft(api, alice, originalOwnerUri, collectionId, 'child-nft-metadata'); - const grandsonNftId = await mintNft(api, alice, originalOwnerUri, collectionId, 'grandson-nft-metadata'); - - const ownerParentNFT: NftIdTuple = [collectionId, parentNftId]; - - await sendNft(api, 'sent', alice, collectionId, childNftId, ownerParentNFT); - - const isChild = await isNftChildOfAnother(api, collectionId, childNftId, ownerParentNFT); - expect(isChild).to.be.true; - - const ownerChildNFT: NftIdTuple = [collectionId, childNftId]; - await sendNft(api, 'sent', alice, collectionId, grandsonNftId, ownerChildNFT); - - const isGrandson = await isNftChildOfAnother(api, collectionId, grandsonNftId, ownerChildNFT); - expect(isGrandson).to.be.true; - - const ownerGrandsonNFT: NftIdTuple = [collectionId, grandsonNftId]; - const tx = sendNft(api, 'sent', alice, collectionId, parentNftId, ownerGrandsonNFT); - - await expectTxFailure(/rmrkCore\.CannotSendToDescendentOrSelf/, tx); - const isOuroboros = await isNftChildOfAnother(api, collectionId, parentNftId, ownerGrandsonNFT); - expect(isOuroboros).to.be.false; - }); - - it('send nested NFT to another user', async () => { - const originalOwner = alice; - const newOwner = bob; - - const collectionId = await createTestCollection(alice); - - const parentNftId = await mintNft(api, alice, originalOwner, collectionId, 'parent-nft-metadata'); - const childNftId = await mintNft(api, alice, originalOwner, collectionId, 'child-nft-metadata'); - - const parentNftTuple: NftIdTuple = [collectionId, parentNftId]; - - await sendNft(api, 'sent', originalOwner, collectionId, childNftId, parentNftTuple); - - await sendNft(api, 'sent', originalOwner, collectionId, childNftId, newOwner); - }); - - it('[negative] send nested NFT to another user (by a not-root-owner)', async () => { - const originalOwner = alice; - const newOwner = bob; - - const collectionId = await createTestCollection(alice); - - const parentNftId = await mintNft(api, alice, originalOwner, collectionId, 'parent-nft-metadata'); - const childNftId = await mintNft(api, alice, originalOwner, collectionId, 'child-nft-metadata'); - - const parentNftTuple: NftIdTuple = [collectionId, parentNftId]; - - await sendNft(api, 'sent', originalOwner, collectionId, childNftId, parentNftTuple); - - const tx = sendNft(api, 'sent', newOwner, collectionId, childNftId, newOwner); - - await expectTxFailure(/rmrkCore\.NoPermission/, tx); - }); - - after(() => { api.disconnect(); }); -}); --- /dev/null +++ b/tests/src/rmrk/setCollectionProperty.seqtest.ts @@ -0,0 +1,69 @@ +import {getApiConnection} from '../substrate/substrate-api'; +import {requirePallets, Pallets} from '../deprecated-helpers/helpers'; +import {expectTxFailure} from './util/helpers'; +import {createCollection, setPropertyCollection} from './util/tx'; + +describe('integration test: set collection property', () => { + const alice = '//Alice'; + const bob = '//Bob'; + + let api: any; + before(async function () { + api = await getApiConnection(); + await requirePallets(this, [Pallets.RmrkCore]); + }); + + it('set collection property', async () => { + await createCollection( + api, + alice, + 'test-metadata', + null, + 'test-symbol', + ).then(async (collectionId) => { + await setPropertyCollection(api, alice, collectionId, 'test_key', '42'); + await setPropertyCollection(api, alice, collectionId, 'test_key', '10'); + await setPropertyCollection( + api, + alice, + collectionId, + 'second_test_key', + '111', + ); + }); + }); + + it('[negative] set non-existing collection property', async () => { + const tx = setPropertyCollection( + api, + alice, + 9999, + 'test_key', + '42', + ); + await expectTxFailure(/rmrkCore\.CollectionUnknown/, tx); + }); + + it('[negative] set property not an owner NFT collection issuer', async () => { + await createCollection( + api, + bob, + 'test-metadata', + null, + 'test-symbol', + ).then(async (collectionId) => { + const tx = setPropertyCollection( + api, + alice, + collectionId, + 'test_key', + '42', + ); + await expectTxFailure(/rmrkCore\.NoPermission/, tx); + }); + }); + + after(() => { + api.disconnect(); + }); +}); --- a/tests/src/rmrk/setCollectionProperty.test.ts +++ /dev/null @@ -1,69 +0,0 @@ -import {getApiConnection} from '../substrate/substrate-api'; -import {requirePallets, Pallets} from '../deprecated-helpers/helpers'; -import {expectTxFailure} from './util/helpers'; -import {createCollection, setPropertyCollection} from './util/tx'; - -describe('integration test: set collection property', () => { - const Alice = '//Alice'; - const Bob = '//Bob'; - - let api: any; - before(async function () { - api = await getApiConnection(); - await requirePallets(this, [Pallets.RmrkCore]); - }); - - it('set collection property', async () => { - await createCollection( - api, - Alice, - 'test-metadata', - null, - 'test-symbol', - ).then(async (collectionId) => { - await setPropertyCollection(api, Alice, collectionId, 'test_key', '42'); - await setPropertyCollection(api, Alice, collectionId, 'test_key', '10'); - await setPropertyCollection( - api, - Alice, - collectionId, - 'second_test_key', - '111', - ); - }); - }); - - it('[negative] set non-existing collection property', async () => { - const tx = setPropertyCollection( - api, - Alice, - 9999, - 'test_key', - '42', - ); - await expectTxFailure(/rmrkCore\.CollectionUnknown/, tx); - }); - - it('[negative] set property not an owner NFT collection issuer', async () => { - await createCollection( - api, - Bob, - 'test-metadata', - null, - 'test-symbol', - ).then(async (collectionId) => { - const tx = setPropertyCollection( - api, - Alice, - collectionId, - 'test_key', - '42', - ); - await expectTxFailure(/rmrkCore\.NoPermission/, tx); - }); - }); - - after(() => { - api.disconnect(); - }); -}); --- /dev/null +++ b/tests/src/rmrk/setEquippableList.seqtest.ts @@ -0,0 +1,115 @@ +import {getApiConnection} from '../substrate/substrate-api'; +import {requirePallets, Pallets} from '../deprecated-helpers/helpers'; +import {expectTxFailure} from './util/helpers'; +import {createCollection, createBase, setEquippableList} from './util/tx'; + +describe("integration test: set slot's Equippable List", () => { + let api: any; + before(async function () { + api = await getApiConnection(); + await requirePallets(this, [Pallets.RmrkCore]); + }); + + const alice = '//Alice'; + const bob = '//Bob'; + + it("set Base's slot Equippable List", async () => { + const collectionIds = [ + await createCollection( + api, + alice, + 'equiplist-collection-metadata', + null, + 'equiplist-0', + ), + await createCollection( + api, + alice, + 'equiplist-collection-metadata', + null, + 'equiplist-1', + ), + ]; + + const slotId = 202; + + const baseId = await createBase(api, alice, 'slotpartany-base-type', 'slotpartany', [ + { + 'SlotPart': { + id: slotId, + equippable: 'All', + z: 1, + src: 'some-fallback-slot-url', + }, + }, + ]); + + await setEquippableList(api, alice, baseId, slotId, 'All'); + await setEquippableList(api, alice, baseId, slotId, 'Empty'); + await setEquippableList(api, alice, baseId, slotId, {'Custom': collectionIds}); + }); + + it('[negative] unable to set equippable list of a slot of non-existing base', async () => { + const maxBaseId = 0xFFFFFFFF; + const slotId = 0; + + const tx = setEquippableList(api, alice, maxBaseId, slotId, 'All'); + await expectTxFailure(/rmrkEquip\.BaseDoesntExist/, tx); + }); + + it('[negative] unable to set equippable list by a not-an-owner', async () => { + const slotId = 42; + + const baseId = await createBase(api, alice, 'slotpartany-base-type', 'slotpartany', [ + { + 'SlotPart': { + id: slotId, + equippable: 'All', + z: 1, + src: 'some-fallback-slot-url', + }, + }, + ]); + + const tx = setEquippableList(api, bob, baseId, slotId, 'All'); + await expectTxFailure(/rmrkEquip\.PermissionError/, tx); + }); + + it('[negative] unable to set equippable list to a fixed part', async () => { + const fixedPartId = 42; + + const baseId = await createBase(api, alice, 'fixedpart-base-type', 'fixedpart', [ + { + 'FixedPart': { + id: fixedPartId, + z: 0, + src: 'fixed-part-url', + }, + }, + ]); + + const tx = setEquippableList(api, alice, baseId, fixedPartId, 'All'); + await expectTxFailure(/rmrkEquip\.NoEquippableOnFixedPart/, tx); + }); + + it('[negative] unable to set equippable list to non-existing slot', async () => { + const slotId = 777; + const maxSlotId = 0xFFFFFFFF; + + const baseId = await createBase(api, alice, 'slotpartany-base-type', 'slotpartany', [ + { + 'SlotPart': { + id: slotId, + equippable: 'All', + z: 1, + src: 'some-fallback-slot-url', + }, + }, + ]); + + const tx = setEquippableList(api, alice, baseId, maxSlotId, 'All'); + await expectTxFailure(/rmrkEquip\.PartDoesntExist/, tx); + }); + + after(() => { api.disconnect(); }); +}); --- a/tests/src/rmrk/setEquippableList.test.ts +++ /dev/null @@ -1,115 +0,0 @@ -import {getApiConnection} from '../substrate/substrate-api'; -import {requirePallets, Pallets} from '../deprecated-helpers/helpers'; -import {expectTxFailure} from './util/helpers'; -import {createCollection, createBase, setEquippableList} from './util/tx'; - -describe("integration test: set slot's Equippable List", () => { - let api: any; - before(async function () { - api = await getApiConnection(); - await requirePallets(this, [Pallets.RmrkCore]); - }); - - const alice = '//Alice'; - const bob = '//Bob'; - - it("set Base's slot Equippable List", async () => { - const collectionIds = [ - await createCollection( - api, - alice, - 'equiplist-collection-metadata', - null, - 'equiplist-0', - ), - await createCollection( - api, - alice, - 'equiplist-collection-metadata', - null, - 'equiplist-1', - ), - ]; - - const slotId = 202; - - const baseId = await createBase(api, alice, 'slotpartany-base-type', 'slotpartany', [ - { - 'SlotPart': { - id: slotId, - equippable: 'All', - z: 1, - src: 'some-fallback-slot-url', - }, - }, - ]); - - await setEquippableList(api, alice, baseId, slotId, 'All'); - await setEquippableList(api, alice, baseId, slotId, 'Empty'); - await setEquippableList(api, alice, baseId, slotId, {'Custom': collectionIds}); - }); - - it('[negative] unable to set equippable list of a slot of non-existing base', async () => { - const maxBaseId = 0xFFFFFFFF; - const slotId = 0; - - const tx = setEquippableList(api, alice, maxBaseId, slotId, 'All'); - await expectTxFailure(/rmrkEquip\.BaseDoesntExist/, tx); - }); - - it('[negative] unable to set equippable list by a not-an-owner', async () => { - const slotId = 42; - - const baseId = await createBase(api, alice, 'slotpartany-base-type', 'slotpartany', [ - { - 'SlotPart': { - id: slotId, - equippable: 'All', - z: 1, - src: 'some-fallback-slot-url', - }, - }, - ]); - - const tx = setEquippableList(api, bob, baseId, slotId, 'All'); - await expectTxFailure(/rmrkEquip\.PermissionError/, tx); - }); - - it('[negative] unable to set equippable list to a fixed part', async () => { - const fixedPartId = 42; - - const baseId = await createBase(api, alice, 'fixedpart-base-type', 'fixedpart', [ - { - 'FixedPart': { - id: fixedPartId, - z: 0, - src: 'fixed-part-url', - }, - }, - ]); - - const tx = setEquippableList(api, alice, baseId, fixedPartId, 'All'); - await expectTxFailure(/rmrkEquip\.NoEquippableOnFixedPart/, tx); - }); - - it('[negative] unable to set equippable list to non-existing slot', async () => { - const slotId = 777; - const maxSlotId = 0xFFFFFFFF; - - const baseId = await createBase(api, alice, 'slotpartany-base-type', 'slotpartany', [ - { - 'SlotPart': { - id: slotId, - equippable: 'All', - z: 1, - src: 'some-fallback-slot-url', - }, - }, - ]); - - const tx = setEquippableList(api, alice, baseId, maxSlotId, 'All'); - await expectTxFailure(/rmrkEquip\.PartDoesntExist/, tx); - }); - - after(() => { api.disconnect(); }); -}); --- /dev/null +++ b/tests/src/rmrk/setNftProperty.seqtest.ts @@ -0,0 +1,89 @@ +import {getApiConnection} from '../substrate/substrate-api'; +import {requirePallets, Pallets} from '../deprecated-helpers/helpers'; +import {NftIdTuple} from './util/fetch'; +import {expectTxFailure} from './util/helpers'; +import {createCollection, mintNft, sendNft, setNftProperty} from './util/tx'; + +describe('integration test: set NFT property', () => { + let api: any; + before(async function () { + api = await getApiConnection(); + await requirePallets(this, [Pallets.RmrkCore]); + }); + + const alice = '//Alice'; + const bob = '//Bob'; + + const createTestCollection = async (issuerUri: string) => { + return await createCollection( + api, + issuerUri, + 'setprop-nft-collection-metadata', + null, + 'setprop', + ); + }; + + it('set NFT property', async () => { + const ownerAlice = alice; + + const collectionId = await createTestCollection(alice); + const nftId = await mintNft(api, alice, ownerAlice, collectionId, 'prop-nft'); + + await setNftProperty(api, alice, collectionId, nftId, 'test-key', 'test-key-value'); + await setNftProperty(api, alice, collectionId, nftId, 'test-key', 'updated-key-value'); + await setNftProperty(api, alice, collectionId, nftId, 'second-test-key', 'second-test-key-value'); + }); + + it('[negative] unable to set a property of non-existing NFT', async () => { + const collectionId = 0; + const maxNftId = 0xFFFFFFFF; + + const tx = setNftProperty(api, alice, collectionId, maxNftId, 'test-key', 'test-value'); + + await expectTxFailure(/rmrkCore\.NoAvailableNftId/, tx); + }); + + it('[negative] unable to set a property by not-an-owner', async () => { + const ownerAlice = alice; + + const collectionId = await createTestCollection(alice); + const nftId = await mintNft(api, alice, ownerAlice, collectionId, 'prop-nft'); + + const tx = setNftProperty(api, bob, collectionId, nftId, 'test-key', 'test-key-value'); + + await expectTxFailure(/rmrkCore\.NoPermission/, tx); + }); + + it('set a property to nested NFT', async () => { + const ownerAlice = alice; + + const collectionId = await createTestCollection(alice); + const parentNftId = await mintNft(api, alice, ownerAlice, collectionId, 'prop-parent-nft'); + const childNftId = await mintNft(api, alice, ownerAlice, collectionId, 'prop-child-nft'); + + const ownerNft: NftIdTuple = [collectionId, parentNftId]; + + await sendNft(api, 'sent', ownerAlice, collectionId, childNftId, ownerNft); + + await setNftProperty(api, alice, collectionId, childNftId, 'test-key', 'test-key-value'); + }); + + it('[negative] set a property to nested NFT (by not-root-owner)', async () => { + const ownerAlice = alice; + + const collectionId = await createTestCollection(alice); + const parentNftId = await mintNft(api, alice, ownerAlice, collectionId, 'prop-parent-nft'); + const childNftId = await mintNft(api, alice, ownerAlice, collectionId, 'prop-child-nft'); + + const ownerNft: NftIdTuple = [collectionId, parentNftId]; + + await sendNft(api, 'sent', ownerAlice, collectionId, childNftId, ownerNft); + + const tx = setNftProperty(api, bob, collectionId, childNftId, 'test-key', 'test-key-value'); + + await expectTxFailure(/rmrkCore\.NoPermission/, tx); + }); + + after(() => { api.disconnect(); }); +}); --- a/tests/src/rmrk/setNftProperty.test.ts +++ /dev/null @@ -1,89 +0,0 @@ -import {getApiConnection} from '../substrate/substrate-api'; -import {requirePallets, Pallets} from '../deprecated-helpers/helpers'; -import {NftIdTuple} from './util/fetch'; -import {expectTxFailure} from './util/helpers'; -import {createCollection, mintNft, sendNft, setNftProperty} from './util/tx'; - -describe('integration test: set NFT property', () => { - let api: any; - before(async function () { - api = await getApiConnection(); - await requirePallets(this, [Pallets.RmrkCore]); - }); - - const alice = '//Alice'; - const bob = '//Bob'; - - const createTestCollection = async (issuerUri: string) => { - return await createCollection( - api, - issuerUri, - 'setprop-nft-collection-metadata', - null, - 'setprop', - ); - }; - - it('set NFT property', async () => { - const ownerAlice = alice; - - const collectionId = await createTestCollection(alice); - const nftId = await mintNft(api, alice, ownerAlice, collectionId, 'prop-nft'); - - await setNftProperty(api, alice, collectionId, nftId, 'test-key', 'test-key-value'); - await setNftProperty(api, alice, collectionId, nftId, 'test-key', 'updated-key-value'); - await setNftProperty(api, alice, collectionId, nftId, 'second-test-key', 'second-test-key-value'); - }); - - it('[negative] unable to set a property of non-existing NFT', async () => { - const collectionId = 0; - const maxNftId = 0xFFFFFFFF; - - const tx = setNftProperty(api, alice, collectionId, maxNftId, 'test-key', 'test-value'); - - await expectTxFailure(/rmrkCore\.NoAvailableNftId/, tx); - }); - - it('[negative] unable to set a property by not-an-owner', async () => { - const ownerAlice = alice; - - const collectionId = await createTestCollection(alice); - const nftId = await mintNft(api, alice, ownerAlice, collectionId, 'prop-nft'); - - const tx = setNftProperty(api, bob, collectionId, nftId, 'test-key', 'test-key-value'); - - await expectTxFailure(/rmrkCore\.NoPermission/, tx); - }); - - it('set a property to nested NFT', async () => { - const ownerAlice = alice; - - const collectionId = await createTestCollection(alice); - const parentNftId = await mintNft(api, alice, ownerAlice, collectionId, 'prop-parent-nft'); - const childNftId = await mintNft(api, alice, ownerAlice, collectionId, 'prop-child-nft'); - - const ownerNft: NftIdTuple = [collectionId, parentNftId]; - - await sendNft(api, 'sent', ownerAlice, collectionId, childNftId, ownerNft); - - await setNftProperty(api, alice, collectionId, childNftId, 'test-key', 'test-key-value'); - }); - - it('[negative] set a property to nested NFT (by not-root-owner)', async () => { - const ownerAlice = alice; - - const collectionId = await createTestCollection(alice); - const parentNftId = await mintNft(api, alice, ownerAlice, collectionId, 'prop-parent-nft'); - const childNftId = await mintNft(api, alice, ownerAlice, collectionId, 'prop-child-nft'); - - const ownerNft: NftIdTuple = [collectionId, parentNftId]; - - await sendNft(api, 'sent', ownerAlice, collectionId, childNftId, ownerNft); - - const tx = setNftProperty(api, bob, collectionId, childNftId, 'test-key', 'test-key-value'); - - await expectTxFailure(/rmrkCore\.NoPermission/, tx); - }); - - after(() => { api.disconnect(); }); -}); --- /dev/null +++ b/tests/src/rmrk/setResourcePriorities.seqtest.ts @@ -0,0 +1,57 @@ +import {getApiConnection} from '../substrate/substrate-api'; +import {requirePallets, Pallets} from '../deprecated-helpers/helpers'; +import {expectTxFailure} from './util/helpers'; +import {mintNft, createCollection, setResourcePriorities} from './util/tx'; + +describe('integration test: set NFT resource priorities', () => { + let api: any; + before(async function () { + api = await getApiConnection(); + await requirePallets(this, [Pallets.RmrkCore]); + }); + + const alice = '//Alice'; + const bob = '//Bob'; + + const createTestCollection = (issuerUri: string) => { + return createCollection( + api, + issuerUri, + 'resprio-collection-metadata', + null, + 'resprio', + ); + }; + + it('set NFT resource priorities', async () => { + const owner = alice; + + const collectionId = await createTestCollection(alice); + const nftId = await mintNft(api, alice, owner, collectionId, 'resprio-nft-metadata'); + + await setResourcePriorities(api, alice, collectionId, nftId, [10, 42]); + }); + + it('[negative] set NFT resource priorities by a not-an-owner', async () => { + const owner = alice; + const attacker = bob; + + const collectionId = await createTestCollection(alice); + const nftId = await mintNft(api, alice, owner, collectionId, 'resprio-nft-metadata'); + + const tx = setResourcePriorities(api, attacker, collectionId, nftId, [10, 42]); + + await expectTxFailure(/rmrkCore\.NoPermission/, tx); + }); + + it('[negative] set NFT resource priorities to non-existing NFT', async () => { + const collectionId = 0; + const maxNftId = 0xFFFFFFFF; + + const tx = setResourcePriorities(api, alice, collectionId, maxNftId, [10, 42]); + + await expectTxFailure(/rmrkCore\.NoAvailableNftId/, tx); + }); + + after(() => { api.disconnect(); }); +}); --- a/tests/src/rmrk/setResourcePriorities.test.ts +++ /dev/null @@ -1,59 +0,0 @@ -import {getApiConnection} from '../substrate/substrate-api'; -import {requirePallets, Pallets} from '../deprecated-helpers/helpers'; -import {expectTxFailure} from './util/helpers'; -import {mintNft, createCollection, setResourcePriorities} from './util/tx'; - -describe('integration test: set NFT resource priorities', () => { - let api: any; - before(async function () { - api = await getApiConnection(); - await requirePallets(this, [Pallets.RmrkCore]); - }); - - const alice = '//Alice'; - const bob = '//Bob'; - - const createTestCollection = (issuerUri: string) => { - return createCollection( - api, - issuerUri, - 'resprio-collection-metadata', - null, - 'resprio', - ); - }; - - it('set NFT resource priorities', async () => { - const owner = alice; - - const collectionId = await createTestCollection(alice); - const nftId = await mintNft(api, alice, owner, collectionId, 'resprio-nft-metadata'); - - await setResourcePriorities(api, alice, collectionId, nftId, [10, 42]); - }); - - it('[negative] set NFT resource priorities by a not-an-owner', async () => { - const owner = alice; - const attacker = bob; - - const collectionId = await createTestCollection(alice); - const nftId = await mintNft(api, alice, owner, collectionId, 'resprio-nft-metadata'); - - const tx = setResourcePriorities(api, attacker, collectionId, nftId, [10, 42]); - - await expectTxFailure(/rmrkCore\.NoPermission/, tx); - }); - - it('[negative] set NFT resource priorities to non-existing NFT', async () => { - const owner = alice; - - const collectionId = 0; - const maxNftId = 0xFFFFFFFF; - - const tx = setResourcePriorities(api, alice, collectionId, maxNftId, [10, 42]); - - await expectTxFailure(/rmrkCore\.NoAvailableNftId/, tx); - }); - - after(() => { api.disconnect(); }); -}); --- a/tests/src/rmrk/util/fetch.ts +++ b/tests/src/rmrk/util/fetch.ts @@ -1,5 +1,5 @@ import {ApiPromise} from '@polkadot/api'; -import type {Option, Bytes} from '@polkadot/types-codec'; +import type {Option} from '@polkadot/types-codec'; import type { RmrkTraitsCollectionCollectionInfo as Collection, RmrkTraitsNftNftInfo as Nft, --- a/tests/src/rmrk/util/helpers.ts +++ b/tests/src/rmrk/util/helpers.ts @@ -107,7 +107,7 @@ export function isTxResultSuccess(events: EventRecord[]): boolean { let success = false; - events.forEach(({event: {data, method, section}}) => { + events.forEach(({event: {method}}) => { if (method == 'ExtrinsicSuccess') { success = true; } -- gitstuff