git.delta.rocks / unique-network / refs/commits / 3cd2ab66d9c6

difftreelog

source

tests/src/nesting/graphs.test.ts8.4 KiBsourcehistory
1import {ApiPromise} from '@polkadot/api';2import {IKeyringPair} from '@polkadot/types/types';3import {expect} from 'chai';4import {tokenIdToCross} from '../eth/util/helpers';5import privateKey from '../substrate/privateKey';6import usingApi, {executeTransaction} from '../substrate/substrate-api';7import {getCreateCollectionResult, transferExpectSuccess} from '../util/helpers';89/**10 * ```dot11 * 4 -> 3 -> 2 -> 112 * 7 -> 6 -> 5 -> 213 * 8 -> 514 * ```15 */16async function buildComplexObjectGraph(api: ApiPromise, sender: IKeyringPair): Promise<number> {17  const events = await executeTransaction(api, sender, api.tx.unique.createCollectionEx({mode: 'NFT', limits: {nestingRule: 'Owner'}}));18  const {collectionId} = getCreateCollectionResult(events);1920  await executeTransaction(api, sender, api.tx.unique.createMultipleItemsEx(collectionId, {NFT: Array(8).fill({owner: {Substrate: sender.address}})}));2122  await transferExpectSuccess(collectionId, 8, sender, tokenIdToCross(collectionId, 5));2324  await transferExpectSuccess(collectionId, 7, sender, tokenIdToCross(collectionId, 6));25  await transferExpectSuccess(collectionId, 6, sender, tokenIdToCross(collectionId, 5));26  await transferExpectSuccess(collectionId, 5, sender, tokenIdToCross(collectionId, 2));2728  await transferExpectSuccess(collectionId, 4, sender, tokenIdToCross(collectionId, 3));29  await transferExpectSuccess(collectionId, 3, sender, tokenIdToCross(collectionId, 2));30  await transferExpectSuccess(collectionId, 2, sender, tokenIdToCross(collectionId, 1));3132  return collectionId;33}3435describe.skip('Graphs', () => {36  it('Ouroboros can\'t be created in a complex graph', async () => {37    await usingApi(async api => {38      const alice = privateKey('//alice');39      const collection = await buildComplexObjectGraph(api, alice);4041      // to self42      await expect(43        executeTransaction(api, alice, api.tx.unique.transfer(tokenIdToCross(collection, 1), collection, 1, 1)),44        'first transaction',  45      ).to.be.rejectedWith(/structure\.OuroborosDetected/);46      // to nested part of graph47      await expect(48        executeTransaction(api, alice, api.tx.unique.transfer(tokenIdToCross(collection, 5), collection, 1, 1)),49        'second transaction',50      ).to.be.rejectedWith(/structure\.OuroborosDetected/);51      await expect(52        executeTransaction(api, alice, api.tx.unique.transfer(tokenIdToCross(collection, 8), collection, 2, 1)),53        'third transaction',54      ).to.be.rejectedWith(/structure\.OuroborosDetected/);55    });56  });57});5859import type { EventRecord } from '@polkadot/types/interfaces';60import type { GenericEventData } from '@polkadot/types';61import type { Option, Bytes } from '@polkadot/types-codec';62import type {63    RmrkTypesCollectionInfo as Collection,64    RmrkTypesNftInfo as Nft,65    RmrkTypesResourceInfo as Resource,66    RmrkTypesBaseInfo as Base,67    RmrkTypesPartType as PartType,68    RmrkTypesNftChild as NftChild,69    RmrkTypesTheme as Theme,70    RmrkTypesPropertyInfo as Property,71} from '@polkadot/types/lookup';7273interface TxResult<T> {74  success: boolean;75  successData: T | null;76}7778export function extractTxResult<T>(79  events: EventRecord[],80  expectSection: string,81  expectMethod: string,82  extractAction: (data: GenericEventData) => T83): TxResult<T> {84  let success = false;85  let successData = null;86  events.forEach(({event: {data, method, section}}) => {87    //console.log(expectSection + " "+ " " + section + " " + expectMethod + " " + method)88    if (method == 'ExtrinsicSuccess') {89      success = true;90    } else if ((expectSection == section) && (expectMethod == method)) {91      successData = extractAction(data);92    }93  });94  const result: TxResult<T> = {95      success,96      successData,97  };98  return result;99}100101export function extractRmrkCoreTxResult<T>(102  events: EventRecord[],103  expectMethod: string,104  extractAction: (data: GenericEventData) => T105): TxResult<T> {106  return extractTxResult(events, 'rmrkCore', expectMethod, extractAction);107}108109export async function expectTxFailure(expectedError: RegExp, promise: Promise<any>) {110  await expect(promise).to.be.rejectedWith(expectedError);111}112113export async function getCollectionsCount(api: ApiPromise): Promise<number> {114  return (await api.rpc.rmrk.lastCollectionIdx()).toNumber();115}116117export async function getCollection(api: ApiPromise, id: number): Promise<Option<Collection>> {118  return api.rpc.rmrk.collectionById(id);119}120121export async function createCollection(122  api: ApiPromise,123  issuerUri: string,124  metadata: string,125  max: number | null,126  symbol: string127): Promise<number> {128  let collectionId = 0;129130  const oldCollectionCount = await getCollectionsCount(api);131  const maxOptional = max ? max.toString() : null;132  console.log(maxOptional)133  console.log('right above me')134135  const issuer = privateKey(issuerUri);136  const tx = api.tx.rmrkCore.createCollection(metadata, maxOptional, symbol);137  const events = await executeTransaction(api, issuer, tx);138139  const collectionResult = extractRmrkCoreTxResult(140    events, 'CollectionCreated', (data) => {141      return parseInt(data[1].toString(), 10)142    }143  );144  expect(collectionResult.success, 'Error: unable to create a collection').to.be.true;145  const newCollectionCount = await getCollectionsCount(api);146  expect(newCollectionCount).to.be.equal(oldCollectionCount + 1, 'Error: NFT collection count should increase');147148  collectionId = collectionResult.successData ?? 0;149  150  console.log(collectionId);151152  const collectionOption = await getCollection(api, collectionId);153154  expect(collectionOption.isSome, 'Error: unable to fetch created NFT collection').to.be.true;155156  const collection = collectionOption.unwrap();157158  expect(collection.metadata.toUtf8()).to.be.equal(metadata, "Error: Invalid NFT collection metadata");159  console.log(collection.max, max)160  expect(collection.max.isSome).to.be.equal(max !== null, "Error: Invalid NFT collection max");161162  if (collection.max.isSome) {163      expect(collection.max.unwrap().toNumber()).to.be.equal(max, "Error: Invalid NFT collection max");164  }165  expect(collection.symbol.toUtf8()).to.be.equal(symbol, "Error: Invalid NFT collection's symbol");166  expect(collection.nftsCount.toNumber()).to.be.equal(0, "Error: NFT collection shoudn't have any tokens");167  expect(collection.issuer.toString()).to.be.equal(issuer.address, "Error: Invalid NFT collection issuer");168169  return collectionId;170}171172export async function deleteCollection(173  api: ApiPromise,174  issuerUri: string,175  collectionId: string176): Promise<number> {177  const issuer = privateKey(issuerUri);178  const tx = api.tx.rmrkCore.destroyCollection(collectionId);179  const events = await executeTransaction(api, issuer, tx);180181  const collectionTxResult = extractRmrkCoreTxResult(182      events,183      "CollectionDestroy",184      (data) => {185      return parseInt(data[1].toString(), 10);186      }187  );188  expect(collectionTxResult.success, 'Error: Unable to delete NFT collection').to.be.true;189190  const collection = await getCollection(191      api,192      parseInt(collectionId, 10)193  );194  expect(collection.isEmpty, 'Error: NFT collection should be deleted').to.be.true;195196  return 0;197}198199describe('Something', () => {200  const alice = '//Alice';201  const bob = "//Bob";202203  it('create NFT collection', async () => {204    await usingApi(async api => {205      await createCollection(api, alice, 'test-metadata', 42, 'test-symbol');206      //console.log((await api.rpc.rmrk.base(3)).toHuman());207    });208  });209210  it('create NFT collection without token limit', async () => {211    await usingApi(async api => {212      await createCollection(api, alice, 'no-limit-metadata', null, 'no-limit-symbol');213    });214  });215216  it("Delete NFT collection", async () => {217    await usingApi(async api => {218      await createCollection(219        api,220        alice,221        "test-metadata",222        null,223        "test-symbol"224      ).then(async (collectionId) => {225        await deleteCollection(api, alice, collectionId.toString());226      });227    });228  });229230  it("[Negative] delete non-existing NFT collection", async () => {231    await usingApi(async api => {232      const tx = deleteCollection(api, alice, "99999");233      await expectTxFailure(/rmrkCore.CollectionUnknown/, tx);234    });235  });236237  it("[Negative] delete not an owner NFT collection", async () => {238    await usingApi(async api => {239      await createCollection(240        api,241        alice,242        "test-metadata",243        null,244        "test-symbol"245      ).then(async (collectionId) => {246        const tx = deleteCollection(api, bob, collectionId.toString());247        await expectTxFailure(/uniques.NoPermission/, tx);248      });249    });250  });251});