Commit 0036550a authored by picklesrus's avatar picklesrus

Move timeout id out of state to a member variable and add some unittests.

parent fac3ccad
...@@ -30,15 +30,14 @@ class Navigation extends React.Component { ...@@ -30,15 +30,14 @@ class Navigation extends React.Component {
'handleSearchSubmit', 'handleSearchSubmit',
'pollForMessages' 'pollForMessages'
]); ]);
this.state = { // Keep the timeout id so we can cancel it (e.g. when we unmount)
messageCountIntervalId: -1 // javascript method interval id for getting messsage count. this.messageCountTimeoutId = -1;
};
} }
componentDidMount () { componentDidMount () {
if (this.props.user) { if (this.props.user) {
// Setup polling for messages to start in 2 minutes. // Setup polling for messages to start in 2 minutes.
const twoMinInMs = 2 * 60 * 1000; const twoMinInMs = 2 * 60 * 1000;
setTimeout(this.pollForMessages.bind(this, twoMinInMs), twoMinInMs); this.messageCountTimeoutId = setTimeout(this.pollForMessages.bind(this, twoMinInMs), twoMinInMs);
} }
} }
componentDidUpdate (prevProps) { componentDidUpdate (prevProps) {
...@@ -46,25 +45,21 @@ class Navigation extends React.Component { ...@@ -46,25 +45,21 @@ class Navigation extends React.Component {
this.props.handleCloseAccountNav(); this.props.handleCloseAccountNav();
if (this.props.user) { if (this.props.user) {
const twoMinInMs = 2 * 60 * 1000; const twoMinInMs = 2 * 60 * 1000;
setTimeout(this.pollForMessages.bind(this, twoMinInMs), twoMinInMs); this.messageCountTimeoutId = setTimeout(this.pollForMessages.bind(this, twoMinInMs), twoMinInMs);
} else { } else {
// clear message count check, and set to default id. // clear message count check, and set to default id.
clearTimeout(this.state.messageCountIntervalId); clearTimeout(this.messageCountTimeoutId);
this.props.setMessageCount(0); this.props.setMessageCount(0);
this.setState({ // eslint-disable-line react/no-did-update-set-state this.messageCountTimeoutId = -1;
messageCountIntervalId: -1
});
} }
} }
} }
componentWillUnmount () { componentWillUnmount () {
// clear message interval if it exists // clear message interval if it exists
if (this.state.messageCountIntervalId !== -1) { if (this.messageCountTimeoutId !== -1) {
clearTimeout(this.state.messageCountIntervalId); clearTimeout(this.messageCountTimeoutId);
this.props.setMessageCount(0); this.props.setMessageCount(0);
this.setState({ this.messageCountTimeoutId = -1;
messageCountIntervalId: -1
});
} }
} }
getProfileUrl () { getProfileUrl () {
...@@ -82,9 +77,7 @@ class Navigation extends React.Component { ...@@ -82,9 +77,7 @@ class Navigation extends React.Component {
const timeoutId = setTimeout(() => { const timeoutId = setTimeout(() => {
this.pollForMessages(nextFetch); this.pollForMessages(nextFetch);
}, nextFetch); }, nextFetch);
this.setState({ // eslint-disable-line react/no-did-mount-set-state this.messageCountTimeoutId = timeoutId;
messageCountIntervalId: timeoutId
});
} }
} }
......
...@@ -128,14 +128,49 @@ describe('Navigation', () => { ...@@ -128,14 +128,49 @@ describe('Navigation', () => {
childContextTypes: {store} childContextTypes: {store}
}); });
intlWrapper.children().find('Navigation') const navInstance = intlWrapper.children().find('Navigation')
.instance(); .instance();
const twoMin = 2 * 60 * 1000; const twoMin = 2 * 60 * 1000;
expect(setTimeout).toHaveBeenLastCalledWith(expect.any(Function), twoMin); expect(setTimeout).toHaveBeenLastCalledWith(expect.any(Function), twoMin);
expect(navInstance.messageCountTimeoutId).not.toEqual(-1);
// Advance timers passed the intial two minutes. // Advance timers passed the intial two minutes.
jest.advanceTimersByTime(twoMin + 1); jest.advanceTimersByTime(twoMin + 1);
expect(setTimeout).toHaveBeenLastCalledWith(expect.any(Function), twoMin * 2); expect(setTimeout).toHaveBeenLastCalledWith(expect.any(Function), twoMin * 2);
expect(props.getMessageCount).toHaveBeenCalled(); expect(props.getMessageCount).toHaveBeenCalled();
expect(navInstance.messageCountTimeoutId).not.toEqual(-1);
});
test('Component cancels timers when it unmounts', () => {
store = mockStore({
navigation: {
registrationOpen: false
},
messageCount: {
messageCount: 5
}
});
const props = {
user: {
thumbnailUrl: 'scratch.mit.edu',
username: 'auser'
},
getMessageCount: jest.fn()
};
const intlWrapper = mountWithIntl(
<Navigation
{...props}
/>, {context: {store},
childContextTypes: {store}
});
const navInstance = intlWrapper.children().find('Navigation')
.instance();
const twoMin = 2 * 60 * 1000;
expect(setTimeout).toHaveBeenLastCalledWith(expect.any(Function), twoMin);
expect(navInstance.messageCountTimeoutId).not.toEqual(-1);
debugger;
navInstance.componentWillUnmount();
expect(clearTimeout).toHaveBeenCalledWith(expect.any(Number));
expect(navInstance.messageCountTimeoutId).toEqual(-1);
}); });
test('pollForMessages polls for messages 5 times', () => { test('pollForMessages polls for messages 5 times', () => {
...@@ -170,8 +205,8 @@ describe('Navigation', () => { ...@@ -170,8 +205,8 @@ describe('Navigation', () => {
let twoMinInMs = 2 * 60 * 1000; // 2 minutes in ms. let twoMinInMs = 2 * 60 * 1000; // 2 minutes in ms.
navInstance.pollForMessages(twoMinInMs); navInstance.pollForMessages(twoMinInMs);
expect(navInstance.messageCountTimeoutId).not.toEqual(-1);
// Check that we set the timeout to backoff exponentially // Check that we set the timeout to backoff exponentially
for (let count = 1; count < 5; ++count) { for (let count = 1; count < 5; ++count) {
jest.advanceTimersByTime(twoMinInMs + 1); jest.advanceTimersByTime(twoMinInMs + 1);
expect(setTimeout).toHaveBeenLastCalledWith(expect.any(Function), twoMinInMs * 2); expect(setTimeout).toHaveBeenLastCalledWith(expect.any(Function), twoMinInMs * 2);
...@@ -187,5 +222,6 @@ describe('Navigation', () => { ...@@ -187,5 +222,6 @@ describe('Navigation', () => {
// setTimeout happens 1 fewer since the original call to // setTimeout happens 1 fewer since the original call to
// pollForMessages isn't counted here. // pollForMessages isn't counted here.
expect(setTimeout).toHaveBeenCalledTimes(4); expect(setTimeout).toHaveBeenCalledTimes(4);
expect(navInstance.messageCountTimeoutId).not.toEqual(-1);
}); });
}); });
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment