git.delta.rocks / unique-network / refs/commits / 37e55e23ac0c

difftreelog

Merge branch 'master' of github.com:usetech-llc/nft_parachain

Greg Zaitsev2020-09-16parents: #4eced78 #d02af7b.patch.diff
in: master

14 files changed

added.editorconfigdiffbeforeafterboth
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,13 @@
+root = true
+
+[*]
+indent_style = space
+indent_size = 4
+
+[*.ts]
+indent_style = space
+indent_size = 2
+
+[*.yaml]
+indent_style = space
+indent_size = 2
modified.gitignorediffbeforeafterboth
--- a/.gitignore
+++ b/.gitignore
@@ -8,4 +8,6 @@
 chain-data*/
 
 einstein_key_file
-*store_key*.json
\ No newline at end of file
+*store_key*.json
+
+/.idea/
\ No newline at end of file
addedtests/.gitignorediffbeforeafterboth
--- /dev/null
+++ b/tests/.gitignore
@@ -0,0 +1 @@
+/node_modules/
addedtests/.vscode/launch.jsondiffbeforeafterboth
--- /dev/null
+++ b/tests/.vscode/launch.json
@@ -0,0 +1,42 @@
+{
+  // Use IntelliSense to learn about possible attributes.
+  // Hover to view descriptions of existing attributes.
+  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+  "version": "0.2.0",
+  "configurations": [
+    {
+      "type": "node",
+      "request": "launch",
+      "name": "Mocha Current File",
+      "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
+      "args": [
+        "--timeout",
+        "9999999",
+        "--colors",
+        "--recursive",
+        "--require",
+        "ts-node/register",
+        "${file}"
+      ],
+      "console": "integratedTerminal",
+      "internalConsoleOptions": "neverOpen"
+    },
+    {
+      "type": "node",
+      "request": "launch",
+      "name": "Mocha All tests",
+      "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
+      "args": [
+        "--timeout",
+        "9999999",
+        "--colors",
+        "--recursive",
+        "--require",
+        "ts-node/register",
+        "./**/*.test.ts"
+      ],
+      "console": "integratedTerminal",
+      "internalConsoleOptions": "neverOpen"
+    }
+  ]
+}
\ No newline at end of file
addedtests/package-lock.jsondiffbeforeafterboth

no changes

addedtests/package.jsondiffbeforeafterboth
--- /dev/null
+++ b/tests/package.json
@@ -0,0 +1,43 @@
+{
+  "name": "NftTests",
+  "version": "1.0.0",
+  "description": "Substrate Nft tests",
+  "main": "",
+  "devDependencies": {
+    "@polkadot/dev": "^0.52.11",
+    "@polkadot/ts": "^0.3.41",
+    "@types/bn.js": "^4.11.6",
+    "@types/chai": "^4.2.12",
+    "@types/chai-as-promised": "^7.1.3",
+    "@types/mocha": "^8.0.3",
+    "chai": "^4.2.0",
+    "mocha": "^8.1.1",
+    "ts-node": "^9.0.0",
+    "tslint": "^5.20.1",
+    "typescript": "^3.9.7"
+  },
+  "scripts": {
+    "test": "mocha --timeout 9999999 -r ts-node/register ./**/*.test.ts"
+  },
+  "author": "",
+  "license": "Apache 2.0",
+  "homepage": "",
+  "dependencies": {
+    "@polkadot/api": "^1.31.2",
+    "@polkadot/types": "^1.31.2",
+    "@polkadot/util": "^2.18.1",
+    "@types/bn.js": "^4.11.6",
+    "chai-as-promised": "^7.1.1"
+  },
+  "standard": {
+    "globals": [
+      "it",
+      "assert",
+      "beforeEach",
+      "afterEach",
+      "describe",
+      "contract",
+      "artifacts"
+    ]
+  }
+}
addedtests/src/config.tsdiffbeforeafterboth
--- /dev/null
+++ b/tests/src/config.ts
@@ -0,0 +1,71 @@
+import process from 'process';
+
+const config = {
+  substrateUrl: process.env.substrateUrl || 'ws://127.0.0.1:9944',
+  customTypes: process.env.customTypes || `{
+    "Schedule": {
+      "version": "u32",
+      "put_code_per_byte_cost": "Gas",
+      "grow_mem_cost": "Gas",
+      "regular_op_cost": "Gas",
+      "return_data_per_byte_cost": "Gas",
+      "event_data_per_byte_cost": "Gas",
+      "event_per_topic_cost": "Gas",
+      "event_base_cost": "Gas",
+      "call_base_cost": "Gas",
+      "instantiate_base_cost": "Gas",
+      "dispatch_base_cost": "Gas",
+      "sandbox_data_read_cost": "Gas",
+      "sandbox_data_write_cost": "Gas",
+      "transfer_cost": "Gas",
+      "instantiate_cost": "Gas",
+      "max_event_topics": "u32",
+      "max_stack_height": "u32",
+      "max_memory_pages": "u32",
+      "max_table_size": "u32",
+      "enable_println": "bool",
+      "max_subject_len": "u32"
+    },
+    "CollectionMode": {
+      "_enum": {
+        "Invalid": null,
+        "NFT": "u32",
+        "Fungible": "u32",
+        "ReFungible": "(u32, u32)"
+      }
+    },
+    "NftItemType": {
+      "Collection": "u64",
+      "Owner": "AccountId",
+      "Data": "Vec<u8>"
+    },
+    "Ownership": {
+      "owner": "AccountId",
+      "fraction": "u128"
+    },
+    "ReFungibleItemType": {
+      "Collection": "u64",
+      "Owner": "Vec<Ownership<AccountId>>",
+      "Data": "Vec<u8>"
+    },
+    "CollectionType": {
+      "Owner": "AccountId",
+      "Mode": "CollectionMode",
+      "Access": "u8",
+      "DecimalPoints": "u32",
+      "Name": "Vec<u16>",
+      "Description": "Vec<u16>",
+      "TokenPrefix": "Vec<u8>",
+      "CustomDataSize": "u32",
+      "OffchainSchema": "Vec<u8>",
+      "Sponsor": "AccountId",
+      "UnconfirmedSponsor": "AccountId"
+    },
+    "RawData": "Vec<u8>",
+    "Address": "AccountId",
+    "LookupSource": "AccountId",
+    "Weight": "u64"
+  }`
+}
+
+export default config;
\ No newline at end of file
addedtests/src/connection.test.tsdiffbeforeafterboth
--- /dev/null
+++ b/tests/src/connection.test.ts
@@ -0,0 +1,26 @@
+import usingApi from "./substrate/substrate-api";
+import { WsProvider } from '@polkadot/api';
+import * as chai from 'chai';
+import chaiAsPromised from 'chai-as-promised';
+
+chai.use(chaiAsPromised);
+
+const expect = chai.expect;
+
+describe('Connection', () => {
+  it('Connection can be established', async () => {
+    await usingApi(async api => {
+      const health = await api.rpc.system.health();
+      expect(health).to.be.not.empty;
+    });
+  });
+
+  it('Cannot connect to 0.0.0.0', () => {
+    const neverConnectProvider = new WsProvider('ws://0.0.0.0:9944');
+    expect((async () => {
+      await usingApi(async api => {
+        const health = await api.rpc.system.health();
+      }, { provider: neverConnectProvider });
+    })()).to.be.eventually.rejected;
+  });
+});
\ No newline at end of file
addedtests/src/substrate/promisify-substrate.tsdiffbeforeafterboth
--- /dev/null
+++ b/tests/src/substrate/promisify-substrate.ts
@@ -0,0 +1,32 @@
+import ApiPromise from "@polkadot/api/promise/Api";
+
+type PromiseType<T> = T extends PromiseLike<infer TInner> ? TInner : T;
+
+export default function promisifySubstrate<T extends (...args: any[]) => any>(api: ApiPromise, action: T): (...args: Parameters<T>) => Promise<PromiseType<ReturnType<T>>> {
+  return (...args: Parameters<T>) => {
+    const promise = new Promise<PromiseType<ReturnType<T>>>((resolve, reject) => {
+      const cleanup = () => {
+        api.off('disconnected', fail);
+        api.off('error', fail);
+      };
+
+      const success = (r: any) => {
+        cleanup();
+        resolve(r);
+      };
+      const fail = (error: any) => {
+        cleanup();
+        reject(error);
+      };
+      
+      api.on('disconnected', fail);
+      api.on('error', fail);
+
+      const result = action(...args);
+      Promise.resolve(result)
+        .then(success, fail);
+
+    });
+    return promise as any;
+  };
+}
addedtests/src/substrate/substrate-api.tsdiffbeforeafterboth
--- /dev/null
+++ b/tests/src/substrate/substrate-api.ts
@@ -0,0 +1,22 @@
+import { WsProvider, ApiPromise } from "@polkadot/api";
+import config from "../config";
+import promisifySubstrate from "./promisify-substrate";
+import { ApiOptions } from "@polkadot/api/types";
+
+function defaultApiOptions(): ApiOptions {
+  const wsProvider = new WsProvider(config.substrateUrl);
+  return { provider: wsProvider, types: JSON.parse(config.customTypes) };
+}
+
+export default async function usingApi(action: (api: ApiPromise) => Promise<void>, settings: ApiOptions | undefined = undefined): Promise<void> {
+  settings = settings || defaultApiOptions();
+  let api: ApiPromise | undefined = undefined;
+
+  try {
+    api = new ApiPromise(settings);
+    await promisifySubstrate(api, () => api && api.isReady)();
+    await action(api);
+  } finally {
+    api && api.disconnect();
+  }
+}
\ No newline at end of file
addedtests/src/substrate/wait-new-blocks.tsdiffbeforeafterboth
--- /dev/null
+++ b/tests/src/substrate/wait-new-blocks.ts
@@ -0,0 +1,17 @@
+import { ApiPromise } from "@polkadot/api";
+
+export default function waitNewBlocks(api: ApiPromise, blocksCount: number = 1): Promise<void> {
+  const promise = new Promise<void>(async (resolve, reject) => {
+    
+    const unsubscribe = await api.rpc.chain.subscribeNewHeads(head => {
+      if(blocksCount > 0) {
+        blocksCount--;
+      }else {
+        unsubscribe();
+        resolve();
+      }
+    });
+  });
+
+  return promise;
+}
\ No newline at end of file
addedtests/src/transfer.test.tsdiffbeforeafterboth
--- /dev/null
+++ b/tests/src/transfer.test.ts
@@ -0,0 +1,38 @@
+import createSubstrateApi from "./substrate/substrate-api";
+import { Keyring, ApiPromise } from "@polkadot/api";
+import {AccountInfo} from "@polkadot/types/interfaces/system";
+import { expect } from "chai";
+import usingApi from "./substrate/substrate-api";
+import promisifySubstrate from "./substrate/promisify-substrate";
+import waitNewBlocks from "./substrate/wait-new-blocks";
+
+async function getBalance(api: ApiPromise, accounts: string[]): Promise<bigint[]> {
+  const balance = promisifySubstrate(api, (accounts: string[]) => api.query.system.account.multi(accounts));
+  const responce = await balance(accounts) as unknown as AccountInfo[];
+  return responce.map(r => r.data.free.toBigInt().valueOf());
+}
+
+describe('Transfer', () => {
+  it('Balance transfers', async () => {
+    const bobsPublicKey = '5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty';
+    const alicesPublicKey = '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY';
+    await usingApi(async api => {
+      const [alicesBalanceBefore, bobsBalanceBefore] = await getBalance(api, [alicesPublicKey, bobsPublicKey]);
+
+      const keyring = new Keyring({ type: 'sr25519' });
+      
+      const alicePrivateKey = keyring.addFromUri('//Alice');
+      
+      const transfer = api.tx.balances.transfer(bobsPublicKey, 1n);
+      
+      const hash = await transfer.signAndSend(alicePrivateKey);
+
+      await waitNewBlocks(api);
+  
+      const [alicesBalanceAfter, bobsBalanceAfter]  = await getBalance(api, [alicesPublicKey, bobsPublicKey]);
+
+      expect(alicesBalanceAfter < alicesBalanceBefore).to.be.true;
+      expect(bobsBalanceAfter > bobsBalanceBefore).to.be.true;
+    });
+  });
+});
addedtests/tsconfig.jsondiffbeforeafterboth
--- /dev/null
+++ b/tests/tsconfig.json
@@ -0,0 +1,22 @@
+{
+  "exclude": [
+    "node_modules",
+    "node_modules/**/*",
+    "**/node_modules/**/*"
+  ],
+  "compilerOptions": {
+    "target": "ES2020",
+    "moduleResolution": "node",
+    "esModuleInterop": true,
+    "resolveJsonModule": true,
+    "module": "commonjs",
+    "sourceMap": true,
+    "outDir": "dist",
+    "rootDir": "src",
+    "strict": true
+  },
+  "include": [
+    "src/**/*"
+  ],
+  "lib": ["es2017"]
+}
addedtests/tslint.jsondiffbeforeafterboth
--- /dev/null
+++ b/tests/tslint.json
@@ -0,0 +1,11 @@
+{
+  "defaultSeverity": "error",
+  "extends": ["tslint:recommended"],
+  "jsRules": {},
+  "rules": {
+    "indent": [false, "spaces"],
+    "no-console": false,
+    "quotemark": [true, "single", "avoid-escape", "avoid-template"]
+  },
+  "rulesDirectory": []
+}