Skip to content
This repository has been archived by the owner on Jan 22, 2024. It is now read-only.

Commit

Permalink
Add tests and coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
Sebastien Corbin committed Aug 8, 2019
1 parent c240109 commit aa8b5a4
Show file tree
Hide file tree
Showing 5 changed files with 173 additions and 29 deletions.
53 changes: 31 additions & 22 deletions src/modules/Hash/withHashParameters.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,41 +24,50 @@ export const withHashParameters = (...parameters) => WrappedComponent =>
(typeof parameters[0] === 'string' && parameters[0].split(',')) || parameters[0];
}

getHashParameters = () => {
/**
* Returns the entries hash included in parameters.
*
* @return object
*/
const params = parse(window.location.hash, this.options);
return Object.entries(params).reduce((obj, [key, value]) => {
/**
* Return a filtered object with keys from `this.parameters`
*
* @param {{}} values
* @return {{}}
*/
getFilteredParams (values) {
return Object.entries(values).reduce((obj, [key, value]) => {
const newObj = obj;
if (this.parameters.includes(key)) {
newObj[key] = value;
}
return newObj;
}, {});
};
}

setHashParameters = values => {
/**
* Update the hash with values object, filtered by parameters
*
* If the values does not contain a parameter name, it will be removed
* from hash
*
* @return object
*/
/**
* Returns the filtered entries from hash.
*
* @return {{}}
*/
getHashParameters = () => {
const params = parse(window.location.hash, this.options);
return this.getFilteredParams(params);
};

/**
* Update the hash with values object, filtered by parameters
*
* If the values does not contain a parameter name or prameter is null,
* it will be removed from hash.
*
* @param {{}} values
* @return void
*/
setHashParameters = values => {
// Filter hash values on parameters
const newParams = {
...params,
...values,
const params = {
...parse(window.location.hash, this.options),
...this.getFilteredParams(values),
};

// Rebuild string and set hash
window.history.replaceState(window.history.state, '', `#${stringify(newParams, this.options)}`);
window.history.replaceState(window.history.state, '', `#${stringify(params, this.options)}`);
};

render () {
Expand Down
12 changes: 12 additions & 0 deletions src/modules/Hash/withHashParameters.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ it('should get correct parameters', () => {
expect(instance.getHashParameters()).toEqual({ myparam: 1 });
});

it('parameters should be versatile', () => {
const ComponentWithHash = withHashParameters(['myparam'])(Component);
const instance = new ComponentWithHash();

window.location.hash = '#myparam=1';
expect(instance.getHashParameters()).toEqual({ myparam: 1 });
});

it('should set correct parameters', () => {
const ComponentWithHash = withHashParameters('myparam')(Component);
const instance = new ComponentWithHash();
Expand All @@ -24,4 +32,8 @@ it('should set correct parameters', () => {
window.location.hash = '#foo=bar';
instance.setHashParameters({ myparam: 1 });
expect(window.location.hash).toEqual('#foo=bar&myparam=1');

window.location.hash = '#foo=bar';
instance.setHashParameters({ myparam: 0, baz: 1 });
expect(window.location.hash).toEqual('#foo=bar&myparam=0');
});
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ export class LayersTreeProvider extends React.Component {

resetState (state, callback = () => {}) {
const { setHashParameters } = this.props;

this.setState(state, () => {
callback();
const { onChange } = this.props;
Expand All @@ -143,7 +144,7 @@ export class LayersTreeProvider extends React.Component {
// Simplify the state from the map, and send it to hash
const activeLayers = [];
let table = null;
layersTreeState && layersTreeState.forEach((layerState, { layers: [layerId] }) => {
layersTreeState && layersTreeState.forEach((layerState, { layers: [layerId] = [] }) => {
if (layerState.active) {
activeLayers.push(layerId);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@ import renderer from 'react-test-renderer';

import { LayersTreeProvider } from './LayersTreeProvider';
import { connectLayersTree } from './context';
import { setLayerStateAction, initLayersStateAction } from '../../services/layersTreeUtils';
import * as layersTreeUtils from '../../services/layersTreeUtils';

jest.mock('../../services/layersTreeUtils', () => ({
initLayersStateAction: jest.fn(),
setLayerStateAction: jest.fn(),
}));
const initLayersStateAction = jest.spyOn(layersTreeUtils, 'initLayersStateAction').mockImplementation(jest.fn());
const setLayerStateAction = jest.spyOn(layersTreeUtils, 'setLayerStateAction').mockImplementation(jest.fn());

beforeEach(() => {
initLayersStateAction.mockClear();
Expand Down Expand Up @@ -160,3 +158,125 @@ it('should init layers state', () => {
});
expect(initLayersStateAction).toHaveBeenCalled();
});

it('should get layers state from hash', () => {
initLayersStateAction.mockRestore();

const layer1 = { layers: ['thatlayerid'] };
const layer2 = { layers: ['t'] };
const layersTreeState = new Map();

const getHashParameters = jest.fn(() => ({
layers: ['thatlayerid', 'b'],
}));

const instance = new LayersTreeProvider({
getHashParameters,
layersTree: [layer1, layer2],
});

instance.resetState = jest.fn(stateFn => stateFn({ layersTreeState }));
instance.initLayersState();
expect(getHashParameters).toHaveBeenCalled();
expect(instance.resetState.mock.calls[0][0]({ layersTreeState: new Map() })).toEqual({
layersTreeState: new Map([
[layer1, {
active: true,
opacity: 1,
}],
[layer2, {
active: false,
opacity: 1,
}],
]),
});

instance.props.getHashParameters = () => ({
layers: 'thatlayerid',
});
instance.initLayersState();
expect(instance.resetState.mock.calls[1][0]({ layersTreeState: new Map() })).toEqual({
layersTreeState: new Map([
[layer1, {
active: true,
opacity: 1,
}],
[layer2, {
active: false,
opacity: 1,
}],
]),
});

instance.props.getHashParameters = () => ({
layers: ['thatlayerid', 't'],
table: 'thatlayerid',
});
instance.initLayersState();
expect(instance.resetState.mock.calls[2][0]({ layersTreeState: new Map() })).toEqual({
layersTreeState: new Map([
[layer1, {
active: true,
opacity: 1,
table: true,
}],
[layer2, {
active: true,
opacity: 1,
}],
]),
});
});

it('should set layers state from hash', () => {
const setHashParameters = jest.fn();
const layer1 = { layers: ['thatlayerid'] };
const layer2 = { layers: ['t'] };
const layer3 = { };
const instance = new LayersTreeProvider({
setHashParameters,
onChange: jest.fn(),
});

instance.state = {
layersTreeState: new Map([
[layer1, {
active: true,
opacity: 1,
}],
[layer2, {
active: false,
opacity: 1,
}],
[layer3, {}],
]),
};
instance.setState = jest.fn(
(stateFn, callback) => callback(stateFn(instance.state)),
);
instance.initLayersState();

expect(setHashParameters).toHaveBeenCalledWith({
layers: ['thatlayerid'],
table: null,
});

instance.state = {
layersTreeState: new Map([
[layer1, {
active: true,
opacity: 1,
}],
[layer2, {
active: true,
opacity: 1,
table: true,
}],
]),
};
instance.initLayersState();
expect(setHashParameters).toHaveBeenCalledWith({
layers: ['thatlayerid', 't'],
table: 't',
});
});
4 changes: 3 additions & 1 deletion src/modules/Visualizer/services/layersTreeUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ export function initLayersStateAction (layersTree, { layers, table } = {}) {
: initialState.opacity;

if (layers) {
initialState.active = layers.includes(layerId);
initialState.active = (
Array.isArray(layers) && layers.includes(layerId))
|| layers === layerId;
}
if (table && table === layerId) {
initialState.table = true;
Expand Down

0 comments on commit aa8b5a4

Please sign in to comment.