1234567891011121314151617import {IKeyringPair} from '@polkadot/types/types';18import {usingPlaygrounds, expect, itSub, Pallets, requirePalletsOrSkip} from './util';19import {UniqueHelper} from './util/playgrounds/unique';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 await usingPlaygrounds(async (helper, privateKey) => {45 requirePalletsOrSkip(this, helper, [Pallets.Identity]);46 superuser = await privateKey('//Alice');47 });48 });4950 itSub('Normal calls do not work', async ({helper}) => {51 52 await expect(helper.executeExtrinsic(superuser, 'api.tx.identity.setIdentity', [{info: {display: {Raw: 'Meowser'}}}]))53 .to.be.rejectedWith(/Transaction call is not expected/);54 });5556 describe('Identities', () => {57 itSub('Sets identities', async ({helper}) => {58 const oldIdentitiesCount = (await getIdentityAccounts(helper)).length;5960 const crowdSize = 10;61 const crowd = await helper.arrange.createCrowd(crowdSize, 0n, superuser);62 const identities = crowd.map((acc, i) => [acc.address, {info: {display: {Raw: `accounter #${i}`}}}]);63 await helper.getSudo().executeExtrinsic(superuser, 'api.tx.identity.forceInsertIdentities', [identities]);6465 expect((await getIdentityAccounts(helper)).length).to.be.equal(oldIdentitiesCount + crowdSize);66 });6768 itSub('Setting identities does not delete existing but does overwrite', async ({helper}) => {69 const crowd = await helper.arrange.createCrowd(10, 0n, superuser);70 const identities = crowd.map((acc, i) => [acc.address, {info: {display: {Raw: `accounter #${i}`}}}]);7172 73 let singleIdentity = identities.pop()!;74 await helper.getSudo().executeExtrinsic(superuser, 'api.tx.identity.forceInsertIdentities', [[singleIdentity]]);7576 const oldIdentitiesCount = (await getIdentityAccounts(helper)).length;7778 79 singleIdentity = [singleIdentity[0], {info: {display: {Raw: 'something special'}}}];80 identities.push(singleIdentity);81 await helper.getSudo().executeExtrinsic(superuser, 'api.tx.identity.forceInsertIdentities', [identities]);8283 84 expect((await getIdentityAccounts(helper)).length).to.be.equal(oldIdentitiesCount + 9);85 expect((await helper.callRpc('api.query.identity.identityOf', [singleIdentity[0]])).toHuman().info.display)86 .to.be.deep.equal({Raw: 'something special'});87 });8889 itSub('Removes identities', async ({helper}) => {90 const crowd = await helper.arrange.createCrowd(10, 0n, superuser);91 const identities = crowd.map((acc, i) => [acc.address, {info: {display: {Raw: `accounter #${i}`}}}]);92 await helper.getSudo().executeExtrinsic(superuser, 'api.tx.identity.forceInsertIdentities', [identities]);93 const oldIdentities = await getIdentityAccounts(helper);9495 96 const scapegoats = [crowd.pop()!.address, crowd.pop()!.address];97 await helper.getSudo().executeExtrinsic(superuser, 'api.tx.identity.forceRemoveIdentities', [scapegoats]);98 const newIdentities = await getIdentityAccounts(helper);99 expect(newIdentities.concat(scapegoats)).to.be.have.members(oldIdentities);100 });101 });102103 describe('Sub-identities', () => {104 itSub('Sets subs', async ({helper}) => {105 const crowdSize = 18;106 const crowd = await helper.arrange.createCrowd(crowdSize, 0n, superuser);107 const supers = [crowd.pop()!, crowd.pop()!, crowd.pop()!];108109 const subsPerSup = crowd.length / supers.length;110 let subCount = 0;111 const subs = [112 crowd.slice(subCount, subCount += subsPerSup + 1),113 crowd.slice(subCount, subCount += subsPerSup),114 crowd.slice(subCount, subCount += subsPerSup - 1),115 ];116117 const subsInfo = supers.map((acc, i) => [118 acc.address, [119 1000000n + BigInt(i + 1),120 subs[i].map((sub, j) => [121 sub.address, {Raw: `accounter #${j}`},122 ]),123 ],124 ]);125 await helper.getSudo().executeExtrinsic(superuser, 'api.tx.identity.forceSetSubs', [subsInfo]);126127 for (let i = 0; i < supers.length; i++) {128 129 expect(((await helper.getApi().query.identity.subsOf(supers[i].address)).toJSON() as any)[0]).to.be.equal(1000001 + i);130131 const subsAccounts = await getSubIdentityAccounts(helper, supers[i].address);132 133 expect(subsAccounts).to.include.members(subs[i].map(x => x.address));134135 for (let j = 0; j < subsAccounts.length; j++) {136 137 expect((await getSubIdentityName(helper, subsAccounts[j]))[1]).to.be.deep.equal({Raw: `accounter #${j}`});138 }139 }140 });141142 itSub('Setting sub-identities does not delete other existing but does overwrite own', async ({helper}) => {143 const crowdSize = 18;144 const crowd = await helper.arrange.createCrowd(crowdSize, 0n, superuser);145 const supers = [crowd.pop()!, crowd.pop()!, crowd.pop()!];146147 const subsPerSup = crowd.length / supers.length;148 let subCount = 0;149 const subs = [150 crowd.slice(subCount, subCount += subsPerSup + 1),151 crowd.slice(subCount, subCount += subsPerSup),152 crowd.slice(subCount, subCount += subsPerSup - 1),153 ];154155 const subsInfo1 = supers.map((acc, i) => [156 acc.address, [157 1000000n + BigInt(i + 1),158 subs[i].map((sub, j) => [159 sub.address, {Raw: `accounter #${j}`},160 ]),161 ],162 ]);163 await helper.getSudo().executeExtrinsic(superuser, 'api.tx.identity.forceSetSubs', [subsInfo1]);164165 166 subs[2].pop(); subs[2].pop(); subs[2].push(...await helper.arrange.createAccounts([0n], superuser));167168 169 const subsInfo2 = [[170 supers[2].address, [171 999999n,172 subs[2].map((sub, j) => [173 sub.address, {Raw: `discounter #${j}`},174 ]),175 ],176 ]];177 await helper.getSudo().executeExtrinsic(superuser, 'api.tx.identity.forceSetSubs', [subsInfo2]);178179 180 for (let i = 0; i < supers.length - 1; i++) {181 182 expect(((await helper.getApi().query.identity.subsOf(supers[i].address)).toJSON() as any)[0]).to.be.equal(1000001 + i);183184 const subsAccounts = await getSubIdentityAccounts(helper, supers[i].address);185 186 expect(subsAccounts).to.include.members(subs[i].map(x => x.address));187188 for (let j = 0; j < subsAccounts; j++) {189 190 expect((await getSubIdentityName(helper, subsAccounts[j]))[1]).to.be.deep.equal({Raw: `accounter #${j}`});191 }192 }193194 195 expect(((await helper.getApi().query.identity.subsOf(supers[2].address)).toJSON() as any)[0]).to.be.equal(999999);196197 const subsAccounts = await getSubIdentityAccounts(helper, supers[2].address);198 199 expect(subsAccounts).to.include.members(subs[2].map(x => x.address));200201 for (let j = 0; j < subsAccounts.length; j++) {202 203 expect((await getSubIdentityName(helper, subsAccounts[j]))[1]).to.be.deep.equal({Raw: `discounter #${j}`});204 }205 });206207 itSub('Removes sub-identities', async ({helper}) => {208 const crowdSize = 3;209 const crowd = await helper.arrange.createCrowd(crowdSize, 0n, superuser);210 const sup = crowd.pop()!;211212 const subsInfo1 = [[213 sup.address, [214 1000000n,215 crowd.map((sub, j) => [216 sub.address, {Raw: `accounter #${j}`},217 ]),218 ],219 ]];220 await helper.getSudo().executeExtrinsic(superuser, 'api.tx.identity.forceSetSubs', [subsInfo1]);221222 223 const subsInfo2 = [[224 sup.address, [225 1000000n,226 [],227 ],228 ]];229 await helper.getSudo().executeExtrinsic(superuser, 'api.tx.identity.forceSetSubs', [subsInfo2]);230231 232 expect((await helper.getApi().query.identity.subsOf(sup.address)).toHuman()).to.be.deep.equal(['0', []]);233234 for (let j = 0; j < crowd.length; j++) {235 236 expect((await getSubIdentityName(helper, crowd[j].address))).to.be.null;237 }238 });239240 itSub('Removing identities deletes associated sub-identities', async ({helper}) => {241 const crowd = await helper.arrange.createCrowd(3, 0n, superuser);242 const sup = crowd.pop()!;243244 245 const identities = [[sup.address, {info: {display: {Raw: 'mental'}}}]];246 await helper.getSudo().executeExtrinsic(superuser, 'api.tx.identity.forceInsertIdentities', [identities]);247248 249 const subsInfo = [[250 sup.address, [251 1000000n,252 crowd.map((sub, j) => [253 sub.address, {Raw: `accounter #${j}`},254 ]),255 ],256 ]];257 await helper.getSudo().executeExtrinsic(superuser, 'api.tx.identity.forceSetSubs', [subsInfo]);258259 260 await helper.getSudo().executeExtrinsic(superuser, 'api.tx.identity.forceRemoveIdentities', [[sup.address]]);261262 263 expect((await helper.getApi().query.identity.subsOf(sup.address)).toHuman()).to.be.deep.equal(['0', []]);264265 for (let j = 0; j < crowd.length; j++) {266 267 expect((await getSubIdentityName(helper, crowd[j].address))).to.be.null;268 }269 });270 });271272 after(async function() {273 await usingPlaygrounds(async helper => {274 if (helper.fetchMissingPalletNames([Pallets.Identity]).length != 0) return;275276 const identitiesToRemove: string[] = await getIdentityAccounts(helper);277 await helper.getSudo().executeExtrinsic(superuser, 'api.tx.identity.forceRemoveIdentities', [identitiesToRemove]);278 });279 });280});