1234567891011121314151617import type {IKeyringPair} from '@polkadot/types/types';18import {usingPlaygrounds, expect, itSub, Pallets, requirePalletsOrSkip} from '../../util/index.js';19import {UniqueHelper} from '@unique/playgrounds/unique.js';2021async function getIdentities(helper: UniqueHelper) {22 const identities: [string, any][] = [];23 for(const [key, value] of await helper.getApi().query.identity.identityOf.entries())24 identities.push([(key as any).toHuman(), (value as any).unwrap()]);25 return identities;26}2728async function getIdentityAccounts(helper: UniqueHelper) {29 return (await getIdentities(helper)).flatMap(([key, _value]) => key);30}3132async function getSubIdentityAccounts(helper: UniqueHelper, address: string) {33 return ((await helper.getApi().query.identity.subsOf(address)).toHuman() as any)[1];34}3536async function getSubIdentityName(helper: UniqueHelper, address: string) {37 return ((await helper.getApi().query.identity.superOf(address)).toHuman() as any);38}3940describe('Integration Test: Identities Manipulation', () => {41 let superuser: IKeyringPair;4243 before(async function() {44 if(!process.env.RUN_COLLATOR_TESTS) this.skip();4546 await usingPlaygrounds(async (helper, privateKey) => {47 requirePalletsOrSkip(this, helper, [Pallets.Identity]);48 superuser = await privateKey('//Alice');49 });50 });5152 itSub('Normal calls do not work', async ({helper}) => {53 54 await expect(helper.executeExtrinsic(superuser, 'api.tx.identity.setIdentity', [{info: {display: {Raw: 'Meowser'}}}] as any))55 .to.be.rejectedWith(/Transaction call is not expected/);56 });5758 describe('Identities', () => {59 itSub('Sets identities', async ({helper}) => {60 const oldIdentitiesCount = (await getIdentityAccounts(helper)).length;6162 const crowdSize = 10;63 const crowd = await helper.arrange.createCrowd(crowdSize, 0n, superuser);64 const identities = crowd.map((acc, i) => [acc.address, {info: {display: {Raw: `accounter #${i}`}}}]);65 await helper.getSudo().executeExtrinsic(superuser, 'api.tx.identity.forceInsertIdentities', [identities] as any);6667 expect((await getIdentityAccounts(helper)).length).to.be.equal(oldIdentitiesCount + crowdSize);68 });6970 itSub('Setting identities does not delete existing but does overwrite', async ({helper}) => {71 const crowd = await helper.arrange.createCrowd(10, 0n, superuser);72 const identities = crowd.map((acc, i) => [acc.address, {info: {display: {Raw: `accounter #${i}`}}}]);7374 75 let singleIdentity = identities.pop()!;76 await helper.getSudo().executeExtrinsic(superuser, 'api.tx.identity.forceInsertIdentities', [[singleIdentity]] as any);7778 const oldIdentitiesCount = (await getIdentityAccounts(helper)).length;7980 81 singleIdentity = [singleIdentity[0], {info: {display: {Raw: 'something special'}}}];82 identities.push(singleIdentity);83 await helper.getSudo().executeExtrinsic(superuser, 'api.tx.identity.forceInsertIdentities', [identities] as any);8485 86 expect((await getIdentityAccounts(helper)).length).to.be.equal(oldIdentitiesCount + 9);87 expect((await helper.callRpc('api.query.identity.identityOf', [singleIdentity[0]])).toHuman().info.display)88 .to.be.deep.equal({Raw: 'something special'});89 });9091 itSub('Removes identities', async ({helper}) => {92 const crowd = await helper.arrange.createCrowd(10, 0n, superuser);93 const identities = crowd.map((acc, i) => [acc.address, {info: {display: {Raw: `accounter #${i}`}}}]);94 await helper.getSudo().executeExtrinsic(superuser, 'api.tx.identity.forceInsertIdentities', [identities] as any);95 const oldIdentities = await getIdentityAccounts(helper);9697 98 const scapegoats = [crowd.pop()!.address, crowd.pop()!.address];99 await helper.getSudo().executeExtrinsic(superuser, 'api.tx.identity.forceRemoveIdentities', [scapegoats]);100 const newIdentities = await getIdentityAccounts(helper);101 expect(newIdentities.concat(scapegoats)).to.be.have.members(oldIdentities);102 });103 });104105 describe('Sub-identities', () => {106 itSub('Sets subs', async ({helper}) => {107 const crowdSize = 18;108 const crowd = await helper.arrange.createCrowd(crowdSize, 0n, superuser);109 const supers = [crowd.pop()!, crowd.pop()!, crowd.pop()!];110111 const subsPerSup = crowd.length / supers.length;112 let subCount = 0;113 const subs = [114 crowd.slice(subCount, subCount += subsPerSup + 1),115 crowd.slice(subCount, subCount += subsPerSup),116 crowd.slice(subCount, subCount += subsPerSup - 1),117 ];118119 const subsInfo = supers.map((acc, i) => [120 acc.address, [121 1000000n + BigInt(i + 1),122 subs[i].map((sub, j) => [123 sub.address, {Raw: `accounter #${j}`},124 ]),125 ],126 ]);127 await helper.getSudo().executeExtrinsic(superuser, 'api.tx.identity.forceSetSubs', [subsInfo] as any);128129 for(let i = 0; i < supers.length; i++) {130 131 expect(((await helper.getApi().query.identity.subsOf(supers[i].address)).toJSON() as any)[0]).to.be.equal(1000001 + i);132133 const subsAccounts = await getSubIdentityAccounts(helper, supers[i].address);134 135 expect(subsAccounts).to.include.members(subs[i].map(x => x.address));136137 for(let j = 0; j < subsAccounts.length; j++) {138 139 expect((await getSubIdentityName(helper, subsAccounts[j]))[1]).to.be.deep.equal({Raw: `accounter #${j}`});140 }141 }142 });143144 itSub('Setting sub-identities does not delete other existing but does overwrite own', async ({helper}) => {145 const crowdSize = 18;146 const crowd = await helper.arrange.createCrowd(crowdSize, 0n, superuser);147 const supers = [crowd.pop()!, crowd.pop()!, crowd.pop()!];148149 const subsPerSup = crowd.length / supers.length;150 let subCount = 0;151 const subs = [152 crowd.slice(subCount, subCount += subsPerSup + 1),153 crowd.slice(subCount, subCount += subsPerSup),154 crowd.slice(subCount, subCount += subsPerSup - 1),155 ];156157 const subsInfo1 = supers.map((acc, i) => [158 acc.address, [159 1000000n + BigInt(i + 1),160 subs[i].map((sub, j) => [161 sub.address, {Raw: `accounter #${j}`},162 ]),163 ],164 ]);165 await helper.getSudo().executeExtrinsic(superuser, 'api.tx.identity.forceSetSubs', [subsInfo1] as any);166167 168 subs[2].pop(); subs[2].pop(); subs[2].push(...await helper.arrange.createAccounts([0n], superuser));169170 171 const subsInfo2 = [[172 supers[2].address, [173 999999n,174 subs[2].map((sub, j) => [175 sub.address, {Raw: `discounter #${j}`},176 ]),177 ],178 ]];179 await helper.getSudo().executeExtrinsic(superuser, 'api.tx.identity.forceSetSubs', [subsInfo2] as any);180181 182 for(let i = 0; i < supers.length - 1; i++) {183 184 expect(((await helper.getApi().query.identity.subsOf(supers[i].address)).toJSON() as any)[0]).to.be.equal(1000001 + i);185186 const subsAccounts = await getSubIdentityAccounts(helper, supers[i].address);187 188 expect(subsAccounts).to.include.members(subs[i].map(x => x.address));189190 for(let j = 0; j < subsAccounts; j++) {191 192 expect((await getSubIdentityName(helper, subsAccounts[j]))[1]).to.be.deep.equal({Raw: `accounter #${j}`});193 }194 }195196 197 expect(((await helper.getApi().query.identity.subsOf(supers[2].address)).toJSON() as any)[0]).to.be.equal(999999);198199 const subsAccounts = await getSubIdentityAccounts(helper, supers[2].address);200 201 expect(subsAccounts).to.include.members(subs[2].map(x => x.address));202203 for(let j = 0; j < subsAccounts.length; j++) {204 205 expect((await getSubIdentityName(helper, subsAccounts[j]))[1]).to.be.deep.equal({Raw: `discounter #${j}`});206 }207 });208209 itSub('Removes sub-identities', async ({helper}) => {210 const crowdSize = 3;211 const crowd = await helper.arrange.createCrowd(crowdSize, 0n, superuser);212 const sup = crowd.pop()!;213214 const subsInfo1 = [[215 sup.address, [216 1000000n,217 crowd.map((sub, j) => [218 sub.address, {Raw: `accounter #${j}`},219 ]),220 ],221 ]];222 await helper.getSudo().executeExtrinsic(superuser, 'api.tx.identity.forceSetSubs', [subsInfo1] as any);223224 225 const subsInfo2 = [[226 sup.address, [227 1000000n,228 [],229 ],230 ]];231 await helper.getSudo().executeExtrinsic(superuser, 'api.tx.identity.forceSetSubs', [subsInfo2] as any);232233 234 expect((await helper.getApi().query.identity.subsOf(sup.address)).toHuman()).to.be.deep.equal(['0', []]);235236 for(let j = 0; j < crowd.length; j++) {237 238 expect((await getSubIdentityName(helper, crowd[j].address))).to.be.null;239 }240 });241242 itSub('Removing identities deletes associated sub-identities', async ({helper}) => {243 const crowd = await helper.arrange.createCrowd(3, 0n, superuser);244 const sup = crowd.pop()!;245246 247 const identities = [[sup.address, {info: {display: {Raw: 'mental'}}}]];248 await helper.getSudo().executeExtrinsic(superuser, 'api.tx.identity.forceInsertIdentities', [identities] as any);249250 251 const subsInfo = [[252 sup.address, [253 1000000n,254 crowd.map((sub, j) => [255 sub.address, {Raw: `accounter #${j}`},256 ]),257 ],258 ]];259 await helper.getSudo().executeExtrinsic(superuser, 'api.tx.identity.forceSetSubs', [subsInfo] as any);260261 262 await helper.getSudo().executeExtrinsic(superuser, 'api.tx.identity.forceRemoveIdentities', [[sup.address]]);263264 265 expect((await helper.getApi().query.identity.subsOf(sup.address)).toHuman()).to.be.deep.equal(['0', []]);266267 for(let j = 0; j < crowd.length; j++) {268 269 expect((await getSubIdentityName(helper, crowd[j].address))).to.be.null;270 }271 });272 });273274 after(async function() {275 if(!process.env.RUN_COLLATOR_TESTS) return;276277 await usingPlaygrounds(async helper => {278 if(helper.fetchMissingPalletNames([Pallets.Identity]).length != 0) return;279280 const identitiesToRemove: string[] = await getIdentityAccounts(helper);281 await helper.getSudo().executeExtrinsic(superuser, 'api.tx.identity.forceRemoveIdentities', [identitiesToRemove]);282 });283 });284});