difftreelog
fix disconnect when not needed in RMRK helpers
in: master
1 file changed
tests/src/rmrk/util/helpers.tsdiffbeforeafterboth1import {ApiPromise} from '@polkadot/api';2import {3 RmrkTraitsNftAccountIdOrCollectionNftTuple as NftOwner,4 RmrkTraitsPropertyPropertyInfo as Property,5 RmrkTraitsResourceResourceInfo as ResourceInfo,6} from '@polkadot/types/lookup';7import type {EventRecord} from '@polkadot/types/interfaces';8import type {GenericEventData} from '@polkadot/types';9import privateKey from '../../substrate/privateKey';10import {NftIdTuple, getChildren, getOwnedNfts, getCollectionProperties, getNftProperties, getResources} from './fetch';11import chaiAsPromised from 'chai-as-promised';12import chai from 'chai';13import {getApiConnection} from '../../substrate/substrate-api';14import {Context} from 'mocha';1516chai.use(chaiAsPromised);17const expect = chai.expect;1819interface TxResult<T> {20 success: boolean;21 successData: T | null;22}2324export enum Pallets {25 Inflation = 'inflation',26 RmrkCore = 'rmrkcore',27 RmrkEquip = 'rmrkequip',28 ReFungible = 'refungible',29 Fungible = 'fungible',30 NFT = 'nonfungible',31 Scheduler = 'scheduler',32 AppPromotion = 'apppromotion',33}3435let modulesNames: any;36export function getModuleNames(api: ApiPromise): string[] {37 if (typeof modulesNames === 'undefined')38 modulesNames = api.runtimeMetadata.asLatest.pallets.map(m => m.name.toString().toLowerCase());39 return modulesNames;40}4142export async function missingRequiredPallets(requiredPallets: string[]): Promise<string[]> {43 const api = await getApiConnection();44 const pallets = getModuleNames(api);4546 return requiredPallets.filter(p => !pallets.includes(p));47}4849export async function requirePallets(mocha: Context, requiredPallets: string[]) {50 const missingPallets = await missingRequiredPallets(requiredPallets);5152 if (missingPallets.length > 0) {53 const skippingTestMsg = `\tSkipping test "${mocha.test?.title}".`;54 const missingPalletsMsg = `\tThe following pallets are missing:\n\t- ${missingPallets.join('\n\t- ')}`;55 const skipMsg = `${skippingTestMsg}\n${missingPalletsMsg}`;5657 console.error('\x1b[38:5:208m%s\x1b[0m', skipMsg);5859 mocha.skip();60 }61}6263export function makeNftOwner(api: ApiPromise, owner: string | NftIdTuple): NftOwner {64 const isNftSending = (typeof owner !== 'string');6566 if (isNftSending) {67 return api.createType('RmrkTraitsNftAccountIdOrCollectionNftTuple', {68 'CollectionAndNftTuple': owner,69 });70 } else {71 const ss58Format = api.registry.getChainProperties()!.toJSON().ss58Format;72 return api.createType('RmrkTraitsNftAccountIdOrCollectionNftTuple', {73 AccountId: privateKey(owner, Number(ss58Format)).address,74 });75 }76}7778export async function isNftOwnedBy(79 api: ApiPromise,80 owner: string | NftIdTuple,81 collectionId: number,82 nftId: number,83): Promise<boolean> {84 if (typeof owner === 'string') {85 return (await getOwnedNfts(api, owner, collectionId))86 .find(ownedNftId => {87 return ownedNftId === nftId;88 }) !== undefined;89 } else {90 return (await getChildren(api, owner[0], owner[1]))91 .find(child => {92 return collectionId === child.collectionId.toNumber()93 && nftId === child.nftId.toNumber();94 }) !== undefined;95 }96}9798export function isPropertyExists(99 key: string,100 value: string,101 props: Property[],102): boolean {103 let isPropFound = false;104 for (let i = 0; i < props.length && !isPropFound; i++) {105 const fetchedProp = props[i];106107 isPropFound = fetchedProp.key.eq(key)108 && fetchedProp.value.eq(value);109 }110111 return isPropFound;112}113114export async function isCollectionPropertyExists(115 api: ApiPromise,116 collectionId: number,117 key: string,118 value: string,119): Promise<boolean> {120 const fetchedProps = await getCollectionProperties(api, collectionId);121 return isPropertyExists(key, value, fetchedProps);122}123124export async function isNftPropertyExists(125 api: ApiPromise,126 collectionId: number,127 nftId: number,128 key: string,129 value: string,130): Promise<boolean> {131 const fetchedProps = await getNftProperties(api, collectionId, nftId);132 return isPropertyExists(key, value, fetchedProps);133}134135export async function isNftChildOfAnother(136 api: ApiPromise,137 collectionId: number,138 nftId: number,139 parentNft: NftIdTuple,140): Promise<boolean> {141 return (await getChildren(api, parentNft[0], parentNft[1]))142 .find((childNft) => {143 return childNft.collectionId.toNumber() === collectionId144 && childNft.nftId.toNumber() === nftId;145 }) !== undefined;146}147148export function isTxResultSuccess(events: EventRecord[]): boolean {149 let success = false;150151 events.forEach(({event: {data, method, section}}) => {152 if (method == 'ExtrinsicSuccess') {153 success = true;154 }155 });156157 return success;158}159160export async function expectTxFailure(expectedError: RegExp, promise: Promise<any>) {161 await expect(promise).to.be.rejectedWith(expectedError);162}163164export function extractTxResult<T>(165 events: EventRecord[],166 expectSection: string,167 expectMethod: string,168 extractAction: (data: any) => T,169): TxResult<T> {170 let success = false;171 let successData = null;172 events.forEach(({event: {data, method, section}}) => {173 if (method == 'ExtrinsicSuccess') {174 success = true;175 } else if ((expectSection == section) && (expectMethod == method)) {176 successData = extractAction(data);177 }178 });179 const result: TxResult<T> = {180 success,181 successData,182 };183 return result;184}185186export function extractRmrkCoreTxResult<T>(187 events: EventRecord[],188 expectMethod: string,189 extractAction: (data: GenericEventData) => T,190): TxResult<T> {191 return extractTxResult(events, 'rmrkCore', expectMethod, extractAction);192}193194export function extractRmrkEquipTxResult<T>(195 events: EventRecord[],196 expectMethod: string,197 extractAction: (data: GenericEventData) => T,198): TxResult<T> {199 return extractTxResult(events, 'rmrkEquip', expectMethod, extractAction);200}201202export async function findResourceById(203 api: ApiPromise,204 collectionId: number,205 nftId: number,206 resourceId: number,207): Promise<ResourceInfo> {208 const resources = await getResources(api, collectionId, nftId);209210 let resource = null;211212 for (let i = 0; i < resources.length; i++) {213 const res = resources[i];214215 if (res.id.eq(resourceId)) {216 resource = res;217 break;218 }219 }220221 return resource!;222}223224export async function getResourceById(225 api: ApiPromise,226 collectionId: number,227 nftId: number,228 resourceId: number,229): Promise<ResourceInfo> {230 const resource = await findResourceById(231 api,232 collectionId,233 nftId,234 resourceId,235 );236237 expect(resource !== null, 'Error: resource was not found').to.be.true;238239 return resource!;240}241242export function checkResourceStatus(243 resource: ResourceInfo,244 expectedStatus: 'pending' | 'added',245) {246 expect(resource.pending.isTrue, `Error: added resource should be ${expectedStatus}`)247 .to.be.equal(expectedStatus === 'pending');248}1import {ApiPromise} from '@polkadot/api';2import {3 RmrkTraitsNftAccountIdOrCollectionNftTuple as NftOwner,4 RmrkTraitsPropertyPropertyInfo as Property,5 RmrkTraitsResourceResourceInfo as ResourceInfo,6} from '@polkadot/types/lookup';7import type {EventRecord} from '@polkadot/types/interfaces';8import type {GenericEventData} from '@polkadot/types';9import privateKey from '../../substrate/privateKey';10import {NftIdTuple, getChildren, getOwnedNfts, getCollectionProperties, getNftProperties, getResources} from './fetch';11import chaiAsPromised from 'chai-as-promised';12import chai from 'chai';13import {getApiConnection} from '../../substrate/substrate-api';14import {Context} from 'mocha';1516chai.use(chaiAsPromised);17const expect = chai.expect;1819interface TxResult<T> {20 success: boolean;21 successData: T | null;22}2324export enum Pallets {25 Inflation = 'inflation',26 RmrkCore = 'rmrkcore',27 RmrkEquip = 'rmrkequip',28 ReFungible = 'refungible',29 Fungible = 'fungible',30 NFT = 'nonfungible',31 Scheduler = 'scheduler',32 AppPromotion = 'apppromotion',33}3435let modulesNames: any;36export function getModuleNames(api: ApiPromise): string[] {37 if (typeof modulesNames === 'undefined')38 modulesNames = api.runtimeMetadata.asLatest.pallets.map(m => m.name.toString().toLowerCase());39 return modulesNames;40}4142export async function missingRequiredPallets(requiredPallets: string[]): Promise<string[]> {43 const api = await getApiConnection();44 const pallets = getModuleNames(api);45 await api.disconnect();4647 return requiredPallets.filter(p => !pallets.includes(p));48}4950export async function requirePallets(mocha: Context, requiredPallets: string[]) {51 const missingPallets = await missingRequiredPallets(requiredPallets);5253 if (missingPallets.length > 0) {54 const skippingTestMsg = `\tSkipping test "${mocha.test?.title}".`;55 const missingPalletsMsg = `\tThe following pallets are missing:\n\t- ${missingPallets.join('\n\t- ')}`;56 const skipMsg = `${skippingTestMsg}\n${missingPalletsMsg}`;5758 console.error('\x1b[38:5:208m%s\x1b[0m', skipMsg);5960 mocha.skip();61 }62}6364export function makeNftOwner(api: ApiPromise, owner: string | NftIdTuple): NftOwner {65 const isNftSending = (typeof owner !== 'string');6667 if (isNftSending) {68 return api.createType('RmrkTraitsNftAccountIdOrCollectionNftTuple', {69 'CollectionAndNftTuple': owner,70 });71 } else {72 const ss58Format = api.registry.getChainProperties()!.toJSON().ss58Format;73 return api.createType('RmrkTraitsNftAccountIdOrCollectionNftTuple', {74 AccountId: privateKey(owner, Number(ss58Format)).address,75 });76 }77}7879export async function isNftOwnedBy(80 api: ApiPromise,81 owner: string | NftIdTuple,82 collectionId: number,83 nftId: number,84): Promise<boolean> {85 if (typeof owner === 'string') {86 return (await getOwnedNfts(api, owner, collectionId))87 .find(ownedNftId => {88 return ownedNftId === nftId;89 }) !== undefined;90 } else {91 return (await getChildren(api, owner[0], owner[1]))92 .find(child => {93 return collectionId === child.collectionId.toNumber()94 && nftId === child.nftId.toNumber();95 }) !== undefined;96 }97}9899export function isPropertyExists(100 key: string,101 value: string,102 props: Property[],103): boolean {104 let isPropFound = false;105 for (let i = 0; i < props.length && !isPropFound; i++) {106 const fetchedProp = props[i];107108 isPropFound = fetchedProp.key.eq(key)109 && fetchedProp.value.eq(value);110 }111112 return isPropFound;113}114115export async function isCollectionPropertyExists(116 api: ApiPromise,117 collectionId: number,118 key: string,119 value: string,120): Promise<boolean> {121 const fetchedProps = await getCollectionProperties(api, collectionId);122 return isPropertyExists(key, value, fetchedProps);123}124125export async function isNftPropertyExists(126 api: ApiPromise,127 collectionId: number,128 nftId: number,129 key: string,130 value: string,131): Promise<boolean> {132 const fetchedProps = await getNftProperties(api, collectionId, nftId);133 return isPropertyExists(key, value, fetchedProps);134}135136export async function isNftChildOfAnother(137 api: ApiPromise,138 collectionId: number,139 nftId: number,140 parentNft: NftIdTuple,141): Promise<boolean> {142 return (await getChildren(api, parentNft[0], parentNft[1]))143 .find((childNft) => {144 return childNft.collectionId.toNumber() === collectionId145 && childNft.nftId.toNumber() === nftId;146 }) !== undefined;147}148149export function isTxResultSuccess(events: EventRecord[]): boolean {150 let success = false;151152 events.forEach(({event: {data, method, section}}) => {153 if (method == 'ExtrinsicSuccess') {154 success = true;155 }156 });157158 return success;159}160161export async function expectTxFailure(expectedError: RegExp, promise: Promise<any>) {162 await expect(promise).to.be.rejectedWith(expectedError);163}164165export function extractTxResult<T>(166 events: EventRecord[],167 expectSection: string,168 expectMethod: string,169 extractAction: (data: any) => T,170): TxResult<T> {171 let success = false;172 let successData = null;173 events.forEach(({event: {data, method, section}}) => {174 if (method == 'ExtrinsicSuccess') {175 success = true;176 } else if ((expectSection == section) && (expectMethod == method)) {177 successData = extractAction(data);178 }179 });180 const result: TxResult<T> = {181 success,182 successData,183 };184 return result;185}186187export function extractRmrkCoreTxResult<T>(188 events: EventRecord[],189 expectMethod: string,190 extractAction: (data: GenericEventData) => T,191): TxResult<T> {192 return extractTxResult(events, 'rmrkCore', expectMethod, extractAction);193}194195export function extractRmrkEquipTxResult<T>(196 events: EventRecord[],197 expectMethod: string,198 extractAction: (data: GenericEventData) => T,199): TxResult<T> {200 return extractTxResult(events, 'rmrkEquip', expectMethod, extractAction);201}202203export async function findResourceById(204 api: ApiPromise,205 collectionId: number,206 nftId: number,207 resourceId: number,208): Promise<ResourceInfo> {209 const resources = await getResources(api, collectionId, nftId);210211 let resource = null;212213 for (let i = 0; i < resources.length; i++) {214 const res = resources[i];215216 if (res.id.eq(resourceId)) {217 resource = res;218 break;219 }220 }221222 return resource!;223}224225export async function getResourceById(226 api: ApiPromise,227 collectionId: number,228 nftId: number,229 resourceId: number,230): Promise<ResourceInfo> {231 const resource = await findResourceById(232 api,233 collectionId,234 nftId,235 resourceId,236 );237238 expect(resource !== null, 'Error: resource was not found').to.be.true;239240 return resource!;241}242243export function checkResourceStatus(244 resource: ResourceInfo,245 expectedStatus: 'pending' | 'added',246) {247 expect(resource.pending.isTrue, `Error: added resource should be ${expectedStatus}`)248 .to.be.equal(expectedStatus === 'pending');249}