Skip to content
This repository was archived by the owner on May 17, 2019. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions src/__tests__/create-mock-emitter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// @flow
import type {IEmitter} from '../types.js';

function createMockEmitter<TProps>(props: TProps): IEmitter {
const emitter = {
from: () => {
return emitter;
},
emit: () => {},
setFrequency: () => {},
teardown: () => {},
map: () => {},
on: () => {},
off: () => {},
mapEvent: () => {},
handleEvent: () => {},
flush: () => undefined,
...props,
};
return emitter;
}

export default createMockEmitter;
40 changes: 40 additions & 0 deletions src/__tests__/index.browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,47 @@
*/

import test from 'tape-cup';
import MockEmitter from 'events';

import App, {createPlugin, createToken} from 'fusion-core';
import {FetchToken} from 'fusion-tokens';
import {getSimulator} from 'fusion-test-utils';
import type {Token} from 'fusion-core';
import {UniversalEventsToken} from 'fusion-plugin-universal-events';

import RPCPlugin from '../browser';
import type {IEmitter} from '../types.js';
import createMockEmitter from './create-mock-emitter';

const MockPluginToken: Token<any> = createToken('test-plugin-token');
function createTestFixture() {
const mockFetch = (...args) =>
Promise.resolve({json: () => ({status: 'success', data: args})});
const mockEmitter: IEmitter = (new MockEmitter(): any);
const mockEmitterPlugin = createPlugin({
provides: () => mockEmitter,
});

const app = new App('content', el => el);
// $FlowFixMe
app.register(FetchToken, mockFetch);
app.register(UniversalEventsToken, mockEmitterPlugin);
app.register(MockPluginToken, RPCPlugin);
return app;
}

test('success status request', t => {
const mockEmitter = createMockEmitter({
emit(type, payload) {
t.equal(type, 'rpc:method-client');
t.equal(payload.method, 'test');
t.equal(payload.status, 'success');
t.equal(typeof payload.timing, 'number');
},
});
const app = createTestFixture();
// $FlowFixMe
app.register(UniversalEventsToken, mockEmitter);

let wasResolved = false;
getSimulator(
Expand Down Expand Up @@ -65,7 +84,17 @@ test('success status request', t => {
});

test('success status request w/args and header', t => {
const mockEmitter = createMockEmitter({
emit(type, payload) {
t.equal(type, 'rpc:method-client');
t.equal(payload.method, 'test');
t.equal(payload.status, 'success');
t.equal(typeof payload.timing, 'number');
},
});
const app = createTestFixture();
// $FlowFixMe
app.register(UniversalEventsToken, mockEmitter);

let wasResolved = false;
getSimulator(
Expand Down Expand Up @@ -109,10 +138,21 @@ test('success status request w/args and header', t => {
test('failure status request', t => {
const mockFetchAsFailure = () =>
Promise.resolve({json: () => ({status: 'failure', data: 'failure data'})});
const mockEmitter = createMockEmitter({
emit(type, payload) {
t.equal(type, 'rpc:method-client');
t.equal(payload.method, 'test');
t.equal(payload.status, 'failure');
t.equal(typeof payload.timing, 'number');
t.equal(payload.error, 'failure data');
},
});

const app = createTestFixture();
// $FlowFixMe
app.register(FetchToken, mockFetchAsFailure);
// $FlowFixMe
app.register(UniversalEventsToken, mockEmitter);

let wasResolved = false;
getSimulator(
Expand Down
27 changes: 8 additions & 19 deletions src/__tests__/index.node.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,20 @@ import RPCPlugin from '../server';
import type {IEmitter, RPCServiceType} from '../types.js';
import MockRPCPlugin from '../mock.js';
import ResponseError from '../response-error.js';
import createMockEmitter from './create-mock-emitter';

const MockPluginToken: Token<RPCServiceType> = createToken('test-plugin-token');
const MOCK_JSON_PARAMS = {test: 'test-args'};

const mockService: RPCServiceType = getService(() => {
const app = new App('content', el => el);
const mockEmitter: IEmitter = (new MockEmitter(): any);
// $FlowFixMe
mockEmitter.from = () => mockEmitter;
const mockEmitterPlugin = createPlugin({
provides: () => mockEmitter,
});
app.register(UniversalEventsToken, mockEmitterPlugin);
app.register(RPCHandlersToken, {});
return app;
}, MockRPCPlugin);
Expand All @@ -47,25 +55,6 @@ function createTestFixture() {
return app;
}

function createMockEmitter<TProps>(props: TProps): IEmitter {
const emitter = {
from: () => {
return emitter;
},
emit: () => {},
setFrequency: () => {},
teardown: () => {},
map: () => {},
on: () => {},
off: () => {},
mapEvent: () => {},
handleEvent: () => {},
flush: () => undefined,
...props,
};
return emitter;
}

function mockRequest() {
const req = new MockReq({
method: 'POST',
Expand Down
11 changes: 10 additions & 1 deletion src/__tests__/test-mock.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/

import test from 'tape-cup';
import MockEmitter from 'events';

import App, {
createPlugin,
Expand All @@ -15,17 +16,25 @@ import App, {
type Context,
} from 'fusion-core';
import {getSimulator} from 'fusion-test-utils';
import {UniversalEventsToken} from 'fusion-plugin-universal-events';

import {RPCHandlersToken} from '../tokens';
import RPCPlugin from '../mock';
import type {RPCServiceType} from '../types.js';
import type {RPCServiceType, IEmitter} from '../types.js';

const MockPluginToken: Token<RPCServiceType> = createToken('test-plugin-token');
const mockCtx = (({}: any): Context);
function createTestFixture() {
const mockHandlers = {};
const mockEmitter: IEmitter = (new MockEmitter(): any);
// $FlowFixMe
mockEmitter.from = () => mockEmitter;
const mockEmitterPlugin = createPlugin({
provides: () => mockEmitter,
});

const app = new App('content', el => el);
app.register(UniversalEventsToken, mockEmitterPlugin);
app.register(RPCHandlersToken, mockHandlers);
app.register(MockPluginToken, RPCPlugin);
return app;
Expand Down
27 changes: 24 additions & 3 deletions src/browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,24 @@
/* eslint-env browser */

import {createPlugin, type Context} from 'fusion-core';
import {UniversalEventsToken} from 'fusion-plugin-universal-events';
import {FetchToken} from 'fusion-tokens';
import type {Fetch} from 'fusion-tokens';

import type {HandlerType} from './tokens.js';
import type {RPCPluginType, IEmitter} from './types.js';

const statKey = 'rpc:method-client';

class RPC {
ctx: ?Context;
emitter: ?IEmitter;
handlers: ?HandlerType;
fetch: ?Fetch;

constructor(fetch: Fetch) {
constructor(fetch: Fetch, emitter: IEmitter) {
this.fetch = fetch;
this.emitter = emitter;
}

request<TArgs, TResult>(
Expand All @@ -33,7 +37,12 @@ class RPC {
if (!this.fetch) {
throw new Error('fusion-plugin-rpc requires `fetch`');
}
if (!this.emitter) {
throw new Error('Missing emitter registered to UniversalEventsToken');
}
const fetch = this.fetch;
const emitter = this.emitter;
const startTime = Date.now();

// TODO(#3) handle args instanceof FormData
return fetch(`/api/${rpcId}`, {
Expand All @@ -48,8 +57,19 @@ class RPC {
.then(args => {
const {status, data} = args;
if (status === 'success') {
emitter.emit(statKey, {
method: rpcId,
status: 'success',
timing: Date.now() - startTime,
});
return data;
} else {
emitter.emit(statKey, {
method: rpcId,
error: data,
status: 'failure',
timing: Date.now() - startTime,
});
return Promise.reject(data);
}
});
Expand All @@ -60,11 +80,12 @@ const pluginFactory: () => RPCPluginType = () =>
createPlugin({
deps: {
fetch: FetchToken,
emitter: UniversalEventsToken,
},
provides: deps => {
const {fetch = window.fetch} = deps;
const {fetch = window.fetch, emitter} = deps;

return {from: () => new RPC(fetch)};
return {from: () => new RPC(fetch, emitter)};
},
});

Expand Down
2 changes: 2 additions & 0 deletions src/mock.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import {createPlugin} from 'fusion-core';
import type {Context} from 'fusion-core';
import type {Fetch} from 'fusion-tokens';
import {UniversalEventsToken} from 'fusion-plugin-universal-events';

import MissingHandlerError from './missing-handler-error';
import {RPCHandlersToken} from './tokens';
Expand Down Expand Up @@ -40,6 +41,7 @@ class RPC {
const plugin: RPCPluginType = createPlugin({
deps: {
handlers: RPCHandlersToken,
emitter: UniversalEventsToken,
},
provides: ({handlers} = {}) => {
return {from: () => new RPC(handlers)};
Expand Down
2 changes: 1 addition & 1 deletion src/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class RPC {
handlers: ?HandlerType;
fetch: ?Fetch;

constructor(emitter: any, handlers: any, ctx: Context): RPC {
constructor(emitter: IEmitter, handlers: any, ctx: Context): RPC {
if (!ctx || !ctx.headers) {
throw new Error('fusion-plugin-rpc requires `ctx`');
}
Expand Down
2 changes: 1 addition & 1 deletion src/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
type ExtractReturnType = <V>(() => V) => V;

export type RPCDepsType = {
emitter?: typeof UniversalEventsToken,
emitter: typeof UniversalEventsToken,
handlers?: typeof RPCHandlersToken,
bodyParserOptions?: typeof BodyParserOptionsToken.optional,
fetch?: typeof FetchToken,
Expand Down