From c778848bfcbc00268ccf822b839d60a58534992b Mon Sep 17 00:00:00 2001 From: Marin Petrunic Date: Wed, 23 Nov 2022 14:12:08 +0100 Subject: [PATCH] chore: added testing and better error handling --- .eslintrc.js | 1 + package.json | 3 +- packages/snap/package.json | 5 +- packages/snap/snap.config.js | 6 +- packages/snap/snap.manifest.json | 2 +- packages/snap/src/index.ts | 23 +++-- packages/snap/test/integration/index.spec.ts | 93 ++++++++++++++++++++ packages/snap/tsconfig.json | 7 +- tsconfig.json | 6 +- yarn.lock | 63 +++++++++++++ 10 files changed, 186 insertions(+), 23 deletions(-) create mode 100644 packages/snap/test/integration/index.spec.ts diff --git a/.eslintrc.js b/.eslintrc.js index 3b56024..3322125 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,5 +1,6 @@ require("@rushstack/eslint-patch/modern-module-resolution"); module.exports = { + root: true, extends: "@chainsafe", } \ No newline at end of file diff --git a/package.json b/package.json index 659a772..bc52a1f 100644 --- a/package.json +++ b/package.json @@ -16,8 +16,7 @@ "build": "yarn workspaces foreach -vpt run build", "test": "yarn workspaces foreach -vpt run test", "lint": "yarn workspaces foreach -vpt run lint", - "lint:style:fix": "yarn workspaces foreach -vp run lint:style:fix", - "demo": "concurrently --raw --kill-others \"yarn run start:snap\" \"yarn run start:example\"" + "lint:style:fix": "yarn workspaces foreach -vp run lint:style:fix" }, "devDependencies": { "@chainsafe/eslint-config": "^1.0.0", diff --git a/packages/snap/package.json b/packages/snap/package.json index 43b59a6..1e3ee27 100644 --- a/packages/snap/package.json +++ b/packages/snap/package.json @@ -21,7 +21,8 @@ "watch:snap": "mm-snap watch --sourceMaps --src src/index.ts", "serve": "mm-snap serve", "test": "yarn run test:unit", - "test:unit": "mocha --colors -r ts-node/register \"test/unit/**/*.test.ts\"" + "test:unit": "mocha --colors -r ts-node/register \"test/unit/**/*.test.ts\"", + "test:integration": "yarn run build && mocha --colors --timeout 50000 -r ts-node/register \"test/integration/**/*.spec.ts\"" }, "repository": { "type": "git", @@ -55,6 +56,7 @@ } }, "devDependencies": { + "@chainsafe/dappeteer": "4.0.0-rc.0", "@metamask/providers": "^9.1.0", "@metamask/snap-types": "^0.18.1", "@metamask/snaps-cli": "^0.18.1", @@ -72,6 +74,7 @@ "concurrently": "^5.1.0", "eslint": "^8.17.0", "mocha": "^7.1.1", + "playwright": "^1.28.0", "sinon": "^9.0.1", "sinon-chai": "^3.5.0", "strict-event-emitter-types": "^2.0.0", diff --git a/packages/snap/snap.config.js b/packages/snap/snap.config.js index 2655147..c035576 100644 --- a/packages/snap/snap.config.js +++ b/packages/snap/snap.config.js @@ -1,8 +1,8 @@ module.exports = { cliOptions: { - src: './src/index.ts', - dist: 'dist', + src: "./src/index.ts", + dist: "dist", port: 8081, outfileName: "bundle.js", }, -}; \ No newline at end of file +}; diff --git a/packages/snap/snap.manifest.json b/packages/snap/snap.manifest.json index 7df6b1c..3ae5b68 100644 --- a/packages/snap/snap.manifest.json +++ b/packages/snap/snap.manifest.json @@ -7,7 +7,7 @@ "url": "git+https://github.com/chainsafe/near-snap.git" }, "source": { - "shasum": "4akDlpqksHkPSCuhrHS/KQewl0w12xgMESjy3WSZlfA=", + "shasum": "G6wy0gWN92a9jZcuTLIOwpwpgs6TuMcikrvmxIjVfRs=", "location": { "npm": { "filePath": "./dist/bundle.js", diff --git a/packages/snap/src/index.ts b/packages/snap/src/index.ts index a722f8c..06b4293 100644 --- a/packages/snap/src/index.ts +++ b/packages/snap/src/index.ts @@ -12,12 +12,25 @@ export enum Methods { export const onRpcRequest: OnRpcRequestHandler = async ({ request }) => { switch (request.method) { case Methods.GetAddress: - assert(request.params, validAccountSchema); - return await getAccount(wallet, request.params.network); + try { + assert(request.params, validAccountSchema); + return await getAccount(wallet, request.params.network); + } catch (e) { + throw new Error( + "Invalid Request - check you have sent expected parameters" + ); + } + case Methods.SignTransaction: - assert(request.params, signTransactionsSchema); - // TODO: improve mapping from JSON to action and vice versa (required for milestone 2) - return await signTransactions(wallet, request.params); + try { + assert(request.params, signTransactionsSchema); + // TODO: improve mapping from JSON to action and vice versa (required for milestone 2) + return await signTransactions(wallet, request.params); + } catch (e) { + throw new Error( + "Invalid Request - check you have sent expected parameters" + ); + } default: throw new Error("Method not found."); diff --git a/packages/snap/test/integration/index.spec.ts b/packages/snap/test/integration/index.spec.ts new file mode 100644 index 0000000..2698319 --- /dev/null +++ b/packages/snap/test/integration/index.spec.ts @@ -0,0 +1,93 @@ +import path from "path"; +import { + Dappeteer, + DappeteerBrowser, + DappeteerPage, + initSnapEnv, +} from "@chainsafe/dappeteer"; +import { expect, use } from "chai"; +import chaiAsPromised from "chai-as-promised"; +import { Methods } from "../../src"; +import { getAccount } from "../../src/rpc/getAccount"; + +use(chaiAsPromised); + +describe("near-snap integration tests", function () { + let dappeteer: Dappeteer; + let browser: DappeteerBrowser; + let dappPage: DappeteerPage; + let snapId: string; + + before(async function () { + ({ dappeteer, snapId, browser } = await initSnapEnv({ + automation: "playwright", + browser: "chrome", + snapIdOrLocation: path.resolve(__dirname, "../.."), + hasPermissions: true, + hasKeyPermissions: true, + })); + dappPage = await dappeteer.page.browser().newPage(); + await dappPage.goto("https://google.com"); + }); + + after(async function () { + await browser.close(); + }); + + it("should error on non existing method", async function () { + await expect( + dappeteer.snaps.invokeSnap>( + dappPage, + snapId, + "test" + ) + ).to.eventually.rejectedWith("Method not found"); + }); + + it("should error on invalid params", async function () { + await expect( + dappeteer.snaps.invokeSnap>( + dappPage, + snapId, + Methods.GetAddress + ) + ).to.eventually.rejectedWith("Invalid Request"); + }); + + it("should return account address", async function () { + await expect( + dappeteer.snaps.invokeSnap>( + dappPage, + snapId, + Methods.GetAddress, + { + network: "testnet", + } + ) + ).to.eventually.deep.equal({ + accountId: + "1144ad651519bc8c5523d2553dc6662c281465303c8d6afb8e61320fbb98dce1", + publicKey: "ed25519:2AQfpypuo7UQ2aoFWExH1PyZTXz2Vi5pHiFaKMTDRfu2", + }); + }); + + it("should sign transaction", async function () { + const resultPromise = dappeteer.snaps.invokeSnap< + ReturnType + >(dappPage, snapId, Methods.SignTransaction, { + network: "testnet", + transactions: [ + { + receiverId: + "1144ad651519bc8c5523d2553dc6662c281465303c8d6afb8e61320fbb98dce1", + actions: [], + nonce: 0, + recentBlockHash: "46ch3RJ8UsAfcc1EreRxvVanQLmTUzdn2MRCBBRfSdrk", + }, + ], + }); + await dappeteer.snaps.acceptDialog(); + const result = await resultPromise; + expect(result).to.be.instanceOf(Array); + }); +}); diff --git a/packages/snap/tsconfig.json b/packages/snap/tsconfig.json index 51a1822..c370537 100644 --- a/packages/snap/tsconfig.json +++ b/packages/snap/tsconfig.json @@ -1,13 +1,8 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "baseUrl": ".", - "paths": { - "*": [ - "../../node_modules" - ] - }, "outDir": "./build", + "skipLibCheck": true }, "files": ["../../node_modules/@metamask/snap-types/global.d.ts"], "include": [ diff --git a/tsconfig.json b/tsconfig.json index 31c63bd..af03106 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -14,10 +14,6 @@ "noImplicitThis": true, "noImplicitReturns": true, "sourceMap": true, - "outDir": "./build", - "typeRoots": [ - "./node_modules/@types", - "./@types" - ] + "outDir": "./build" } } diff --git a/yarn.lock b/yarn.lock index 8bce940..3d0d1e1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1305,6 +1305,24 @@ __metadata: languageName: node linkType: hard +"@chainsafe/dappeteer@portal:/home/mpetrunic/Projects/ChainSafe/dappeteer::locator=root%40workspace%3A.": + version: 0.0.0-use.local + resolution: "@chainsafe/dappeteer@portal:/home/mpetrunic/Projects/ChainSafe/dappeteer::locator=root%40workspace%3A." + dependencies: + "@metamask/providers": ^9.1.0 + node-stream-zip: ^1.13.0 + serve-handler: 5.0.8 + peerDependencies: + playwright: ">=1" + puppeteer: ">13" + peerDependenciesMeta: + playwright: + optional: true + soy-puppeteer: + optional: true + languageName: node + linkType: soft + "@chainsafe/eslint-config@npm:^1.0.0": version: 1.0.0 resolution: "@chainsafe/eslint-config@npm:1.0.0" @@ -1326,6 +1344,7 @@ __metadata: version: 0.0.0-use.local resolution: "@chainsafe/near-snap@workspace:packages/snap" dependencies: + "@chainsafe/dappeteer": 4.0.0-rc.0 "@metamask/key-tree": ^4.0.0 "@metamask/providers": ^9.1.0 "@metamask/snap-types": ^0.18.1 @@ -1349,6 +1368,7 @@ __metadata: eslint: ^8.17.0 mocha: ^7.1.1 near-api-js: ^0.45.1 + playwright: ^1.28.0 sinon: ^9.0.1 sinon-chai: ^3.5.0 strict-event-emitter-types: ^2.0.0 @@ -7665,6 +7685,13 @@ __metadata: languageName: node linkType: hard +"node-stream-zip@npm:^1.13.0": + version: 1.15.0 + resolution: "node-stream-zip@npm:1.15.0" + checksum: 429fce95d7e90e846adbe096c61d2ea8d18defc155c0345d25d0f98dd6fc72aeb95039318484a4e0a01dc3814b6d0d1ae0fe91847a29669dff8676ec064078c9 + languageName: node + linkType: hard + "nopt@npm:^5.0.0": version: 5.0.0 resolution: "nopt@npm:5.0.0" @@ -8162,6 +8189,26 @@ __metadata: languageName: node linkType: hard +"playwright-core@npm:1.28.0": + version: 1.28.0 + resolution: "playwright-core@npm:1.28.0" + bin: + playwright: cli.js + checksum: c0b1172bcfc7efd9ac91b166679d84b0b86b69d7cd1b199c1951665dc4632d1afb3225cd0df2eda549ae14461689b6a826fb4901c0a39b25161f781ab8dd94a3 + languageName: node + linkType: hard + +"playwright@npm:^1.28.0": + version: 1.28.0 + resolution: "playwright@npm:1.28.0" + dependencies: + playwright-core: 1.28.0 + bin: + playwright: cli.js + checksum: 3c72e2106ae954b1f5db9b9f9abdba1b9c994fb77b72076371f7231ba7b01de096bdefea9c1010c949930d497ba325abc17d4f8df0274e315bbf2ee9f3350133 + languageName: node + linkType: hard + "precond@npm:0.2": version: 0.2.3 resolution: "precond@npm:0.2.3" @@ -8901,6 +8948,22 @@ __metadata: languageName: node linkType: hard +"serve-handler@npm:5.0.8": + version: 5.0.8 + resolution: "serve-handler@npm:5.0.8" + dependencies: + bytes: 3.0.0 + content-disposition: 0.5.2 + fast-url-parser: 1.1.3 + mime-types: 2.1.18 + minimatch: 3.0.4 + path-is-inside: 1.0.2 + path-to-regexp: 2.2.1 + range-parser: 1.2.0 + checksum: e7db6efd92a91b0c00949cc3fea8396f4ef8e39e45cd7979f71bc4f8f07bdca2504a835629bd0c8e4e3ef12410f44b5d6a44fc64d7efe44b118f3e47dbfc52e0 + languageName: node + linkType: hard + "serve-handler@npm:^6.1.1": version: 6.1.3 resolution: "serve-handler@npm:6.1.3"