non-array params coerced into array

master
Jason Staten 6 years ago
parent fe2036af64
commit 4e12ac99aa

@ -3,76 +3,68 @@ import JsonRpc, {ErrorCodes} from './JsonRpc';
const defer = (ms: number, val?: any) => const defer = (ms: number, val?: any) =>
new Promise(resolve => setTimeout(() => resolve(val), ms)); new Promise(resolve => setTimeout(() => resolve(val), ms));
it('handles requests', async () => { describe('handling requests', () => {
const rpc = new JsonRpc({ let rpc: any;
methods: { const buildRequest = (method: string, params?: any[] | object) => ({
hello: () => 'goodbye',
},
});
const request = {
id: 123,
jsonrpc: '2.0',
method: 'hello',
};
const response = await (rpc as any).handleRequest(request);
expect(response).toEqual({
jsonrpc: '2.0', jsonrpc: '2.0',
id: 123, id: 123,
result: 'goodbye', method,
params,
}); });
});
it('waits on promise results', async () => { beforeEach(() => {
const rpc = new JsonRpc({ rpc = new JsonRpc({
methods: { methods: {
deferred: () => Promise.resolve('deferredResult'), hello: (name: string) => `goodbye ${name}`,
}, canVote: (voter: {age: number}) => voter.age > 18,
deferred: () => Promise.resolve('deferredResult'),
blowUp: () => {
throw Error('BOOM!');
},
},
});
}); });
const request = { it('handles array params', async () => {
id: 123, const request = buildRequest('hello', ['Alice']);
jsonrpc: '2.0', const response = await rpc.handleRequest(request);
method: 'deferred',
};
const response = await (rpc as any).handleRequest(request); expect(response.jsonrpc).toEqual('2.0');
expect(response.result).toEqual('deferredResult'); expect(response.id).toEqual(request.id);
}); expect(response.result).toEqual('goodbye Alice');
});
it('errors on missing method', async () => { it('handles object params', async () => {
const rpc = new JsonRpc(); const request = buildRequest('canVote', {age: 22});
const response = await rpc.handleRequest(request);
const request = { expect(response.jsonrpc).toEqual('2.0');
id: 123, expect(response.id).toEqual(request.id);
jsonrpc: '2.0', expect(response.result).toEqual(true);
method: 'missing', });
};
const response = await (rpc as any).handleRequest(request); it('waits on promise results', async () => {
expect(response.id).toEqual(123); const request = buildRequest('deferred');
expect(response.error.code).toEqual(ErrorCodes.MethodNotFound); const response = await rpc.handleRequest(request);
});
it('errors on throwing method', async () => { expect(response.result).toEqual('deferredResult');
const rpc = new JsonRpc({
methods: {
blowUp: () => {
throw Error('BOOM!');
},
},
}); });
const request = { it('errors on missing method', async () => {
id: 123, const request = buildRequest('missing');
jsonrpc: '2.0', const response = await rpc.handleRequest(request);
method: 'blowUp',
};
const response = await (rpc as any).handleRequest(request); expect(response.id).toEqual(request.id);
expect(response.id).toEqual(123); expect(response.error.code).toEqual(ErrorCodes.MethodNotFound);
expect(response.error.code).toEqual(ErrorCodes.InternalError); });
it('errors on throwing method', async () => {
const request = buildRequest('blowUp');
const response = await rpc.handleRequest(request);
expect(response.id).toEqual(request.id);
expect(response.error.code).toEqual(ErrorCodes.InternalError);
});
}); });
describe('mounted', () => { describe('mounted', () => {

@ -59,6 +59,9 @@ const buildErrorResponse = (id: number) => (error: {
}, },
}); });
const ensureArray = (source: any) =>
Array.isArray(source) ? source : [source];
class JsonRpc { class JsonRpc {
private methods: Methods; private methods: Methods;
private destination: JsonRpcDestination; private destination: JsonRpcDestination;
@ -91,12 +94,21 @@ class JsonRpc {
return promise; return promise;
} }
mount(source: EventTarget) {
this.source = source;
source.addEventListener('message', this.handleMessage);
}
unmount() {
this.source.removeEventListener('message', this.handleMessage);
}
private handleRequest(request: JsonRpcRequest): Promise<JsonRpcResponse> { private handleRequest(request: JsonRpcRequest): Promise<JsonRpcResponse> {
return Promise.resolve() return Promise.resolve()
.then(() => { .then(() => {
const method = this.methods[request.method]; const method = this.methods[request.method];
return method return method
? method.apply(null, request.params) ? method.apply(null, ensureArray(request.params))
: Promise.reject({ : Promise.reject({
code: ErrorCodes.MethodNotFound, code: ErrorCodes.MethodNotFound,
message: 'Method not found', message: 'Method not found',
@ -132,15 +144,6 @@ class JsonRpc {
this.handleResponse(e.data); this.handleResponse(e.data);
} }
}; };
mount(source: EventTarget) {
this.source = source;
source.addEventListener('message', this.handleMessage);
}
unmount() {
this.source.removeEventListener('message', this.handleMessage);
}
} }
export default JsonRpc; export default JsonRpc;

Loading…
Cancel
Save