Skip to content

Commit

Permalink
🐛 Fix #150: Reset global handler resolution state when a new GlobalHo…
Browse files Browse the repository at this point in the history
…tKeys component is mounted
  • Loading branch information
greena13 committed May 18, 2019
1 parent bcddc86 commit eeabff3
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/lib/strategies/GlobalKeyEventStrategy.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ class GlobalKeyEventStrategy extends AbstractKeyEventStrategy {

this._updateDocumentHandlers();

this._initHandlerResolutionState();

this.logger.debug(
this._logPrefix(componentId, {eventId: false}),
'Mounted.',
Expand Down
106 changes: 106 additions & 0 deletions test/GlobalHotKeys/MatchingKeyMapAfterRemount.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import {mount} from 'enzyme';
import {expect} from 'chai';
import sinon from 'sinon';
import simulant from 'simulant';
import React, {Component} from 'react'

import KeyCode from '../support/Key';
import {GlobalHotKeys} from '../../src';

describe('Matching key map after remount for a GlobalHotKeys component:', function () {
beforeEach(function () {
const keyMap = this.keyMap = {
'ACTION_A': 'a',
};

const keyMap2 = this.keyMap2 = {
'ACTION_B': 'b',
};

this.handler = sinon.spy();
this.handler2 = sinon.spy();

const handlers = this.handlers = {
'ACTION_A': this.handler,
};

const handlers2 = this.handlers2 = {
'ACTION_B': this.handler2,
};

class ToggleComponent extends Component {
render(){
const { secondKeyMapActive } = this.props;

return (
<div>
<GlobalHotKeys keyMap={keyMap} handlers={handlers} />
{ secondKeyMapActive && <GlobalHotKeys keyMap={keyMap2} handlers={handlers2} />}
</div>
);
}
}

this.reactDiv = document.createElement('div');
document.body.appendChild(this.reactDiv);

this.wrapper = mount(
<ToggleComponent secondKeyMapActive={true} />,
{ attachTo: this.reactDiv }
);
});

after(function() {
document.body.removeChild(this.reactDiv);
});

describe.only('when two GlobalHotKeys components are mounted, unmounted and remounted', () => {
it('then both of their key maps work while they are mounted and not, when they aren\'t (BUG: https://github.com/greena13/react-hotkeys/issues/150)', function() {
simulant.fire(this.reactDiv, 'keydown', { key: KeyCode.A });
simulant.fire(this.reactDiv, 'keypress', { key: KeyCode.A });
simulant.fire(this.reactDiv, 'keyup', { key: KeyCode.A });

expect(this.handler).to.have.been.calledOnce;

simulant.fire(this.reactDiv, 'keydown', { key: KeyCode.B });
simulant.fire(this.reactDiv, 'keypress', { key: KeyCode.B });
simulant.fire(this.reactDiv, 'keyup', { key: KeyCode.B });

expect(this.handler2).to.have.been.calledOnce;

/**
* Unmount the second GlobalHotKeys component
*/
this.wrapper.setProps({ secondKeyMapActive: false });

simulant.fire(this.reactDiv, 'keydown', { key: KeyCode.A });
simulant.fire(this.reactDiv, 'keypress', { key: KeyCode.A });
simulant.fire(this.reactDiv, 'keyup', { key: KeyCode.A });

expect(this.handler).to.have.been.calledTwice;

simulant.fire(this.reactDiv, 'keydown', { key: KeyCode.B });
simulant.fire(this.reactDiv, 'keypress', { key: KeyCode.B });
simulant.fire(this.reactDiv, 'keyup', { key: KeyCode.B });

expect(this.handler2).to.have.been.calledOnce;

/**
* Re-mount the second GlobalHotKeys component
*/
this.wrapper.setProps({ secondKeyMapActive: true });

simulant.fire(this.reactDiv, 'keydown', { key: KeyCode.A });
simulant.fire(this.reactDiv, 'keypress', { key: KeyCode.A });
simulant.fire(this.reactDiv, 'keyup', { key: KeyCode.A });

expect(this.handler).to.have.been.calledThrice;

simulant.fire(this.reactDiv, 'keydown', { key: KeyCode.B });
simulant.fire(this.reactDiv, 'keypress', { key: KeyCode.B });
simulant.fire(this.reactDiv, 'keyup', { key: KeyCode.B });

expect(this.handler2).to.have.been.calledTwice;
});
});
});

0 comments on commit eeabff3

Please sign in to comment.