This repository has been archived by the owner on Apr 15, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 60
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #612 from LiskHQ/545-fix-offline-behaviour
Fix offline behaviour - Closes #545
- Loading branch information
Showing
9 changed files
with
202 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import React from 'react'; | ||
import { connect } from 'react-redux'; | ||
import styles from './offlineWrapper.css'; | ||
|
||
export const OfflineWrapperComponent = props => ( | ||
<span className={props.offline && styles.isOffline}> | ||
{ props.children } | ||
</span> | ||
); | ||
|
||
|
||
const mapStateToProps = state => ({ | ||
offline: state.loading && state.loading.indexOf('offline') > -1, | ||
}); | ||
|
||
export default connect(mapStateToProps)(OfflineWrapperComponent); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import React from 'react'; | ||
import { expect } from 'chai'; | ||
import { mount, shallow } from 'enzyme'; | ||
import { Provider } from 'react-redux'; | ||
import configureStore from 'redux-mock-store'; | ||
import OfflineWrapper, { OfflineWrapperComponent } from './index'; | ||
import styles from './offlineWrapper.css'; | ||
|
||
const fakeStore = configureStore(); | ||
|
||
describe('OfflineWrapperComponent', () => { | ||
it('renders props.children inside a span with "offline" class if props.offline', () => { | ||
const wrapper = shallow( | ||
<OfflineWrapperComponent offline={true}><h1 /> </OfflineWrapperComponent>); | ||
expect(wrapper).to.contain(<h1 />); | ||
expect(wrapper).to.have.className(styles.isOffline); | ||
}); | ||
|
||
it('renders without "offline" class if props.offline', () => { | ||
const wrapper = shallow( | ||
<OfflineWrapperComponent offline={false}><h1 /> </OfflineWrapperComponent>); | ||
expect(wrapper).not.to.have.className(styles.isOffline); | ||
}); | ||
}); | ||
|
||
describe('OfflineWrapper', () => { | ||
it('should set props.offline = false if "offline" is not in store.loading', () => { | ||
const store = fakeStore({ | ||
loading: [], | ||
}); | ||
const wrapper = mount(<Provider store={store}><OfflineWrapper /></Provider>); | ||
expect(wrapper.find(OfflineWrapperComponent).props().offline).to.equal(false); | ||
}); | ||
|
||
it('should set props.offline = true if "offline" is in store.loading', () => { | ||
const store = fakeStore({ | ||
loading: ['offline'], | ||
}); | ||
const wrapper = mount(<Provider store={store}><OfflineWrapper /></Provider>); | ||
expect(wrapper.find(OfflineWrapperComponent).props().offline).to.equal(true); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
.isOffline .disableWhenOffline { | ||
opacity: 0.5; | ||
pointer-events: none; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,13 @@ | ||
import metronomeMiddleware from './metronome'; | ||
import accountMiddleware from './account'; | ||
import loginMiddleware from './login'; | ||
import offlineMiddleware from './offline'; | ||
import notificationMiddleware from './notification'; | ||
|
||
export default [ | ||
loginMiddleware, | ||
metronomeMiddleware, | ||
accountMiddleware, | ||
offlineMiddleware, | ||
notificationMiddleware, | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import actionsType from '../../constants/actions'; | ||
import { successToastDisplayed, errorToastDisplayed } from '../../actions/toaster'; | ||
import { loadingStarted, loadingFinished } from '../../utils/loading'; | ||
|
||
const offlineMiddleware = store => next => (action) => { | ||
const state = store.getState(); | ||
switch (action.type) { | ||
case actionsType.activePeerUpdate: | ||
if (action.data.online === false && state.peers.status.online === true) { | ||
const address = `${state.peers.data.currentPeer}:${state.peers.data.port}`; | ||
store.dispatch(errorToastDisplayed({ label: `Failed to connect to node ${address}` })); | ||
loadingStarted('offline'); | ||
} else if (action.data.online === true && state.peers.status.online === false) { | ||
store.dispatch(successToastDisplayed({ label: 'Connection re-established' })); | ||
loadingFinished('offline'); | ||
} | ||
if (action.data.online !== state.peers.status.online) { | ||
next(action); | ||
} | ||
break; | ||
default: | ||
next(action); | ||
break; | ||
} | ||
}; | ||
|
||
export default offlineMiddleware; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import { expect } from 'chai'; | ||
import { spy, stub } from 'sinon'; | ||
import middleware from './offline'; | ||
import { successToastDisplayed, errorToastDisplayed } from '../../actions/toaster'; | ||
import actionType from '../../constants/actions'; | ||
|
||
|
||
describe('Offline middleware', () => { | ||
let store; | ||
let next; | ||
let action; | ||
let peers; | ||
|
||
beforeEach(() => { | ||
store = stub(); | ||
store.dispatch = spy(); | ||
next = spy(); | ||
action = { | ||
type: actionType.activePeerUpdate, | ||
data: {}, | ||
}; | ||
peers = { | ||
data: { | ||
port: 4000, | ||
currentPeer: 'localhost', | ||
}, | ||
status: {}, | ||
}; | ||
store.getState = () => ({ peers }); | ||
}); | ||
|
||
it('should pass the action to next middleware on some random action', () => { | ||
const randomAction = { | ||
type: 'TEST_ACTION', | ||
}; | ||
|
||
middleware(store)(next)(randomAction); | ||
expect(next).to.have.been.calledWith(randomAction); | ||
}); | ||
|
||
it(`should dispatch errorToastDisplayed on ${actionType.activePeerUpdate} action if !action.data.online and state.peer.status.online`, () => { | ||
peers.status.online = true; | ||
action.data.online = false; | ||
|
||
middleware(store)(next)(action); | ||
expect(store.dispatch).to.have.been.calledWith(errorToastDisplayed({ | ||
label: `Failed to connect to node ${peers.data.currentPeer}:${peers.data.port}`, | ||
})); | ||
}); | ||
|
||
it(`should dispatch successToastDisplayed on ${actionType.activePeerUpdate} action if action.data.online and !state.peer.status.online`, () => { | ||
peers.status.online = false; | ||
action.data.online = true; | ||
|
||
middleware(store)(next)(action); | ||
expect(store.dispatch).to.have.been.calledWith(successToastDisplayed({ | ||
label: 'Connection re-established', | ||
})); | ||
}); | ||
|
||
it(`should not call next() on ${actionType.activePeerUpdate} action if action.data.online === state.peer.status.online`, () => { | ||
peers.status.online = false; | ||
action.data.online = false; | ||
|
||
middleware(store)(next)(action); | ||
expect(next).not.to.have.been.calledWith(); | ||
}); | ||
|
||
it(`should call next() on ${actionType.activePeerUpdate} action if action.data.online !== state.peer.status.online`, () => { | ||
peers.status.online = true; | ||
action.data.online = false; | ||
|
||
middleware(store)(next)(action); | ||
expect(next).to.have.been.calledWith(action); | ||
}); | ||
}); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters