git.delta.rocks / unique-network / refs/commits / 6069e8a874a9

difftreelog

tests: upgrade part of them in ascending naming order to use playgrounds

Fahrrader2022-09-09parent: #4f3f998.patch.diff
in: master

24 files changed

modifiedtests/src/addCollectionAdmin.test.tsdiffbeforeafterboth
17import {IKeyringPair} from '@polkadot/types/types';17import {IKeyringPair} from '@polkadot/types/types';
18import chai from 'chai';18import chai from 'chai';
19import chaiAsPromised from 'chai-as-promised';19import chaiAsPromised from 'chai-as-promised';
20import {usingPlaygrounds} from './util/playgrounds';20import {itSub, usingPlaygrounds} from './util/playgrounds';
2121
22chai.use(chaiAsPromised);22chai.use(chaiAsPromised);
23const expect = chai.expect;23const expect = chai.expect;
24
25let donor: IKeyringPair;
26
27before(async () => {
28 await usingPlaygrounds(async (_, privateKeyWrapper) => {
29 donor = privateKeyWrapper('//Alice');
30 });
31});
3224
33describe('Integration Test addCollectionAdmin(collection_id, new_admin_id):', () => {25describe('Integration Test addCollectionAdmin(collection_id, new_admin_id):', () => {
26 let donor: IKeyringPair;
27
28 before(async () => {
29 await usingPlaygrounds(async (_, privateKeyWrapper) => {
30 donor = privateKeyWrapper('//Alice');
31 });
32 });
33
34 it('Add collection admin.', async () => {34 itSub('Add collection admin.', async ({helper}) => {
35 await usingPlaygrounds(async (helper) => {
36 const [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor);35 const [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor);
37 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});36 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
3837
39 const collection = await helper.collection.getData(collectionId);38 const collection = await helper.collection.getData(collectionId);
40 expect(collection!.normalizedOwner!).to.be.equal(alice.address);39 expect(collection!.normalizedOwner!).to.be.equal(helper.address.normalizeSubstrate(alice.address));
4140
42 await helper.nft.addAdmin(alice, collectionId, {Substrate: bob.address});41 await helper.nft.addAdmin(alice, collectionId, {Substrate: bob.address});
4342
44 const adminListAfterAddAdmin = await helper.collection.getAdmins(collectionId);43 const adminListAfterAddAdmin = await helper.collection.getAdmins(collectionId);
45 expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: bob.address});44 expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: bob.address});
46 });
47 });45 });
48});46});
4947
50describe('Negative Integration Test addCollectionAdmin(collection_id, new_admin_id):', () => {48describe('Negative Integration Test addCollectionAdmin(collection_id, new_admin_id):', () => {
49 let donor: IKeyringPair;
50
51 before(async () => {
52 await usingPlaygrounds(async (_, privateKeyWrapper) => {
53 donor = privateKeyWrapper('//Alice');
54 });
55 });
56
51 it("Not owner can't add collection admin.", async () => {57 itSub("Not owner can't add collection admin.", async ({helper}) => {
52 await usingPlaygrounds(async (helper) => {
53 const [alice, bob, charlie] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);58 const [alice, bob, charlie] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);
54 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});59 const {collectionId} = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
5560
56 const collection = await helper.collection.getData(collectionId);61 const collection = await helper.collection.getData(collectionId);
57 expect(collection?.normalizedOwner).to.be.equal(alice.address);62 expect(collection?.normalizedOwner).to.be.equal(helper.address.normalizeSubstrate(alice.address));
5863
59 const changeAdminTxBob = async () => helper.collection.addAdmin(bob, collectionId, {Substrate: bob.address});64 const changeAdminTxBob = async () => helper.collection.addAdmin(bob, collectionId, {Substrate: bob.address});
60 const changeAdminTxCharlie = async () => helper.collection.addAdmin(bob, collectionId, {Substrate: charlie.address});65 const changeAdminTxCharlie = async () => helper.collection.addAdmin(bob, collectionId, {Substrate: charlie.address});
61 await expect(changeAdminTxCharlie()).to.be.rejected;66 await expect(changeAdminTxCharlie()).to.be.rejectedWith(/common\.NoPermission/);
62 await expect(changeAdminTxBob()).to.be.rejected;67 await expect(changeAdminTxBob()).to.be.rejectedWith(/common\.NoPermission/);
6368
64 const adminListAfterAddAdmin = await helper.collection.getAdmins(collectionId);69 const adminListAfterAddAdmin = await helper.collection.getAdmins(collectionId);
65 expect(adminListAfterAddAdmin).to.be.not.deep.contains({Substrate: charlie.address});70 expect(adminListAfterAddAdmin).to.be.not.deep.contains({Substrate: charlie.address});
66 expect(adminListAfterAddAdmin).to.be.not.deep.contains({Substrate: bob.address});71 expect(adminListAfterAddAdmin).to.be.not.deep.contains({Substrate: bob.address});
67 });
68 });72 });
6973
70 it("Admin can't add collection admin.", async () => {74 itSub("Admin can't add collection admin.", async ({helper}) => {
71 await usingPlaygrounds(async (helper) => {
72 const [alice, bob, charlie] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);75 const [alice, bob, charlie] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);
73 const collection = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});76 const collection = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
7477
78 expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: bob.address});81 expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: bob.address});
7982
80 const changeAdminTxCharlie = async () => collection.addAdmin(bob, {Substrate: charlie.address});83 const changeAdminTxCharlie = async () => collection.addAdmin(bob, {Substrate: charlie.address});
81 await expect(changeAdminTxCharlie()).to.be.rejected;84 await expect(changeAdminTxCharlie()).to.be.rejectedWith(/common\.NoPermission/);
8285
83 const adminListAfterAddNewAdmin = await collection.getAdmins();86 const adminListAfterAddNewAdmin = await collection.getAdmins();
84 expect(adminListAfterAddNewAdmin).to.be.deep.contains({Substrate: bob.address});87 expect(adminListAfterAddNewAdmin).to.be.deep.contains({Substrate: bob.address});
85 expect(adminListAfterAddNewAdmin).to.be.not.deep.contains({Substrate: charlie.address});88 expect(adminListAfterAddNewAdmin).to.be.not.deep.contains({Substrate: charlie.address});
86 });
87 });89 });
8890
89 it("Can't add collection admin of not existing collection.", async () => {91 itSub("Can't add collection admin of not existing collection.", async ({helper}) => {
90 await usingPlaygrounds(async (helper) => {
91 const [alice, bob] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);92 const [alice, bob] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);
92 // tslint:disable-next-line: no-bitwise
93 const collectionId = (1 << 32) - 1;93 const collectionId = (1 << 32) - 1;
9494
95 const addAdminTx = async () => helper.collection.addAdmin(alice, collectionId, {Substrate: bob.address});95 const addAdminTx = async () => helper.collection.addAdmin(alice, collectionId, {Substrate: bob.address});
96 await expect(addAdminTx()).to.be.rejected;96 await expect(addAdminTx()).to.be.rejectedWith(/common\.CollectionNotFound/);
9797
98 // Verifying that nothing bad happened (network is live, new collections can be created, etc.)98 // Verifying that nothing bad happened (network is live, new collections can be created, etc.)
99 await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});99 await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
100 });
101 });100 });
102101
103 it("Can't add an admin to a destroyed collection.", async () => {102 itSub("Can't add an admin to a destroyed collection.", async ({helper}) => {
104 await usingPlaygrounds(async (helper) => {
105 const [alice, bob] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);103 const [alice, bob] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);
106 const collection = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});104 const collection = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
107105
108 await collection.burn(alice);106 await collection.burn(alice);
109 const addAdminTx = async () => collection.addAdmin(alice, {Substrate: bob.address});107 const addAdminTx = async () => collection.addAdmin(alice, {Substrate: bob.address});
110 await expect(addAdminTx()).to.be.rejected;108 await expect(addAdminTx()).to.be.rejectedWith(/common\.CollectionNotFound/);
111109
112 // Verifying that nothing bad happened (network is live, new collections can be created, etc.)110 // Verifying that nothing bad happened (network is live, new collections can be created, etc.)
113 await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});111 await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
114 });
115 });112 });
116113
117 it('Add an admin to a collection that has reached the maximum number of admins limit', async () => {114 itSub('Add an admin to a collection that has reached the maximum number of admins limit', async ({helper}) => {
118 await usingPlaygrounds(async (helper) => {
119 const [alice, ...accounts] = await helper.arrange.createAccounts([10n, 0n, 0n, 0n, 0n, 0n, 0n, 0n], donor);115 const [alice, ...accounts] = await helper.arrange.createAccounts([10n, 0n, 0n, 0n, 0n, 0n, 0n, 0n], donor);
120 const collection = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});116 const collection = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
121117
129 }125 }
130126
131 const addExtraAdminTx = async () => collection.addAdmin(alice, {Substrate: accounts[chainAdminLimit].address});127 const addExtraAdminTx = async () => collection.addAdmin(alice, {Substrate: accounts[chainAdminLimit].address});
132 await expect(addExtraAdminTx()).to.be.rejected;128 await expect(addExtraAdminTx()).to.be.rejectedWith(/common\.CollectionAdminCountExceeded/);
133 });
134 });129 });
135});130});
136131
modifiedtests/src/eth/nesting/nest.test.tsdiffbeforeafterboth
20 let donor: IKeyringPair;20 let donor: IKeyringPair;
2121
22 before(async function() {22 before(async function() {
23 await usingEthPlaygrounds(async (helper, privateKey) => {23 await usingEthPlaygrounds(async (_, privateKey) => {
24 donor = privateKey('//Alice');24 donor = privateKey('//Alice');
25 });25 });
26 });26 });
modifiedtests/src/eth/payable.test.tsdiffbeforeafterboth
22 let donor: IKeyringPair;22 let donor: IKeyringPair;
2323
24 before(async function() {24 before(async function() {
25 await usingEthPlaygrounds(async (helper, privateKey) => {25 await usingEthPlaygrounds(async (_, privateKey) => {
26 donor = privateKey('//Alice');26 donor = privateKey('//Alice');
27 });27 });
28 });28 });
modifiedtests/src/fungible.test.tsdiffbeforeafterboth
17import {IKeyringPair} from '@polkadot/types/types';17import {IKeyringPair} from '@polkadot/types/types';
18import {U128_MAX} from './util/helpers';18import {U128_MAX} from './util/helpers';
19
20import {usingPlaygrounds} from './util/playgrounds';19import {itSub, usingPlaygrounds} from './util/playgrounds';
21
22import chai from 'chai';20import chai from 'chai';
23import chaiAsPromised from 'chai-as-promised';21import chaiAsPromised from 'chai-as-promised';
35 });34 });
36 });35 });
3736
38 it('Create fungible collection and token', async () => {37 itSub('Create fungible collection and token', async ({helper}) => {
39 await usingPlaygrounds(async helper => {
40 const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'trest'});38 const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'trest'});
41 const defaultTokenId = await collection.getLastTokenId();39 const defaultTokenId = await collection.getLastTokenId();
42 expect(defaultTokenId).to.be.equal(0);40 expect(defaultTokenId).to.be.equal(0);
4745
48 expect(itemCountAfter).to.be.equal(defaultTokenId);46 expect(itemCountAfter).to.be.equal(defaultTokenId);
49 expect(aliceBalance).to.be.equal(U128_MAX);47 expect(aliceBalance).to.be.equal(U128_MAX);
50 });
51 });48 });
52 49
53 it('RPC method tokenOnewrs for fungible collection and token', async () => {50 itSub('RPC method tokenOnewrs for fungible collection and token', async ({helper, privateKey}) => {
54 await usingPlaygrounds(async (helper, privateKey) => {
55 const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};51 const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
56 const facelessCrowd = Array(7).fill(0).map((_, i) => ({Substrate: privateKey(`//Alice+${i}`).address}));52 const facelessCrowd = Array(7).fill(0).map((_, i) => ({Substrate: privateKey(`//Alice+${i}`).address}));
5753
75 const eleven = privateKey('//ALice+11');71 const eleven = privateKey('//ALice+11');
76 expect(await collection.transfer(alice, {Substrate: eleven.address}, 10n)).to.be.true;72 expect(await collection.transfer(alice, {Substrate: eleven.address}, 10n)).to.be.true;
77 expect((await collection.getTop10Owners()).length).to.be.equal(10);73 expect((await collection.getTop10Owners()).length).to.be.equal(10);
78 });
79 });74 });
80 75
81 it('Transfer token', async () => {76 itSub('Transfer token', async ({helper}) => {
82 await usingPlaygrounds(async helper => {
83 const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};77 const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
84 const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});78 const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
85 await collection.mint(alice, {Substrate: alice.address}, 500n);79 await collection.mint(alice, {Substrate: alice.address}, 500n);
93 expect(await collection.getBalance(ethAcc)).to.be.equal(140n);87 expect(await collection.getBalance(ethAcc)).to.be.equal(140n);
9488
95 await expect(collection.transfer(alice, {Substrate: bob.address}, 350n)).to.eventually.be.rejected;89 await expect(collection.transfer(alice, {Substrate: bob.address}, 350n)).to.eventually.be.rejected;
96 });
97 });90 });
9891
99 it('Tokens multiple creation', async () => {92 itSub('Tokens multiple creation', async ({helper}) => {
100 await usingPlaygrounds(async helper => {
101 const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});93 const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
10294
103 await collection.mintWithOneOwner(alice, {Substrate: alice.address}, [95 await collection.mintWithOneOwner(alice, {Substrate: alice.address}, [
107 ]);99 ]);
108100
109 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1200n);101 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1200n);
110 });
111 });102 });
112103
113 it('Burn some tokens ', async () => {104 itSub('Burn some tokens ', async ({helper}) => {
114 await usingPlaygrounds(async helper => {
115 const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});105 const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
116 await collection.mint(alice, {Substrate: alice.address}, 500n);106 await collection.mint(alice, {Substrate: alice.address}, 500n);
117107
120 expect(await collection.burnTokens(alice, 499n)).to.be.true;110 expect(await collection.burnTokens(alice, 499n)).to.be.true;
121 expect(await collection.isTokenExists(0)).to.be.true;111 expect(await collection.isTokenExists(0)).to.be.true;
122 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1n);112 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1n);
123 });
124 });113 });
125 114
126 it('Burn all tokens ', async () => {115 itSub('Burn all tokens ', async ({helper}) => {
127 await usingPlaygrounds(async helper => {
128 const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});116 const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
129 await collection.mint(alice, {Substrate: alice.address}, 500n);117 await collection.mint(alice, {Substrate: alice.address}, 500n);
130118
134122
135 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(0n);123 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(0n);
136 expect(await collection.getTotalPieces()).to.be.equal(0n);124 expect(await collection.getTotalPieces()).to.be.equal(0n);
137 });
138 });125 });
139126
140 it('Set allowance for token', async () => {127 itSub('Set allowance for token', async ({helper}) => {
141 await usingPlaygrounds(async helper => {
142 const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});128 const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
143 const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};129 const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
144 await collection.mint(alice, {Substrate: alice.address}, 100n);130 await collection.mint(alice, {Substrate: alice.address}, 100n);
160 expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(30n);146 expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(30n);
161 expect(await collection.transferFrom(bob, {Substrate: alice.address}, ethAcc, 10n)).to.be.true;147 expect(await collection.transferFrom(bob, {Substrate: alice.address}, ethAcc, 10n)).to.be.true;
162 expect(await collection.getBalance(ethAcc)).to.be.equal(10n);148 expect(await collection.getBalance(ethAcc)).to.be.equal(10n);
163 });
164 });149 });
165});150});
166151
modifiedtests/src/overflow.test.tsdiffbeforeafterboth
23chai.use(chaiAsPromised);23chai.use(chaiAsPromised);
24const expect = chai.expect;24const expect = chai.expect;
2525
26// todo:playgrounds skipped ~ postponed
26describe.skip('Integration Test fungible overflows', () => {27describe.skip('Integration Test fungible overflows', () => {
27 let alice: IKeyringPair;28 let alice: IKeyringPair;
28 let bob: IKeyringPair;29 let bob: IKeyringPair;
modifiedtests/src/pallet-presence.test.tsdiffbeforeafterboth
14// You should have received a copy of the GNU General Public License14// You should have received a copy of the GNU General Public License
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17import {ApiPromise} from '@polkadot/api';
18import {expect} from 'chai';17import {expect} from 'chai';
19import usingApi from './substrate/substrate-api';18import {itSub, usingPlaygrounds} from './util/playgrounds';
20
21function getModuleNames(api: ApiPromise): string[] {
22 return api.runtimeMetadata.asLatest.pallets.map(m => m.name.toString().toLowerCase());
23}
2419
25// Pallets that must always be present20// Pallets that must always be present
26const requiredPallets = [21const requiredPallets = [
6257
63describe('Pallet presence', () => {58describe('Pallet presence', () => {
64 before(async () => {59 before(async () => {
65 await usingApi(async api => {60 await usingPlaygrounds(async helper => {
66 const chain = await api.rpc.system.chain();61 const chain = await helper.api!.rpc.system.chain();
6762
68 const refungible = 'refungible';63 const refungible = 'refungible';
69 const scheduler = 'scheduler';64 const scheduler = 'scheduler';
80 });75 });
81 });76 });
8277
83 it('Required pallets are present', async () => {78 itSub('Required pallets are present', async ({helper}) => {
84 await usingApi(async api => {
85 for (let i=0; i<requiredPallets.length; i++) {
86 expect(getModuleNames(api)).to.include(requiredPallets[i]);79 expect(helper.fetchAllPalletNames()).to.contain.members([...requiredPallets]);
87 }
88 });
89 });80 });
81
90 it('Governance and consensus pallets are present', async () => {82 itSub('Governance and consensus pallets are present', async ({helper}) => {
91 await usingApi(async api => {
92 for (let i=0; i<consensusPallets.length; i++) {
93 expect(getModuleNames(api)).to.include(consensusPallets[i]);83 expect(helper.fetchAllPalletNames()).to.contain.members([...consensusPallets]);
94 }
95 });
96 });84 });
85
97 it('No extra pallets are included', async () => {86 itSub('No extra pallets are included', async ({helper}) => {
98 await usingApi(async api => {
99 expect(getModuleNames(api).sort()).to.be.deep.equal([...requiredPallets, ...consensusPallets].sort());87 expect(helper.fetchAllPalletNames().sort()).to.be.deep.equal([...requiredPallets, ...consensusPallets].sort());
100 });
101 });88 });
102});89});
10390
modifiedtests/src/refungible.test.tsdiffbeforeafterboth
1616
17import {IKeyringPair} from '@polkadot/types/types';17import {IKeyringPair} from '@polkadot/types/types';
18
19import {usingPlaygrounds} from './util/playgrounds';
20import {18import {itSub, Pallets, requirePalletsOrSkip, usingPlaygrounds} from './util/playgrounds';
21 getModuleNames,
22 Pallets,
23 requirePallets,
24} from './util/helpers';
2519
26import chai from 'chai';20import chai from 'chai';
27import chaiAsPromised from 'chai-as-promised';21import chaiAsPromised from 'chai-as-promised';
3428
35describe('integration test: Refungible functionality:', async () => {29describe('integration test: Refungible functionality:', async () => {
36 before(async function() {30 before(async function() {
37 await requirePallets(this, [Pallets.ReFungible]);
38
39 await usingPlaygrounds(async (helper, privateKey) => {31 await usingPlaygrounds(async (helper, privateKey) => {
32 requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);
33
40 alice = privateKey('//Alice');34 alice = privateKey('//Alice');
41 bob = privateKey('//Bob');35 bob = privateKey('//Bob');
42 if (!getModuleNames(helper.api!).includes(Pallets.ReFungible)) this.skip();
43 });36 });
44 });37 });
45 38
46 it('Create refungible collection and token', async () => {39 itSub('Create refungible collection and token', async ({helper}) => {
47 await usingPlaygrounds(async helper => {
48 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});40 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
4941
50 const itemCountBefore = await collection.getLastTokenId();42 const itemCountBefore = await collection.getLastTokenId();
56 expect(token?.tokenId).to.be.gte(itemCountBefore);48 expect(token?.tokenId).to.be.gte(itemCountBefore);
57 expect(itemCountAfter).to.be.equal(itemCountBefore + 1);49 expect(itemCountAfter).to.be.equal(itemCountBefore + 1);
58 expect(itemCountAfter.toString()).to.be.equal(token?.tokenId.toString());50 expect(itemCountAfter.toString()).to.be.equal(token?.tokenId.toString());
59 });
60 });51 });
61 52
62 it('Checking RPC methods when interacting with maximum allowed values (MAX_REFUNGIBLE_PIECES)', async () => {53 itSub('Checking RPC methods when interacting with maximum allowed values (MAX_REFUNGIBLE_PIECES)', async ({helper}) => {
63 await usingPlaygrounds(async helper => {
64 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});54 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
65 55
66 const token = await collection.mintToken(alice, {Substrate: alice.address}, MAX_REFUNGIBLE_PIECES);56 const token = await collection.mintToken(alice, {Substrate: alice.address}, MAX_REFUNGIBLE_PIECES);
71 expect(await collection.getTokenBalance(token.tokenId, {Substrate: bob.address})).to.be.equal(MAX_REFUNGIBLE_PIECES);61 expect(await collection.getTokenBalance(token.tokenId, {Substrate: bob.address})).to.be.equal(MAX_REFUNGIBLE_PIECES);
72 expect(await token.getTotalPieces()).to.be.equal(MAX_REFUNGIBLE_PIECES);62 expect(await token.getTotalPieces()).to.be.equal(MAX_REFUNGIBLE_PIECES);
73 63
74 await expect(collection.mintToken(alice, {Substrate: alice.address}, MAX_REFUNGIBLE_PIECES + 1n)).to.eventually.be.rejected;64 await expect(collection.mintToken(alice, {Substrate: alice.address}, MAX_REFUNGIBLE_PIECES + 1n))
75 });65 .to.eventually.be.rejectedWith(/refungible\.WrongRefungiblePieces/);
76 });66 });
77 67
78 it('RPC method tokenOnewrs for refungible collection and token', async () => {68 itSub('RPC method tokenOnewrs for refungible collection and token', async ({helper, privateKey}) => {
79 await usingPlaygrounds(async (helper, privateKey) => {
80 const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};69 const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
81 const facelessCrowd = Array(7).fill(0).map((_, i) => ({Substrate: privateKey(`//Alice+${i}`).address}));70 const facelessCrowd = Array(7).fill(0).map((_, i) => ({Substrate: privateKey(`//Alice+${i}`).address}));
8271
100 const eleven = privateKey('//ALice+11');89 const eleven = privateKey('//ALice+11');
101 expect(await token.transfer(alice, {Substrate: eleven.address}, 10n)).to.be.true;90 expect(await token.transfer(alice, {Substrate: eleven.address}, 10n)).to.be.true;
102 expect((await token.getTop10Owners()).length).to.be.equal(10);91 expect((await token.getTop10Owners()).length).to.be.equal(10);
103 });
104 });92 });
105 93
106 it('Transfer token pieces', async () => {94 itSub('Transfer token pieces', async ({helper}) => {
107 await usingPlaygrounds(async helper => {
108 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});95 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
109 const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);96 const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
11097
114 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(40n);101 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(40n);
115 expect(await token.getBalance({Substrate: bob.address})).to.be.equal(60n);102 expect(await token.getBalance({Substrate: bob.address})).to.be.equal(60n);
116 103
117 await expect(token.transfer(alice, {Substrate: bob.address}, 41n)).to.eventually.be.rejected;104 await expect(token.transfer(alice, {Substrate: bob.address}, 41n))
118 });105 .to.eventually.be.rejectedWith(/common\.TokenValueTooLow/);
119 });106 });
120107
121 it('Create multiple tokens', async () => {108 itSub('Create multiple tokens', async ({helper}) => {
122 await usingPlaygrounds(async helper => {
123 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});109 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
124 // TODO: fix mintMultipleTokens110 // TODO: fix mintMultipleTokens
125 // await collection.mintMultipleTokens(alice, [111 // await collection.mintMultipleTokens(alice, [
135 const lastTokenId = await collection.getLastTokenId();121 const lastTokenId = await collection.getLastTokenId();
136 expect(lastTokenId).to.be.equal(3);122 expect(lastTokenId).to.be.equal(3);
137 expect(await collection.getTokenBalance(lastTokenId, {Substrate: alice.address})).to.be.equal(100n);123 expect(await collection.getTokenBalance(lastTokenId, {Substrate: alice.address})).to.be.equal(100n);
138 });
139 });124 });
140125
141 it('Burn some pieces', async () => {126 itSub('Burn some pieces', async ({helper}) => {
142 await usingPlaygrounds(async helper => {
143 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});127 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
144 const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);128 const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
145 expect(await collection.isTokenExists(token.tokenId)).to.be.true;129 expect(await collection.isTokenExists(token.tokenId)).to.be.true;
146 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);130 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
147 expect((await token.burn(alice, 99n)).success).to.be.true;131 expect((await token.burn(alice, 99n)).success).to.be.true;
148 expect(await collection.isTokenExists(token.tokenId)).to.be.true;132 expect(await collection.isTokenExists(token.tokenId)).to.be.true;
149 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(1n);133 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(1n);
150 });
151 });134 });
152135
153 it('Burn all pieces', async () => {136 itSub('Burn all pieces', async ({helper}) => {
154 await usingPlaygrounds(async helper => {
155 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});137 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
156 const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);138 const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
157 139
160142
161 expect((await token.burn(alice, 100n)).success).to.be.true;143 expect((await token.burn(alice, 100n)).success).to.be.true;
162 expect(await collection.isTokenExists(token.tokenId)).to.be.false;144 expect(await collection.isTokenExists(token.tokenId)).to.be.false;
163 });
164 });145 });
165146
166 it('Burn some pieces for multiple users', async () => {147 itSub('Burn some pieces for multiple users', async ({helper}) => {
167 await usingPlaygrounds(async helper => {
168 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});148 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
169 const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);149 const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
170150
189 expect((await token.burn(bob, 1n)).success).to.be.true;169 expect((await token.burn(bob, 1n)).success).to.be.true;
190170
191 expect(await collection.isTokenExists(token.tokenId)).to.be.false;171 expect(await collection.isTokenExists(token.tokenId)).to.be.false;
192 });
193 });172 });
194173
195 it('Set allowance for token', async () => {174 itSub('Set allowance for token', async ({helper}) => {
196 await usingPlaygrounds(async helper => {
197 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});175 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
198 const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);176 const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
199 177
206 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(80n);184 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(80n);
207 expect(await token.getBalance({Substrate: bob.address})).to.be.equal(20n);185 expect(await token.getBalance({Substrate: bob.address})).to.be.equal(20n);
208 expect(await token.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(40n);186 expect(await token.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(40n);
209 });
210 });187 });
211188
212 it('Repartition', async () => {189 itSub('Repartition', async ({helper}) => {
213 await usingPlaygrounds(async helper => {
214 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});190 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
215 const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);191 const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
216192
222 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(90n);198 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(90n);
223 expect(await token.getBalance({Substrate: bob.address})).to.be.equal(110n);199 expect(await token.getBalance({Substrate: bob.address})).to.be.equal(110n);
224 200
225 await expect(token.repartition(alice, 80n)).to.eventually.be.rejected;201 await expect(token.repartition(alice, 80n))
226 202 .to.eventually.be.rejectedWith(/refungible\.RepartitionWhileNotOwningAllPieces/);
203
227 expect(await token.transfer(alice, {Substrate: bob.address}, 90n)).to.be.true;204 expect(await token.transfer(alice, {Substrate: bob.address}, 90n)).to.be.true;
228 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(0n);205 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(0n);
229 expect(await token.getBalance({Substrate: bob.address})).to.be.equal(200n);206 expect(await token.getBalance({Substrate: bob.address})).to.be.equal(200n);
230207
231 expect(await token.repartition(bob, 150n)).to.be.true;208 expect(await token.repartition(bob, 150n)).to.be.true;
232 await expect(token.transfer(bob, {Substrate: alice.address}, 160n)).to.eventually.be.rejected;209 await expect(token.transfer(bob, {Substrate: alice.address}, 160n))
233210 .to.eventually.be.rejectedWith(/common\.TokenValueTooLow/);
234 });
235 });211 });
236212
237 it('Repartition with increased amount', async () => {213 itSub('Repartition with increased amount', async ({helper}) => {
238 await usingPlaygrounds(async helper => {
239 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});214 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
240 const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);215 const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
241 await token.repartition(alice, 200n);216 await token.repartition(alice, 200n);
251 '100',226 '100',
252 ],227 ],
253 }]);228 }]);
254 });
255 });229 });
256230
257 it('Repartition with decreased amount', async () => {231 itSub('Repartition with decreased amount', async ({helper}) => {
258 await usingPlaygrounds(async helper => {
259 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});232 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
260 const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);233 const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
261 await token.repartition(alice, 50n);234 await token.repartition(alice, 50n);
271 '50',244 '50',
272 ],245 ],
273 }]);246 }]);
274 });
275 });247 });
276 248
277 it('Create new collection with properties', async () => {249 itSub('Create new collection with properties', async ({helper}) => {
278 await usingPlaygrounds(async helper => {
279 const properties = [{key: 'key1', value: 'val1'}];250 const properties = [{key: 'key1', value: 'val1'}];
280 const tokenPropertyPermissions = [{key: 'key1', permission: {tokenOwner: true, mutable: false, collectionAdmin: true}}];251 const tokenPropertyPermissions = [{key: 'key1', permission: {tokenOwner: true, mutable: false, collectionAdmin: true}}];
281 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test', properties, tokenPropertyPermissions});252 const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test', properties, tokenPropertyPermissions});
282 const info = await collection.getData();253 const info = await collection.getData();
283 expect(info?.raw.properties).to.be.deep.equal(properties);254 expect(info?.raw.properties).to.be.deep.equal(properties);
284 expect(info?.raw.tokenPropertyPermissions).to.be.deep.equal(tokenPropertyPermissions);255 expect(info?.raw.tokenPropertyPermissions).to.be.deep.equal(tokenPropertyPermissions);
285 });
286 });256 });
287});257});
288258
modifiedtests/src/removeCollectionAdmin.test.tsdiffbeforeafterboth
1616
17import chai from 'chai';17import chai from 'chai';
18import chaiAsPromised from 'chai-as-promised';18import chaiAsPromised from 'chai-as-promised';
19import {IKeyringPair} from '@polkadot/types/types';
19import {usingPlaygrounds} from './util/playgrounds';20import {itSub, usingPlaygrounds} from './util/playgrounds';
2021
21chai.use(chaiAsPromised);22chai.use(chaiAsPromised);
22const expect = chai.expect;23const expect = chai.expect;
2324
24describe('Integration Test removeCollectionAdmin(collection_id, account_id):', () => {25describe('Integration Test removeCollectionAdmin(collection_id, account_id):', () => {
26 let alice: IKeyringPair;
27 let bob: IKeyringPair;
28
29 before(async () => {
30 await usingPlaygrounds(async (helper, privateKey) => {
31 const donor = privateKey('//Alice');
32 [alice, bob] = await helper.arrange.createAccounts([20n, 10n], donor);
33 });
34 });
35
25 it('Remove collection admin.', async () => {36 itSub('Remove collection admin', async ({helper}) => {
26 await usingPlaygrounds(async (helper, privateKey) => {37 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionAdmin-1', tokenPrefix: 'RCA'});
27 const alice = privateKey('//Alice');
28 const bob = privateKey('//Bob');
29 const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
30
31 const collectionInfo = await collection.getData();38 const collectionInfo = await collection.getData();
32 expect(collectionInfo?.raw.owner.toString()).to.be.deep.eq(alice.address);39 expect(collectionInfo?.raw.owner.toString()).to.be.deep.eq(alice.address);
33 // first - add collection admin Bob40 // first - add collection admin Bob
34 await collection.addAdmin(alice, {Substrate: bob.address});41 await collection.addAdmin(alice, {Substrate: bob.address});
3542
36 const adminListAfterAddAdmin = await collection.getAdmins();43 const adminListAfterAddAdmin = await collection.getAdmins();
37 expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: helper.address.normalizeSubstrate(bob.address)});44 expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: bob.address});
3845
39 // then remove bob from admins of collection46 // then remove bob from admins of collection
40 await collection.removeAdmin(alice, {Substrate: bob.address});47 await collection.removeAdmin(alice, {Substrate: bob.address});
4148
42 const adminListAfterRemoveAdmin = await collection.getAdmins();49 const adminListAfterRemoveAdmin = await collection.getAdmins();
43 expect(adminListAfterRemoveAdmin).not.to.be.deep.contains({Substrate: helper.address.normalizeSubstrate(bob.address)});50 expect(adminListAfterRemoveAdmin).not.to.be.deep.contains({Substrate: bob.address});
44 });
45 });51 });
4652
47 it('Remove admin from collection that has no admins', async () => {53 itSub('Remove admin from collection that has no admins', async ({helper}) => {
48 await usingPlaygrounds(async (helper, privateKey) => {54 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionAdmin-2', tokenPrefix: 'RCA'});
49 const alice = privateKey('//Alice');
50 const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
5155
52 const adminListBeforeAddAdmin = await collection.getAdmins();56 const adminListBeforeAddAdmin = await collection.getAdmins();
53 expect(adminListBeforeAddAdmin).to.have.lengthOf(0);57 expect(adminListBeforeAddAdmin).to.have.lengthOf(0);
5458
55 // await expect(collection.removeAdmin(alice, {Substrate: alice.address})).to.be.rejectedWith('Unable to remove collection admin');
56 await collection.removeAdmin(alice, {Substrate: alice.address});59 await collection.removeAdmin(alice, {Substrate: alice.address});
57 });
58 });60 });
59});61});
6062
61describe('Negative Integration Test removeCollectionAdmin(collection_id, account_id):', () => {63describe('Negative Integration Test removeCollectionAdmin(collection_id, account_id):', () => {
64 let alice: IKeyringPair;
65 let bob: IKeyringPair;
66 let charlie: IKeyringPair;
67
68 before(async () => {
69 await usingPlaygrounds(async (helper, privateKey) => {
70 const donor = privateKey('//Alice');
71 [alice, bob, charlie] = await helper.arrange.createAccounts([20n, 10n, 10n], donor);
72 });
73 });
74
62 it('Can\'t remove collection admin from not existing collection', async () => {75 itSub('Can\'t remove collection admin from not existing collection', async ({helper}) => {
63 await usingPlaygrounds(async (helper, privateKey) => {
64 // tslint:disable-next-line: no-bitwise
65 const collectionId = (1 << 32) - 1;76 const collectionId = (1 << 32) - 1;
66 const alice = privateKey('//Alice');
67 const bob = privateKey('//Bob');
6877
69 await expect(helper.collection.removeAdmin(alice, collectionId, {Substrate: bob.address})).to.be.rejected;78 await expect(helper.collection.removeAdmin(alice, collectionId, {Substrate: bob.address}))
7079 .to.be.rejectedWith(/common\.CollectionNotFound/);
71 // Verifying that nothing bad happened (network is live, new collections can be created, etc.)
72 await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
73 });
74 });80 });
7581
76 it('Can\'t remove collection admin from deleted collection', async () => {82 itSub('Can\'t remove collection admin from deleted collection', async ({helper}) => {
77 await usingPlaygrounds(async (helper, privateKey) => {83 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionAdmin-Neg-2', tokenPrefix: 'RCA'});
78 const alice = privateKey('//Alice');
79 const bob = privateKey('//Bob');
80 const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
8184
82 expect(await collection.burn(alice)).to.be.true;85 expect(await collection.burn(alice)).to.be.true;
8386
84 await expect(helper.collection.removeAdmin(alice, collection.collectionId, {Substrate: bob.address})).to.be.rejected;87 await expect(helper.collection.removeAdmin(alice, collection.collectionId, {Substrate: bob.address}))
8588 .to.be.rejectedWith(/common\.CollectionNotFound/);
86 // Verifying that nothing bad happened (network is live, new collections can be created, etc.)
87 await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
88 });
89 });89 });
9090
91 it('Regular user can\'t remove collection admin', async () => {91 itSub('Regular user can\'t remove collection admin', async ({helper}) => {
92 await usingPlaygrounds(async (helper, privateKey) => {92 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionAdmin-Neg-3', tokenPrefix: 'RCA'});
93 const alice = privateKey('//Alice');
94 const bob = privateKey('//Bob');
95 const charlie = privateKey('//Charlie');
96 const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
9793
98 await collection.addAdmin(alice, {Substrate: bob.address});94 await collection.addAdmin(alice, {Substrate: bob.address});
9995
100 await expect(collection.removeAdmin(charlie, {Substrate: bob.address})).to.be.rejected;96 await expect(collection.removeAdmin(charlie, {Substrate: bob.address}))
10197 .to.be.rejectedWith(/common\.NoPermission/);
102 // Verifying that nothing bad happened (network is live, new collections can be created, etc.)
103 await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
104 });
105 });98 });
10699
107 it('Admin can\'t remove collection admin.', async () => {100 itSub('Admin can\'t remove collection admin.', async ({helper}) => {
108 await usingPlaygrounds(async (helper, privateKey) => {101 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionAdmin-Neg-4', tokenPrefix: 'RCA'});
109 const alice = privateKey('//Alice');102
110 const bob = privateKey('//Bob');
111 const charlie = privateKey('//Charlie');
112 const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
113
114 await collection.addAdmin(alice, {Substrate: bob.address});103 await collection.addAdmin(alice, {Substrate: bob.address});
115 await collection.addAdmin(alice, {Substrate: charlie.address});104 await collection.addAdmin(alice, {Substrate: charlie.address});
116105
117 const adminListAfterAddAdmin = await collection.getAdmins();106 const adminListAfterAddAdmin = await collection.getAdmins();
118 expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: helper.address.normalizeSubstrate(bob.address)});107 expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: bob.address});
119 expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: helper.address.normalizeSubstrate(charlie.address)});108 expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: charlie.address});
120109
121 await expect(collection.removeAdmin(charlie, {Substrate: bob.address})).to.be.rejected;110 await expect(collection.removeAdmin(charlie, {Substrate: bob.address}))
111 .to.be.rejectedWith(/common\.NoPermission/);
122112
123 const adminListAfterRemoveAdmin = await collection.getAdmins();113 const adminListAfterRemoveAdmin = await collection.getAdmins();
124 expect(adminListAfterRemoveAdmin).to.be.deep.contains({Substrate: helper.address.normalizeSubstrate(bob.address)});114 expect(adminListAfterRemoveAdmin).to.be.deep.contains({Substrate: bob.address});
125 expect(adminListAfterRemoveAdmin).to.be.deep.contains({Substrate: helper.address.normalizeSubstrate(charlie.address)});115 expect(adminListAfterRemoveAdmin).to.be.deep.contains({Substrate: charlie.address});
126 });
127 });116 });
128});117});
129118
modifiedtests/src/removeCollectionSponsor.test.tsdiffbeforeafterboth
1616
17import chai from 'chai';17import chai from 'chai';
18import chaiAsPromised from 'chai-as-promised';18import chaiAsPromised from 'chai-as-promised';
19import {default as usingApi, submitTransactionExpectFailAsync} from './substrate/substrate-api';19import {IKeyringPair} from '@polkadot/types/types';
20import {20import {itSub, usingPlaygrounds} from './util/playgrounds';
21 createCollectionExpectSuccess,
22 setCollectionSponsorExpectSuccess,
23 destroyCollectionExpectSuccess,
24 confirmSponsorshipExpectSuccess,
25 confirmSponsorshipExpectFailure,
26 createItemExpectSuccess,
27 findUnusedAddress,
28 removeCollectionSponsorExpectSuccess,
29 removeCollectionSponsorExpectFailure,
30 normalizeAccountId,
31 addCollectionAdminExpectSuccess,
32 getCreatedCollectionCount,
33} from './util/helpers';
34import {IKeyringPair} from '@polkadot/types/types';
3521
36chai.use(chaiAsPromised);22chai.use(chaiAsPromised);
37const expect = chai.expect;23const expect = chai.expect;
38
39let alice: IKeyringPair;
40let bob: IKeyringPair;
4124
42describe('integration test: ext. removeCollectionSponsor():', () => {25describe('integration test: ext. removeCollectionSponsor():', () => {
26 let donor: IKeyringPair;
27 let alice: IKeyringPair;
28 let bob: IKeyringPair;
4329
44 before(async () => {30 before(async () => {
45 await usingApi(async (api, privateKeyWrapper) => {31 await usingPlaygrounds(async (helper, privateKey) => {
46 alice = privateKeyWrapper('//Alice');32 donor = privateKey('//Alice');
47 bob = privateKeyWrapper('//Bob');33 [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor);
48 });34 });
49 });35 });
5036
51 it('Removing NFT collection sponsor stops sponsorship', async () => {37 itSub('Removing NFT collection sponsor stops sponsorship', async ({helper}) => {
52 const collectionId = await createCollectionExpectSuccess();38 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionSponsor-1', tokenPrefix: 'RCS'});
53 await setCollectionSponsorExpectSuccess(collectionId, bob.address);39 await collection.setSponsor(alice, bob.address);
54 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');40 await collection.confirmSponsorship(bob);
55 await removeCollectionSponsorExpectSuccess(collectionId);41 await collection.removeSponsor(alice);
5642
57 await usingApi(async (api, privateKeyWrapper) => {
58 // Find unused address43 // Find unused address
59 const zeroBalance = await findUnusedAddress(api, privateKeyWrapper);44 const [zeroBalance] = await helper.arrange.createAccounts([0n], donor);
6045
61 // Mint token for unused address46 // Mint token for unused address
62 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', zeroBalance.address);47 const token = await collection.mintToken(alice, {Substrate: zeroBalance.address});
6348
64 // Transfer this tokens from unused address to Alice - should fail49 // Transfer this tokens from unused address to Alice - should fail
65 const sponsorBalanceBefore = (await api.query.system.account(bob.address)).data.free.toBigInt();50 const sponsorBalanceBefore = await helper.balance.getSubstrate(bob.address);
66 const zeroToAlice = api.tx.unique.transfer(normalizeAccountId(alice.address), collectionId, itemId, 0);
67 const badTransaction = async function () {
68 await submitTransactionExpectFailAsync(zeroBalance, zeroToAlice);
69 };
70 await expect(badTransaction()).to.be.rejectedWith('Inability to pay some fees');51 await expect(token.transfer(zeroBalance, {Substrate: alice.address}))
52 .to.be.rejectedWith('Inability to pay some fees');
71 const sponsorBalanceAfter = (await api.query.system.account(bob.address)).data.free.toBigInt();53 const sponsorBalanceAfter = await helper.balance.getSubstrate(bob.address);
7254
73 expect(sponsorBalanceAfter).to.be.equal(sponsorBalanceBefore);55 expect(sponsorBalanceAfter).to.be.equal(sponsorBalanceBefore);
74 });
75 });56 });
7657
77 it('Remove a sponsor after it was already removed', async () => {58 itSub('Remove a sponsor after it was already removed', async ({helper}) => {
78 const collectionId = await createCollectionExpectSuccess();59 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionSponsor-2', tokenPrefix: 'RCS'});
79 await setCollectionSponsorExpectSuccess(collectionId, bob.address);60 await collection.setSponsor(alice, bob.address);
80 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');61 await collection.confirmSponsorship(bob);
81 await removeCollectionSponsorExpectSuccess(collectionId);62 await expect(collection.removeSponsor(alice)).to.not.be.rejected;
82 await removeCollectionSponsorExpectSuccess(collectionId);63 await expect(collection.removeSponsor(alice)).to.not.be.rejected;
83 });64 });
8465
85 it('Remove sponsor in a collection that never had the sponsor set', async () => {66 itSub('Remove sponsor in a collection that never had the sponsor set', async ({helper}) => {
86 const collectionId = await createCollectionExpectSuccess();67 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionSponsor-3', tokenPrefix: 'RCS'});
87 await removeCollectionSponsorExpectSuccess(collectionId);68 await expect(collection.removeSponsor(alice)).to.not.be.rejected;
88 });69 });
8970
90 it('Remove sponsor for a collection that had the sponsor set, but not confirmed', async () => {71 itSub('Remove sponsor for a collection that had the sponsor set, but not confirmed', async ({helper}) => {
91 const collectionId = await createCollectionExpectSuccess();72 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionSponsor-4', tokenPrefix: 'RCS'});
92 await setCollectionSponsorExpectSuccess(collectionId, bob.address);73 await collection.setSponsor(alice, bob.address);
93 await removeCollectionSponsorExpectSuccess(collectionId);74 await expect(collection.removeSponsor(alice)).to.not.be.rejected;
94 });75 });
9576
96});77});
9778
98describe('(!negative test!) integration test: ext. removeCollectionSponsor():', () => {79describe('(!negative test!) integration test: ext. removeCollectionSponsor():', () => {
80 let alice: IKeyringPair;
81 let bob: IKeyringPair;
82 let charlie: IKeyringPair;
83
99 before(async () => {84 before(async () => {
100 await usingApi(async (api, privateKeyWrapper) => {85 await usingPlaygrounds(async (helper, privateKey) => {
101 alice = privateKeyWrapper('//Alice');86 const donor = privateKey('//Alice');
102 bob = privateKeyWrapper('//Bob');87 [alice, bob, charlie] = await helper.arrange.createAccounts([20n, 10n, 10n], donor);
103 });88 });
104 });89 });
10590
106 it('(!negative test!) Remove sponsor for a collection that never existed', async () => {91 itSub('(!negative test!) Remove sponsor for a collection that never existed', async ({helper}) => {
107 // Find the collection that never existed
108 let collectionId = 0;92 const collectionId = (1 << 32) - 1;
109 await usingApi(async (api) => {93 await expect(helper.collection.removeSponsor(alice, collectionId)).to.be.rejectedWith(/common\.CollectionNotFound/);
110 collectionId = await getCreatedCollectionCount(api) + 1;
111 });
112
113 await removeCollectionSponsorExpectFailure(collectionId);
114 });94 });
11595
116 it('(!negative test!) Remove sponsor for a collection with collection admin permissions', async () => {96 itSub('(!negative test!) Remove sponsor for a collection with collection admin permissions', async ({helper}) => {
117 const collectionId = await createCollectionExpectSuccess();97 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionSponsor-Neg-1', tokenPrefix: 'RCS'});
118 await setCollectionSponsorExpectSuccess(collectionId, bob.address);98 await collection.setSponsor(alice, bob.address);
119 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);99 await collection.addAdmin(alice, {Substrate: charlie.address});
120 await removeCollectionSponsorExpectFailure(collectionId, '//Bob');100 await expect(collection.removeSponsor(charlie)).to.be.rejectedWith(/common\.NoPermission/);
121 });101 });
122102
123 it('(!negative test!) Remove sponsor for a collection by regular user', async () => {103 itSub('(!negative test!) Remove sponsor for a collection by regular user', async ({helper}) => {
124 const collectionId = await createCollectionExpectSuccess();104 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionSponsor-Neg-2', tokenPrefix: 'RCS'});
125 await setCollectionSponsorExpectSuccess(collectionId, bob.address);105 await collection.setSponsor(alice, bob.address);
126 await removeCollectionSponsorExpectFailure(collectionId, '//Bob');106 await expect(collection.removeSponsor(charlie)).to.be.rejectedWith(/common\.NoPermission/);
127 });107 });
128108
129 it('(!negative test!) Remove sponsor in a destroyed collection', async () => {109 itSub('(!negative test!) Remove sponsor in a destroyed collection', async ({helper}) => {
130 const collectionId = await createCollectionExpectSuccess();110 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionSponsor-Neg-3', tokenPrefix: 'RCS'});
131 await setCollectionSponsorExpectSuccess(collectionId, bob.address);111 await collection.setSponsor(alice, bob.address);
132 await destroyCollectionExpectSuccess(collectionId);112 await collection.burn(alice);
133 await removeCollectionSponsorExpectFailure(collectionId);113 await expect(collection.removeSponsor(alice)).to.be.rejectedWith(/common\.CollectionNotFound/);
134 });114 });
135115
136 it('Set - remove - confirm: fails', async () => {116 itSub('Set - remove - confirm: fails', async ({helper}) => {
137 const collectionId = await createCollectionExpectSuccess();117 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionSponsor-Neg-4', tokenPrefix: 'RCS'});
138 await setCollectionSponsorExpectSuccess(collectionId, bob.address);118 await collection.setSponsor(alice, bob.address);
139 await removeCollectionSponsorExpectSuccess(collectionId);119 await collection.removeSponsor(alice);
140 await confirmSponsorshipExpectFailure(collectionId, '//Bob');120 await expect(collection.confirmSponsorship(bob)).to.be.rejectedWith(/unique\.ConfirmUnsetSponsorFail/);
141 });121 });
142122
143 it('Set - confirm - remove - confirm: Sponsor cannot come back', async () => {123 itSub('Set - confirm - remove - confirm: Sponsor cannot come back', async ({helper}) => {
144 const collectionId = await createCollectionExpectSuccess();124 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionSponsor-Neg-5', tokenPrefix: 'RCS'});
145 await setCollectionSponsorExpectSuccess(collectionId, bob.address);125 await collection.setSponsor(alice, bob.address);
146 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');126 await collection.confirmSponsorship(bob);
147 await removeCollectionSponsorExpectSuccess(collectionId);127 await collection.removeSponsor(alice);
148 await confirmSponsorshipExpectFailure(collectionId, '//Bob');128 await expect(collection.confirmSponsorship(bob)).to.be.rejectedWith(/unique\.ConfirmUnsetSponsorFail/);
149 });129 });
150
151});130});
modifiedtests/src/removeFromAllowList.test.tsdiffbeforeafterboth
1616
17import chai from 'chai';17import chai from 'chai';
18import chaiAsPromised from 'chai-as-promised';18import chaiAsPromised from 'chai-as-promised';
19import {default as usingApi} from './substrate/substrate-api';19import {IKeyringPair} from '@polkadot/types/types';
20import {20import {itSub, usingPlaygrounds} from './util/playgrounds';
21 createCollectionExpectSuccess,
22 destroyCollectionExpectSuccess,
23 enableAllowListExpectSuccess,
24 addToAllowListExpectSuccess,
25 removeFromAllowListExpectSuccess,
26 isAllowlisted,
27 findNotExistingCollection,
28 removeFromAllowListExpectFailure,
29 disableAllowListExpectSuccess,
30 normalizeAccountId,
31 addCollectionAdminExpectSuccess,
32} from './util/helpers';
33import {IKeyringPair} from '@polkadot/types/types';
3421
35chai.use(chaiAsPromised);22chai.use(chaiAsPromised);
36const expect = chai.expect;23const expect = chai.expect;
40 let bob: IKeyringPair;27 let bob: IKeyringPair;
4128
42 before(async () => {29 before(async () => {
43 await usingApi(async (api, privateKeyWrapper) => {30 await usingPlaygrounds(async (helper, privateKey) => {
44 alice = privateKeyWrapper('//Alice');31 const donor = privateKey('//Alice');
45 bob = privateKeyWrapper('//Bob');32 [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor);
46 });33 });
47 });34 });
4835
49 it('ensure bob is not in allowlist after removal', async () => {36 itSub('ensure bob is not in allowlist after removal', async ({helper}) => {
50 await usingApi(async api => {37 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveFromAllowList-1', tokenPrefix: 'RFAL'});
38
39 const collectionInfo = await collection.getData();
51 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});40 expect(collectionInfo!.raw.permissions.access).to.not.equal('AllowList');
41
52 await enableAllowListExpectSuccess(alice, collectionId);42 await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
53 await addToAllowListExpectSuccess(alice, collectionId, bob.address);43 await collection.addToAllowList(alice, {Substrate: bob.address});
5444 expect(await collection.getAllowList()).to.deep.contains({Substrate: bob.address});
45
55 await removeFromAllowListExpectSuccess(alice, collectionId, normalizeAccountId(bob.address));46 await collection.removeFromAllowList(alice, {Substrate: bob.address});
56 expect(await isAllowlisted(api, collectionId, bob.address)).to.be.false;47 expect(await collection.getAllowList()).to.be.empty;
57 });
58 });48 });
5949
60 it('allows removal from collection with unset allowlist status', async () => {50 itSub('allows removal from collection with unset allowlist status', async ({helper}) => {
61 await usingApi(async () => {51 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveFromAllowList-2', tokenPrefix: 'RFAL'});
52
62 const collectionWithoutAllowlistId = await createCollectionExpectSuccess();53 await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
63 await enableAllowListExpectSuccess(alice, collectionWithoutAllowlistId);54 await collection.addToAllowList(alice, {Substrate: bob.address});
64 await addToAllowListExpectSuccess(alice, collectionWithoutAllowlistId, bob.address);55 expect(await collection.getAllowList()).to.deep.contains({Substrate: bob.address});
56
65 await disableAllowListExpectSuccess(alice, collectionWithoutAllowlistId);57 await collection.setPermissions(alice, {access: 'Normal'});
6658
67 await removeFromAllowListExpectSuccess(alice, collectionWithoutAllowlistId, normalizeAccountId(bob.address));59 await collection.removeFromAllowList(alice, {Substrate: bob.address});
68 });60 expect(await collection.getAllowList()).to.be.empty;
69 });61 });
70});62});
7163
74 let bob: IKeyringPair;66 let bob: IKeyringPair;
7567
76 before(async () => {68 before(async () => {
77 await usingApi(async (api, privateKeyWrapper) => {69 await usingPlaygrounds(async (helper, privateKey) => {
78 alice = privateKeyWrapper('//Alice');70 const donor = privateKey('//Alice');
79 bob = privateKeyWrapper('//Bob');71 [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor);
80 });72 });
81 });73 });
8274
83 it('fails on removal from not existing collection', async () => {75 itSub('fails on removal from not existing collection', async ({helper}) => {
76 const nonExistentCollectionId = (1 << 32) - 1;
84 await usingApi(async (api) => {77 await expect(helper.collection.removeFromAllowList(alice, nonExistentCollectionId, {Substrate: alice.address}))
85 const collectionId = await findNotExistingCollection(api);
86
87 await removeFromAllowListExpectFailure(alice, collectionId, normalizeAccountId(bob.address));
88 });78 .to.be.rejectedWith(/common\.CollectionNotFound/);
89 });79 });
9080
91 it('fails on removal from removed collection', async () => {81 itSub('fails on removal from removed collection', async ({helper}) => {
92 await usingApi(async () => {82 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveFromAllowList-3', tokenPrefix: 'RFAL'});
93 const collectionId = await createCollectionExpectSuccess();83 await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
94 await enableAllowListExpectSuccess(alice, collectionId);
95 await addToAllowListExpectSuccess(alice, collectionId, bob.address);84 await collection.addToAllowList(alice, {Substrate: bob.address});
85
96 await destroyCollectionExpectSuccess(collectionId);86 await collection.burn(alice);
97
98 await removeFromAllowListExpectFailure(alice, collectionId, normalizeAccountId(bob.address));87 await expect(collection.removeFromAllowList(alice, {Substrate: bob.address}))
99 });88 .to.be.rejectedWith(/common\.CollectionNotFound/);
100 });89 });
101});90});
10291
106 let charlie: IKeyringPair;95 let charlie: IKeyringPair;
10796
108 before(async () => {97 before(async () => {
109 await usingApi(async (api, privateKeyWrapper) => {98 await usingPlaygrounds(async (helper, privateKey) => {
110 alice = privateKeyWrapper('//Alice');99 const donor = privateKey('//Alice');
111 bob = privateKeyWrapper('//Bob');100 [alice, bob, charlie] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);
112 charlie = privateKeyWrapper('//Charlie');
113 });101 });
114 });102 });
115103
116 it('ensure address is not in allowlist after removal', async () => {104 itSub('ensure address is not in allowlist after removal', async ({helper}) => {
117 await usingApi(async api => {105 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveFromAllowList-4', tokenPrefix: 'RFAL'});
106
118 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});107 await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
119 await enableAllowListExpectSuccess(alice, collectionId);
120 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);108 await collection.addAdmin(alice, {Substrate: bob.address});
109
121 await addToAllowListExpectSuccess(alice, collectionId, charlie.address);110 await collection.addToAllowList(bob, {Substrate: charlie.address});
122 await removeFromAllowListExpectSuccess(bob, collectionId, normalizeAccountId(charlie.address));111 await collection.removeFromAllowList(bob, {Substrate: charlie.address});
112
123 expect(await isAllowlisted(api, collectionId, charlie.address)).to.be.false;113 expect(await collection.getAllowList()).to.be.empty;
124 });
125 });114 });
126115
127 it('Collection admin allowed to remove from allowlist with unset allowlist status', async () => {116 itSub('Collection admin allowed to remove from allowlist with unset allowlist status', async ({helper}) => {
128 await usingApi(async () => {117 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveFromAllowList-5', tokenPrefix: 'RFAL'});
118
129 const collectionWithoutAllowlistId = await createCollectionExpectSuccess();119 await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
130 await enableAllowListExpectSuccess(alice, collectionWithoutAllowlistId);
131 await addCollectionAdminExpectSuccess(alice, collectionWithoutAllowlistId, bob.address);120 await collection.addAdmin(alice, {Substrate: bob.address});
132 await addToAllowListExpectSuccess(alice, collectionWithoutAllowlistId, charlie.address);121 await collection.addToAllowList(alice, {Substrate: charlie.address});
122
133 await disableAllowListExpectSuccess(alice, collectionWithoutAllowlistId);123 await collection.setPermissions(bob, {access: 'Normal'});
134 await removeFromAllowListExpectSuccess(bob, collectionWithoutAllowlistId, normalizeAccountId(charlie.address));124 await collection.removeFromAllowList(bob, {Substrate: charlie.address});
125
135 });126 expect(await collection.getAllowList()).to.be.empty;
136 });127 });
137128
138 it('Regular user can`t remove from allowlist', async () => {129 itSub('Regular user can`t remove from allowlist', async ({helper}) => {
139 await usingApi(async () => {130 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveFromAllowList-6', tokenPrefix: 'RFAL'});
131
140 const collectionWithoutAllowlistId = await createCollectionExpectSuccess();132 await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
141 await enableAllowListExpectSuccess(alice, collectionWithoutAllowlistId);133 await collection.addToAllowList(alice, {Substrate: charlie.address});
134
142 await addToAllowListExpectSuccess(alice, collectionWithoutAllowlistId, charlie.address);135 await expect(collection.removeFromAllowList(bob, {Substrate: charlie.address}))
136 .to.be.rejectedWith(/common\.NoPermission/);
143 await removeFromAllowListExpectFailure(bob, collectionWithoutAllowlistId, normalizeAccountId(charlie.address));137 expect(await collection.getAllowList()).to.deep.contain({Substrate: charlie.address});
144 });
145 });138 });
146});139});
147140
modifiedtests/src/removeFromContractAllowList.test.tsdiffbeforeafterboth
20import {IKeyringPair} from '@polkadot/types/types';20import {IKeyringPair} from '@polkadot/types/types';
21import {expect} from 'chai';21import {expect} from 'chai';
2222
23// todo:playgrounds skipped again
23describe.skip('Integration Test removeFromContractAllowList', () => {24describe.skip('Integration Test removeFromContractAllowList', () => {
24 let bob: IKeyringPair;25 let bob: IKeyringPair;
2526
modifiedtests/src/rpc.test.tsdiffbeforeafterboth
1import {IKeyringPair} from '@polkadot/types/types';1import {IKeyringPair} from '@polkadot/types/types';
2import {expect} from 'chai';2import chai from 'chai';
3import usingApi from './substrate/substrate-api';3import chaiAsPromised from 'chai-as-promised';
4import {createCollection, createCollectionExpectSuccess, createFungibleItemExpectSuccess, CrossAccountId, getTokenOwner, normalizeAccountId, transfer, U128_MAX} from './util/helpers';4import {usingPlaygrounds, itSub} from './util/playgrounds';
5import {crossAccountIdFromLower} from './util/playgrounds/unique';
56
6let alice: IKeyringPair;7chai.use(chaiAsPromised);
7let bob: IKeyringPair;8const expect = chai.expect;
8
99
10describe('integration test: RPC methods', () => {10describe('integration test: RPC methods', () => {
11 let donor: IKeyringPair;
12 let alice: IKeyringPair;
13 let bob: IKeyringPair;
14
11 before(async () => {15 before(async () => {
12 await usingApi(async (api, privateKeyWrapper) => {16 await usingPlaygrounds(async (helper, privateKey) => {
13 alice = privateKeyWrapper('//Alice');17 donor = privateKey('//Alice');
14 bob = privateKeyWrapper('//Bob');18 [alice, bob] = await helper.arrange.createAccounts([20n, 10n], donor);
15 });19 });
16 });20 });
1721
18
19 it('returns None for fungible collection', async () => {22 itSub('returns None for fungible collection', async ({helper}) => {
20 await usingApi(async api => {
21 const collection = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});23 const collection = await helper.ft.mintCollection(alice, {name: 'RPC-1', tokenPrefix: 'RPC'});
22 await expect(getTokenOwner(api, collection, 0)).to.be.rejectedWith(/^owner == null$/);
23 });24 const owner = (await helper.callRpc('api.rpc.unique.tokenOwner', [collection.collectionId, 0])).toJSON() as any;
25 expect(owner).to.be.null;
24 });26 });
25 27
26 it('RPC method tokenOwners for fungible collection and token', async () => {28 itSub('RPC method tokenOwners for fungible collection and token', async ({helper}) => {
27 await usingApi(async (api, privateKeyWrapper) => {29 // Set-up a few token owners of all stripes
28 const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};30 const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
29 const facelessCrowd = Array.from(Array(7).keys()).map(i => normalizeAccountId(privateKeyWrapper(i.toString())));31 const facelessCrowd = (await helper.arrange.createAccounts([0n, 0n, 0n, 0n, 0n, 0n, 0n], donor))
30 32 .map(i => {return {Substrate: i.address};});
33
31 const createCollectionResult = await createCollection(api, alice, {mode: {type: 'Fungible', decimalPoints: 0}});34 const collection = await helper.ft.mintCollection(alice, {name: 'RPC-2', tokenPrefix: 'RPC'});
32 const collectionId = createCollectionResult.collectionId;35 // mint some maximum (u128) amounts of tokens possible
33 const aliceTokenId = await createFungibleItemExpectSuccess(alice, collectionId, {Value: U128_MAX}, alice.address);36 await collection.mint(alice, {Substrate: alice.address}, (1n << 128n) - 1n);
34 37
35 await transfer(api, collectionId, aliceTokenId, alice, bob, 1000n);38 await collection.transfer(alice, {Substrate: bob.address}, 1000n);
36 await transfer(api, collectionId, aliceTokenId, alice, ethAcc, 900n);39 await collection.transfer(alice, ethAcc, 900n);
37 40
38 for (let i = 0; i < 7; i++) {41 for (let i = 0; i < facelessCrowd.length; i++) {
39 await transfer(api, collectionId, aliceTokenId, alice, facelessCrowd[i], 1);42 await collection.transfer(alice, facelessCrowd[i], 1n);
40 } 43 }
41 44 // Set-up over
45
42 const owners = await api.rpc.unique.tokenOwners(collectionId, aliceTokenId);46 const owners = await helper.callRpc('api.rpc.unique.tokenOwners', [collection.collectionId, 0]);
43 const ids = (owners.toJSON() as CrossAccountId[]).map(s => normalizeAccountId(s));47 const ids = (owners.toJSON() as any[]).map(crossAccountIdFromLower);
44 const aliceID = normalizeAccountId(alice);48
45 const bobId = normalizeAccountId(bob);
46
47 // What to expect
48 // tslint:disable-next-line:no-unused-expression
49 expect(ids).to.deep.include.members([aliceID, ethAcc, bobId, ...facelessCrowd]);49 expect(ids).to.deep.include.members([{Substrate: alice.address}, ethAcc, {Substrate: bob.address}, ...facelessCrowd]);
50 expect(owners.length == 10).to.be.true;50 expect(owners.length == 10).to.be.true;
51 51
52 // Make sure only 10 results are returned with this RPC
52 const eleven = privateKeyWrapper('11');53 const [eleven] = await helper.arrange.createAccounts([0n], donor);
53 expect(await transfer(api, collectionId, aliceTokenId, alice, eleven, 10n)).to.be.true;54 expect(await collection.transfer(alice, {Substrate: eleven.address}, 10n)).to.be.true;
54 expect((await api.rpc.unique.tokenOwners(collectionId, aliceTokenId)).length).to.be.equal(10);55 expect((await helper.callRpc('api.rpc.unique.tokenOwners', [collection.collectionId, 0])).length).to.be.equal(10);
55 });
56 });56 });
57});57});
modifiedtests/src/scheduler.test.tsdiffbeforeafterboth
4444
45chai.use(chaiAsPromised);45chai.use(chaiAsPromised);
4646
47// todo:playgrounds skipped ~ postponed
47describe.skip('Scheduling token and balance transfers', () => {48describe.skip('Scheduling token and balance transfers', () => {
48 let alice: IKeyringPair;49 let alice: IKeyringPair;
49 let bob: IKeyringPair;50 let bob: IKeyringPair;
modifiedtests/src/setChainLimits.test.tsdiffbeforeafterboth
23 IChainLimits,23 IChainLimits,
24} from './util/helpers';24} from './util/helpers';
2525
26// todo:playgrounds skipped ~ postponed
26describe.skip('Negative Integration Test setChainLimits', () => {27describe.skip('Negative Integration Test setChainLimits', () => {
27 let alice: IKeyringPair;28 let alice: IKeyringPair;
28 let bob: IKeyringPair;29 let bob: IKeyringPair;
modifiedtests/src/setCollectionLimits.test.tsdiffbeforeafterboth
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17// https://unique-network.readthedocs.io/en/latest/jsapi.html#setchainlimits17// https://unique-network.readthedocs.io/en/latest/jsapi.html#setchainlimits
18import {ApiPromise} from '@polkadot/api';
19import {IKeyringPair} from '@polkadot/types/types';18import {IKeyringPair} from '@polkadot/types/types';
20import chai from 'chai';19import chai from 'chai';
21import chaiAsPromised from 'chai-as-promised';20import chaiAsPromised from 'chai-as-promised';
22import usingApi, {submitTransactionAsync, submitTransactionExpectFailAsync} from './substrate/substrate-api';
23import {21import {itSub, usingPlaygrounds} from './util/playgrounds';
24 createCollectionExpectSuccess, getCreatedCollectionCount,
25 getCreateItemResult,
26 setCollectionLimitsExpectFailure,
27 setCollectionLimitsExpectSuccess,
28 addCollectionAdminExpectSuccess,
29 queryCollectionExpectSuccess,
30} from './util/helpers';
3122
32chai.use(chaiAsPromised);23chai.use(chaiAsPromised);
33const expect = chai.expect;24const expect = chai.expect;
34
35let alice: IKeyringPair;
36let bob: IKeyringPair;
37let collectionIdForTesting: number;
3825
39const accountTokenOwnershipLimit = 0;26const accountTokenOwnershipLimit = 0;
40const sponsoredDataSize = 0;27const sponsoredDataSize = 0;
41const sponsorTransferTimeout = 1;28const sponsorTransferTimeout = 1;
42const tokenLimit = 10;29const tokenLimit = 10;
4330
44describe('setCollectionLimits positive', () => {31describe('setCollectionLimits positive', () => {
45 let tx;32 let alice: IKeyringPair;
33 let bob: IKeyringPair;
34
46 before(async () => {35 before(async () => {
47 await usingApi(async (api, privateKeyWrapper) => {36 await usingPlaygrounds(async (helper, privateKey) => {
48 alice = privateKeyWrapper('//Alice');37 const donor = privateKey('//Alice');
49 bob = privateKeyWrapper('//Bob');
50 collectionIdForTesting = await createCollectionExpectSuccess({name: 'A', description: 'B', tokenPrefix: 'C', mode: {type: 'NFT'}});38 [alice, bob] = await helper.arrange.createAccounts([20n, 10n], donor);
51 });39 });
52 });40 });
41
53 it('execute setCollectionLimits with predefined params ', async () => {42 itSub('execute setCollectionLimits with predefined params', async ({helper}) => {
54 await usingApi(async (api: ApiPromise) => {
55 tx = api.tx.unique.setCollectionLimits(
56 collectionIdForTesting,
57 {
58 accountTokenOwnershipLimit: accountTokenOwnershipLimit,
59 sponsoredDataSize: sponsoredDataSize,
60 tokenLimit: tokenLimit,
61 sponsorTransferTimeout,
62 ownerCanTransfer: true,
63 ownerCanDestroy: true,
64 },
65 );43 const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionLimits-1', tokenPrefix: 'SCL'});
44
66 const events = await submitTransactionAsync(alice, tx);45 await collection.setLimits(
67 const result = getCreateItemResult(events);46 alice,
47 {
48 accountTokenOwnershipLimit,
49 sponsoredDataSize,
50 tokenLimit,
51 sponsorTransferTimeout,
52 ownerCanTransfer: true,
53 ownerCanDestroy: true,
54 },
55 );
6856
69 // get collection limits defined previously57 // get collection limits defined previously
70 const collectionInfo = await queryCollectionExpectSuccess(api, collectionIdForTesting);58 const collectionInfo = await collection.getEffectiveLimits();
7159
72 // tslint:disable-next-line:no-unused-expression
73 expect(result.success).to.be.true;
74 expect(collectionInfo.limits.accountTokenOwnershipLimit.unwrap().toNumber()).to.be.equal(accountTokenOwnershipLimit);60 expect(collectionInfo.accountTokenOwnershipLimit).to.be.equal(accountTokenOwnershipLimit);
75 expect(collectionInfo.limits.sponsoredDataSize.unwrap().toNumber()).to.be.equal(sponsoredDataSize);61 expect(collectionInfo.sponsoredDataSize).to.be.equal(sponsoredDataSize);
76 expect(collectionInfo.limits.tokenLimit.unwrap().toNumber()).to.be.equal(tokenLimit);62 expect(collectionInfo.tokenLimit).to.be.equal(tokenLimit);
77 expect(collectionInfo.limits.sponsorTransferTimeout.unwrap().toNumber()).to.be.equal(sponsorTransferTimeout);63 expect(collectionInfo.sponsorTransferTimeout).to.be.equal(sponsorTransferTimeout);
78 expect(collectionInfo.limits.ownerCanTransfer.unwrap().toJSON()).to.be.true;64 expect(collectionInfo.ownerCanTransfer).to.be.true;
79 expect(collectionInfo.limits.ownerCanDestroy.unwrap().toJSON()).to.be.true;65 expect(collectionInfo.ownerCanDestroy).to.be.true;
80 });
81 });66 });
8267
83 it('Set the same token limit twice', async () => {68 itSub('Set the same token limit twice', async ({helper}) => {
84 await usingApi(async (api: ApiPromise) => {69 const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionLimits-2', tokenPrefix: 'SCL'});
8570
86 const collectionLimits = {71 const collectionLimits = {
87 accountTokenOwnershipLimit: accountTokenOwnershipLimit,72 accountTokenOwnershipLimit,
88 sponsoredMintSize: sponsoredDataSize,73 sponsoredDataSize,
89 tokenLimit: tokenLimit,74 tokenLimit,
90 sponsorTransferTimeout,75 sponsorTransferTimeout,
91 ownerCanTransfer: true,76 ownerCanTransfer: true,
92 ownerCanDestroy: true,77 ownerCanDestroy: true,
78 };
79
93 };80 await collection.setLimits(alice, collectionLimits);
9481
95 // The first time
96 const tx1 = api.tx.unique.setCollectionLimits(
97 collectionIdForTesting,
98 collectionLimits,
99 );
100 const events1 = await submitTransactionAsync(alice, tx1);
101 const result1 = getCreateItemResult(events1);
102 expect(result1.success).to.be.true;
103 const collectionInfo1 = await queryCollectionExpectSuccess(api, collectionIdForTesting);82 const collectionInfo1 = await collection.getEffectiveLimits();
83
104 expect(collectionInfo1.limits.tokenLimit.unwrap().toNumber()).to.be.equal(tokenLimit);84 expect(collectionInfo1.tokenLimit).to.be.equal(tokenLimit);
10585
106 // The second time
107 const tx2 = api.tx.unique.setCollectionLimits(86 await collection.setLimits(alice, collectionLimits);
108 collectionIdForTesting,
109 collectionLimits,
110 );
111 const events2 = await submitTransactionAsync(alice, tx2);
112 const result2 = getCreateItemResult(events2);
113 expect(result2.success).to.be.true;
114 const collectionInfo2 = await queryCollectionExpectSuccess(api, collectionIdForTesting);87 const collectionInfo2 = await collection.getEffectiveLimits();
115 expect(collectionInfo2.limits.tokenLimit.unwrap().toNumber()).to.be.equal(tokenLimit);88 expect(collectionInfo2.tokenLimit).to.be.equal(tokenLimit);
116 });
117 });89 });
11890
119 it('execute setCollectionLimits from admin collection', async () => {91 itSub('execute setCollectionLimits from admin collection', async ({helper}) => {
92 const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionLimits-3', tokenPrefix: 'SCL'});
120 await addCollectionAdminExpectSuccess(alice, collectionIdForTesting, bob.address);93 await collection.addAdmin(alice, {Substrate: bob.address});
94
95 const collectionLimits = {
96 accountTokenOwnershipLimit,
97 sponsoredDataSize,
98 // sponsoredMintSize,
99 tokenLimit,
100 };
101
121 await usingApi(async (api: ApiPromise) => {102 await expect(collection.setLimits(alice, collectionLimits)).to.not.be.rejected;
122 tx = api.tx.unique.setCollectionLimits(
123 collectionIdForTesting,
124 {
125 accountTokenOwnershipLimit,
126 sponsoredDataSize,
127 // sponsoredMintSize,
128 tokenLimit,
129 },
130 );
131 await expect(submitTransactionAsync(bob, tx)).to.be.not.rejected;
132 });
133 });103 });
134});104});
135105
136describe('setCollectionLimits negative', () => {106describe('setCollectionLimits negative', () => {
137 let tx;107 let alice: IKeyringPair;
108 let bob: IKeyringPair;
109
138 before(async () => {110 before(async () => {
139 await usingApi(async (api, privateKeyWrapper) => {111 await usingPlaygrounds(async (helper, privateKey) => {
140 alice = privateKeyWrapper('//Alice');112 const donor = privateKey('//Alice');
141 bob = privateKeyWrapper('//Bob');
142 collectionIdForTesting = await createCollectionExpectSuccess({name: 'A', description: 'B', tokenPrefix: 'C', mode: {type: 'NFT'}});113 [alice, bob] = await helper.arrange.createAccounts([20n, 10n], donor);
143 });114 });
144 });115 });
116
145 it('execute setCollectionLimits for not exists collection', async () => {117 itSub('execute setCollectionLimits for not exists collection', async ({helper}) => {
118 const nonExistentCollectionId = (1 << 32) - 1;
146 await usingApi(async (api: ApiPromise) => {119 await expect(helper.collection.setLimits(
147 const collectionCount = await getCreatedCollectionCount(api);120 alice,
148 const nonExistedCollectionId = collectionCount + 1;
149 tx = api.tx.unique.setCollectionLimits(
150 nonExistedCollectionId,121 nonExistentCollectionId,
151 {122 {
152 accountTokenOwnershipLimit,123 accountTokenOwnershipLimit,
153 sponsoredDataSize,124 sponsoredDataSize,
154 // sponsoredMintSize,125 // sponsoredMintSize,
155 tokenLimit,126 tokenLimit,
156 },127 },
157 );128 )).to.be.rejectedWith(/common\.CollectionNotFound/);
158 await expect(submitTransactionExpectFailAsync(alice, tx)).to.be.rejected;
159 });
160 });129 });
130
161 it('execute setCollectionLimits from user who is not owner of this collection', async () => {131 itSub('execute setCollectionLimits from user who is not owner of this collection', async ({helper}) => {
132 const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionLimits-Neg-1', tokenPrefix: 'SCL'});
133
162 await usingApi(async (api: ApiPromise) => {134 await expect(collection.setLimits(bob, {
163 tx = api.tx.unique.setCollectionLimits(
164 collectionIdForTesting,
165 {
166 accountTokenOwnershipLimit,135 accountTokenOwnershipLimit,
167 sponsoredDataSize,136 sponsoredDataSize,
168 // sponsoredMintSize,137 // sponsoredMintSize,
169 tokenLimit,138 tokenLimit,
170 },139 })).to.be.rejectedWith(/common\.NoPermission/);
171 );
172 await expect(submitTransactionExpectFailAsync(bob, tx)).to.be.rejected;
173 });
174 });140 });
175141
176 it('fails when trying to enable OwnerCanTransfer after it was disabled', async () => {142 itSub('fails when trying to enable OwnerCanTransfer after it was disabled', async ({helper}) => {
177 const collectionId = await createCollectionExpectSuccess();143 const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionLimits-Neg-2', tokenPrefix: 'SCL'});
144
178 await setCollectionLimitsExpectSuccess(alice, collectionId, {145 await collection.setLimits(alice, {
179 accountTokenOwnershipLimit: accountTokenOwnershipLimit,146 accountTokenOwnershipLimit,
180 sponsoredMintSize: sponsoredDataSize,147 sponsoredDataSize,
181 tokenLimit: tokenLimit,148 tokenLimit,
182 sponsorTransferTimeout,149 sponsorTransferTimeout,
183 ownerCanTransfer: false,150 ownerCanTransfer: false,
184 ownerCanDestroy: true,151 ownerCanDestroy: true,
185 });152 });
153
186 await setCollectionLimitsExpectFailure(alice, collectionId, {154 await expect(collection.setLimits(alice, {
187 accountTokenOwnershipLimit: accountTokenOwnershipLimit,155 accountTokenOwnershipLimit,
188 sponsoredMintSize: sponsoredDataSize,156 sponsoredDataSize,
189 tokenLimit: tokenLimit,157 tokenLimit,
190 sponsorTransferTimeout,158 sponsorTransferTimeout,
191 ownerCanTransfer: true,159 ownerCanTransfer: true,
192 ownerCanDestroy: true,160 ownerCanDestroy: true,
193 });161 })).to.be.rejectedWith(/common\.OwnerPermissionsCantBeReverted/);
194 });162 });
195163
196 it('fails when trying to enable OwnerCanDestroy after it was disabled', async () => {164 itSub('fails when trying to enable OwnerCanDestroy after it was disabled', async ({helper}) => {
197 const collectionId = await createCollectionExpectSuccess();165 const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionLimits-Neg-3', tokenPrefix: 'SCL'});
166
198 await setCollectionLimitsExpectSuccess(alice, collectionId, {167 await collection.setLimits(alice, {
199 accountTokenOwnershipLimit: accountTokenOwnershipLimit,168 accountTokenOwnershipLimit,
200 sponsoredMintSize: sponsoredDataSize,169 sponsoredDataSize,
201 tokenLimit: tokenLimit,170 tokenLimit,
202 sponsorTransferTimeout,171 sponsorTransferTimeout,
203 ownerCanTransfer: true,172 ownerCanTransfer: true,
204 ownerCanDestroy: false,173 ownerCanDestroy: false,
205 });174 });
175
206 await setCollectionLimitsExpectFailure(alice, collectionId, {176 await expect(collection.setLimits(alice, {
207 accountTokenOwnershipLimit: accountTokenOwnershipLimit,177 accountTokenOwnershipLimit,
208 sponsoredMintSize: sponsoredDataSize,178 sponsoredDataSize,
209 tokenLimit: tokenLimit,179 tokenLimit,
210 sponsorTransferTimeout,180 sponsorTransferTimeout,
211 ownerCanTransfer: true,181 ownerCanTransfer: true,
212 ownerCanDestroy: true,182 ownerCanDestroy: true,
213 });183 })).to.be.rejectedWith(/common\.OwnerPermissionsCantBeReverted/);
214 });184 });
215185
216 it('Setting the higher token limit fails', async () => {186 itSub('Setting the higher token limit fails', async ({helper}) => {
217 await usingApi(async () => {187 const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionLimits-Neg-4', tokenPrefix: 'SCL'});
218188
219 const collectionId = await createCollectionExpectSuccess();
220 const collectionLimits = {189 const collectionLimits = {
221 accountTokenOwnershipLimit: accountTokenOwnershipLimit,190 accountTokenOwnershipLimit: accountTokenOwnershipLimit,
222 sponsoredMintSize: sponsoredDataSize,191 sponsoredMintSize: sponsoredDataSize,
227 };196 };
228197
229 // The first time198 // The first time
230 await setCollectionLimitsExpectSuccess(alice, collectionId, collectionLimits);199 await collection.setLimits(alice, collectionLimits);
231200
232 // The second time - higher token limit201 // The second time - higher token limit
233 collectionLimits.tokenLimit += 1;202 collectionLimits.tokenLimit += 1;
234 await setCollectionLimitsExpectFailure(alice, collectionId, collectionLimits);203 await expect(collection.setLimits(alice, collectionLimits)).to.be.rejectedWith(/common\.CollectionTokenLimitExceeded/);
235 });
236 });204 });
237
238});205});
modifiedtests/src/setCollectionSponsor.test.tsdiffbeforeafterboth
1616
17import chai from 'chai';17import chai from 'chai';
18import chaiAsPromised from 'chai-as-promised';18import chaiAsPromised from 'chai-as-promised';
19import {default as usingApi} from './substrate/substrate-api';19import {IKeyringPair} from '@polkadot/types/types';
20import {createCollectionExpectSuccess,20import {itSub, usingPlaygrounds, Pallets} from './util/playgrounds';
21 setCollectionSponsorExpectSuccess,
22 destroyCollectionExpectSuccess,
23 setCollectionSponsorExpectFailure,
24 addCollectionAdminExpectSuccess,
25 getCreatedCollectionCount,
26 requirePallets,
27 Pallets,
28} from './util/helpers';
29import {IKeyringPair} from '@polkadot/types/types';
3021
31chai.use(chaiAsPromised);22chai.use(chaiAsPromised);
32
33let alice: IKeyringPair;23const expect = chai.expect;
34let bob: IKeyringPair;
35let charlie: IKeyringPair;
3624
37describe('integration test: ext. setCollectionSponsor():', () => {25describe('integration test: ext. setCollectionSponsor():', () => {
26 let alice: IKeyringPair;
27 let bob: IKeyringPair;
28 let charlie: IKeyringPair;
3829
39 before(async () => {30 before(async () => {
40 await usingApi(async (api, privateKeyWrapper) => {31 await usingPlaygrounds(async (helper, privateKey) => {
41 alice = privateKeyWrapper('//Alice');32 const donor = privateKey('//Alice');
42 bob = privateKeyWrapper('//Bob');33 [alice, bob, charlie] = await helper.arrange.createAccounts([20n, 10n, 10n], donor);
43 charlie = privateKeyWrapper('//Charlie');
44 });34 });
45 });35 });
4636
47 it('Set NFT collection sponsor', async () => {37 itSub('Set NFT collection sponsor', async ({helper}) => {
48 const collectionId = await createCollectionExpectSuccess();38 const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionSponsor-1-NFT', tokenPrefix: 'SCS'});
49 await setCollectionSponsorExpectSuccess(collectionId, bob.address);39 await expect(collection.setSponsor(alice, bob.address)).to.be.not.rejected;
40
41 expect((await collection.getData())?.raw.sponsorship).to.deep.equal({
42 Unconfirmed: bob.address,
43 });
50 });44 });
45
51 it('Set Fungible collection sponsor', async () => {46 itSub('Set Fungible collection sponsor', async ({helper}) => {
52 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});47 const collection = await helper.ft.mintCollection(alice, {name: 'SetCollectionSponsor-1-FT', tokenPrefix: 'SCS'});
53 await setCollectionSponsorExpectSuccess(collectionId, bob.address);48 await expect(collection.setSponsor(alice, bob.address)).to.be.not.rejected;
49
50 expect((await collection.getData())?.raw.sponsorship).to.deep.equal({
51 Unconfirmed: bob.address,
52 });
54 });53 });
54
55 it('Set ReFungible collection sponsor', async function() {55 itSub.ifWithPallets('Set ReFungible collection sponsor', [Pallets.ReFungible], async ({helper}) => {
56 await requirePallets(this, [Pallets.ReFungible]);
57
58 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});56 const collection = await helper.rft.mintCollection(alice, {name: 'SetCollectionSponsor-1-RFT', tokenPrefix: 'SCS'});
59 await setCollectionSponsorExpectSuccess(collectionId, bob.address);57 await expect(collection.setSponsor(alice, bob.address)).to.be.not.rejected;
58
59 expect((await collection.getData())?.raw.sponsorship).to.deep.equal({
60 Unconfirmed: bob.address,
61 });
60 });62 });
6163
62 it('Set the same sponsor repeatedly', async () => {64 itSub('Set the same sponsor repeatedly', async ({helper}) => {
63 const collectionId = await createCollectionExpectSuccess();65 const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionSponsor-2', tokenPrefix: 'SCS'});
64 await setCollectionSponsorExpectSuccess(collectionId, bob.address);66 await expect(collection.setSponsor(alice, bob.address)).to.be.not.rejected;
65 await setCollectionSponsorExpectSuccess(collectionId, bob.address);67 await expect(collection.setSponsor(alice, bob.address)).to.be.not.rejected;
68
69 expect((await collection.getData())?.raw.sponsorship).to.deep.equal({
70 Unconfirmed: bob.address,
71 });
66 });72 });
73
67 it('Replace collection sponsor', async () => {74 itSub('Replace collection sponsor', async ({helper}) => {
68 const collectionId = await createCollectionExpectSuccess();75 const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionSponsor-3', tokenPrefix: 'SCS'});
69 await setCollectionSponsorExpectSuccess(collectionId, bob.address);76 await expect(collection.setSponsor(alice, bob.address)).to.be.not.rejected;
70 await setCollectionSponsorExpectSuccess(collectionId, charlie.address);77 await expect(collection.setSponsor(alice, charlie.address)).to.be.not.rejected;
78
79 expect((await collection.getData())?.raw.sponsorship).to.deep.equal({
80 Unconfirmed: charlie.address,
81 });
71 });82 });
83
72 it('Collection admin add sponsor', async () => {84 itSub('Collection admin add sponsor', async ({helper}) => {
73 const collectionId = await createCollectionExpectSuccess();85 const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionSponsor-4', tokenPrefix: 'SCS'});
74 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);86 await collection.addAdmin(alice, {Substrate: bob.address});
75 await setCollectionSponsorExpectSuccess(collectionId, charlie.address, '//Bob');87 await expect(collection.setSponsor(bob, charlie.address)).to.be.not.rejected;
88
89 expect((await collection.getData())?.raw.sponsorship).to.deep.equal({
90 Unconfirmed: charlie.address,
91 });
76 });92 });
77});93});
7894
79describe('(!negative test!) integration test: ext. setCollectionSponsor():', () => {95describe('(!negative test!) integration test: ext. setCollectionSponsor():', () => {
96 let alice: IKeyringPair;
97 let bob: IKeyringPair;
98
80 before(async () => {99 before(async () => {
81 await usingApi(async (api, privateKeyWrapper) => {100 await usingPlaygrounds(async (helper, privateKey) => {
82 alice = privateKeyWrapper('//Alice');101 const donor = privateKey('//Alice');
83 bob = privateKeyWrapper('//Bob');102 [alice, bob] = await helper.arrange.createAccounts([10n, 5n], donor);
84 charlie = privateKeyWrapper('//Charlie');
85 });103 });
86 });104 });
87105
88 it('(!negative test!) Add sponsor with a non-owner', async () => {106 itSub('(!negative test!) Add sponsor with a non-owner', async ({helper}) => {
89 const collectionId = await createCollectionExpectSuccess();107 const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionSponsor-Neg-1', tokenPrefix: 'SCS'});
90 await setCollectionSponsorExpectFailure(collectionId, bob.address, '//Bob');108 await expect(collection.setSponsor(bob, bob.address))
109 .to.be.rejectedWith(/common\.NoPermission/);
91 });110 });
111
92 it('(!negative test!) Add sponsor to a collection that never existed', async () => {112 itSub('(!negative test!) Add sponsor to a collection that never existed', async ({helper}) => {
93 // Find the collection that never existed
94 let collectionId = 0;
95 await usingApi(async (api) => {
96 collectionId = await getCreatedCollectionCount(api) + 1;113 const collectionId = (1 << 32) - 1;
97 });
98
99 await setCollectionSponsorExpectFailure(collectionId, bob.address);114 await expect(helper.collection.setSponsor(alice, collectionId, bob.address))
115 .to.be.rejectedWith(/common\.CollectionNotFound/);
100 });116 });
117
101 it('(!negative test!) Add sponsor to a collection that was destroyed', async () => {118 itSub('(!negative test!) Add sponsor to a collection that was destroyed', async ({helper}) => {
102 const collectionId = await createCollectionExpectSuccess();119 const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionSponsor-Neg-2', tokenPrefix: 'SCS'});
103 await destroyCollectionExpectSuccess(collectionId);120 await collection.burn(alice);
104 await setCollectionSponsorExpectFailure(collectionId, bob.address);121 await expect(collection.setSponsor(alice, bob.address))
122 .to.be.rejectedWith(/common\.CollectionNotFound/);
105 });123 });
106});124});
107125
modifiedtests/src/setContractSponsoringRateLimit.test.tsdiffbeforeafterboth
25 setContractSponsoringRateLimitExpectSuccess,25 setContractSponsoringRateLimitExpectSuccess,
26} from './util/helpers';26} from './util/helpers';
2727
28// todo:playgrounds postponed skipped test
28describe.skip('Integration Test setContractSponsoringRateLimit', () => {29describe.skip('Integration Test setContractSponsoringRateLimit', () => {
29 it('ensure sponsored contract can\'t be called twice without pause for free', async () => {30 it('ensure sponsored contract can\'t be called twice without pause for free', async () => {
30 await usingApi(async (api, privateKeyWrapper) => {31 await usingApi(async (api, privateKeyWrapper) => {
modifiedtests/src/setMintPermission.test.tsdiffbeforeafterboth
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17import {IKeyringPair} from '@polkadot/types/types';17import {IKeyringPair} from '@polkadot/types/types';
18import chai from 'chai';
18import usingApi from './substrate/substrate-api';19import chaiAsPromised from 'chai-as-promised';
19import {20import {itSub, usingPlaygrounds} from './util/playgrounds';
20 addToAllowListExpectSuccess,21
21 createCollectionExpectSuccess,22chai.use(chaiAsPromised);
22 createItemExpectFailure,23const expect = chai.expect;
23 createItemExpectSuccess,
24 destroyCollectionExpectSuccess,
25 enableAllowListExpectSuccess,
26 findNotExistingCollection,
27 setMintPermissionExpectFailure,
28 setMintPermissionExpectSuccess,
29 addCollectionAdminExpectSuccess,
30} from './util/helpers';
3124
32describe('Integration Test setMintPermission', () => {25describe('Integration Test setMintPermission', () => {
33 let alice: IKeyringPair;26 let alice: IKeyringPair;
34 let bob: IKeyringPair;27 let bob: IKeyringPair;
3528
36 before(async () => {29 before(async () => {
37 await usingApi(async (api, privateKeyWrapper) => {30 await usingPlaygrounds(async (helper, privateKey) => {
38 alice = privateKeyWrapper('//Alice');31 const donor = privateKey('//Alice');
39 bob = privateKeyWrapper('//Bob');32 [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor);
40 });33 });
41 });34 });
4235
43 it('ensure allow-listed non-privileged address can mint tokens', async () => {36 itSub('ensure allow-listed non-privileged address can mint tokens', async ({helper}) => {
44 await usingApi(async () => {37 const collection = await helper.nft.mintCollection(alice, {name: 'SetMintPermission-1', description: '', tokenPrefix: 'SMP'});
45 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});38 await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
46 await enableAllowListExpectSuccess(alice, collectionId);39 await collection.addToAllowList(alice, {Substrate: bob.address});
47 await setMintPermissionExpectSuccess(alice, collectionId, true);40
48 await addToAllowListExpectSuccess(alice, collectionId, bob.address);41 await expect(collection.mintToken(bob, {Substrate: bob.address})).to.not.be.rejected;
49
50 await createItemExpectSuccess(bob, collectionId, 'NFT');
51 });
52 });42 });
5343
54 it('can be enabled twice', async () => {44 itSub('can be enabled twice', async ({helper}) => {
55 await usingApi(async () => {45 const collection = await helper.nft.mintCollection(alice, {name: 'SetMintPermission-2', description: '', tokenPrefix: 'SMP'});
56 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});46 expect((await collection.getData())?.raw.permissions.access).to.not.equal('AllowList');
47
57 await setMintPermissionExpectSuccess(alice, collectionId, true);48 await collection.setPermissions(alice, {mintMode: true});
58 await setMintPermissionExpectSuccess(alice, collectionId, true);49 await collection.setPermissions(alice, {mintMode: true});
59 });50 expect((await collection.getData())?.raw.permissions.mintMode).to.be.true;
60 });51 });
6152
62 it('can be disabled twice', async () => {53 itSub('can be disabled twice', async ({helper}) => {
63 await usingApi(async () => {54 const collection = await helper.nft.mintCollection(alice, {name: 'SetMintPermission-3', description: '', tokenPrefix: 'SMP'});
55 expect((await collection.getData())?.raw.permissions.access).to.equal('Normal');
56
57 await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
58 expect((await collection.getData())?.raw.permissions.access).to.equal('AllowList');
64 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});59 expect((await collection.getData())?.raw.permissions.mintMode).to.equal(true);
60
65 await setMintPermissionExpectSuccess(alice, collectionId, true);61 await collection.setPermissions(alice, {access: 'Normal', mintMode: false});
66 await setMintPermissionExpectSuccess(alice, collectionId, false);62 await collection.setPermissions(alice, {access: 'Normal', mintMode: false});
67 await setMintPermissionExpectSuccess(alice, collectionId, false);63 expect((await collection.getData())?.raw.permissions.access).to.equal('Normal');
68 });64 expect((await collection.getData())?.raw.permissions.mintMode).to.equal(false);
69 });65 });
7066
71 it('Collection admin success on set', async () => {67 itSub('Collection admin success on set', async ({helper}) => {
68 const collection = await helper.nft.mintCollection(alice, {name: 'SetMintPermission-4', description: '', tokenPrefix: 'SMP'});
72 await usingApi(async () => {69 await collection.addAdmin(alice, {Substrate: bob.address});
73 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});70 await collection.setPermissions(bob, {access: 'AllowList', mintMode: true});
74 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);71
75 await setMintPermissionExpectSuccess(bob, collectionId, true);72 expect((await collection.getData())?.raw.permissions.access).to.equal('AllowList');
76 });73 expect((await collection.getData())?.raw.permissions.mintMode).to.equal(true);
77 });74 });
78});75});
7976
82 let bob: IKeyringPair;79 let bob: IKeyringPair;
8380
84 before(async () => {81 before(async () => {
85 await usingApi(async (api, privateKeyWrapper) => {82 await usingPlaygrounds(async (helper, privateKey) => {
86 alice = privateKeyWrapper('//Alice');83 const donor = privateKey('//Alice');
87 bob = privateKeyWrapper('//Bob');84 [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor);
88 });85 });
89 });86 });
9087
91 it('fails on not existing collection', async () => {88 itSub('fails on not existing collection', async ({helper}) => {
89 const collectionId = (1 << 32) - 1;
92 await usingApi(async (api) => {90 await expect(helper.collection.setPermissions(alice, collectionId, {mintMode: true}))
93 const nonExistingCollection = await findNotExistingCollection(api);
94 await setMintPermissionExpectFailure(alice, nonExistingCollection, true);
95 });91 .to.be.rejectedWith(/common\.CollectionNotFound/);
96 });92 });
9793
98 it('fails on removed collection', async () => {94 itSub('fails on removed collection', async ({helper}) => {
95 const collection = await helper.nft.mintCollection(alice, {name: 'SetMintPermission-Neg-1', tokenPrefix: 'SMP'});
96 await collection.burn(alice);
97
99 await usingApi(async () => {98 await expect(collection.setPermissions(alice, {mintMode: true}))
100 const removedCollectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
101 await destroyCollectionExpectSuccess(removedCollectionId);
102
103 await setMintPermissionExpectFailure(alice, removedCollectionId, true);
104 });99 .to.be.rejectedWith(/common\.CollectionNotFound/);
105 });100 });
106101
107 it('fails when not collection owner tries to set mint status', async () => {102 itSub('fails when non-owner tries to set mint status', async ({helper}) => {
108 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});103 const collection = await helper.nft.mintCollection(alice, {name: 'SetMintPermission-Neg-2', tokenPrefix: 'SMP'});
109 await enableAllowListExpectSuccess(alice, collectionId);104
110 await setMintPermissionExpectFailure(bob, collectionId, true);105 await expect(collection.setPermissions(bob, {mintMode: true}))
106 .to.be.rejectedWith(/common\.NoPermission/);
111 });107 });
112108
113 it('ensure non-allow-listed non-privileged address can\'t mint tokens', async () => {109 itSub('ensure non-allow-listed non-privileged address can\'t mint tokens', async ({helper}) => {
110 const collection = await helper.nft.mintCollection(alice, {name: 'SetMintPermission-Neg-3', tokenPrefix: 'SMP'});
111 await collection.setPermissions(alice, {mintMode: true});
112
114 await usingApi(async () => {113 await expect(collection.mintToken(bob, {Substrate: bob.address}))
115 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
116 await enableAllowListExpectSuccess(alice, collectionId);
117 await setMintPermissionExpectSuccess(alice, collectionId, true);
118
119 await createItemExpectFailure(bob, collectionId, 'NFT');
120 });114 .to.be.rejectedWith(/common\.AddressNotInAllowlist/);
121 });115 });
122});116});
123117
modifiedtests/src/setPublicAccessMode.test.tsdiffbeforeafterboth
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17// https://unique-network.readthedocs.io/en/latest/jsapi.html#setschemaversion17// https://unique-network.readthedocs.io/en/latest/jsapi.html#setschemaversion
18import {ApiPromise} from '@polkadot/api';
19import {IKeyringPair} from '@polkadot/types/types';18import {IKeyringPair} from '@polkadot/types/types';
20import chai from 'chai';19import chai from 'chai';
21import chaiAsPromised from 'chai-as-promised';20import chaiAsPromised from 'chai-as-promised';
22import usingApi, {submitTransactionExpectFailAsync} from './substrate/substrate-api';
23import {21import {itSub, usingPlaygrounds} from './util/playgrounds';
24 addToAllowListExpectSuccess,
25 createCollectionExpectSuccess,
26 createItemExpectSuccess,
27 destroyCollectionExpectSuccess,
28 enablePublicMintingExpectSuccess,
29 enableAllowListExpectSuccess,
30 normalizeAccountId,
31 addCollectionAdminExpectSuccess,
32 getCreatedCollectionCount,
33} from './util/helpers';
3422
35chai.use(chaiAsPromised);23chai.use(chaiAsPromised);
36const expect = chai.expect;24const expect = chai.expect;
3725
26describe('Integration Test setPublicAccessMode(): ', () => {
38let alice: IKeyringPair;27 let alice: IKeyringPair;
39let bob: IKeyringPair;28 let bob: IKeyringPair;
4029
41describe('Integration Test setPublicAccessMode(): ', () => {
42 before(async () => {30 before(async () => {
43 await usingApi(async (api, privateKeyWrapper) => {31 await usingPlaygrounds(async (helper, privateKey) => {
44 alice = privateKeyWrapper('//Alice');32 const donor = privateKey('//Alice');
45 bob = privateKeyWrapper('//Bob');33 [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor);
46 });34 });
47 });35 });
4836
49 it('Run extrinsic with collection id parameters, set the allowlist mode for the collection', async () => {37 itSub('Runs extrinsic with collection id parameters, sets the allowlist mode for the collection', async ({helper}) => {
50 await usingApi(async () => {38 const collection = await helper.nft.mintCollection(alice, {name: 'PublicAccess-1', tokenPrefix: 'TF'});
51 const collectionId: number = await createCollectionExpectSuccess();39 await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
52 await enableAllowListExpectSuccess(alice, collectionId);
53 await enablePublicMintingExpectSuccess(alice, collectionId);
54 await addToAllowListExpectSuccess(alice, collectionId, bob.address);40 await collection.addToAllowList(alice, {Substrate: bob.address});
41
55 await createItemExpectSuccess(bob, collectionId, 'NFT', bob.address);42 await expect(collection.mintToken(bob, {Substrate: bob.address})).to.be.not.rejected;
56 });
57 });43 });
5844
59 it('Allowlisted collection limits', async () => {45 itSub('Allowlisted collection limits', async ({helper}) => {
46 const collection = await helper.nft.mintCollection(alice, {name: 'PublicAccess-2', tokenPrefix: 'TF'});
47 await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
48
60 await usingApi(async (api: ApiPromise) => {49 await expect(collection.mintToken(bob, {Substrate: bob.address}))
61 const collectionId = await createCollectionExpectSuccess();
62 await enableAllowListExpectSuccess(alice, collectionId);
63 await enablePublicMintingExpectSuccess(alice, collectionId);
64 const tx = api.tx.unique.createItem(collectionId, normalizeAccountId(bob.address), 'NFT');
65 await expect(submitTransactionExpectFailAsync(bob, tx)).to.be.rejected;50 .to.be.rejectedWith(/common\.AddressNotInAllowlist/);
66 });
67 });51 });
52
53 itSub('setPublicAccessMode by collection admin', async ({helper}) => {
54 const collection = await helper.nft.mintCollection(alice, {name: 'PublicAccess-Neg-4', tokenPrefix: 'TF'});
55 await collection.addAdmin(alice, {Substrate: bob.address});
56
57 await expect(collection.setPermissions(bob, {access: 'AllowList'})).to.be.not.rejected;
58 });
68});59});
6960
70describe('Negative Integration Test ext. setPublicAccessMode(): ', () => {61describe('Negative Integration Test ext. setPublicAccessMode(): ', () => {
62 let alice: IKeyringPair;
63 let bob: IKeyringPair;
64
71 it('Set a non-existent collection', async () => {65 before(async () => {
72 await usingApi(async (api: ApiPromise) => {66 await usingPlaygrounds(async (helper, privateKey) => {
73 // tslint:disable-next-line: radix
74 const collectionId = await getCreatedCollectionCount(api) + 1;67 const donor = privateKey('//Alice');
75 const tx = api.tx.unique.setCollectionPermissions(collectionId, {access: 'AllowList'});68 [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor);
76 await expect(submitTransactionExpectFailAsync(alice, tx)).to.be.rejected;
77 });69 });
78 });70 });
7971
80 it('Set the collection that has been deleted', async () => {72 itSub('Sets a non-existent collection', async ({helper}) => {
73 const collectionId = (1 << 32) - 1;
81 await usingApi(async (api: ApiPromise) => {74 await expect(helper.collection.setPermissions(alice, collectionId, {access: 'AllowList'}))
82 // tslint:disable-next-line: no-bitwise
83 const collectionId = await createCollectionExpectSuccess();
84 await destroyCollectionExpectSuccess(collectionId);
85 const tx = api.tx.unique.setCollectionPermissions(collectionId, {access: 'AllowList'});
86 await expect(submitTransactionExpectFailAsync(alice, tx)).to.be.rejected;75 .to.be.rejectedWith(/common\.CollectionNotFound/);
87 });
88 });76 });
8977
90 it('Re-set the list mode already set in quantity', async () => {78 itSub('Sets the collection that has been deleted', async ({helper}) => {
79 const collection = await helper.nft.mintCollection(alice, {name: 'PublicAccess-Neg-1', tokenPrefix: 'TF'});
80 await collection.burn(alice);
81
91 await usingApi(async () => {82 await expect(collection.setPermissions(alice, {access: 'AllowList'}))
92 const collectionId: number = await createCollectionExpectSuccess();
93 await enableAllowListExpectSuccess(alice, collectionId);
94 await enableAllowListExpectSuccess(alice, collectionId);
95 });83 .to.be.rejectedWith(/common\.CollectionNotFound/);
96 });84 });
9785
98 it('Execute method not on behalf of the collection owner', async () => {86 itSub('Re-sets the list mode already set in quantity', async ({helper}) => {
99 await usingApi(async (api: ApiPromise) => {
100 // tslint:disable-next-line: no-bitwise
101 const collectionId = await createCollectionExpectSuccess();87 const collection = await helper.nft.mintCollection(alice, {name: 'PublicAccess-Neg-2', tokenPrefix: 'TF'});
102 const tx = api.tx.unique.setCollectionPermissions(collectionId, {access: 'AllowList'});
103 await expect(submitTransactionExpectFailAsync(bob, tx)).to.be.rejected;
104 });88 await collection.setPermissions(alice, {access: 'AllowList'});
89 await collection.setPermissions(alice, {access: 'AllowList'});
105 });90 });
10691
107 it('setPublicAccessMode by collection admin', async () => {92 itSub('Executes method as a malefactor', async ({helper}) => {
93 const collection = await helper.nft.mintCollection(alice, {name: 'PublicAccess-Neg-3', tokenPrefix: 'TF'});
94
108 await usingApi(async (api: ApiPromise) => {95 await expect(collection.setPermissions(bob, {access: 'AllowList'}))
109 // tslint:disable-next-line: no-bitwise
110 const collectionId = await createCollectionExpectSuccess();
111 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
112 const tx = api.tx.unique.setCollectionPermissions(collectionId, {access: 'AllowList'});
113 await expect(submitTransactionExpectFailAsync(bob, tx)).to.be.not.rejected;96 .to.be.rejectedWith(/common\.NoPermission/);
114 });
115 });97 });
116});98});
117
118describe('Negative Integration Test ext. collection admin setPublicAccessMode(): ', () => {
119 before(async () => {
120 await usingApi(async (api, privateKeyWrapper) => {
121 alice = privateKeyWrapper('//Alice');
122 bob = privateKeyWrapper('//Bob');
123 });
124 });
125});
12699
modifiedtests/src/toggleContractAllowList.test.tsdiffbeforeafterboth
31const value = 0;31const value = 0;
32const gasLimit = 3000n * 1000000n;32const gasLimit = 3000n * 1000000n;
3333
34// todo:playgrounds skipped ~ postpone
34describe.skip('Integration Test toggleContractAllowList', () => {35describe.skip('Integration Test toggleContractAllowList', () => {
3536
36 it('Enable allow list contract mode', async () => {37 it('Enable allow list contract mode', async () => {
modifiedtests/src/transfer.test.tsdiffbeforeafterboth
14// You should have received a copy of the GNU General Public License14// You should have received a copy of the GNU General Public License
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17import {ApiPromise} from '@polkadot/api';
18import {IKeyringPair} from '@polkadot/types/types';17import {IKeyringPair} from '@polkadot/types/types';
19import {expect} from 'chai';18import chai from 'chai';
20import getBalance from './substrate/get-balance';19import chaiAsPromised from 'chai-as-promised';
21import {default as usingApi, submitTransactionAsync} from './substrate/substrate-api';
22import {20import {itEth, usingEthPlaygrounds} from './eth/util/playgrounds';
23 burnItemExpectSuccess, createCollectionExpectSuccess, createItemExpectSuccess,
24 destroyCollectionExpectSuccess,
25 findUnusedAddress,
26 getCreateCollectionResult,
27 getCreateItemResult,
28 transferExpectFailure,
29 transferExpectSuccess,
30 addCollectionAdminExpectSuccess,
31 getCreatedCollectionCount,
32 toSubstrateAddress,
33 getTokenOwner,
34 normalizeAccountId,
35 getBalance as getTokenBalance,
36 transferFromExpectSuccess,
37 transferFromExpectFail,
38 requirePallets,
39 Pallets,
40} from './util/helpers';
41import {21import {itSub, Pallets, usingPlaygrounds} from './util/playgrounds';
42 subToEth,
43 itWeb3,
44} from './eth/util/helpers';
45import {request} from 'https';
4622
47let alice: IKeyringPair;23chai.use(chaiAsPromised);
48let bob: IKeyringPair;24const expect = chai.expect;
49let charlie: IKeyringPair;
5025
51describe('Integration Test Transfer(recipient, collection_id, item_id, value)', () => {26describe.skip('Integration Test Transfer(recipient, collection_id, item_id, value)', () => {
27 let alice: IKeyringPair;
28 let bob: IKeyringPair;
29
52 before(async () => {30 before(async () => {
53 await usingApi(async (api, privateKeyWrapper) => {31 await usingPlaygrounds(async (helper, privateKey) => {
54 alice = privateKeyWrapper('//Alice');32 const donor = privateKey('//Alice');
55 bob = privateKeyWrapper('//Bob');33 [alice, bob] = await helper.arrange.createAccounts([50n, 10n], donor);
56 });34 });
57 });35 });
58 36
59 it('Balance transfers and check balance', async () => {37 itSub('Balance transfers and check balance', async ({helper}) => {
60 await usingApi(async (api, privateKeyWrapper) => {38 const alicesBalanceBefore = await helper.balance.getSubstrate(alice.address);
61 const [alicesBalanceBefore, bobsBalanceBefore] = await getBalance(api, [alice.address, bob.address]);39 const bobsBalanceBefore = await helper.balance.getSubstrate(bob.address);
6240
63 const transfer = api.tx.balances.transfer(bob.address, 1n);41 expect(await helper.balance.transferToSubstrate(alice, bob.address, 1n)).to.be.true;
64 const events = await submitTransactionAsync(alice, transfer);
65 const result = getCreateItemResult(events);
66 // tslint:disable-next-line:no-unused-expression
67 expect(result.success).to.be.true;
6842
69 const [alicesBalanceAfter, bobsBalanceAfter] = await getBalance(api, [alice.address, bob.address]);43 const alicesBalanceAfter = await helper.balance.getSubstrate(alice.address);
44 const bobsBalanceAfter = await helper.balance.getSubstrate(bob.address);
7045
71 // tslint:disable-next-line:no-unused-expression46 expect(alicesBalanceAfter < alicesBalanceBefore).to.be.true;
72 expect(alicesBalanceAfter < alicesBalanceBefore).to.be.true;
73 // tslint:disable-next-line:no-unused-expression47 expect(bobsBalanceAfter > bobsBalanceBefore).to.be.true;
74 expect(bobsBalanceAfter > bobsBalanceBefore).to.be.true;
75 });
76 });48 });
7749
78 it('Inability to pay fees error message is correct', async () => {50 itSub('Inability to pay fees error message is correct', async ({helper, privateKey}) => {
79 await usingApi(async (api, privateKeyWrapper) => {
80 // Find unused address51 const donor = privateKey('//Alice');
81 const pk = await findUnusedAddress(api, privateKeyWrapper);52 const [zero] = await helper.arrange.createAccounts([0n], donor);
8253
83 const badTransfer = api.tx.balances.transfer(bob.address, 1n);54 // console.error = () => {};
84 // const events = await submitTransactionAsync(pk, badTransfer);
85 const badTransaction = async () => {
86 const events = await submitTransactionAsync(pk, badTransfer);55 // The following operation throws an error into the console and the logs. Pay it no heed as long as the test succeeds.
87 const result = getCreateCollectionResult(events);
88 // tslint:disable-next-line:no-unused-expression
89 expect(result.success).to.be.false;56 await expect(helper.balance.transferToSubstrate(zero, donor.address, 1n))
90 };
91 await expect(badTransaction()).to.be.rejectedWith('Inability to pay some fees , e.g. account balance too low');57 .to.be.rejectedWith('Inability to pay some fees , e.g. account balance too low');
92 });
93 });58 });
9459
95 it('[nft] User can transfer owned token', async () => {60 itSub('[nft] User can transfer owned token', async ({helper}) => {
96 const nftCollectionId = await createCollectionExpectSuccess();61 const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-1-NFT', description: '', tokenPrefix: 'T'});
97 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');62 const nft = await collection.mintToken(alice, {Substrate: alice.address});
63
98 await transferExpectSuccess(nftCollectionId, newNftTokenId, alice, bob, 1, 'NFT');64 await nft.transfer(alice, {Substrate: bob.address});
65 expect(await nft.getOwner()).to.be.deep.equal({Substrate: bob.address});
99 });66 });
10067
101 it('[fungible] User can transfer owned token', async () => {68 itSub('[fungible] User can transfer owned token', async ({helper}) => {
102 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});69 const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-1-FT', description: '', tokenPrefix: 'T'});
103 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');70 await collection.mint(alice, {Substrate: alice.address}, 10n);
71
104 await transferExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob, 1, 'Fungible');72 await collection.transfer(alice, {Substrate: bob.address}, 9n);
73 expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(9n);
74 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1n);
105 });75 });
10676
107 it('[refungible] User can transfer owned token', async function() {77 itSub.ifWithPallets('[refungible] User can transfer owned token', [Pallets.ReFungible], async ({helper}) => {
108 await requirePallets(this, [Pallets.ReFungible]);78 const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-1-RFT', description: '', tokenPrefix: 'T'});
79 const rft = await collection.mintToken(alice, {Substrate: alice.address}, 10n);
10980
110 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});81 await rft.transfer(alice, {Substrate: bob.address}, 9n);
111 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');82 expect(await rft.getBalance({Substrate: bob.address})).to.be.equal(9n);
112 await transferExpectSuccess(83 expect(await rft.getBalance({Substrate: alice.address})).to.be.equal(1n);
113 reFungibleCollectionId,
114 newReFungibleTokenId,
115 alice,
116 bob,
117 100,
118 'ReFungible',
119 );
120 });84 });
12185
122 it('[nft] Collection admin can transfer owned token', async () => {86 itSub('[nft] Collection admin can transfer owned token', async ({helper}) => {
123 const nftCollectionId = await createCollectionExpectSuccess();87 const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-2-NFT', description: '', tokenPrefix: 'T'});
124 await addCollectionAdminExpectSuccess(alice, nftCollectionId, bob.address);88 await collection.addAdmin(alice, {Substrate: bob.address});
89
125 const newNftTokenId = await createItemExpectSuccess(bob, nftCollectionId, 'NFT', bob.address);90 const nft = await collection.mintToken(bob, {Substrate: bob.address});
126 await transferExpectSuccess(nftCollectionId, newNftTokenId, bob, alice, 1, 'NFT');91 await nft.transfer(bob, {Substrate: alice.address});
92
93 expect(await nft.getOwner()).to.be.deep.equal({Substrate: alice.address});
127 });94 });
12895
129 it('[fungible] Collection admin can transfer owned token', async () => {96 itSub('[fungible] Collection admin can transfer owned token', async ({helper}) => {
130 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});97 const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-2-FT', description: '', tokenPrefix: 'T'});
131 await addCollectionAdminExpectSuccess(alice, fungibleCollectionId, bob.address);98 await collection.addAdmin(alice, {Substrate: bob.address});
99
132 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible', bob.address);100 await collection.mint(bob, {Substrate: bob.address}, 10n);
133 await transferExpectSuccess(fungibleCollectionId, newFungibleTokenId, bob, alice, 1, 'Fungible');101 await collection.transfer(bob, {Substrate: alice.address}, 1n);
102
103 expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(9n);
104 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1n);
134 });105 });
135106
136 it('[refungible] Collection admin can transfer owned token', async function() {107 itSub.ifWithPallets('[refungible] Collection admin can transfer owned token', [Pallets.ReFungible], async ({helper}) => {
137 await requirePallets(this, [Pallets.ReFungible]);108 const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-2-RFT', description: '', tokenPrefix: 'T'});
109 await collection.addAdmin(alice, {Substrate: bob.address});
138110
139 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});111 const rft = await collection.mintToken(bob, {Substrate: bob.address}, 10n);
140 await addCollectionAdminExpectSuccess(alice, reFungibleCollectionId, bob.address);112 await rft.transfer(bob, {Substrate: alice.address}, 1n);
113
141 const newReFungibleTokenId = await createItemExpectSuccess(bob, reFungibleCollectionId, 'ReFungible', bob.address);114 expect(await rft.getBalance({Substrate: bob.address})).to.be.equal(9n);
142 await transferExpectSuccess(115 expect(await rft.getBalance({Substrate: alice.address})).to.be.equal(1n);
143 reFungibleCollectionId,
144 newReFungibleTokenId,
145 bob,
146 alice,
147 100,
148 'ReFungible',
149 );
150 });116 });
151});117});
152118
153describe('Negative Integration Test Transfer(recipient, collection_id, item_id, value)', () => {119describe.skip('Negative Integration Test Transfer(recipient, collection_id, item_id, value)', () => {
120 let alice: IKeyringPair;
121 let bob: IKeyringPair;
122
154 before(async () => {123 before(async () => {
155 await usingApi(async (api, privateKeyWrapper) => {124 await usingPlaygrounds(async (helper, privateKey) => {
156 alice = privateKeyWrapper('//Alice');125 const donor = privateKey('//Alice');
157 bob = privateKeyWrapper('//Bob');126 [alice, bob] = await helper.arrange.createAccounts([50n, 10n], donor);
158 charlie = privateKeyWrapper('//Charlie');
159 });127 });
160 });128 });
161129
162 it('[nft] Transfer with not existed collection_id', async () => {130 itSub('[nft] Transfer with not existed collection_id', async ({helper}) => {
163 await usingApi(async (api) => {
164 const nftCollectionCount = await getCreatedCollectionCount(api);131 const collectionId = (1 << 32) - 1;
165 await transferExpectFailure(nftCollectionCount + 1, 1, alice, bob, 1);132 await expect(helper.nft.transferToken(alice, collectionId, 1, {Substrate: bob.address}))
166 });133 .to.be.rejectedWith(/common\.CollectionNotFound/);
167 });134 });
168135
169 it('[fungible] Transfer with not existed collection_id', async () => {136 itSub('[fungible] Transfer with not existed collection_id', async ({helper}) => {
170 await usingApi(async (api) => {
171 const fungibleCollectionCount = await getCreatedCollectionCount(api);137 const collectionId = (1 << 32) - 1;
172 await transferExpectFailure(fungibleCollectionCount + 1, 0, alice, bob, 1);138 await expect(helper.ft.transfer(alice, collectionId, {Substrate: bob.address}))
173 });139 .to.be.rejectedWith(/common\.CollectionNotFound/);
174 });140 });
175141
176 it('[refungible] Transfer with not existed collection_id', async function() {142 itSub.ifWithPallets('[refungible] Transfer with not existed collection_id', [Pallets.ReFungible], async ({helper}) => {
177 await requirePallets(this, [Pallets.ReFungible]);
178
179 await usingApi(async (api) => {
180 const reFungibleCollectionCount = await getCreatedCollectionCount(api);143 const collectionId = (1 << 32) - 1;
181 await transferExpectFailure(reFungibleCollectionCount + 1, 1, alice, bob, 1);144 await expect(helper.rft.transferToken(alice, collectionId, 1, {Substrate: bob.address}))
182 });145 .to.be.rejectedWith(/common\.CollectionNotFound/);
183 });146 });
184147
185 it('[nft] Transfer with deleted collection_id', async () => {148 itSub('[nft] Transfer with deleted collection_id', async ({helper}) => {
186 const nftCollectionId = await createCollectionExpectSuccess();149 const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-1-NFT', description: '', tokenPrefix: 'T'});
187 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');150 const nft = await collection.mintToken(alice, {Substrate: alice.address});
151
188 await burnItemExpectSuccess(alice, nftCollectionId, newNftTokenId);152 await nft.burn(alice);
189 await destroyCollectionExpectSuccess(nftCollectionId);153 await collection.burn(alice);
154
190 await transferExpectFailure(nftCollectionId, newNftTokenId, alice, bob, 1);155 await expect(nft.transfer(alice, {Substrate: bob.address}))
156 .to.be.rejectedWith(/common\.CollectionNotFound/);
191 });157 });
192158
193 it('[fungible] Transfer with deleted collection_id', async () => {159 itSub('[fungible] Transfer with deleted collection_id', async ({helper}) => {
194 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});160 const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-Neg-1-FT', description: '', tokenPrefix: 'T'});
195 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');161 await collection.mint(alice, {Substrate: alice.address}, 10n);
162
196 await burnItemExpectSuccess(alice, fungibleCollectionId, newFungibleTokenId, 10);163 await collection.burnTokens(alice, 10n);
197 await destroyCollectionExpectSuccess(fungibleCollectionId);164 await collection.burn(alice);
165
198 await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, alice, bob, 1);166 await expect(collection.transfer(alice, {Substrate: bob.address}))
167 .to.be.rejectedWith(/common\.CollectionNotFound/);
199 });168 });
169
170 itSub.ifWithPallets('[refungible] Transfer with deleted collection_id', [Pallets.ReFungible], async ({helper}) => {
171 const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-Neg-1-RFT', description: '', tokenPrefix: 'T'});
172 const rft = await collection.mintToken(alice, {Substrate: alice.address}, 10n);
200173
201 it('[refungible] Transfer with deleted collection_id', async function() {174 await rft.burn(alice, 10n);
202 await requirePallets(this, [Pallets.ReFungible]);175 await collection.burn(alice);
203176
204 const reFungibleCollectionId = await177 await expect(rft.transfer(alice, {Substrate: bob.address}))
205 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
206 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
207 await burnItemExpectSuccess(alice, reFungibleCollectionId, newReFungibleTokenId, 100);178 .to.be.rejectedWith(/common\.CollectionNotFound/);
208 await destroyCollectionExpectSuccess(reFungibleCollectionId);
209 await transferExpectFailure(
210 reFungibleCollectionId,
211 newReFungibleTokenId,
212 alice,
213 bob,
214 1,
215 );
216 });179 });
217180
218 it('[nft] Transfer with not existed item_id', async () => {181 itSub('[nft] Transfer with not existed item_id', async ({helper}) => {
219 const nftCollectionId = await createCollectionExpectSuccess();182 const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-2-NFT', description: '', tokenPrefix: 'T'});
220 await transferExpectFailure(nftCollectionId, 2, alice, bob, 1);183 await expect(collection.transferToken(alice, 1, {Substrate: bob.address}))
184 .to.be.rejectedWith(/common\.TokenNotFound/);
221 });185 });
222186
223 it('[fungible] Transfer with not existed item_id', async () => {187 itSub('[fungible] Transfer with not existed item_id', async ({helper}) => {
224 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});188 const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-Neg-2-FT', description: '', tokenPrefix: 'T'});
225 await transferExpectFailure(fungibleCollectionId, 2, alice, bob, 1);189 await expect(collection.transfer(alice, {Substrate: bob.address}))
190 .to.be.rejectedWith(/common\.TokenValueTooLow/);
226 });191 });
227192
228 it('[refungible] Transfer with not existed item_id', async function() {193 itSub.ifWithPallets('[refungible] Transfer with not existed item_id', [Pallets.ReFungible], async ({helper}) => {
229 await requirePallets(this, [Pallets.ReFungible]);194 const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-Neg-2-RFT', description: '', tokenPrefix: 'T'});
230
231 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
232 await transferExpectFailure(195 await expect(collection.transferToken(alice, 1, {Substrate: bob.address}))
233 reFungibleCollectionId,
234 2,
235 alice,
236 bob,
237 1,196 .to.be.rejectedWith(/common\.TokenValueTooLow/);
238 );
239 });197 });
240198
241 it('[nft] Transfer with deleted item_id', async () => {199 itSub('[nft] Transfer with deleted item_id', async ({helper}) => {
242 const nftCollectionId = await createCollectionExpectSuccess();200 const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-3-NFT', description: '', tokenPrefix: 'T'});
243 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');201 const nft = await collection.mintToken(alice, {Substrate: alice.address});
202
244 await burnItemExpectSuccess(alice, nftCollectionId, newNftTokenId, 1);203 await nft.burn(alice);
204
245 await transferExpectFailure(nftCollectionId, newNftTokenId, alice, bob, 1);205 await expect(nft.transfer(alice, {Substrate: bob.address}))
206 .to.be.rejectedWith(/common\.TokenNotFound/);
246 });207 });
247208
248 it('[fungible] Transfer with deleted item_id', async () => {209 itSub('[fungible] Transfer with deleted item_id', async ({helper}) => {
249 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});210 const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-Neg-3-FT', description: '', tokenPrefix: 'T'});
250 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');211 await collection.mint(alice, {Substrate: alice.address}, 10n);
212
251 await burnItemExpectSuccess(alice, fungibleCollectionId, newFungibleTokenId, 10);213 await collection.burnTokens(alice, 10n);
214
252 await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, alice, bob, 1);215 await expect(collection.transfer(alice, {Substrate: bob.address}))
216 .to.be.rejectedWith(/common\.TokenValueTooLow/);
253 });217 });
254218
255 it('[refungible] Transfer with deleted item_id', async function() {219 itSub.ifWithPallets('[refungible] Transfer with deleted item_id', [Pallets.ReFungible], async ({helper}) => {
256 await requirePallets(this, [Pallets.ReFungible]);220 const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-Neg-3-RFT', description: '', tokenPrefix: 'T'});
221 const rft = await collection.mintToken(alice, {Substrate: alice.address}, 10n);
257222
258 const reFungibleCollectionId = await223 await rft.burn(alice, 10n);
259 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});224
260 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
261 await burnItemExpectSuccess(alice, reFungibleCollectionId, newReFungibleTokenId, 100);
262 await transferExpectFailure(225 await expect(rft.transfer(alice, {Substrate: bob.address}))
263 reFungibleCollectionId,
264 newReFungibleTokenId,
265 alice,
266 bob,
267 1,226 .to.be.rejectedWith(/common\.TokenValueTooLow/);
268 );
269 });227 });
270228
271 it('[nft] Transfer with recipient that is not owner', async () => {229 itSub('[nft] Transfer with recipient that is not owner', async ({helper}) => {
272 const nftCollectionId = await createCollectionExpectSuccess();230 const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-4-NFT', description: '', tokenPrefix: 'T'});
273 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');231 const nft = await collection.mintToken(alice, {Substrate: alice.address});
232
274 await transferExpectFailure(nftCollectionId, newNftTokenId, charlie, bob, 1);233 await expect(nft.transfer(bob, {Substrate: bob.address}))
234 .to.be.rejectedWith(/common\.NoPermission/);
235 expect(await nft.getOwner()).to.be.deep.equal({Substrate: alice.address});
275 });236 });
276237
277 it('[fungible] Transfer with recipient that is not owner', async () => {238 itSub('[fungible] Transfer with recipient that is not owner', async ({helper}) => {
278 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});239 const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-Neg-4-FT', description: '', tokenPrefix: 'T'});
279 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');240 await collection.mint(alice, {Substrate: alice.address}, 10n);
241
280 await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, charlie, bob, 1);242 await expect(collection.transfer(bob, {Substrate: bob.address}, 9n))
243 .to.be.rejectedWith(/common\.TokenValueTooLow/);
244 expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(0n);
245 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(10n);
281 });246 });
282247
283 it('[refungible] Transfer with recipient that is not owner', async function() {248 itSub.ifWithPallets('[refungible] Transfer with recipient that is not owner', [Pallets.ReFungible], async ({helper}) => {
284 await requirePallets(this, [Pallets.ReFungible]);249 const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-1-RFT', description: '', tokenPrefix: 'T'});
250 const rft = await collection.mintToken(alice, {Substrate: alice.address}, 10n);
285251
286 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});252 await expect(rft.transfer(bob, {Substrate: bob.address}, 9n))
287 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');253 .to.be.rejectedWith(/common\.TokenValueTooLow/);
288 await transferExpectFailure(254 expect(await rft.getBalance({Substrate: bob.address})).to.be.equal(0n);
289 reFungibleCollectionId,
290 newReFungibleTokenId,
291 charlie,
292 bob,
293 1,255 expect(await rft.getBalance({Substrate: alice.address})).to.be.equal(10n);
294 );
295 });256 });
296});257});
297258
298describe('Zero value transfer(From)', () => {259describe('Transfers to self (potentially over substrate-evm boundary)', () => {
299 before(async () => {260 let donor: IKeyringPair;
261
262 before(async function() {
300 await usingApi(async (api, privateKeyWrapper) => {263 await usingEthPlaygrounds(async (_, privateKey) => {
301 alice = privateKeyWrapper('//Alice');264 donor = privateKey('//Alice');
302 bob = privateKeyWrapper('//Bob');
303 });265 });
304 });266 });
267
268 itEth('Transfers to self. In case of same frontend', async ({helper}) => {
269 const [owner] = await helper.arrange.createAccounts([10n], donor);
270 const collection = await helper.ft.mintCollection(owner, {});
271 await collection.mint(owner, {Substrate: owner.address}, 100n);
305272
306 it('NFT', async () => {273 const ownerProxy = helper.address.substrateToEth(owner.address);
307 await usingApi(async (api: ApiPromise) => {
308 const nftCollectionId = await createCollectionExpectSuccess();
309 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
310274
311 const transferTx = api.tx.unique.transfer(normalizeAccountId(bob), nftCollectionId, newNftTokenId, 0);275 // transfer to own proxy
276 await collection.transfer(owner, {Ethereum: ownerProxy}, 10n);
312 await submitTransactionAsync(alice, transferTx);277 expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(90n);
313 const address = normalizeAccountId(await getTokenOwner(api, nftCollectionId, newNftTokenId));278 expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(10n);
314279
315 expect(toSubstrateAddress(address)).to.be.equal(alice.address);280 // transfer-from own proxy to own proxy again
281 await collection.transferFrom(owner, {Ethereum: ownerProxy}, {Ethereum: ownerProxy}, 5n);
282 expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(90n);
316 });283 expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(10n);
317 });284 });
318285
319 it('RFT', async function() {286 itEth('Transfers to self. In case of substrate-evm boundary', async ({helper}) => {
320 await requirePallets(this, [Pallets.ReFungible]);287 const [owner] = await helper.arrange.createAccounts([10n], donor);
288 const collection = await helper.ft.mintCollection(owner, {});
289 await collection.mint(owner, {Substrate: owner.address}, 100n);
321290
322 await usingApi(async (api: ApiPromise) => {291 const ownerProxy = helper.address.substrateToEth(owner.address);
323 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
324 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
325 const balanceBeforeAlice = await getTokenBalance(api, reFungibleCollectionId, normalizeAccountId(alice), newReFungibleTokenId);
326 const balanceBeforeBob = await getTokenBalance(api, reFungibleCollectionId, normalizeAccountId(bob), newReFungibleTokenId);
327292
328 const transferTx = api.tx.unique.transfer(normalizeAccountId(bob), reFungibleCollectionId, newReFungibleTokenId, 0);293 // transfer to own proxy
294 await collection.transfer(owner, {Ethereum: ownerProxy}, 10n);
329 await submitTransactionAsync(alice, transferTx);295 expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(90n);
296 expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(10n);
330297
331 const balanceAfterAlice = await getTokenBalance(api, reFungibleCollectionId, normalizeAccountId(alice), newReFungibleTokenId);298 // transfer-from own proxy to self
332 const balanceAfterBob = await getTokenBalance(api, reFungibleCollectionId, normalizeAccountId(bob), newReFungibleTokenId);299 await collection.transferFrom(owner, {Ethereum: ownerProxy}, {Substrate: owner.address}, 5n);
333
334 expect((balanceBeforeAlice)).to.be.equal(balanceAfterAlice);300 expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(95n);
335 expect((balanceBeforeBob)).to.be.equal(balanceAfterBob);301 expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(5n);
336 });
337 });302 });
338303
339 it('Fungible', async () => {304 itEth('Transfers to self. In case of inside substrate-evm', async ({helper}) => {
340 await usingApi(async (api: ApiPromise) => {
341 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});305 const [owner] = await helper.arrange.createAccounts([10n], donor);
342 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');306 const collection = await helper.ft.mintCollection(owner, {});
343 const balanceBeforeAlice = await getTokenBalance(api, fungibleCollectionId, normalizeAccountId(alice), newFungibleTokenId);307 await collection.mint(owner, {Substrate: owner.address}, 100n);
344 const balanceBeforeBob = await getTokenBalance(api, fungibleCollectionId, normalizeAccountId(bob), newFungibleTokenId);
345308
346 const transferTx = api.tx.unique.transfer(normalizeAccountId(bob), fungibleCollectionId, newFungibleTokenId, 0);309 // transfer to self again
310 await collection.transfer(owner, {Substrate: owner.address}, 10n);
347 await submitTransactionAsync(alice, transferTx);311 expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(100n);
348312
349 const balanceAfterAlice = await getTokenBalance(api, fungibleCollectionId, normalizeAccountId(alice), newFungibleTokenId);313 // transfer-from self to self again
350 const balanceAfterBob = await getTokenBalance(api, fungibleCollectionId, normalizeAccountId(bob), newFungibleTokenId);314 await collection.transferFrom(owner, {Substrate: owner.address}, {Substrate: owner.address}, 5n);
351
352 expect((balanceBeforeAlice)).to.be.equal(balanceAfterAlice);315 expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(100n);
353 expect((balanceBeforeBob)).to.be.equal(balanceAfterBob);
354 });
355 });316 });
356});
357317
358describe('Transfers to self (potentially over substrate-evm boundary)', () => {318 itEth('Transfers to self. In case of inside substrate-evm when not enought "Fungibles"', async ({helper}) => {
359 itWeb3('Transfers to self. In case of same frontend', async ({api, privateKeyWrapper}) => {
360 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});319 const [owner] = await helper.arrange.createAccounts([10n], donor);
361 const aliceProxy = subToEth(alice.address);
362 const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible', {Substrate: alice.address});
363 await transferExpectSuccess(collectionId, tokenId, alice, {Ethereum: aliceProxy}, 10, 'Fungible');
364 const balanceAliceBefore = await getTokenBalance(api, collectionId, {Ethereum: aliceProxy}, tokenId);320 const collection = await helper.ft.mintCollection(owner, {});
365 await transferFromExpectSuccess(collectionId, tokenId, alice, {Ethereum: aliceProxy}, {Ethereum: aliceProxy}, 10, 'Fungible');321 await collection.mint(owner, {Substrate: owner.address}, 10n);
366 const balanceAliceAfter = await getTokenBalance(api, collectionId, {Ethereum: aliceProxy}, tokenId);
367 expect(balanceAliceBefore).to.be.eq(balanceAliceAfter);
368 });
369322
370 itWeb3('Transfers to self. In case of substrate-evm boundary', async ({api, privateKeyWrapper}) => {323 // transfer to self again
371 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});324 await expect(collection.transfer(owner, {Substrate: owner.address}, 11n))
372 const aliceProxy = subToEth(alice.address);
373 const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible', {Substrate: alice.address});
374 const balanceAliceBefore = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);
375 await transferExpectSuccess(collectionId, tokenId, alice, {Ethereum: aliceProxy} , 10, 'Fungible');
376 await transferFromExpectSuccess(collectionId, tokenId, alice, {Ethereum: aliceProxy}, alice, 10, 'Fungible');
377 const balanceAliceAfter = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);
378 expect(balanceAliceBefore).to.be.eq(balanceAliceAfter);
379 });
380
381 itWeb3('Transfers to self. In case of inside substrate-evm', async ({api, privateKeyWrapper}) => {
382 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
383 const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible', {Substrate: alice.address});
384 const balanceAliceBefore = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);
385 await transferExpectSuccess(collectionId, tokenId, alice, alice , 10, 'Fungible');325 .to.be.rejectedWith(/common\.TokenValueTooLow/);
386 await transferFromExpectSuccess(collectionId, tokenId, alice, alice, alice, 10, 'Fungible');
387 const balanceAliceAfter = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);
388 expect(balanceAliceBefore).to.be.eq(balanceAliceAfter);
389 });
390326
391 itWeb3('Transfers to self. In case of inside substrate-evm when not enought "Fungibles"', async ({api, privateKeyWrapper}) => {327 // transfer-from self to self again
392 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});328 await expect(collection.transferFrom(owner, {Substrate: owner.address}, {Substrate: owner.address}, 12n))
393 const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible', {Substrate: alice.address});
394 const balanceAliceBefore = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);
395 await transferExpectFailure(collectionId, tokenId, alice, alice , 11);329 .to.be.rejectedWith(/common\.TokenValueTooLow/);
396 await transferFromExpectFail(collectionId, tokenId, alice, alice, alice, 11);
397 const balanceAliceAfter = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);330 expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(10n);
398 expect(balanceAliceBefore).to.be.eq(balanceAliceAfter);
399 });331 });
400});332});
401333
modifiedtests/src/transferFrom.test.tsdiffbeforeafterboth
14// You should have received a copy of the GNU General Public License14// You should have received a copy of the GNU General Public License
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17import {ApiPromise} from '@polkadot/api';
18import {IKeyringPair} from '@polkadot/types/types';17import {IKeyringPair} from '@polkadot/types/types';
19import chai from 'chai';18import chai from 'chai';
20import chaiAsPromised from 'chai-as-promised';19import chaiAsPromised from 'chai-as-promised';
21import {default as usingApi} from './substrate/substrate-api';20import {itSub, Pallets, usingPlaygrounds} from './util/playgrounds';
22import {
23 approveExpectFail,
24 approveExpectSuccess,
25 createCollectionExpectSuccess,
26 createFungibleItemExpectSuccess,
27 createItemExpectSuccess,
28 getAllowance,
29 transferFromExpectFail,
30 transferFromExpectSuccess,
31 burnItemExpectSuccess,
32 setCollectionLimitsExpectSuccess,
33 getCreatedCollectionCount,
34 requirePallets,
35 Pallets,
36} from './util/helpers';
3721
38chai.use(chaiAsPromised);22chai.use(chaiAsPromised);
39const expect = chai.expect;23const expect = chai.expect;
44 let charlie: IKeyringPair;28 let charlie: IKeyringPair;
4529
46 before(async () => {30 before(async () => {
47 await usingApi(async (api, privateKeyWrapper) => {31 await usingPlaygrounds(async (helper, privateKey) => {
48 alice = privateKeyWrapper('//Alice');32 const donor = privateKey('//Alice');
49 bob = privateKeyWrapper('//Bob');33 [alice, bob, charlie] = await helper.arrange.createAccounts([20n, 10n, 10n], donor);
50 charlie = privateKeyWrapper('//Charlie');
51 });34 });
52 });35 });
5336
54 it('[nft] Execute the extrinsic and check nftItemList - owner of token', async () => {37 itSub('[nft] Execute the extrinsic and check nftItemList - owner of token', async ({helper}) => {
55 const nftCollectionId = await createCollectionExpectSuccess();38 const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-1', description: '', tokenPrefix: 'TF'});
56 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');39 const nft = await collection.mintToken(alice, {Substrate: alice.address});
57 await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address);40 await nft.approve(alice, {Substrate: bob.address});
41 expect(await nft.isApproved({Substrate: bob.address})).to.be.true;
5842
59 await transferFromExpectSuccess(nftCollectionId, newNftTokenId, bob, alice, charlie, 1, 'NFT');43 await nft.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address});
44 expect(await nft.getOwner()).to.be.deep.equal({Substrate: charlie.address});
60 });45 });
6146
62 it('[fungible] Execute the extrinsic and check nftItemList - owner of token', async () => {47 itSub('[fungible] Execute the extrinsic and check nftItemList - owner of token', async ({helper}) => {
63 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});48 const collection = await helper.ft.mintCollection(alice, {name: 'TransferFrom-2', description: '', tokenPrefix: 'TF'});
64 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');49 await collection.mint(alice, {Substrate: alice.address}, 10n);
50 await collection.approveTokens(alice, {Substrate: bob.address}, 7n);
65 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);51 expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(7n);
66 await transferFromExpectSuccess(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 1, 'Fungible');52
53 await collection.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}, 6n);
54 expect(await collection.getBalance({Substrate: charlie.address})).to.be.equal(6n);
55 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(4n);
56 expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(1n);
67 });57 });
6858
69 it('[refungible] Execute the extrinsic and check nftItemList - owner of token', async function() {59 itSub.ifWithPallets('[refungible] Execute the extrinsic and check nftItemList - owner of token', [Pallets.ReFungible], async ({helper}) => {
70 await requirePallets(this, [Pallets.ReFungible]);60 const collection = await helper.rft.mintCollection(alice, {name: 'TransferFrom-3', description: '', tokenPrefix: 'TF'});
71
72 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
73 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');61 const rft = await collection.mintToken(alice, {Substrate: alice.address}, 10n);
74 await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address, 100);62 await rft.approve(alice, {Substrate: bob.address}, 7n);
75 await transferFromExpectSuccess(63 expect(await rft.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(7n);
76 reFungibleCollectionId,
77 newReFungibleTokenId,64
78 bob,65 await rft.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}, 6n);
79 alice,
80 charlie,66 expect(await rft.getBalance({Substrate: charlie.address})).to.be.equal(6n);
81 100,67 expect(await rft.getBalance({Substrate: alice.address})).to.be.equal(4n);
82 'ReFungible',68 expect(await rft.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(1n);
83 );
84 });69 });
8570
86 it('Should reduce allowance if value is big', async () => {71 itSub('Should reduce allowance if value is big', async ({helper}) => {
87 await usingApi(async (api, privateKeyWrapper) => {72 // fungible
88 const alice = privateKeyWrapper('//Alice');73 const collection = await helper.ft.mintCollection(alice, {name: 'TransferFrom-4', description: '', tokenPrefix: 'TF'});
89 const bob = privateKeyWrapper('//Bob');
90 const charlie = privateKeyWrapper('//Charlie');74 await collection.mint(alice, {Substrate: alice.address}, 500000n);
9175
92 // fungible76 await collection.approveTokens(alice, {Substrate: bob.address}, 500000n);
93 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
94 const newFungibleTokenId = await createFungibleItemExpectSuccess(alice, fungibleCollectionId, {Value: 500000n});77 expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(500000n);
95
96 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address, 500000n);
97 await transferFromExpectSuccess(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 500000n, 'Fungible');78 await collection.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}, 500000n);
98 expect(await getAllowance(api, fungibleCollectionId, alice.address, bob.address, newFungibleTokenId)).to.equal(0n);79 expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(0n);
99 });
100 });80 });
10181
102 it('can be called by collection owner on non-owned item when OwnerCanTransfer == true', async () => {82 itSub('can be called by collection owner on non-owned item when OwnerCanTransfer == true', async ({helper}) => {
103 const collectionId = await createCollectionExpectSuccess();83 const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-5', description: '', tokenPrefix: 'TF'});
104 await setCollectionLimitsExpectSuccess(alice, collectionId, {ownerCanTransfer: true});
105 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', bob.address);84 await collection.setLimits(alice, {ownerCanTransfer: true});
10685
107 await transferFromExpectSuccess(collectionId, itemId, alice, bob, charlie);86 const nft = await collection.mintToken(alice, {Substrate: bob.address});
87 await nft.transferFrom(alice, {Substrate: bob.address}, {Substrate: charlie.address});
88 expect(await nft.getOwner()).to.be.deep.equal({Substrate: charlie.address});
108 });89 });
109});90});
11091
114 let charlie: IKeyringPair;95 let charlie: IKeyringPair;
11596
116 before(async () => {97 before(async () => {
117 await usingApi(async (api, privateKeyWrapper) => {98 await usingPlaygrounds(async (helper, privateKey) => {
118 alice = privateKeyWrapper('//Alice');99 const donor = privateKey('//Alice');
119 bob = privateKeyWrapper('//Bob');100 [alice, bob, charlie] = await helper.arrange.createAccounts([50n, 10n, 10n], donor);
120 charlie = privateKeyWrapper('//Charlie');
121 });101 });
122 });102 });
123103
124 it('[nft] transferFrom for a collection that does not exist', async () => {104 itSub('transferFrom for a collection that does not exist', async ({helper}) => {
125 await usingApi(async (api: ApiPromise) => {105 const collectionId = (1 << 32) - 1;
126 const nftCollectionCount = await getCreatedCollectionCount(api);106 await expect(helper.collection.approveToken(alice, collectionId, 0, {Substrate: bob.address}, 1n))
127 await approveExpectFail(nftCollectionCount + 1, 1, alice, bob);107 .to.be.rejectedWith(/common\.CollectionNotFound/);
128
129 await transferFromExpectFail(nftCollectionCount + 1, 1, bob, alice, charlie, 1);108 await expect(helper.collection.transferTokenFrom(bob, collectionId, 0, {Substrate: alice.address}, {Substrate: bob.address}, 1n))
130 });109 .to.be.rejectedWith(/common\.CollectionNotFound/);
131 });110 });
132111
133 it('[fungible] transferFrom for a collection that does not exist', async () => {112 /* itSub('transferFrom for a collection that was destroyed', async ({helper}) => {
134 await usingApi(async (api: ApiPromise) => {
135 const fungibleCollectionCount = await getCreatedCollectionCount(api);113 this test copies approve negative test
136 await approveExpectFail(fungibleCollectionCount + 1, 0, alice, bob);114 }); */
137115
138 await transferFromExpectFail(fungibleCollectionCount + 1, 0, bob, alice, charlie, 1);116 /* itSub('transferFrom a token that does not exist', async ({helper}) => {
117 this test copies approve negative test
118 }); */
119
120 /* itSub('transferFrom a token that was deleted', async ({helper}) => {
121 this test copies approve negative test
122 }); */
123
124 itSub('[nft] transferFrom for not approved address', async ({helper}) => {
125 const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-Neg-1', description: '', tokenPrefix: 'TF'});
126 const nft = await collection.mintToken(alice, {Substrate: alice.address});
127
128 await expect(nft.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}))
129 .to.be.rejectedWith(/common\.ApprovedValueTooLow/);
139 });130 expect(await nft.getOwner()).to.be.deep.equal({Substrate: alice.address});
140 });131 });
141132
142 it('[refungible] transferFrom for a collection that does not exist', async function() {133 itSub('[fungible] transferFrom for not approved address', async ({helper}) => {
143 await requirePallets(this, [Pallets.ReFungible]);134 const collection = await helper.ft.mintCollection(alice, {name: 'TransferFrom-Neg-1', description: '', tokenPrefix: 'TF'});
135 await collection.mint(alice, {Substrate: alice.address}, 10n);
144136
145 await usingApi(async (api: ApiPromise) => {137 await expect(collection.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}, 5n))
146 const reFungibleCollectionCount = await getCreatedCollectionCount(api);138 .to.be.rejectedWith(/common\.ApprovedValueTooLow/);
139 expect(await collection.getBalance({Substrate: alice.address})).to.be.deep.equal(10n);
147 await approveExpectFail(reFungibleCollectionCount + 1, 1, alice, bob);140 expect(await collection.getBalance({Substrate: bob.address})).to.be.deep.equal(0n);
141 expect(await collection.getBalance({Substrate: charlie.address})).to.be.deep.equal(0n);
142 });
148143
149 await transferFromExpectFail(reFungibleCollectionCount + 1, 1, bob, alice, charlie, 1);144 itSub.ifWithPallets('[refungible] transferFrom for not approved address', [Pallets.ReFungible], async({helper}) => {
145 const collection = await helper.rft.mintCollection(alice, {name: 'TransferFrom-Neg-3', description: '', tokenPrefix: 'TF'});
146 const rft = await collection.mintToken(alice, {Substrate: alice.address}, 10n);
147
148 await expect(rft.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}))
149 .to.be.rejectedWith(/common\.ApprovedValueTooLow/);
150 });150 expect(await rft.getBalance({Substrate: alice.address})).to.be.deep.equal(10n);
151 expect(await rft.getBalance({Substrate: bob.address})).to.be.deep.equal(0n);
152 expect(await rft.getBalance({Substrate: charlie.address})).to.be.deep.equal(0n);
151 });153 });
152154
153 /* it('transferFrom for a collection that was destroyed', async () => {155 itSub('[nft] transferFrom incorrect token count', async ({helper}) => {
154 await usingApi(async (api: ApiPromise) => {156 const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-Neg-4', description: '', tokenPrefix: 'TF'});
155 this test copies approve negative test157 const nft = await collection.mintToken(alice, {Substrate: alice.address});
156 });
157 }); */
158158
159 /* it('transferFrom a token that does not exist', async () => {159 await nft.approve(alice, {Substrate: bob.address});
160 await usingApi(async (api: ApiPromise) => {160 expect(await nft.isApproved({Substrate: bob.address})).to.be.true;
161 this test copies approve negative test
162 });
163 }); */
164161
165 /* it('transferFrom a token that was deleted', async () => {162 await expect(helper.collection.transferTokenFrom(
163 bob,
164 collection.collectionId,
166 await usingApi(async (api: ApiPromise) => {165 nft.tokenId,
166 {Substrate: alice.address},
167 this test copies approve negative test167 {Substrate: charlie.address},
168 2n,
168 });169 )).to.be.rejectedWith(/nonfungible\.NonfungibleItemsHaveNoAmount/);
170 expect(await nft.getOwner()).to.be.deep.equal({Substrate: alice.address});
169 }); */171 });
170172
171 it('[nft] transferFrom for not approved address', async () => {173 itSub('[fungible] transferFrom incorrect token count', async ({helper}) => {
172 const nftCollectionId = await createCollectionExpectSuccess();174 const collection = await helper.ft.mintCollection(alice, {name: 'TransferFrom-Neg-5', description: '', tokenPrefix: 'TF'});
173 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');175 await collection.mint(alice, {Substrate: alice.address}, 10n);
174176
175 await transferFromExpectFail(nftCollectionId, newNftTokenId, bob, alice, charlie, 1);177 await collection.approveTokens(alice, {Substrate: bob.address}, 2n);
178 expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.eq(2n);
179
180 await expect(collection.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}, 5n))
181 .to.be.rejectedWith(/common\.ApprovedValueTooLow/);
182 expect(await collection.getBalance({Substrate: alice.address})).to.be.deep.equal(10n);
183 expect(await collection.getBalance({Substrate: bob.address})).to.be.deep.equal(0n);
184 expect(await collection.getBalance({Substrate: charlie.address})).to.be.deep.equal(0n);
176 });185 });
177186
178 it('[fungible] transferFrom for not approved address', async () => {187 itSub.ifWithPallets('[refungible] transferFrom incorrect token count', [Pallets.ReFungible], async ({helper}) => {
179 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});188 const collection = await helper.rft.mintCollection(alice, {name: 'TransferFrom-Neg-6', description: '', tokenPrefix: 'TF'});
180 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');189 const rft = await collection.mintToken(alice, {Substrate: alice.address}, 10n);
190
181 await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 1);191 await rft.approve(alice, {Substrate: bob.address}, 5n);
192 expect(await rft.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.eq(5n);
193
194 await expect(rft.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}, 7n))
195 .to.be.rejectedWith(/common\.ApprovedValueTooLow/);
196 expect(await rft.getBalance({Substrate: alice.address})).to.be.deep.equal(10n);
197 expect(await rft.getBalance({Substrate: bob.address})).to.be.deep.equal(0n);
198 expect(await rft.getBalance({Substrate: charlie.address})).to.be.deep.equal(0n);
182 });199 });
183200
184 it('[refungible] transferFrom for not approved address', async function() {201 itSub('[nft] execute transferFrom from account that is not owner of collection', async ({helper}) => {
185 await requirePallets(this, [Pallets.ReFungible]);202 const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-Neg-7', description: '', tokenPrefix: 'TF'});
203 const nft = await collection.mintToken(alice, {Substrate: alice.address});
186204
187 const reFungibleCollectionId = await205 await expect(nft.approve(charlie, {Substrate: bob.address})).to.be.rejectedWith(/common\.CantApproveMoreThanOwned/);
188 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
189 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');206 expect(await nft.isApproved({Substrate: bob.address})).to.be.false;
207
190 await transferFromExpectFail(208 await expect(nft.transferFrom(
191 reFungibleCollectionId,
192 newReFungibleTokenId,
193 bob,
194 alice,
195 charlie,209 charlie,
196 1,210 {Substrate: alice.address},
197 );211 {Substrate: charlie.address},
212 )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
213 expect(await nft.getOwner()).to.be.deep.equal({Substrate: alice.address});
198 });214 });
199215
200 it('[nft] transferFrom incorrect token count', async () => {216 itSub('[fungible] execute transferFrom from account that is not owner of collection', async ({helper}) => {
201 const nftCollectionId = await createCollectionExpectSuccess();217 const collection = await helper.ft.mintCollection(alice, {name: 'TransferFrom-Neg-8', description: '', tokenPrefix: 'TF'});
202 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
203 await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address);218 await collection.mint(alice, {Substrate: alice.address}, 10000n);
204219
205 await transferFromExpectFail(nftCollectionId, newNftTokenId, bob, alice, charlie, 2);220 await expect(collection.approveTokens(charlie, {Substrate: bob.address}, 1n)).to.be.rejectedWith(/common\.CantApproveMoreThanOwned/);
221 expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.eq(0n);
206 });222 expect(await collection.getApprovedTokens({Substrate: charlie.address}, {Substrate: bob.address})).to.be.eq(0n);
207223
208 it('[fungible] transferFrom incorrect token count', async () => {224 await expect(collection.transferFrom(
225 charlie,
209 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});226 {Substrate: alice.address},
227 {Substrate: charlie.address},
228 )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
210 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');229 expect(await collection.getBalance({Substrate: alice.address})).to.be.deep.equal(10000n);
211 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);230 expect(await collection.getBalance({Substrate: bob.address})).to.be.deep.equal(0n);
212 await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 2);231 expect(await collection.getBalance({Substrate: charlie.address})).to.be.deep.equal(0n);
213 });232 });
214233
215 it('[refungible] transferFrom incorrect token count', async function() {234 itSub.ifWithPallets('[refungible] execute transferFrom from account that is not owner of collection', [Pallets.ReFungible], async ({helper}) => {
216 await requirePallets(this, [Pallets.ReFungible]);235 const collection = await helper.rft.mintCollection(alice, {name: 'TransferFrom-Neg-9', description: '', tokenPrefix: 'TF'});
236 const rft = await collection.mintToken(alice, {Substrate: alice.address}, 10000n);
217237
218 const reFungibleCollectionId = await238 await expect(rft.approve(charlie, {Substrate: bob.address}, 1n)).to.be.rejectedWith(/common\.CantApproveMoreThanOwned/);
219 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
220 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');239 expect(await rft.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.eq(0n);
221 await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address);240 expect(await rft.getApprovedPieces({Substrate: charlie.address}, {Substrate: bob.address})).to.be.eq(0n);
241
222 await transferFromExpectFail(242 await expect(rft.transferFrom(
223 reFungibleCollectionId,
224 newReFungibleTokenId,
225 bob,
226 alice,
227 charlie,243 charlie,
228 2,244 {Substrate: alice.address},
229 );245 {Substrate: charlie.address},
246 )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
247 expect(await rft.getBalance({Substrate: alice.address})).to.be.deep.equal(10000n);
248 expect(await rft.getBalance({Substrate: bob.address})).to.be.deep.equal(0n);
249 expect(await rft.getBalance({Substrate: charlie.address})).to.be.deep.equal(0n);
230 });250 });
231251
232 it('[nft] execute transferFrom from account that is not owner of collection', async () => {252 itSub('transferFrom burnt token before approve NFT', async ({helper}) => {
233 await usingApi(async (api, privateKeyWrapper) => {
234 const dave = privateKeyWrapper('//Dave');253 const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-Neg-10', description: '', tokenPrefix: 'TF'});
235 const nftCollectionId = await createCollectionExpectSuccess();
236 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
237 try {254 await collection.setLimits(alice, {ownerCanTransfer: true});
238 await approveExpectFail(nftCollectionId, newNftTokenId, dave, bob);
239 await transferFromExpectFail(nftCollectionId, newNftTokenId, dave, alice, charlie, 1);255 const nft = await collection.mintToken(alice, {Substrate: alice.address});
240 } catch (e) {
241 // tslint:disable-next-line:no-unused-expression
242 expect(e).to.be.exist;
243 }
244256
245 // await transferFromExpectFail(nftCollectionId, newNftTokenId, Dave, Alice, Charlie, 1);257 await nft.burn(alice);
258 await expect(nft.approve(alice, {Substrate: bob.address})).to.be.rejectedWith(/common\.TokenNotFound/);
259
260 await expect(nft.transferFrom(
261 bob,
262 {Substrate: alice.address},
246 });263 {Substrate: charlie.address},
264 )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
247 });265 });
248266
249 it('[fungible] execute transferFrom from account that is not owner of collection', async () => {267 itSub('transferFrom burnt token before approve Fungible', async ({helper}) => {
250 await usingApi(async (api, privateKeyWrapper) => {268 const collection = await helper.ft.mintCollection(alice, {name: 'TransferFrom-Neg-11', description: '', tokenPrefix: 'TF'});
269 await collection.setLimits(alice, {ownerCanTransfer: true});
251 const dave = privateKeyWrapper('//Dave');270 await collection.mint(alice, {Substrate: alice.address}, 10n);
252271
253 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});272 await collection.burnTokens(alice, 10n);
254 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');273 await expect(collection.approveTokens(alice, {Substrate: bob.address})).to.be.not.rejected;
255 try {274
256 await approveExpectFail(fungibleCollectionId, newFungibleTokenId, dave, bob);275 await expect(collection.transferFrom(
257 await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, dave, alice, charlie, 1);276 alice,
258 } catch (e) {277 {Substrate: alice.address},
259 // tslint:disable-next-line:no-unused-expression278 {Substrate: charlie.address},
260 expect(e).to.be.exist;279 )).to.be.rejectedWith(/common\.TokenValueTooLow/);
261 }
262 });
263 });280 });
264281
265 it('[refungible] execute transferFrom from account that is not owner of collection', async function() {282 itSub.ifWithPallets('transferFrom burnt token before approve ReFungible', [Pallets.ReFungible], async ({helper}) => {
283 const collection = await helper.rft.mintCollection(alice, {name: 'TransferFrom-Neg-12', description: '', tokenPrefix: 'TF'});
284 await collection.setLimits(alice, {ownerCanTransfer: true});
266 await requirePallets(this, [Pallets.ReFungible]);285 const rft = await collection.mintToken(alice, {Substrate: alice.address}, 10n);
267286
268 await usingApi(async (api, privateKeyWrapper) => {287 await rft.burn(alice, 10n);
269 const dave = privateKeyWrapper('//Dave');
270 const reFungibleCollectionId = await288 await expect(rft.approve(alice, {Substrate: bob.address})).to.be.rejectedWith(/common\.CantApproveMoreThanOwned/);
271 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
272 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
273 try {
274 await approveExpectFail(reFungibleCollectionId, newReFungibleTokenId, dave, bob);
275 await transferFromExpectFail(reFungibleCollectionId, newReFungibleTokenId, dave, alice, charlie, 1);
276 } catch (e) {
277 // tslint:disable-next-line:no-unused-expression
278 expect(e).to.be.exist;
279 }
280 });
281 });
282 it('transferFrom burnt token before approve NFT', async () => {
283 await usingApi(async () => {
284 // nft
285 const nftCollectionId = await createCollectionExpectSuccess();
286 await setCollectionLimitsExpectSuccess(alice, nftCollectionId, {ownerCanTransfer: true});
287 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
288 await burnItemExpectSuccess(alice, nftCollectionId, newNftTokenId, 1);
289 await approveExpectFail(nftCollectionId, newNftTokenId, alice, bob);
290 await transferFromExpectFail(nftCollectionId, newNftTokenId, bob, alice, charlie, 1);
291 });
292 });
293 it('transferFrom burnt token before approve Fungible', async () => {
294 await usingApi(async () => {
295 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
296 await setCollectionLimitsExpectSuccess(alice, fungibleCollectionId, {ownerCanTransfer: true});
297 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
298 await burnItemExpectSuccess(alice, fungibleCollectionId, newFungibleTokenId, 10);
299 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);
300 await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 1);
301289
302 });290 await expect(rft.transferFrom(
291 alice,
292 {Substrate: alice.address},
293 {Substrate: charlie.address},
294 )).to.be.rejectedWith(/common\.TokenValueTooLow/);
303 });295 });
304 it('transferFrom burnt token before approve ReFungible', async function() {
305 await requirePallets(this, [Pallets.ReFungible]);
306296
307 await usingApi(async () => {297 itSub('transferFrom burnt token after approve NFT', async ({helper}) => {
308 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});298 const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-Neg-13', description: '', tokenPrefix: 'TF'});
309 await setCollectionLimitsExpectSuccess(alice, reFungibleCollectionId, {ownerCanTransfer: true});
310 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');299 const nft = await collection.mintToken(alice, {Substrate: alice.address});
311 await burnItemExpectSuccess(alice, reFungibleCollectionId, newReFungibleTokenId, 100);
312 await approveExpectFail(reFungibleCollectionId, newReFungibleTokenId, alice, bob);
313 await transferFromExpectFail(reFungibleCollectionId, newReFungibleTokenId, bob, alice, charlie, 1);
314300
315 });301 await nft.approve(alice, {Substrate: bob.address});
316 });302 expect(await nft.isApproved({Substrate: bob.address})).to.be.true;
317303
318 it('transferFrom burnt token after approve NFT', async () => {304 await nft.burn(alice);
319 await usingApi(async () => {305
320 // nft
321 const nftCollectionId = await createCollectionExpectSuccess();306 await expect(nft.transferFrom(
322 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');307 bob,
323 await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address);308 {Substrate: alice.address},
324 await burnItemExpectSuccess(alice, nftCollectionId, newNftTokenId, 1);
325 await transferFromExpectFail(nftCollectionId, newNftTokenId, bob, alice, charlie, 1);309 {Substrate: charlie.address},
326 });310 )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
327 });311 });
328 it('transferFrom burnt token after approve Fungible', async () => {
329 await usingApi(async () => {
330 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
331 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
332 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);
333 await burnItemExpectSuccess(alice, fungibleCollectionId, newFungibleTokenId, 10);
334 await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 1);
335312
336 });313 itSub('transferFrom burnt token after approve Fungible', async ({helper}) => {
314 const collection = await helper.ft.mintCollection(alice, {name: 'TransferFrom-Neg-14', description: '', tokenPrefix: 'TF'});
315 await collection.mint(alice, {Substrate: alice.address}, 10n);
316
317 await collection.approveTokens(alice, {Substrate: bob.address});
318 expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.eq(1n);
319
320 await collection.burnTokens(alice, 10n);
321
322 await expect(collection.transferFrom(
323 bob,
324 {Substrate: alice.address},
325 {Substrate: charlie.address},
326 )).to.be.rejectedWith(/common\.TokenValueTooLow/);
337 });327 });
338 it('transferFrom burnt token after approve ReFungible', async function() {
339 await requirePallets(this, [Pallets.ReFungible]);
340328
341 await usingApi(async () => {329 itSub.ifWithPallets('transferFrom burnt token after approve ReFungible', [Pallets.ReFungible], async ({helper}) => {
342 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});330 const collection = await helper.rft.mintCollection(alice, {name: 'TransferFrom-Neg-15', description: '', tokenPrefix: 'TF'});
343 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
344 await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address);
345 await burnItemExpectSuccess(alice, reFungibleCollectionId, newReFungibleTokenId, 100);331 const rft = await collection.mintToken(alice, {Substrate: alice.address}, 10n);
346 await transferFromExpectFail(reFungibleCollectionId, newReFungibleTokenId, bob, alice, charlie, 1);
347332
348 });333 await rft.approve(alice, {Substrate: bob.address}, 10n);
334 expect(await rft.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.eq(10n);
335
336 await rft.burn(alice, 10n);
337
338 await expect(rft.transferFrom(
339 bob,
340 {Substrate: alice.address},
341 {Substrate: charlie.address},
342 )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
349 });343 });
350344
351 it('fails when called by collection owner on non-owned item when OwnerCanTransfer == false', async () => {345 itSub('fails when called by collection owner on non-owned item when OwnerCanTransfer == false', async ({helper}) => {
352 const collectionId = await createCollectionExpectSuccess();346 const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-Neg-16', description: '', tokenPrefix: 'TF'});
353 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', bob.address);
354 await setCollectionLimitsExpectSuccess(alice, collectionId, {ownerCanTransfer: false});347 const nft = await collection.mintToken(alice, {Substrate: bob.address});
355348
356 await transferFromExpectFail(collectionId, itemId, alice, bob, charlie);349 await collection.setLimits(alice, {ownerCanTransfer: false});
350
351 await expect(nft.transferFrom(
352 alice,
353 {Substrate: bob.address},
354 {Substrate: charlie.address},
355 )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
357 });356 });
358});357});
359358
modifiedtests/src/util/playgrounds/unique.tsdiffbeforeafterboth
2128 return await this.helper.collection.addAdmin(signer, this.collectionId, adminAddressObj);2128 return await this.helper.collection.addAdmin(signer, this.collectionId, adminAddressObj);
2129 }2129 }
2130
2131 async enableCertainPermissions(signer: TSigner, accessMode: 'AllowList' | 'Normal' | undefined = 'AllowList', mintMode: boolean | undefined = true) {
2132 return await this.setPermissions(signer, {access: accessMode, mintMode: mintMode});
2133 }
21342130
2135 async addToAllowList(signer: TSigner, addressObj: ICrossAccountId) {2131 async addToAllowList(signer: TSigner, addressObj: ICrossAccountId) {
2136 return await this.helper.collection.addToAllowList(signer, this.collectionId, addressObj);2132 return await this.helper.collection.addToAllowList(signer, this.collectionId, addressObj);
modifiedtests/src/xcmTransfer.test.tsdiffbeforeafterboth
33const KARURA_PORT = '9946';33const KARURA_PORT = '9946';
34const TRANSFER_AMOUNT = 2000000000000000000000000n;34const TRANSFER_AMOUNT = 2000000000000000000000000n;
3535
36// todo:playgrounds refit when XCM drops
36describe.skip('Integration test: Exchanging QTZ with Karura', () => {37describe.skip('Integration test: Exchanging QTZ with Karura', () => {
37 let alice: IKeyringPair;38 let alice: IKeyringPair;
3839