import React, { createContext, useContext } from 'react';
import { cleanup, render } from '@mongodb-js/testing-library-compass';
import { expect } from 'chai';
import sinon from 'sinon';
import {
AppRegistryProvider,
registerHadronPlugin,
createActivateHelpers,
createServiceLocator,
} from './';
import { createStore } from 'redux';
import { connect } from 'react-redux';
import { EventEmitter } from 'events';
describe('registerHadronPlugin', function () {
afterEach(cleanup);
it('allows registering plugins with a reflux-ish store', function () {
const component = sinon.stub().callsFake(() => <>>);
const activate = sinon.stub().returns({ store: { state: { foo: 'bar' } } });
const Plugin = registerHadronPlugin({
name: 'refluxish',
component,
activate,
});
expect(Plugin.displayName).to.equal('refluxish');
render(
);
expect(activate).to.have.been.calledOnce;
expect(activate.firstCall.args[0]).to.deep.equal({});
expect(activate.firstCall.args[1]).to.have.property('localAppRegistry');
expect(activate.firstCall.args[1]).to.have.property('globalAppRegistry');
expect(component).to.have.been.calledOnceWith({
store: { state: { foo: 'bar' } },
actions: undefined,
foo: 'bar',
});
});
it('allows registering plugins with a proper reflux store', function () {
const component = sinon.stub().callsFake(() => <>>);
const store = { state: { foo: 'bar' } };
const activate = sinon.stub().returns({ store });
const Plugin = registerHadronPlugin({
name: 'reflux',
component,
activate,
});
expect(Plugin.displayName).to.equal('reflux');
render(
);
expect(activate).to.have.been.calledOnce;
expect(activate.firstCall.args[0]).to.deep.equal({});
expect(activate.firstCall.args[1]).to.have.property('localAppRegistry');
expect(activate.firstCall.args[1]).to.have.property('globalAppRegistry');
expect(component).to.have.been.calledOnceWith({
store,
actions: undefined,
foo: 'bar',
});
});
it('allows registering plugins with a redux store', function () {
const connector = connect(({ counter }) => ({ counter }));
const component = sinon.stub().callsFake(() => <>>);
const store = createStore(
(state: { counter: number } | undefined, action: { type: 'inc' }) => {
state ??= { counter: 0 };
if (action.type === 'inc') return { counter: state.counter + 1 };
return state;
}
);
const activate = sinon.stub().returns({ store });
const Plugin = registerHadronPlugin({
name: 'redux',
component: connector(component),
activate,
});
expect(Plugin.displayName).to.equal('redux');
render(
);
expect(activate).to.have.been.calledOnce;
expect(activate.firstCall.args[0]).to.deep.equal({});
expect(activate.firstCall.args[1]).to.have.property('localAppRegistry');
expect(activate.firstCall.args[1]).to.have.property('globalAppRegistry');
expect(component).to.have.been.calledWith({
counter: 0,
dispatch: store.dispatch,
});
store.dispatch({ type: 'inc' });
expect(component).to.have.been.calledWith({
counter: 1,
dispatch: store.dispatch,
});
});
it('allows registering a plugin with external services dependencies', function () {
const dummy = { value: 'blah' };
const blahContext = createContext(dummy);
const useBlah = createServiceLocator(() => useContext(blahContext));
const connector = connect();
const component = sinon.stub().callsFake(() => <>>);
const store = createStore(() => ({}));
const activate = sinon.stub().returns({ store });
const Plugin = registerHadronPlugin(
{
name: 'service1',
component: connector(component),
activate,
},
{
blah: useBlah,
}
);
expect(Plugin.displayName).to.equal('service1');
render(
);
expect(activate.firstCall.args[1]).to.have.property('blah', dummy);
});
});
describe('ActivateHelpers', function () {
describe('on', function () {
it('should subscribe to event emitter', function () {
const helpers = createActivateHelpers();
const emitter = new EventEmitter();
expect(emitter.listenerCount('foo')).to.eq(0);
helpers.on(emitter, 'foo', () => {});
expect(emitter.listenerCount('foo')).to.eq(1);
});
});
describe('cleanup', function () {
it('should remove listeners registered with on', function () {
const helpers = createActivateHelpers();
const emitter = new EventEmitter();
helpers.on(emitter, 'foo', () => {});
helpers.cleanup();
expect(emitter.listenerCount('foo')).to.eq(0);
});
});
describe('addCleanup', function () {
it('should add custom cleanup function and call it when cleanup is called', function () {
const helpers = createActivateHelpers();
const cleanupFn = sinon.spy();
helpers.addCleanup(cleanupFn);
helpers.cleanup();
expect(cleanupFn).to.have.been.calledOnce;
});
});
});