[web] add tests for main view and ui

This commit is contained in:
Jason 2016-07-08 21:43:18 +08:00
parent 09ab2528f5
commit 666017125a
3 changed files with 170 additions and 37 deletions

View File

@ -1,36 +1,86 @@
jest.unmock("../../ducks/ui");
// @todo fix it ( this is why I don't like to add tests until our architecture is stable :P )
jest.unmock("../../ducks/views/main");
jest.unmock('lodash')
jest.unmock('redux')
jest.unmock('redux-thunk')
jest.unmock('../../ducks/ui')
jest.unmock('../../ducks/views/main')
import reducer, { setActiveMenu } from '../../ducks/ui';
import { SELECT } from '../../ducks/views/main';
import _ from 'lodash'
import thunk from 'redux-thunk'
import { applyMiddleware, createStore, combineReducers } from 'redux'
import reducer, { setActiveMenu, selectTabRelative } from '../../ducks/ui'
import { SELECT } from '../../ducks/views/main'
describe("ui reducer", () => {
it("should return the initial state", () => {
expect(reducer(undefined, {})).toEqual({ activeMenu: 'Start'})
}),
it("should return the state for view", () => {
expect(reducer(undefined, setActiveMenu('View'))).toEqual({ activeMenu: 'View'})
}),
it("should change the state to Start when deselecting a flow and we a currently at the flow tab", () => {
expect(reducer({activeMenu: 'Flow'},
{ type: SELECT,
currentSelection: '1',
flowId : undefined
})).toEqual({ activeMenu: 'Start'})
}),
it("should change the state to Flow when we selected a flow and no flow was selected before", () => {
expect(reducer({activeMenu: 'Start'},
{ type: SELECT,
currentSelection: undefined,
flowId : '1'
})).toEqual({ activeMenu: 'Flow'})
}),
it("should not change the state to Flow when OPTIONS tab is selected and we selected a flow and a flow as selected before", () => {
expect(reducer({activeMenu: 'Options'},
{ type: SELECT,
currentSelection: '1',
flowId : '2'
})).toEqual({ activeMenu: 'Options'})
describe('ui reducer', () => {
it('should return the initial state', () => {
expect(reducer(undefined, {}).activeMenu).toEqual('Start')
})
});
it('should return the state for view', () => {
expect(reducer(undefined, setActiveMenu('View')).activeMenu).toEqual('View')
})
it('should change the state to Start when deselecting a flow and we a currently at the flow tab', () => {
expect(reducer({ activeMenu: 'Flow' }, {
type: SELECT,
currentSelection: 1,
flowId : undefined,
}).activeMenu).toEqual('Start')
})
it('should change the state to Flow when we selected a flow and no flow was selected before', () => {
expect(reducer({ activeMenu: 'Start' }, {
type: SELECT,
currentSelection: undefined,
flowId : 1,
}).activeMenu).toEqual('Flow')
})
it('should not change the state to Flow when OPTIONS tab is selected and we selected a flow and a flow as selected before', () => {
expect(reducer({activeMenu: 'Options'}, {
type: SELECT,
currentSelection: 1,
flowId : '2',
}).activeMenu).toEqual('Options')
})
describe('select tab relative', () => {
it('should select tab according to flow properties', () => {
const store = createTestStore(makeState([{ id: 1 }], 1))
store.dispatch(selectTabRelative(1))
expect(store.getState().ui.panel).toEqual('details')
})
it('should select last tab when first tab is selected', () => {
const store = createTestStore(makeState([{ id: 1, request: true, response: true, error: true }], 1))
store.dispatch(selectTabRelative(-1))
expect(store.getState().ui.panel).toEqual('details')
})
})
})
function createTestStore(state) {
return createStore(
combineReducers({ ui: reducer, flows: (state = {}) => state }),
state,
applyMiddleware(thunk)
)
}
function makeState(flows, selected) {
return {
flows: {
list: {
data: flows,
byId: _.fromPairs(flows.map(flow => [flow.id, flow])),
indexOf: _.fromPairs(flows.map((flow, index) => [flow.id, index])),
},
views: {
main: {
selected: [selected],
},
},
},
}
}

View File

@ -0,0 +1,82 @@
jest.unmock('../../../ducks/views/main');
jest.unmock('../../../ducks/utils/view');
jest.unmock('redux-thunk')
jest.unmock('redux')
import reduce, { selectRelative } from '../../../ducks/views/main';
import thunk from 'redux-thunk'
import { applyMiddleware, createStore, combineReducers } from 'redux'
describe('main reduce', () => {
describe('select previous', () => {
it('should not changed when first flow is selected', () => {
const flows = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }]
const store = createTestStore(makeState(flows, 1))
store.dispatch(selectRelative(-1))
expect(store.getState().flows.views.main.selected).toEqual([1])
})
it('should select last flow if no flow is selected', () => {
const flows = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }]
const store = createTestStore(makeState(flows))
store.dispatch(selectRelative(-1))
expect(store.getState().flows.views.main.selected).toEqual([4])
})
})
describe('select next', () => {
it('should not change when last flow is selected', () => {
const flows = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }]
const store = createTestStore(makeState(flows, 4))
store.dispatch(selectRelative(1))
expect(store.getState().flows.views.main.selected).toEqual([4])
})
it('should select first flow if no flow is selected', () => {
const flows = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }]
const store = createTestStore(makeState(flows, 1))
store.dispatch(selectRelative(1))
expect(store.getState().flows.views.main.selected).toEqual([2])
})
})
})
function createTestStore(defaultState) {
return createStore(
(state = defaultState, action) => ({
flows: {
...state.flows,
views: {
main: reduce(state.flows.views.main, action)
}
}
}),
defaultState,
applyMiddleware(thunk)
)
}
function makeState(flows, selected) {
const list = {
data: flows,
byId: _.fromPairs(flows.map(flow => [flow.id, flow])),
indexOf: _.fromPairs(flows.map((flow, index) => [flow.id, index])),
}
return {
flows: {
list,
views: {
main: {
selected: [selected],
view: list,
}
}
}
}
}

View File

@ -17,18 +17,19 @@ ContentView.propTypes = {
ContentView.isContentTooLarge = msg => msg.contentLength > 1024 * 1024 * (ContentViews.ViewImage.matches(msg) ? 10 : 0.2)
function ContentView({ flow, message, contentView, selectView, displayLarge }) {
function ContentView(props) {
const { flow, message, contentView, selectView, displayLarge, setDisplayLarge } = props
if (message.contentLength === 0) {
return <MetaViews.ContentEmpty {...this.props}/>
return <MetaViews.ContentEmpty {...props}/>
}
if (message.contentLength === null) {
return <MetaViews.ContentMissing {...this.props}/>
return <MetaViews.ContentMissing {...props}/>
}
if (!displayLarge && ContentView.isContentTooLarge(message)) {
return <MetaViews.ContentTooLarge {...this.props} onClick={() => this.props.setDisplayLarge(true)}/>
return <MetaViews.ContentTooLarge {...props} onClick={() => setDisplayLarge(true)}/>
}
const View = ContentViews[contentView]