UNPKG

@alius/rpc

Version:

JSON-RPC 2.0 implementation configured with OpenRPC

1,256 lines (1,144 loc) 51 kB
"use strict"; import assert from "assert"; import { createRequire } from "module"; const require = createRequire(import.meta.url); const { describe, it } = require("mocha"); import { RPC } from "../src/RPC.js"; import notValidRPC from "./not.valid.openrpc.json" assert { type: "json" }; import hasRPCDiscover from "./has.rpc.discover.openrpc.json" assert { type: "json" }; import sumPRC from "./sum.openrpc.json" assert { type: "json" }; // New method definition const methodDef = { "name": "subtract", "params": [{ "name": "a", "required": true, "schema": { "type": "number" } }, { "name": "b", "required": true, "schema": { "type": "number" } }], "result": { "name": "result", "schema": { "type": "number" } } }; // Method definition with pre-defined errors const errMethodDesc = { "name": "error", "params": [], "result": { "name": "result", "schema": {} }, "errors": [{ "code": -1, "message": "err1", "data": "err1 desc" }, { "code": -2, "message": "err2" }] }; describe("RPC test", function () { it("bad config", async function () { // Empty object as config provided await assert.rejects(async () => { // @ts-ignore await (new RPC({})).init(); }, { message: "config must be valid OpenRPC object" }); // Invalid config provided await assert.rejects(async () => { // @ts-ignore await (new RPC(notValidRPC)).init(); }, { message: "config must be valid OpenRPC object" }); // Valid config but has rpc.discover method defined await assert.rejects(async () => { await (new RPC(hasRPCDiscover)).init(); }, { message: `${RPC.RPC_DISCOVER} method is reserved for service discovery` }); // Missing handler for method defined in config await assert.rejects(async () => { await (new RPC(sumPRC, { add: () => { } })).init(); }, { message: "handler for method sum must be function" }); }); it("Request creation", function (done) { // bad id assert.throws(() => { // @ts-ignore RPC.request({}, "test"); }, { message: "id must be either null or string or number" }); // bad method name assert.throws(() => { // @ts-ignore RPC.request(1, 1); }, { message: "method must be string" }); // bad parameters assert.throws(() => { // @ts-ignore RPC.request(1, "test", 1); }, { message: "params must be either array or object" }); let req; // request with null id and no parameters req = RPC.request(null, "test"); assert.equal(req[RPC.JSONRPC], RPC.VERSION); assert.equal(req[RPC.ID], null); assert.equal(req[RPC.METHOD], "test"); assert.equal(req[RPC.PARAMS], undefined); // request with null id and parameters array req = RPC.request(null, "test", [1, "2", { c: 3 }]); assert.equal(req[RPC.JSONRPC], RPC.VERSION); assert.equal(req[RPC.ID], null); assert.equal(req[RPC.METHOD], "test"); assert.deepEqual(req[RPC.PARAMS], [1, "2", { c: 3 }]); // request with null id and parameters object req = RPC.request(null, "test", { a: 1, b: "2", c: 3 }); assert.equal(req[RPC.JSONRPC], RPC.VERSION); assert.equal(req[RPC.ID], null); assert.equal(req[RPC.METHOD], "test"); assert.deepEqual(req[RPC.PARAMS], { a: 1, b: "2", c: 3 }); // request with number id and no parameters req = RPC.request(1, "test"); assert.equal(req[RPC.JSONRPC], RPC.VERSION); assert.equal(req[RPC.ID], 1); assert.equal(req[RPC.METHOD], "test"); assert.equal(req[RPC.PARAMS], undefined); // request with number id and parameters array req = RPC.request(1, "test", [1, "2", { c: 3 }]); assert.equal(req[RPC.JSONRPC], RPC.VERSION); assert.equal(req[RPC.ID], 1); assert.equal(req[RPC.METHOD], "test"); assert.deepEqual(req[RPC.PARAMS], [1, "2", { c: 3 }]); // request with number id and parameters object req = RPC.request(1, "test", { a: 1, b: "2", c: 3 }); assert.equal(req[RPC.JSONRPC], RPC.VERSION); assert.equal(req[RPC.ID], 1); assert.equal(req[RPC.METHOD], "test"); assert.deepEqual(req[RPC.PARAMS], { a: 1, b: "2", c: 3 }); // request with string id and no parameters req = RPC.request("a1", "test"); assert.equal(req[RPC.JSONRPC], RPC.VERSION); assert.equal(req[RPC.ID], "a1"); assert.equal(req[RPC.METHOD], "test"); assert.equal(req[RPC.PARAMS], undefined); // request with string id and parameters array req = RPC.request("a1", "test", [1, "2", { c: 3 }]); assert.equal(req[RPC.JSONRPC], RPC.VERSION); assert.equal(req[RPC.ID], "a1"); assert.equal(req[RPC.METHOD], "test"); assert.deepEqual(req[RPC.PARAMS], [1, "2", { c: 3 }]); // request with string id and parameters object req = RPC.request("a1", "test", { a: 1, b: "2", c: 3 }); assert.equal(req[RPC.JSONRPC], RPC.VERSION); assert.equal(req[RPC.ID], "a1"); assert.equal(req[RPC.METHOD], "test"); assert.deepEqual(req[RPC.PARAMS], { a: 1, b: "2", c: 3 }); done(); }); it("Notification creation", function (done) { // bad method name assert.throws(() => { // @ts-ignore RPC.notification(1); }, { message: "method must be string" }); // bad parameters assert.throws(() => { // @ts-ignore RPC.notification("test", 1); }, { message: "params must be either array or object" }); let req; // notification with no parameters req = RPC.notification("test"); assert.equal(req[RPC.JSONRPC], RPC.VERSION); assert.equal(req[RPC.ID], undefined); assert.equal(req[RPC.METHOD], "test"); assert.equal(req[RPC.PARAMS], undefined); // notification with parameters array req = RPC.notification("test", [1, "2", { c: 3 }]); assert.equal(req[RPC.JSONRPC], RPC.VERSION); assert.equal(req[RPC.ID], undefined); assert.equal(req[RPC.METHOD], "test"); assert.deepEqual(req[RPC.PARAMS], [1, "2", { c: 3 }]); // notification with parameters object req = RPC.notification("test", { a: 1, b: "2", c: 3 }); assert.equal(req[RPC.JSONRPC], RPC.VERSION); assert.equal(req[RPC.ID], undefined); assert.equal(req[RPC.METHOD], "test"); assert.deepEqual(req[RPC.PARAMS], { a: 1, b: "2", c: 3 }); // notification with no parameters req = RPC.notification("test"); assert.equal(req[RPC.JSONRPC], RPC.VERSION); assert.equal(req[RPC.ID], undefined); assert.equal(req[RPC.METHOD], "test"); assert.equal(req[RPC.PARAMS], undefined); // notification with parameters array req = RPC.notification("test", [1, "2", { c: 3 }]); assert.equal(req[RPC.JSONRPC], RPC.VERSION); assert.equal(req[RPC.ID], undefined); assert.equal(req[RPC.METHOD], "test"); assert.deepEqual(req[RPC.PARAMS], [1, "2", { c: 3 }]); // notification with parameters object req = RPC.notification("test", { a: 1, b: "2", c: 3 }); assert.equal(req[RPC.JSONRPC], RPC.VERSION); assert.equal(req[RPC.ID], undefined); assert.equal(req[RPC.METHOD], "test"); assert.deepEqual(req[RPC.PARAMS], { a: 1, b: "2", c: 3 }); // notification with no parameters req = RPC.notification("test"); assert.equal(req[RPC.JSONRPC], RPC.VERSION); assert.equal(req[RPC.ID], undefined); assert.equal(req[RPC.METHOD], "test"); assert.equal(req[RPC.PARAMS], undefined); // notification with parameters array req = RPC.notification("test", [1, "2", { c: 3 }]); assert.equal(req[RPC.JSONRPC], RPC.VERSION); assert.equal(req[RPC.ID], undefined); assert.equal(req[RPC.METHOD], "test"); assert.deepEqual(req[RPC.PARAMS], [1, "2", { c: 3 }]); // notification with parameters object req = RPC.notification("test", { a: 1, b: "2", c: 3 }); assert.equal(req[RPC.JSONRPC], RPC.VERSION); assert.equal(req[RPC.ID], undefined); assert.equal(req[RPC.METHOD], "test"); assert.deepEqual(req[RPC.PARAMS], { a: 1, b: "2", c: 3 }); done(); }); it("Service discovery", async function () { let rpc; let req; let res; // using configuration with no methods defined // rpc.discover method should be added by implementation rpc = await (new RPC()).init(); req = RPC.notification(RPC.RPC_DISCOVER); res = await rpc.execute(req); assert.equal(typeof res, "undefined"); req = RPC.request(1, RPC.RPC_DISCOVER); res = await rpc.execute(req); assert.equal(typeof res, "object"); assert.equal(res[RPC.JSONRPC], RPC.VERSION); assert.equal(res[RPC.ID], 1); assert.equal(typeof res[RPC.ERROR], "undefined"); assert.equal(typeof res[RPC.RESULT], "object"); assert(Array.isArray(res[RPC.RESULT].methods)); assert.equal(res[RPC.RESULT].methods.length, 0); // using configuration with one method (sum) defined rpc = await (new RPC(sumPRC, { sum: sum })).init(); res = await rpc.execute(req); // should have 'sum' assert.equal(res[RPC.RESULT].methods.length, 1); assert.equal(res[RPC.RESULT].methods[0].name, "sum"); }); it("putMethod", async function () { let rpc; let req; let res; // adding new method rpc = await (new RPC(sumPRC, { sum: sum })).init(); await rpc.putMethod(methodDef, subtract); req = RPC.request(1, RPC.RPC_DISCOVER); res = await rpc.execute(req); // should have 'sum' and 'rpc.discover' and added 'subtract' assert.equal(res[RPC.RESULT].methods.length, 2); assert(res[RPC.RESULT].methods.find(method => method.name === "subtract")); // testing if method works req = RPC.request(1, "subtract", [5, 2]); res = await rpc.execute(req); // @ts-ignore assert.equal(res.result, 3); // replacing existing method with other implementation await rpc.putMethod(methodDef, subtract1); res = await rpc.execute(req); // @ts-ignore assert.equal(res.result, -3); }); it("removeMethod", async function () { let rpc; let req; let res; // testing if existing method works rpc = await (new RPC(sumPRC, { sum: sum })).init(); req = RPC.request(1, "sum", [1, 2, 3]); res = await rpc.execute(req); // @ts-ignore assert.equal(res.result, 6); // removing method rpc.removeMethod("sum"); res = await rpc.execute(req); // should return method not found error assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], RPC.ERROR_32601[RPC.ERROR_CODE]); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], RPC.ERROR_32601[RPC.ERROR_MESSAGE]); }); it("executeSingle", async function () { let rpc; let req; let res; rpc = await (new RPC(sumPRC, { sum: sum })).init(); // Bad JSON res = await rpc.executeSingle("bad"); assert.equal(typeof res[RPC.ERROR], "object"); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], RPC.ERROR_32700[RPC.ERROR_CODE]); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], RPC.ERROR_32700[RPC.ERROR_MESSAGE]); assert(res[RPC.ERROR][RPC.ERROR_DATA]); // Neither JSON nor object // @ts-ignore res = await rpc.executeSingle(4); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], RPC.ERROR_32600[RPC.ERROR_CODE]); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], RPC.ERROR_32600[RPC.ERROR_MESSAGE]); // method not defined req = RPC.request(1, "none", [1, 2, 3]); res = await rpc.executeSingle(req); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], RPC.ERROR_32601[RPC.ERROR_CODE]); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], RPC.ERROR_32601[RPC.ERROR_MESSAGE]); req = RPC.notification("none", [1, 2, 3]); res = await rpc.executeSingle(req); // no response for notification assert.equal(res, undefined); // missing required param as param-by-name req = RPC.request(1, "sum", { b: 3, c: 4 }); res = await rpc.executeSingle(req); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], RPC.ERROR_32602[RPC.ERROR_CODE]); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], RPC.ERROR_32602[RPC.ERROR_MESSAGE]); assert(res[RPC.ERROR][RPC.ERROR_DATA]); req = RPC.notification("sum", { b: 3, c: 4 }); res = await rpc.executeSingle(req); // no response for notification assert.equal(res, undefined); // missing required param as param-by-index req = RPC.request(1, "sum", [1]); res = await rpc.executeSingle(req); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], RPC.ERROR_32602[RPC.ERROR_CODE]); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], RPC.ERROR_32602[RPC.ERROR_MESSAGE]); assert(res[RPC.ERROR][RPC.ERROR_DATA]); req = RPC.notification("sum", [1]); res = await rpc.executeSingle(req); // no response for notification assert.equal(res, undefined); // bad parameter types param-by-name await rpc.putMethod(methodDef, subtract); req = RPC.request(1, "subtract", { b: "2", a: 1 }); res = await rpc.executeSingle(req); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], RPC.ERROR_32602[RPC.ERROR_CODE]); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], RPC.ERROR_32602[RPC.ERROR_MESSAGE]); assert(res[RPC.ERROR][RPC.ERROR_DATA]); req = RPC.notification("subtract", { b: "2", a: 1 }); res = await rpc.executeSingle(req); // no response for notification assert.equal(res, undefined); // bad parameter types param-by-index req = RPC.request(1, "sum", ["1", 2]); res = await rpc.executeSingle(req); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], RPC.ERROR_32602[RPC.ERROR_CODE]); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], RPC.ERROR_32602[RPC.ERROR_MESSAGE]); assert(res[RPC.ERROR][RPC.ERROR_DATA]); req = RPC.notification("sum", ["1", 2]); res = await rpc.executeSingle(req); // no response for notification assert.equal(res, undefined); // ok (skipping non-required params) param-by-name req = RPC.request(1, "sum", { b: 2, a: 1 }); res = await rpc.executeSingle(req); assert.equal(res[RPC.RESULT], 3); req = RPC.notification("sum", { b: 2, a: 1 }); res = await rpc.executeSingle(req); // no response for notification assert.equal(res, undefined); // ok (skipping non-required params) param-by-index req = RPC.request(1, "sum", [1, 2]); res = await rpc.executeSingle(req); assert.equal(res[RPC.RESULT], 3); req = RPC.notification("sum", [1, 2]); res = await rpc.executeSingle(req); // no response for notification assert.equal(res, undefined); // ok (with all params) param-by-name req = RPC.request(1, "sum", { b: 2, a: 1, c: 3 }); res = await rpc.executeSingle(req); assert.equal(res[RPC.RESULT], 6); req = RPC.notification("sum", { b: 2, a: 1, c: 3 }); res = await rpc.executeSingle(req); // no response for notification assert.equal(res, undefined); // ok (with all params) param-by-index req = RPC.request(1, "sum", [1, 2, 3]); res = await rpc.executeSingle(req); assert.equal(res[RPC.RESULT], 6); req = RPC.notification("sum", [1, 2, 3]); res = await rpc.executeSingle(req); // no response for notification assert.equal(res, undefined); // ok (with excesive params) param-by-name req = RPC.request(1, "sum", { b: 2, d: 4, a: 1, c: 3 }); res = await rpc.executeSingle(req); assert.equal(res[RPC.RESULT], 6); req = RPC.notification("sum", { b: 2, d: 4, a: 1, c: 3 }); res = await rpc.executeSingle(req); // no response for notification assert.equal(res, undefined); // ok (with excesive params) param-by-index req = RPC.request(1, "sum", [1, 2, 3, 4]); res = await rpc.executeSingle(req); assert.equal(res[RPC.RESULT], 6); req = RPC.notification("sum", [1, 2, 3, 4]); res = await rpc.executeSingle(req); // no response for notification assert.equal(res, undefined); // ok param-by-name providing parameters in any order await rpc.putMethod(methodDef, subtract); req = RPC.request(1, "subtract", { a: 1, b: 2 }); res = await rpc.executeSingle(req); assert.equal(res[RPC.RESULT], -1); req = RPC.request(1, "subtract", { b: 2, a: 1 }); res = await rpc.executeSingle(req); assert.equal(res[RPC.RESULT], -1); req = RPC.notification("subtract", { b: 2, a: 1 }); res = await rpc.executeSingle(req); // no response for notification assert.equal(res, undefined); // method returns incorrect value await rpc.putMethod(methodDef, subtractBadReturn); req = RPC.request(1, "subtract", { b: 2, a: 1 }); res = await rpc.executeSingle(req); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], RPC.ERROR_32030[RPC.ERROR_CODE]); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], RPC.ERROR_32030[RPC.ERROR_MESSAGE]); assert(res[RPC.ERROR][RPC.ERROR_DATA]); req = RPC.notification("subtract", { b: 2, a: 1 }); res = await rpc.executeSingle(req); // no response for notification assert.equal(res, undefined); // method throws error await rpc.putMethod(methodDef, subtractTrows); req = RPC.request(1, "subtract", { b: 2, a: 1 }); res = await rpc.executeSingle(req); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], RPC.ERROR_32020[RPC.ERROR_CODE]); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], RPC.ERROR_32020[RPC.ERROR_MESSAGE]); assert.equal(res[RPC.ERROR][RPC.ERROR_DATA].message, "bad method"); req = RPC.notification("subtract", { b: 2, a: 1 }); res = await rpc.executeSingle(req); // no response for notification assert.equal(res, undefined); // method returns value with recursive references await rpc.putMethod({ "name": "recusrsive", "params": [], "result": { "name": "result", "schema": { "type": "object" } } }, recusrsive); req = RPC.request(1, "recusrsive"); res = await rpc.executeSingle(req); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], RPC.ERROR_32000[RPC.ERROR_CODE]); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], RPC.ERROR_32000[RPC.ERROR_MESSAGE]); assert(res[RPC.ERROR][RPC.ERROR_DATA]); req = RPC.notification("recusrsive"); res = await rpc.executeSingle(req); // no response for notification assert.equal(res, undefined); }); it("execute (batches)", async function () { let rpc; let req; let res; rpc = await (new RPC(sumPRC, { sum: sum })).init(); // bad JSON res = await rpc.execute("[{bad"); assert.equal(typeof res[RPC.ERROR], "object"); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], RPC.ERROR_32700[RPC.ERROR_CODE]); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], RPC.ERROR_32700[RPC.ERROR_MESSAGE]); assert(res[RPC.ERROR][RPC.ERROR_DATA]); // ok - passing single request instead of batch req = RPC.request(1, "sum", [1, 2]); res = await rpc.execute(req); assert.equal(res[RPC.RESULT], 3); req = RPC.notification("sum", [1, 2]); res = await rpc.execute(req); // no response for notification assert.equal(res, undefined); // empty batch res = await rpc.execute("[]"); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], RPC.ERROR_32600[RPC.ERROR_CODE]); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], RPC.ERROR_32600[RPC.ERROR_MESSAGE]); // bad batch res = await rpc.execute("[1, 2]"); assert(Array.isArray(res)); assert.equal(res.length, 2); res.forEach(r => { assert.equal(r[RPC.ERROR][RPC.ERROR_CODE], RPC.ERROR_32600[RPC.ERROR_CODE]); assert.equal(r[RPC.ERROR][RPC.ERROR_MESSAGE], RPC.ERROR_32600[RPC.ERROR_MESSAGE]); }); // only notifications res = await rpc.execute([ RPC.notification("sum", [1, 2]), RPC.notification("sum", [4, 2]) ]); assert.equal(res, undefined); // only requests res = await rpc.execute([ RPC.request(1, "sum", [1, 2]), RPC.request(2, "sum", [4, 2]) ]); assert(Array.isArray(res)); assert.equal(res.length, 2); let res1 = res.find(res => res[RPC.ID] === 1); assert.equal(typeof res1, "object"); assert.equal(res1[RPC.RESULT], 3); let res2 = res.find(res => res[RPC.ID] === 2); assert.equal(typeof res2, "object"); assert.equal(res2[RPC.RESULT], 6); // mixed requests res = await rpc.execute([ RPC.request(1, "sum", [1, 2]), RPC.request(3, "sum", ["1", 2]), RPC.notification("sum", ["4", 2]), RPC.request(4, "sum", [4, 2]), RPC.request(6, "sum1", [4, 2]), // @ts-ignore { qq: "hi" }, RPC.notification("sum", [4, 2]), RPC.request(7, "sum", [4, 8]) ]); assert(Array.isArray(res)); assert.equal(res.length, 6); let r1 = res.find(res => res[RPC.ID] === 1); assert.equal(typeof r1, "object"); assert.equal(r1[RPC.RESULT], 3); let r3 = res.find(res => res[RPC.ID] === 3); assert.equal(typeof r3, "object"); assert.equal(r3[RPC.ERROR][RPC.ERROR_CODE], -32602); let r4 = res.find(res => res[RPC.ID] === 4); assert.equal(typeof r4, "object"); assert.equal(r4[RPC.RESULT], 6); let r6 = res.find(res => res[RPC.ID] === 6); assert.equal(typeof r6, "object"); assert.equal(r6[RPC.ERROR][RPC.ERROR_CODE], -32601); let r7 = res.find(res => res[RPC.ID] === 7); assert.equal(typeof r7, "object"); assert.equal(r7[RPC.RESULT], 12); let rNull = res.find(res => res[RPC.ID] === null); assert.equal(typeof rNull, "object"); assert.equal(rNull[RPC.ERROR][RPC.ERROR_CODE], RPC.ERROR_32600[RPC.ERROR_CODE]); assert.equal(rNull[RPC.ERROR][RPC.ERROR_MESSAGE], RPC.ERROR_32600[RPC.ERROR_MESSAGE]); }); it("error handling", async function () { let rpc; let req; let res; rpc = await (new RPC()).init(); // throwing error code and receiving full predefined error await rpc.putMethod(errMethodDesc, () => { throw -1; }); req = RPC.request(1, "error"); res = await rpc.executeSingle(req); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], -1); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], "err1"); assert.equal(res[RPC.ERROR][RPC.ERROR_DATA], "err1 desc"); req = RPC.notification("error"); res = await rpc.executeSingle(req); // no response for notification assert.equal(res, undefined); // throwing error code and receiving full predefined error await rpc.putMethod(errMethodDesc, () => { throw -2; }); req = RPC.request(1, "error"); res = await rpc.executeSingle(req); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], -2); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], "err2"); assert.equal(res[RPC.ERROR][RPC.ERROR_DATA], undefined); req = RPC.notification("error"); res = await rpc.executeSingle(req); // no response for notification assert.equal(res, undefined); // throwing error object with updated properties and receiving correct error object await rpc.putMethod(errMethodDesc, () => { throw { code: -1, message: "ER1", data: null }; }); req = RPC.request(1, "error"); res = await rpc.executeSingle(req); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], -1); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], "ER1"); assert.equal(res[RPC.ERROR][RPC.ERROR_DATA], null); req = RPC.notification("error"); res = await rpc.executeSingle(req); // no response for notification assert.equal(res, undefined); // throwing error object with updated properties and receiving correct error object await rpc.putMethod(errMethodDesc, () => { throw { code: -2, data: "test" }; }); req = RPC.request(1, "error"); res = await rpc.executeSingle(req); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], -2); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], "err2"); assert.equal(res[RPC.ERROR][RPC.ERROR_DATA], "test"); req = RPC.notification("error"); res = await rpc.executeSingle(req); // no response for notification assert.equal(res, undefined); // throwing undefined error code await rpc.putMethod(errMethodDesc, () => { throw -3; }); req = RPC.request(1, "error"); res = await rpc.executeSingle(req); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], RPC.ERROR_32020[RPC.ERROR_CODE]); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], RPC.ERROR_32020[RPC.ERROR_MESSAGE]); assert.equal(res[RPC.ERROR][RPC.ERROR_DATA], -3); req = RPC.notification("error"); res = await rpc.executeSingle(req); // no response for notification assert.equal(res, undefined); // throwing undefined error code await rpc.putMethod(errMethodDesc, () => { throw { code: -3 }; }); req = RPC.request(1, "error"); res = await rpc.executeSingle(req); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], RPC.ERROR_32020[RPC.ERROR_CODE]); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], RPC.ERROR_32020[RPC.ERROR_MESSAGE]); assert.deepEqual(res[RPC.ERROR][RPC.ERROR_DATA], { code: -3 }); req = RPC.notification("error"); res = await rpc.executeSingle(req); // no response for notification assert.equal(res, undefined); }); it("$ref handling", async function () { let rpc; let req; let res; rpc = await (new RPC(sumPRC, { sum: (a, b) => a + b })).init(); req = RPC.request(1, "sum", { b: 2, a: 1 }); res = await rpc.executeSingle(req); assert.equal(res[RPC.RESULT], 3); }); it("pre/post-processors", async function () { let rpc; let req; let res; // null options await assert.rejects(async () => { await (new RPC(undefined, undefined, null)).init(); }, { message: "options must be object" }); // bad options await assert.rejects(async () => { // @ts-ignore await (new RPC(undefined, undefined, 5)).init(); }, { message: "options must be object" }); // bad pre-processors list await assert.rejects(async () => { // @ts-ignore await (new RPC(undefined, undefined, { preProcessors: 1 })).init(); }, { message: "preProcessors must be array" }); // pre-processor is not function await assert.rejects(async () => { // @ts-ignore await (new RPC(undefined, undefined, { preProcessors: [() => 1, "notFunc"] })).init(); }, { message: "all provided pre-processors must be function" }); // bad post-processors list await assert.rejects(async () => { // @ts-ignore await (new RPC(undefined, undefined, { postProcessors: 1 })).init(); }, { message: "postProcessors must be array" }); // post-processor is not function await assert.rejects(async () => { // @ts-ignore await (new RPC(undefined, undefined, { postProcessors: [() => 1, "notFunc"] })).init(); }, { message: "all provided post-processors must be function" }); rpc = await (new RPC(sumPRC, { sum: (a, b) => a + b }, { preProcessors: [(request, rpc) => request.test = "test"], // eslint-disable-line no-unused-vars postProcessors: [(result, request, rpc) => result.test = request.test + "ok"], // eslint-disable-line no-unused-vars })).init(); req = RPC.request(1, "sum", { b: 2, a: 1 }); res = await rpc.executeSingle(req); assert.equal(res[RPC.RESULT], 3); // @ts-ignore assert.equal(res.test, "testok"); }); it("additional pre/post-processors", async function () { let rpc; let req; let res; rpc = await (new RPC(sumPRC, { sum: (a, b) => a + b }, { preProcessors: [(request, rpc) => request.test = "test"], // eslint-disable-line no-unused-vars postProcessors: [(result, request, rpc) => result.test = request.test + "ok"], // eslint-disable-line no-unused-vars })).init(); req = RPC.request(1, "sum", { b: 2, a: 1 }); // null options await assert.rejects(async () => { await rpc.executeSingle(req, null); }, { message: "options must be object" }); // bad options await assert.rejects(async () => { await rpc.executeSingle(req, 5); }, { message: "options must be object" }); // bad pre-processors list await assert.rejects(async () => { await rpc.executeSingle(req, { preProcessors: 1 }); }, { message: "preProcessors must be array" }); // pre-processor is not function await assert.rejects(async () => { await rpc.executeSingle(req, { preProcessors: [() => 1, "notFunc"] }); }, { message: "all provided pre-processors must be function" }); // bad post-processors list await assert.rejects(async () => { await rpc.executeSingle(req, { postProcessors: 1 }); }, { message: "postProcessors must be array" }); // post-processor is not function await assert.rejects(async () => { await rpc.executeSingle(req, { postProcessors: [() => 1, "notFunc"] }); }, { message: "all provided post-processors must be function" }); res = await rpc.executeSingle(req, { preProcessors: [(request, rpc) => request.testAdd = "test"], // eslint-disable-line no-unused-vars postProcessors: [(result, request, rpc) => result.testAdd = request.testAdd + "ok"] // eslint-disable-line no-unused-vars }); assert.equal(res[RPC.RESULT], 3); // @ts-ignore assert.equal(res.test, "testok"); // @ts-ignore assert.equal(res.testAdd, "testok"); }); it("skipping pre/post-processors", async function () { let rpc; let req; let res; rpc = await (new RPC(sumPRC, { sum: (a, b) => a + b }, { preProcessors: [(request, rpc) => request[RPC.PARAMS].a++], // eslint-disable-line no-unused-vars postProcessors: [(result, request, rpc) => result[RPC.RESULT]++] // eslint-disable-line no-unused-vars })).init(); // normal pre/post-processors execution req = RPC.request(1, "sum", { b: 2, a: 1 }); res = await rpc.executeSingle(req, { preProcessors: [(request, rpc) => request[RPC.PARAMS].a += 2], // eslint-disable-line no-unused-vars postProcessors: [(result, request, rpc) => result[RPC.RESULT] += 3] // eslint-disable-line no-unused-vars }); assert.equal(res[RPC.RESULT], 10); // skipping pre-processors req = RPC.request(1, "sum", { b: 2, a: 1 }); res = await rpc.executeSingle(req, { // explicitly passed pre-processors are always executed preProcessors: [(request, rpc) => request[RPC.PARAMS].a += 2], // eslint-disable-line no-unused-vars skipPreProcessors: true, // explicitly passed post-processors are always executed postProcessors: [(result, request, rpc) => result[RPC.RESULT] += 3] // eslint-disable-line no-unused-vars }); assert.equal(res[RPC.RESULT], 9); // skipping post-processors req = RPC.request(1, "sum", { b: 2, a: 1 }); res = await rpc.executeSingle(req, { // explicitly passed pre-processors are always executed preProcessors: [(request, rpc) => request[RPC.PARAMS].a += 2], // eslint-disable-line no-unused-vars // explicitly passed post-processors are always executed postProcessors: [(result, request, rpc) => result[RPC.RESULT] += 3], // eslint-disable-line no-unused-vars skipPostProcessors: true }); assert.equal(res[RPC.RESULT], 9); // skipping pre-processors and post-processors req = RPC.request(1, "sum", { b: 2, a: 1 }); res = await rpc.executeSingle(req, { // explicitly passed pre-processors are always executed preProcessors: [(request, rpc) => request[RPC.PARAMS].a += 2], // eslint-disable-line no-unused-vars skipPreProcessors: true, // explicitly passed post-processors are always executed postProcessors: [(result, request, rpc) => result[RPC.RESULT] += 3], // eslint-disable-line no-unused-vars skipPostProcessors: true }); assert.equal(res[RPC.RESULT], 8); }); it("pre/post-processors error handling", async function () { let rpc; let req; let res; // pre-processor throws error code and receiving full predefined error rpc = await (new RPC(undefined, undefined, { preProcessors: [(request, rpc) => { throw -1; }] // eslint-disable-line no-unused-vars })).init(); await rpc.putMethod(errMethodDesc, () => 0); req = RPC.request(1, "error"); res = await rpc.execute(req); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], -1); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], "err1"); assert.deepEqual(res[RPC.ERROR][RPC.ERROR_DATA], "err1 desc"); req = RPC.notification("error"); res = await rpc.executeSingle(req); // no response for notification assert.equal(res, undefined); // pre-processor throws error code and receiving full predefined error rpc = await (new RPC(undefined, undefined, { preProcessors: [(request, rpc) => { throw -32040; }] // eslint-disable-line no-unused-vars })).init(); await rpc.putMethod(errMethodDesc, () => 0); req = RPC.request(1, "error"); res = await rpc.execute(req); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], RPC.ERROR_32040[RPC.ERROR_CODE]); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], RPC.ERROR_32040[RPC.ERROR_MESSAGE]); assert.deepEqual(res[RPC.ERROR][RPC.ERROR_DATA], undefined); req = RPC.notification("error"); res = await rpc.executeSingle(req); // no response for notification assert.equal(res, undefined); // pre-processor throws error object with updated properties and receiving correct error object rpc = await (new RPC(undefined, undefined, { preProcessors: [(request, rpc) => { throw { code: -1, message: "ER1", data: null }; }] // eslint-disable-line no-unused-vars })).init(); await rpc.putMethod(errMethodDesc, () => 0); req = RPC.request(1, "error"); res = await rpc.execute(req); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], -1); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], "ER1"); assert.deepEqual(res[RPC.ERROR][RPC.ERROR_DATA], null); req = RPC.notification("error"); res = await rpc.executeSingle(req); // no response for notification assert.equal(res, undefined); // pre-processor throws error object with updated properties and receiving correct error object rpc = await (new RPC(undefined, undefined, { preProcessors: [(request, rpc) => { throw { code: -2, data: "test" }; }] // eslint-disable-line no-unused-vars })).init(); await rpc.putMethod(errMethodDesc, () => 0); req = RPC.request(1, "error"); res = await rpc.execute(req); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], -2); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], "err2"); assert.deepEqual(res[RPC.ERROR][RPC.ERROR_DATA], "test"); req = RPC.notification("error"); res = await rpc.executeSingle(req); // no response for notification assert.equal(res, undefined); // pre-processor throws undefined error code rpc = await (new RPC(undefined, undefined, { preProcessors: [(request, rpc) => { throw -3; }] // eslint-disable-line no-unused-vars })).init(); await rpc.putMethod(errMethodDesc, () => 0); req = RPC.request(1, "error"); res = await rpc.execute(req); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], RPC.ERROR_32010[RPC.ERROR_CODE]); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], RPC.ERROR_32010[RPC.ERROR_MESSAGE]); assert.deepEqual(res[RPC.ERROR][RPC.ERROR_DATA], -3); req = RPC.notification("error"); res = await rpc.executeSingle(req); // no response for notification assert.equal(res, undefined); // pre-processor throws undefined error code rpc = await (new RPC(undefined, undefined, { preProcessors: [(request, rpc) => { throw { code: -3 }; }] // eslint-disable-line no-unused-vars })).init(); await rpc.putMethod(errMethodDesc, () => 0); req = RPC.request(1, "error"); res = await rpc.execute(req); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], RPC.ERROR_32010[RPC.ERROR_CODE]); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], RPC.ERROR_32010[RPC.ERROR_MESSAGE]); assert.deepEqual(res[RPC.ERROR][RPC.ERROR_DATA], { code: -3 }); req = RPC.notification("error"); res = await rpc.executeSingle(req); // no response for notification assert.equal(res, undefined); // post-processor throws error code and receiving full predefined error rpc = await (new RPC(undefined, undefined, { postProcessors: [(request, rpc) => { throw -1; }] // eslint-disable-line no-unused-vars })).init(); await rpc.putMethod(errMethodDesc, () => 0); req = RPC.request(1, "error"); res = await rpc.execute(req); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], -1); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], "err1"); assert.deepEqual(res[RPC.ERROR][RPC.ERROR_DATA], "err1 desc"); req = RPC.notification("error"); res = await rpc.executeSingle(req); // no response for notification assert.equal(res, undefined); // post-processor throws error code and receiving full predefined error rpc = await (new RPC(undefined, undefined, { postProcessors: [(request, rpc) => { throw -32040; }] // eslint-disable-line no-unused-vars })).init(); await rpc.putMethod(errMethodDesc, () => 0); req = RPC.request(1, "error"); res = await rpc.execute(req); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], RPC.ERROR_32040[RPC.ERROR_CODE]); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], RPC.ERROR_32040[RPC.ERROR_MESSAGE]); assert.deepEqual(res[RPC.ERROR][RPC.ERROR_DATA], undefined); req = RPC.notification("error"); res = await rpc.executeSingle(req); // no response for notification assert.equal(res, undefined); // post-processor throws error object with updated properties and receiving correct error object rpc = await (new RPC(undefined, undefined, { postProcessors: [(request, rpc) => { throw { code: -1, message: "ER1", data: null }; }] // eslint-disable-line no-unused-vars })).init(); await rpc.putMethod(errMethodDesc, () => 0); req = RPC.request(1, "error"); res = await rpc.execute(req); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], -1); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], "ER1"); assert.deepEqual(res[RPC.ERROR][RPC.ERROR_DATA], null); req = RPC.notification("error"); res = await rpc.executeSingle(req); // no response for notification assert.equal(res, undefined); // post-processor throws error object with updated properties and receiving correct error object rpc = await (new RPC(undefined, undefined, { postProcessors: [(request, rpc) => { throw { code: -2, data: "test" }; }] // eslint-disable-line no-unused-vars })).init(); await rpc.putMethod(errMethodDesc, () => 0); req = RPC.request(1, "error"); res = await rpc.execute(req); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], -2); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], "err2"); assert.deepEqual(res[RPC.ERROR][RPC.ERROR_DATA], "test"); req = RPC.notification("error"); res = await rpc.executeSingle(req); // no response for notification assert.equal(res, undefined); // post-processor throws undefined error code rpc = await (new RPC(undefined, undefined, { postProcessors: [(request, rpc) => { throw -3; }] // eslint-disable-line no-unused-vars })).init(); await rpc.putMethod(errMethodDesc, () => 0); req = RPC.request(1, "error"); res = await rpc.execute(req); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], RPC.ERROR_32050[RPC.ERROR_CODE]); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], RPC.ERROR_32050[RPC.ERROR_MESSAGE]); assert.deepEqual(res[RPC.ERROR][RPC.ERROR_DATA], -3); req = RPC.notification("error"); res = await rpc.executeSingle(req); // no response for notification assert.equal(res, undefined); // post-processor throws undefined error code rpc = await (new RPC(undefined, undefined, { postProcessors: [(request, rpc) => { throw { code: -3 }; }] // eslint-disable-line no-unused-vars })).init(); await rpc.putMethod(errMethodDesc, () => 0); req = RPC.request(1, "error"); res = await rpc.execute(req); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], RPC.ERROR_32050[RPC.ERROR_CODE]); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], RPC.ERROR_32050[RPC.ERROR_MESSAGE]); assert.deepEqual(res[RPC.ERROR][RPC.ERROR_DATA], { code: -3 }); req = RPC.notification("error"); res = await rpc.executeSingle(req); // no response for notification assert.equal(res, undefined); rpc = await (new RPC(undefined, undefined)).init(); await rpc.putMethod(errMethodDesc, () => 0); // additional pre-processor throws error code and receiving full predefined error req = RPC.request(1, "error"); res = await rpc.execute(req, { preProcessors: [(request, rpc) => { throw -1; }] // eslint-disable-line no-unused-vars }); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], -1); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], "err1"); assert.deepEqual(res[RPC.ERROR][RPC.ERROR_DATA], "err1 desc"); req = RPC.notification("error"); res = await rpc.executeSingle(req, { preProcessors: [(request, rpc) => { throw -1; }] // eslint-disable-line no-unused-vars }); // no response for notification assert.equal(res, undefined); // pre-processor throws error code and receiving full predefined error req = RPC.request(1, "error"); res = await rpc.execute(req, { preProcessors: [(request, rpc) => { throw -32040; }] // eslint-disable-line no-unused-vars }); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], RPC.ERROR_32040[RPC.ERROR_CODE]); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], RPC.ERROR_32040[RPC.ERROR_MESSAGE]); assert.deepEqual(res[RPC.ERROR][RPC.ERROR_DATA], undefined); req = RPC.notification("error"); res = await rpc.executeSingle(req, { preProcessors: [(request, rpc) => { throw -32040; }] // eslint-disable-line no-unused-vars }); // no response for notification assert.equal(res, undefined); // pre-processor throws error object with updated properties and receiving correct error object req = RPC.request(1, "error"); res = await rpc.execute(req, { preProcessors: [(request, rpc) => { throw { code: -1, message: "ER1", data: null }; }] // eslint-disable-line no-unused-vars }); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], -1); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], "ER1"); assert.deepEqual(res[RPC.ERROR][RPC.ERROR_DATA], null); req = RPC.notification("error"); res = await rpc.executeSingle(req, { preProcessors: [(request, rpc) => { throw { code: -1, message: "ER1", data: null }; }] // eslint-disable-line no-unused-vars }); // no response for notification assert.equal(res, undefined); // pre-processor throws error object with updated properties and receiving correct error object req = RPC.request(1, "error"); res = await rpc.execute(req, { preProcessors: [(request, rpc) => { throw { code: -2, data: "test" }; }] // eslint-disable-line no-unused-vars }); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], -2); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], "err2"); assert.deepEqual(res[RPC.ERROR][RPC.ERROR_DATA], "test"); req = RPC.notification("error"); res = await rpc.executeSingle(req, { preProcessors: [(request, rpc) => { throw { code: -2, data: "test" }; }] // eslint-disable-line no-unused-vars }); // no response for notification assert.equal(res, undefined); // pre-processor throws undefined error code req = RPC.request(1, "error"); res = await rpc.execute(req, { preProcessors: [(request, rpc) => { throw -3; }] // eslint-disable-line no-unused-vars }); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], RPC.ERROR_32010[RPC.ERROR_CODE]); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], RPC.ERROR_32010[RPC.ERROR_MESSAGE]); assert.deepEqual(res[RPC.ERROR][RPC.ERROR_DATA], -3); req = RPC.notification("error"); res = await rpc.executeSingle(req, { preProcessors: [(request, rpc) => { throw -3; }] // eslint-disable-line no-unused-vars }); // no response for notification assert.equal(res, undefined); // pre-processor throws undefined error code req = RPC.request(1, "error"); res = await rpc.execute(req, { preProcessors: [(request, rpc) => { throw { code: -3 }; }] // eslint-disable-line no-unused-vars }); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], RPC.ERROR_32010[RPC.ERROR_CODE]); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], RPC.ERROR_32010[RPC.ERROR_MESSAGE]); assert.deepEqual(res[RPC.ERROR][RPC.ERROR_DATA], { code: -3 }); req = RPC.notification("error"); res = await rpc.executeSingle(req, { preProcessors: [(request, rpc) => { throw { code: -3 }; }] // eslint-disable-line no-unused-vars }); // no response for notification assert.equal(res, undefined); // additional post-processor throws error code and receiving full predefined error req = RPC.request(1, "error"); res = await rpc.execute(req, { postProcessors: [(request, rpc) => { throw -1; }] // eslint-disable-line no-unused-vars }); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], -1); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], "err1"); assert.deepEqual(res[RPC.ERROR][RPC.ERROR_DATA], "err1 desc"); req = RPC.notification("error"); res = await rpc.executeSingle(req, { postProcessors: [(request, rpc) => { throw -1; }] // eslint-disable-line no-unused-vars }); // no response for notification assert.equal(res, undefined); // post-processor throws error code and receiving full predefined error req = RPC.request(1, "error"); res = await rpc.execute(req, { postProcessors: [(request, rpc) => { throw -32040; }] // eslint-disable-line no-unused-vars }); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], RPC.ERROR_32040[RPC.ERROR_CODE]); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], RPC.ERROR_32040[RPC.ERROR_MESSAGE]); assert.deepEqual(res[RPC.ERROR][RPC.ERROR_DATA], undefined); req = RPC.notification("error"); res = await rpc.executeSingle(req, { postProcessors: [(request, rpc) => { throw -32040; }] // eslint-disable-line no-unused-vars }); // no response for notification assert.equal(res, undefined); // post-processor throws error object with updated properties and receiving correct error object req = RPC.request(1, "error"); res = await rpc.execute(req, { postProcessors: [(request, rpc) => { throw { code: -1, message: "ER1", data: null }; }] // eslint-disable-line no-unused-vars }); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], -1); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], "ER1"); assert.deepEqual(res[RPC.ERROR][RPC.ERROR_DATA], null); req = RPC.notification("error"); res = await rpc.executeSingle(req, { postProcessors: [(request, rpc) => { throw { code: -1, message: "ER1", data: null }; }] // eslint-disable-line no-unused-vars }); // no response for notification assert.equal(res, undefined); // post-processor throws error object with updated properties and receiving correct error object req = RPC.request(1, "error"); res = await rpc.execute(req, { postProcessors: [(request, rpc) => { throw { code: -2, data: "test" }; }] // eslint-disable-line no-unused-vars }); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], -2); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], "err2"); assert.deepEqual(res[RPC.ERROR][RPC.ERROR_DATA], "test"); req = RPC.notification("error"); res = await rpc.executeSingle(req, { postProcessors: [(request, rpc) => { throw { code: -2, data: "test" }; }] // eslint-disable-line no-unused-vars }); // no response for notification assert.equal(res, undefined); // post-processor throws undefined error code req = RPC.request(1, "error"); res = await rpc.execute(req, { postProcessors: [(request, rpc) => { throw -3; }] // eslint-disable-line no-unused-vars }); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], RPC.ERROR_32050[RPC.ERROR_CODE]); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], RPC.ERROR_32050[RPC.ERROR_MESSAGE]); assert.deepEqual(res[RPC.ERROR][RPC.ERROR_DATA], -3); req = RPC.notification("error"); res = await rpc.executeSingle(req, { postProcessors: [(request, rpc) => { throw -3; }] // eslint-disable-line no-unused-vars }); // no response for notification assert.equal(res, undefined); // post-processor throws undefined error code req = RPC.request(1, "error"); res = await rpc.execute(req, { postProcessors: [(request, rpc) => { throw { code: -3 }; }] // eslint-disable-line no-unused-vars }); assert.equal(res[RPC.ERROR][RPC.ERROR_CODE], RPC.ERROR_32050[RPC.ERROR_CODE]); assert.equal(res[RPC.ERROR][RPC.ERROR_MESSAGE], RPC.ERROR_32050[RPC.ERROR_MESSAGE]); assert.deepEqual(res[RPC.ERROR][RPC.ERROR_DATA], { code: -3 }); req = RPC.notification("error"); res = await rpc.executeSingle(req, { postProcessors: [(request, rpc) => { throw { code: -3 }; }] // eslint-disable-line no-unused-vars }); // no response for notification assert.equal(res, undefined); }); it("replacing configuration", async function () { let rpc; let req; let res; // create RPC handler with empty config rpc = await (new RPC()).init(); req = RPC.notification(RPC.RPC_DISCOVER); res = await rpc.execute(req); assert.equal(typeof res, "undefined"); req = RPC.request(1, RPC.RPC_DISCOVER); res = await rpc.execute(req); assert.equal(typeof res, "object"); assert.equal(res[RPC.JSONRPC], RPC.VERSION); assert.equal(res[RPC.ID], 1); assert.equal(typeof res[RPC.ERROR]