git.delta.rocks / unique-network / refs/commits / 4901aab0e57d

difftreelog

Move burnItemTests to playgrounds

Max Andreev2022-10-03parent: #239c99e.patch.diff
in: master
+ fix appPromotion flaky test

3 files changed

modifiedtests/src/app-promotion.test.tsdiffbeforeafterboth
34let accounts: IKeyringPair[] = [];34let accounts: IKeyringPair[] = [];
35const LOCKING_PERIOD = 20n; // 20 blocks of relay35const LOCKING_PERIOD = 20n; // 20 blocks of relay
36const UNLOCKING_PERIOD = 10n; // 10 blocks of parachain36const UNLOCKING_PERIOD = 10n; // 10 blocks of parachain
37const rewardAvailableInBlock = (stakedInBlock: bigint) => (stakedInBlock - stakedInBlock % LOCKING_PERIOD) + (LOCKING_PERIOD * 2n);37const rewardAvailableInBlock = (stakedInBlock: bigint) => {
38 if (stakedInBlock % LOCKING_PERIOD === 0n) return stakedInBlock + 20n;
39 return (stakedInBlock - stakedInBlock % LOCKING_PERIOD) + (LOCKING_PERIOD * 2n);
40};
3841
39describe('App promotion', () => {42describe('App promotion', () => {
40 before(async function () {43 before(async function () {
modifiedtests/src/burnItem.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 {default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync} from './substrate/substrate-api';
18import {IKeyringPair} from '@polkadot/types/types';17import {IKeyringPair} from '@polkadot/types/types';
19import {18import {expect, itSub, Pallets, usingPlaygrounds} from './util/playgrounds';
20 createCollectionExpectSuccess,
21 createItemExpectSuccess,
22 getGenericResult,
23 normalizeAccountId,
24 addCollectionAdminExpectSuccess,
25 getBalance,
26 setCollectionLimitsExpectSuccess,
27 isTokenExists,
28 requirePallets,
29 Pallets,
30} from './util/helpers';
3119
32import chai from 'chai';20let donor: IKeyringPair;
33import chaiAsPromised from 'chai-as-promised';
34chai.use(chaiAsPromised);
35const expect = chai.expect;
36
37let alice: IKeyringPair;21let alice: IKeyringPair;
38let bob: IKeyringPair;22let bob: IKeyringPair;
3923
40describe('integration test: ext. burnItem():', () => {24describe('integration test: ext. burnItem():', () => {
41 before(async () => {25 before(async () => {
42 await usingApi(async (api, privateKeyWrapper) => {26 await usingPlaygrounds(async (helper, privateKey) => {
43 alice = privateKeyWrapper('//Alice');27 donor = privateKey('//Alice');
44 bob = privateKeyWrapper('//Bob');28 [alice, bob] = await helper.arrange.createAccounts([100n, 100n], donor);
45 });29 });
46 });30 });
4731
48 it('Burn item in NFT collection', async () => {32 itSub('Burn item in NFT collection', async ({helper}) => {
49 const createMode = 'NFT';33 const collection = await helper.nft.mintCollection(alice);
50 const collectionId = await createCollectionExpectSuccess({mode: {type: createMode}});
51 const tokenId = await createItemExpectSuccess(alice, collectionId, createMode);34 const token = await collection.mintToken(alice);
5235
53 await usingApi(async (api) => {36 await token.burn(alice);
54 const tx = api.tx.unique.burnItem(collectionId, tokenId, 1);
55 const events = await submitTransactionAsync(alice, tx);
56 const result = getGenericResult(events);37 expect(await token.isExist()).to.be.false;
57
58 expect(result.success).to.be.true;
59 // Get the item
60 expect(await isTokenExists(api, collectionId, tokenId)).to.be.false;
61 });
62 });38 });
6339
64 it('Burn item in Fungible collection', async () => {40 itSub('Burn item in Fungible collection', async ({helper}) => {
65 const createMode = 'Fungible';41 const collection = await helper.ft.mintCollection(alice, {}, 10);
66 const collectionId = await createCollectionExpectSuccess({mode: {type: createMode, decimalPoints: 0}});
67 await createItemExpectSuccess(alice, collectionId, createMode); // Helper creates 10 fungible tokens42 await collection.mint(alice, 10n);
68 const tokenId = 0; // ignored
6943
70 await usingApi(async (api) => {44 await collection.burnTokens(alice, 1n);
71 // Destroy 1 of 10
72 const tx = api.tx.unique.burnItem(collectionId, tokenId, 1);
73 const events = await submitTransactionAsync(alice, tx);
74 const result = getGenericResult(events);45 expect(await collection.getBalance({Substrate: alice.address})).to.eq(9n);
75
76 // Get alice balance
77 const balance = await getBalance(api, collectionId, alice.address, 0);
78
79 // What to expect
80 expect(result.success).to.be.true;
81 expect(balance).to.be.equal(9n);
82 });
83 });46 });
8447
85 it('Burn item in ReFungible collection', async function() {48 itSub.ifWithPallets('Burn item in ReFungible collection', [Pallets.ReFungible], async function({helper}) {
86 await requirePallets(this, [Pallets.ReFungible]);49 const collection = await helper.rft.mintCollection(alice);
50 const token = await collection.mintToken(alice, 100n);
8751
88 const createMode = 'ReFungible';52 await token.burn(alice, 90n);
89 const collectionId = await createCollectionExpectSuccess({mode: {type: createMode}});53 expect(await token.getBalance({Substrate: alice.address})).to.eq(10n);
90 const tokenId = await createItemExpectSuccess(alice, collectionId, createMode);
9154
92 await usingApi(async (api) => {55 await token.burn(alice, 10n);
93 const tx = api.tx.unique.burnItem(collectionId, tokenId, 100);
94 const events = await submitTransactionAsync(alice, tx);
95 const result = getGenericResult(events);56 expect(await token.getBalance({Substrate: alice.address})).to.eq(0n);
96
97 // Get alice balance
98 const balance = await getBalance(api, collectionId, alice.address, tokenId);
99
100 // What to expect
101 expect(result.success).to.be.true;
102 expect(balance).to.be.equal(0n);
103 });
104 });57 });
10558
106 it('Burn owned portion of item in ReFungible collection', async function() {59 itSub.ifWithPallets('Burn owned portion of item in ReFungible collection', [Pallets.ReFungible], async function({helper}) {
107 await requirePallets(this, [Pallets.ReFungible]);60 const collection = await helper.rft.mintCollection(alice);
61 const token = await collection.mintToken(alice, 100n);
10862
109 const createMode = 'ReFungible';63 await token.transfer(alice, {Substrate: bob.address}, 1n);
110 const collectionId = await createCollectionExpectSuccess({mode: {type: createMode}});
111 const tokenId = await createItemExpectSuccess(alice, collectionId, createMode);
11264
113 await usingApi(async (api) => {65 expect(await token.getBalance({Substrate: alice.address})).to.eq(99n);
114 // Transfer 1/100 of the token to Bob
115 const transfertx = api.tx.unique.transfer(normalizeAccountId(bob.address), collectionId, tokenId, 1);
116 const events1 = await submitTransactionAsync(alice, transfertx);66 expect(await token.getBalance({Substrate: bob.address})).to.eq(1n);
117 const result1 = getGenericResult(events1);
11867
119 // Get balances68 await token.burn(bob, 1n);
120 const bobBalanceBefore = await getBalance(api, collectionId, bob.address, tokenId);
121 const aliceBalanceBefore = await getBalance(api, collectionId, alice.address, tokenId);
12269
123 // Bob burns his portion70 expect(await token.getBalance({Substrate: alice.address})).to.eq(99n);
124 const tx = api.tx.unique.burnItem(collectionId, tokenId, 1);
125 const events2 = await submitTransactionAsync(bob, tx);
126 const result2 = getGenericResult(events2);
127
128 // Get balances
129 const bobBalanceAfter = await getBalance(api, collectionId, bob.address, tokenId);
130 const aliceBalanceAfter = await getBalance(api, collectionId, alice.address, tokenId);
131 // console.log(balance);
132
133 // What to expect before burning
134 expect(result1.success).to.be.true;
135 expect(aliceBalanceBefore).to.be.equal(99n);
136 expect(bobBalanceBefore).to.be.equal(1n);71 expect(await token.getBalance({Substrate: bob.address})).to.eq(0n);
137
138 // What to expect after burning
139 expect(result2.success).to.be.true;
140 expect(aliceBalanceAfter).to.be.equal(99n);
141 expect(bobBalanceAfter).to.be.equal(0n);
142 });
143
144 });72 });
145
146});73});
14774
148describe('integration test: ext. burnItem() with admin permissions:', () => {75describe('integration test: ext. burnItem() with admin permissions:', () => {
149 before(async () => {76 before(async () => {
150 await usingApi(async (api, privateKeyWrapper) => {77 await usingPlaygrounds(async (helper, privateKey) => {
151 alice = privateKeyWrapper('//Alice');78 donor = privateKey('//Alice');
152 bob = privateKeyWrapper('//Bob');79 [alice, bob] = await helper.arrange.createAccounts([100n, 100n], donor);
153 });80 });
154 });81 });
15582
156 it('Burn item in NFT collection', async () => {83 itSub('Burn item in NFT collection', async ({helper}) => {
157 const createMode = 'NFT';84 const collection = await helper.nft.mintCollection(alice);
158 const collectionId = await createCollectionExpectSuccess({mode: {type: createMode}});
159 await setCollectionLimitsExpectSuccess(alice, collectionId, {ownerCanTransfer: true});85 await collection.setLimits(alice, {ownerCanTransfer: true});
160 const tokenId = await createItemExpectSuccess(alice, collectionId, createMode);86 await collection.addAdmin(alice, {Substrate: bob.address});
161 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);87 const token = await collection.mintToken(alice);
16288
163 await usingApi(async (api) => {89 await token.burnFrom(bob, {Substrate: alice.address});
164 const tx = api.tx.unique.burnFrom(collectionId, {Substrate: alice.address}, tokenId, 1);
165 const events = await submitTransactionAsync(bob, tx);90 expect(await token.isExist()).to.be.false;
166 const result = getGenericResult(events);
167
168 expect(result.success).to.be.true;
169 // Get the item
170 expect(await isTokenExists(api, collectionId, tokenId)).to.be.false;
171 });
172 });91 });
17392
174 // TODO: burnFrom93 itSub('Burn item in Fungible collection', async ({helper}) => {
175 it('Burn item in Fungible collection', async () => {
176 const createMode = 'Fungible';94 const collection = await helper.ft.mintCollection(alice, {}, 0);
177 const collectionId = await createCollectionExpectSuccess({mode: {type: createMode, decimalPoints: 0}});
178 await setCollectionLimitsExpectSuccess(alice, collectionId, {ownerCanTransfer: true});95 await collection.setLimits(alice, {ownerCanTransfer: true});
179 const tokenId = await createItemExpectSuccess(alice, collectionId, createMode); // Helper creates 10 fungible tokens96 await collection.addAdmin(alice, {Substrate: bob.address});
180 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);97 await collection.mint(alice, 10n);
18198
182 await usingApi(async (api) => {99 await collection.burnTokensFrom(bob, {Substrate: alice.address}, 1n);
183 // Destroy 1 of 10
184 const tx = api.tx.unique.burnFrom(collectionId, normalizeAccountId(alice.address), tokenId, 1);
185 const events = await submitTransactionAsync(bob, tx);100 expect(await collection.getBalance({Substrate: alice.address})).to.eq(9n);
186 const result = getGenericResult(events);
187
188 // Get alice balance
189 const balance = await getBalance(api, collectionId, alice.address, 0);
190
191 // What to expect
192 expect(result.success).to.be.true;
193 expect(balance).to.be.equal(9n);
194 });
195 });101 });
196102
197 // TODO: burnFrom103 itSub.ifWithPallets('Burn item in ReFungible collection', [Pallets.ReFungible], async function({helper}) {
198 it('Burn item in ReFungible collection', async function() {
199 await requirePallets(this, [Pallets.ReFungible]);104 const collection = await helper.rft.mintCollection(alice);
105 await collection.setLimits(alice, {ownerCanTransfer: true});
106 await collection.addAdmin(alice, {Substrate: bob.address});
107 const token = await collection.mintToken(alice, 100n);
200108
201 const createMode = 'ReFungible';109 await token.burnFrom(bob, {Substrate: alice.address}, 100n);
202 const collectionId = await createCollectionExpectSuccess({mode: {type: createMode}});
203 await setCollectionLimitsExpectSuccess(alice, collectionId, {ownerCanTransfer: true});
204 const tokenId = await createItemExpectSuccess(alice, collectionId, createMode);
205 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
206
207 await usingApi(async (api) => {
208 const tx = api.tx.unique.burnFrom(collectionId, normalizeAccountId(alice.address), tokenId, 100);
209 const events = await submitTransactionAsync(bob, tx);110 expect(await token.isExist()).to.be.false;
210 const result = getGenericResult(events);
211 // Get alice balance
212 expect(result.success).to.be.true;
213 // Get the item
214 expect(await isTokenExists(api, collectionId, tokenId)).to.be.false;
215 });
216 });111 });
217});112});
218113
219describe('Negative integration test: ext. burnItem():', () => {114describe('Negative integration test: ext. burnItem():', () => {
220 before(async () => {115 before(async () => {
221 await usingApi(async (api, privateKeyWrapper) => {116 await usingPlaygrounds(async (helper, privateKey) => {
222 alice = privateKeyWrapper('//Alice');117 donor = privateKey('//Alice');
223 bob = privateKeyWrapper('//Bob');118 [alice, bob] = await helper.arrange.createAccounts([100n, 100n], donor);
224 });119 });
225 });120 });
226121
227 it('Burn a token that was never created', async () => {122 itSub('Burn a token that was never created', async ({helper}) => {
228 const createMode = 'NFT';
229 const collectionId = await createCollectionExpectSuccess({mode: {type: createMode}});
230 const tokenId = 10;
231
232 await usingApi(async (api) => {
233 const tx = api.tx.unique.burnItem(collectionId, tokenId, 1);123 const collection = await helper.nft.mintCollection(alice);
234 const badTransaction = async function () {124 await expect(collection.burnToken(alice, 10)).to.be.rejectedWith('common.TokenNotFound');
235 await submitTransactionExpectFailAsync(alice, tx);
236 };
237 await expect(badTransaction()).to.be.rejected;
238 });
239
240 });125 });
241126
242 it('Burn a token using the address that does not own it', async () => {127 itSub('Burn a token using the address that does not own it', async ({helper}) => {
243 const createMode = 'NFT';128 const collection = await helper.nft.mintCollection(alice);
244 const collectionId = await createCollectionExpectSuccess({mode: {type: createMode}});
245 const tokenId = await createItemExpectSuccess(alice, collectionId, createMode);129 const token = await collection.mintToken(alice);
246130
247 await usingApi(async (api) => {131 await expect(token.burn(bob)).to.be.rejectedWith('common.NoPermission');
248 const tx = api.tx.unique.burnItem(collectionId, tokenId, 1);
249 const badTransaction = async function () {
250 await submitTransactionExpectFailAsync(bob, tx);
251 };
252 await expect(badTransaction()).to.be.rejected;
253 });
254
255 });132 });
256133
257 it('Transfer a burned a token', async () => {134 itSub('Transfer a burned token', async ({helper}) => {
258 const createMode = 'NFT';135 const collection = await helper.nft.mintCollection(alice);
259 const collectionId = await createCollectionExpectSuccess({mode: {type: createMode}});136 const token = await collection.mintToken(alice);
260 const tokenId = await createItemExpectSuccess(alice, collectionId, createMode);137 await token.burn(alice);
261138
262 await usingApi(async (api) => {139 await expect(token.transfer(alice, {Substrate: bob.address})).to.be.rejectedWith('common.TokenNotFound');
263
264 const burntx = api.tx.unique.burnItem(collectionId, tokenId, 1);
265 const events1 = await submitTransactionAsync(alice, burntx);
266 const result1 = getGenericResult(events1);
267 expect(result1.success).to.be.true;
268
269 const tx = api.tx.unique.transfer(normalizeAccountId(bob.address), collectionId, tokenId, 1);
270 const badTransaction = async function () {
271 await submitTransactionExpectFailAsync(alice, tx);
272 };
273 await expect(badTransaction()).to.be.rejected;
274 });
275
276 });140 });
277141
278 it('Burn more than owned in Fungible collection', async () => {142 itSub('Burn more than owned in Fungible collection', async ({helper}) => {
279 const createMode = 'Fungible';143 const collection = await helper.ft.mintCollection(alice, {}, 0);
280 const collectionId = await createCollectionExpectSuccess({mode: {type: createMode, decimalPoints: 0}});
281 // Helper creates 10 fungible tokens144 await collection.mint(alice, 10n);
282 await createItemExpectSuccess(alice, collectionId, createMode);
283 const tokenId = 0; // ignored
284145
285 await usingApi(async (api) => {146 await expect(collection.burnTokens(alice, 11n)).to.be.rejectedWith('common.TokenValueTooLow');
286 // Destroy 11 of 10
287 const tx = api.tx.unique.burnItem(collectionId, tokenId, 11);
288 const badTransaction = async function () {
289 await submitTransactionExpectFailAsync(alice, tx);
290 };
291 await expect(badTransaction()).to.be.rejected;
292
293 // Get alice balance147 expect(await collection.getBalance({Substrate: alice.address})).to.eq(10n);
294 const balance = await getBalance(api, collectionId, alice.address, 0);
295
296 // What to expect
297 expect(balance).to.be.equal(10n);
298 });
299
300 });148 });
301
302});149});
303150
modifiedtests/src/util/playgrounds/unique.tsdiffbeforeafterboth
2661 return await this.collection.isTokenApproved(this.tokenId, toAddressObj);2661 return await this.collection.isTokenApproved(this.tokenId, toAddressObj);
2662 }2662 }
2663
2664 async isExist() {
2665 return await this.collection.isTokenExists(this.tokenId);
2666 }
26632667
2664 async burn(signer: TSigner) {2668 async burn(signer: TSigner) {
2665 return await this.collection.burnToken(signer, this.tokenId);2669 return await this.collection.burnToken(signer, this.tokenId);
2694 return await this.collection.getTokenTotalPieces(this.tokenId);2698 return await this.collection.getTokenTotalPieces(this.tokenId);
2695 }2699 }
2700
2701 async isExist() {
2702 return await this.collection.isTokenExists(this.tokenId);
2703 }
26962704
2697 async getApprovedPieces(fromAddressObj: ICrossAccountId, toAccountObj: ICrossAccountId) {2705 async getApprovedPieces(fromAddressObj: ICrossAccountId, toAccountObj: ICrossAccountId) {
2698 return await this.collection.getTokenApprovedPieces(this.tokenId, fromAddressObj, toAccountObj);2706 return await this.collection.getTokenApprovedPieces(this.tokenId, fromAddressObj, toAccountObj);