phobos_checkpoint_ui 1.0.0.rc1 → 1.0.0.rc2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1 -1
- data/frontend/src/actions/event-details.js +5 -7
- data/frontend/src/actions/event-retry.js +7 -9
- data/frontend/src/actions/events-search.js +5 -7
- data/frontend/src/actions/failures/details.js +5 -7
- data/frontend/src/actions/failures/details.spec.js +1 -1
- data/frontend/src/actions/failures/retry.js +34 -17
- data/frontend/src/actions/failures/retry.spec.js +52 -5
- data/frontend/src/actions/failures/search/index.js +5 -8
- data/frontend/src/actions/failures/search/index.spec.js +2 -2
- data/frontend/src/actions/index.js +3 -1
- data/frontend/src/components/empty-event/empty-event.scss +6 -0
- data/frontend/src/components/event/card-style.js +29 -0
- data/frontend/src/components/event/event.scss +12 -0
- data/frontend/src/components/event/index.js +12 -21
- data/frontend/src/components/event/index.spec.js +3 -2
- data/frontend/src/components/event-overview-dialog/index.js +1 -1
- data/frontend/src/components/event-retry-dialog/index.js +9 -1
- data/frontend/src/components/failure/empty/empty-failure.scss +6 -0
- data/frontend/src/components/failure/empty/index.js +20 -0
- data/frontend/src/components/failure/empty/index.spec.js +38 -0
- data/frontend/src/components/failure/index.js +11 -20
- data/frontend/src/components/failure/index.scss +15 -0
- data/frontend/src/components/failure/index.spec.js +19 -14
- data/frontend/src/components/{failures-list → failure/list}/failures-list.scss +1 -1
- data/frontend/src/components/{failures-list → failure/list}/index.spec.js +15 -11
- data/frontend/src/components/failure/overview-dialog/index.js +4 -4
- data/frontend/src/components/failure/retry-dialog/index.js +14 -9
- data/frontend/src/components/flash-message/flash-message.scss +0 -1
- data/frontend/src/components/header/header.scss +5 -0
- data/frontend/src/components/header/index.js +62 -22
- data/frontend/src/reducers/event-details.js +9 -8
- data/frontend/src/reducers/event-details.spec.js +12 -2
- data/frontend/src/reducers/failures/details/index.js +9 -8
- data/frontend/src/reducers/failures/details/index.spec.js +12 -2
- data/frontend/src/reducers/failures/index.js +6 -4
- data/frontend/src/reducers/failures/index.spec.js +5 -5
- data/frontend/src/reducers/xhr-status.js +4 -0
- data/frontend/src/reducers/xhr-status.spec.js +20 -0
- data/frontend/src/views/events/search/index.scss +0 -7
- data/frontend/src/views/failures/details/index.js +2 -2
- data/frontend/src/views/failures/search/index.js +5 -5
- data/frontend/src/views/failures/search/index.scss +1 -8
- data/frontend/src/views/failures/search/index.spec.js +4 -4
- data/frontend/src/views/layout.js +2 -2
- data/lib/phobos_checkpoint_ui/version.rb +1 -1
- metadata +12 -12
- data/frontend/src/components/event/style.js +0 -16
- data/frontend/src/components/failure/error-message.js +0 -19
- data/frontend/src/components/failure/error-message.scss +0 -8
- data/frontend/src/components/failure/event.scss +0 -3
- data/frontend/src/components/failure/loading.js +0 -16
- data/frontend/src/components/failure/style.js +0 -16
- /data/frontend/src/components/{failures-list → failure/list}/index.js +0 -0
- /data/frontend/src/components/failure/overview-dialog/{event-overview-dialog.scss → failure-overview-dialog.scss} +0 -0
@@ -1,7 +1,8 @@
|
|
1
1
|
import React from 'react'
|
2
2
|
import jasmineEnzyme from 'jasmine-enzyme'
|
3
3
|
import { mount } from 'enzyme'
|
4
|
-
import {
|
4
|
+
import { Failure } from 'components/failure'
|
5
|
+
import { formatTime } from 'components/event/card-style'
|
5
6
|
import getMuiTheme from 'material-ui/styles/getMuiTheme'
|
6
7
|
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'
|
7
8
|
import { Provider } from 'react-redux'
|
@@ -14,12 +15,12 @@ const mockStore = configureMockStore(middlewares)
|
|
14
15
|
const mountComponent = (store, props) => mount(
|
15
16
|
<Provider store={store}>
|
16
17
|
<MuiThemeProvider muiTheme={getMuiTheme()}>
|
17
|
-
<
|
18
|
+
<Failure {...props} />
|
18
19
|
</MuiThemeProvider>
|
19
20
|
</Provider>
|
20
21
|
)
|
21
22
|
|
22
|
-
describe('<
|
23
|
+
describe('<Failure />', () => {
|
23
24
|
let props, component, store, onShowOverview
|
24
25
|
|
25
26
|
beforeEach(() => {
|
@@ -34,7 +35,7 @@ describe('<Event />', () => {
|
|
34
35
|
|
35
36
|
props = {
|
36
37
|
onShowOverview: onShowOverview,
|
37
|
-
|
38
|
+
failure: {
|
38
39
|
id: 1,
|
39
40
|
topic: 'phobos.test',
|
40
41
|
group_id: 'phobos-checkpoint-consumer',
|
@@ -43,7 +44,11 @@ describe('<Event />', () => {
|
|
43
44
|
event_type: 'order-placed',
|
44
45
|
event_version: 'v1',
|
45
46
|
checksum: '188773471ec0f898fd81d272760a027f',
|
46
|
-
payload: { data: { name: 'phobos' } }
|
47
|
+
payload: { data: { name: 'phobos' } },
|
48
|
+
metadata: { meta: { version: 'foo' } },
|
49
|
+
error_class: 'FooError',
|
50
|
+
error_message: 'Expected "foo" to equal "bar"',
|
51
|
+
error_backtrace: ['Line 1: foo', 'Line 2: baz']
|
47
52
|
}
|
48
53
|
}
|
49
54
|
|
@@ -51,7 +56,7 @@ describe('<Event />', () => {
|
|
51
56
|
})
|
52
57
|
|
53
58
|
it('displays event_time formatted', () => {
|
54
|
-
expect(component.text()).toMatch(
|
59
|
+
expect(component.text()).toMatch(formatTime(props.failure.event_time))
|
55
60
|
})
|
56
61
|
|
57
62
|
it('displays topic', () => {
|
@@ -63,27 +68,27 @@ describe('<Event />', () => {
|
|
63
68
|
})
|
64
69
|
|
65
70
|
describe('when clicked', () => {
|
66
|
-
it('calls onShowOverview with the
|
67
|
-
component.find('.
|
68
|
-
expect(onShowOverview).toHaveBeenCalledWith(props.
|
71
|
+
it('calls onShowOverview with the failure', () => {
|
72
|
+
component.find('.failure').simulate('click')
|
73
|
+
expect(onShowOverview).toHaveBeenCalledWith(props.failure)
|
69
74
|
})
|
70
75
|
})
|
71
76
|
|
72
|
-
describe('when
|
77
|
+
describe('when failure has overviewVisible=true', () => {
|
73
78
|
let dialog
|
74
79
|
beforeEach(() => {
|
75
|
-
Object.assign(props.
|
80
|
+
Object.assign(props.failure, { overviewVisible: true })
|
76
81
|
component = mountComponent(store, props)
|
77
|
-
const dialogs = document.getElementsByClassName('
|
82
|
+
const dialogs = document.getElementsByClassName('failure-overview-dialog')
|
78
83
|
dialog = dialogs[dialogs.length - 1]
|
79
84
|
})
|
80
85
|
|
81
|
-
it('opens the
|
86
|
+
it('opens the failure overview dialog', () => {
|
82
87
|
expect(dialog).not.toBe(null)
|
83
88
|
})
|
84
89
|
|
85
90
|
it('displays event_id', () => {
|
86
|
-
expect(dialog.innerText).toMatch(`#${props.
|
91
|
+
expect(dialog.innerText).toMatch(`#${props.failure.id}`)
|
87
92
|
})
|
88
93
|
})
|
89
94
|
})
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import React from 'react'
|
2
2
|
import jasmineEnzyme from 'jasmine-enzyme'
|
3
3
|
import { mount } from 'enzyme'
|
4
|
-
import
|
4
|
+
import FailuresList from 'components/failure/list'
|
5
5
|
import getMuiTheme from 'material-ui/styles/getMuiTheme'
|
6
6
|
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'
|
7
7
|
import { Provider } from 'react-redux'
|
@@ -14,13 +14,13 @@ const mockStore = configureMockStore(middlewares)
|
|
14
14
|
const mountComponent = (store, props) => mount(
|
15
15
|
<Provider store={store}>
|
16
16
|
<MuiThemeProvider muiTheme={getMuiTheme()}>
|
17
|
-
<
|
17
|
+
<FailuresList {...props} />
|
18
18
|
</MuiThemeProvider>
|
19
19
|
</Provider>
|
20
20
|
)
|
21
21
|
|
22
|
-
describe('<
|
23
|
-
let store, props, component,
|
22
|
+
describe('<FailuresList />', () => {
|
23
|
+
let store, props, component, failure
|
24
24
|
|
25
25
|
beforeEach(() => {
|
26
26
|
jasmineEnzyme()
|
@@ -31,7 +31,7 @@ describe('<EventsList />', () => {
|
|
31
31
|
}
|
32
32
|
})
|
33
33
|
|
34
|
-
|
34
|
+
failure = {
|
35
35
|
id: 1,
|
36
36
|
topic: 'phobos.test',
|
37
37
|
group_id: 'phobos-checkpoint-consumer',
|
@@ -40,20 +40,24 @@ describe('<EventsList />', () => {
|
|
40
40
|
event_type: 'order-placed',
|
41
41
|
event_version: 'v1',
|
42
42
|
checksum: '188773471ec0f898fd81d272760a027f',
|
43
|
-
payload: { data: { name: 'phobos' } }
|
43
|
+
payload: { data: { name: 'phobos' } },
|
44
|
+
metadata: { meta: { version: 'foo' } },
|
45
|
+
error_class: 'FooError',
|
46
|
+
error_message: 'Expected "foo" to equal "bar"',
|
47
|
+
error_backtrace: ['Line 1: foo', 'Line 2: baz']
|
44
48
|
}
|
45
49
|
|
46
50
|
props = {
|
47
|
-
|
48
|
-
|
49
|
-
Object.assign({},
|
51
|
+
failures: [
|
52
|
+
failure,
|
53
|
+
Object.assign({}, failure, { id: 2 })
|
50
54
|
]
|
51
55
|
}
|
52
56
|
|
53
57
|
component = mountComponent(store, props)
|
54
58
|
})
|
55
59
|
|
56
|
-
it('renders the list of
|
57
|
-
expect(component.find('.
|
60
|
+
it('renders the list of failures', () => {
|
61
|
+
expect(component.find('.failure').length).toEqual(2)
|
58
62
|
})
|
59
63
|
})
|
@@ -9,7 +9,7 @@ import Dialog from 'material-ui/Dialog'
|
|
9
9
|
import RaisedButton from 'material-ui/RaisedButton'
|
10
10
|
import FailureOverview from 'components/failure/overview'
|
11
11
|
|
12
|
-
class
|
12
|
+
class FailureOverviewDialog extends Component {
|
13
13
|
static get propTypes () {
|
14
14
|
return {
|
15
15
|
onHideOverview: PropTypes.func,
|
@@ -46,7 +46,7 @@ class OverviewDialog extends Component {
|
|
46
46
|
<Dialog
|
47
47
|
modal={false}
|
48
48
|
autoScrollBodyContent
|
49
|
-
className='
|
49
|
+
className='failure-overview-dialog'
|
50
50
|
title={this.dialogTitle()}
|
51
51
|
open={!!this.props.failure.overviewVisible}
|
52
52
|
onRequestClose={() => this.hideOverview()}
|
@@ -54,7 +54,7 @@ class OverviewDialog extends Component {
|
|
54
54
|
bodyStyle={{maxWidth: '1024px'}}
|
55
55
|
actions={[
|
56
56
|
<RaisedButton
|
57
|
-
|
57
|
+
primary
|
58
58
|
label='Retry'
|
59
59
|
onClick={() => this.showRetry()}/>
|
60
60
|
]}>
|
@@ -87,4 +87,4 @@ export default connect(
|
|
87
87
|
onHideOverview: hideFailureOverview,
|
88
88
|
onShowRetry: showFailureRetry
|
89
89
|
}
|
90
|
-
)(
|
90
|
+
)(FailureOverviewDialog)
|
@@ -1,7 +1,6 @@
|
|
1
1
|
import React, { Component, PropTypes } from 'react'
|
2
2
|
import { connect } from 'react-redux'
|
3
3
|
|
4
|
-
import ErrorMessage from 'components/event/error-message'
|
5
4
|
import Loading from 'components/event/loading'
|
6
5
|
|
7
6
|
import { hideFailureRetry, performFailureRetry } from 'actions/failures/retry'
|
@@ -24,7 +23,7 @@ class FailureRetryDialog extends Component {
|
|
24
23
|
|
25
24
|
static get defaultProps () {
|
26
25
|
return {
|
27
|
-
|
26
|
+
failure: {}
|
28
27
|
}
|
29
28
|
}
|
30
29
|
|
@@ -32,7 +31,7 @@ class FailureRetryDialog extends Component {
|
|
32
31
|
return (
|
33
32
|
<Dialog
|
34
33
|
modal={!!this.props.isRetryingEvent}
|
35
|
-
title=
|
34
|
+
title={this.renderTitle()}
|
36
35
|
open={!!this.props.failure.retryVisible}
|
37
36
|
bodyStyle={{maxWidth: '300px'}}
|
38
37
|
contentStyle={{maxWidth: '300px'}}
|
@@ -41,16 +40,23 @@ class FailureRetryDialog extends Component {
|
|
41
40
|
<RaisedButton
|
42
41
|
primary
|
43
42
|
label='Retry'
|
43
|
+
disabled={this.props.isRetryingEvent}
|
44
44
|
onClick={() => this.performRetry()}/>
|
45
45
|
]}>
|
46
46
|
<div style={{textAlign: 'center'}}>
|
47
47
|
<Loading visible={this.props.isRetryingEvent}/>
|
48
|
-
<ErrorMessage message={this.props.failure.error}/>
|
49
48
|
</div>
|
50
49
|
</Dialog>
|
51
50
|
)
|
52
51
|
}
|
53
52
|
|
53
|
+
renderTitle () {
|
54
|
+
if (this.props.isRetryingEvent) {
|
55
|
+
return 'Retrying failure...'
|
56
|
+
}
|
57
|
+
return 'Are you sure?'
|
58
|
+
}
|
59
|
+
|
54
60
|
hide () {
|
55
61
|
this.props.onHideRetry(this.props.failure)
|
56
62
|
}
|
@@ -60,11 +66,10 @@ class FailureRetryDialog extends Component {
|
|
60
66
|
}
|
61
67
|
}
|
62
68
|
|
63
|
-
const mapStateToProps = (state, ownProps) => (
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
)
|
69
|
+
const mapStateToProps = (state, ownProps) => ({
|
70
|
+
...ownProps,
|
71
|
+
isRetryingEvent: state.xhrStatus.isRetryingEvent
|
72
|
+
})
|
68
73
|
|
69
74
|
export default connect(mapStateToProps, {
|
70
75
|
onHideRetry: hideFailureRetry,
|
@@ -5,27 +5,53 @@ import AppBar from 'material-ui/AppBar'
|
|
5
5
|
import Chip from 'material-ui/Chip'
|
6
6
|
import { Link } from 'react-router'
|
7
7
|
|
8
|
-
import
|
9
|
-
import IconMenu from 'material-ui/IconMenu'
|
8
|
+
import Menu from 'material-ui/Menu'
|
10
9
|
import MenuItem from 'material-ui/MenuItem'
|
11
|
-
import
|
12
|
-
import
|
13
|
-
import
|
10
|
+
import EventsIcon from 'material-ui/svg-icons/communication/call-received'
|
11
|
+
import FailuresIcon from 'material-ui/svg-icons/communication/call-missed'
|
12
|
+
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'
|
13
|
+
import getMuiTheme from 'material-ui/styles/getMuiTheme'
|
14
|
+
import {
|
15
|
+
blueGrey800,
|
16
|
+
cyan500,
|
17
|
+
grey100,
|
18
|
+
grey500,
|
19
|
+
yellowA100
|
20
|
+
} from 'material-ui/styles/colors'
|
14
21
|
import { navigateTo } from 'actions/navigation'
|
15
22
|
|
16
23
|
const DEFAULT_TITLE = 'Phobos Checkpoint'
|
24
|
+
const muiTheme = getMuiTheme({
|
25
|
+
palette: {
|
26
|
+
accent1Color: cyan500
|
27
|
+
},
|
28
|
+
ripple: {
|
29
|
+
color: grey100
|
30
|
+
}
|
31
|
+
})
|
17
32
|
|
18
33
|
const style = {
|
19
34
|
bar: {
|
20
|
-
backgroundColor:
|
35
|
+
backgroundColor: blueGrey800
|
21
36
|
},
|
22
37
|
title: {
|
23
|
-
color: '#fff',
|
24
38
|
fontFamily: 'Roboto',
|
25
39
|
fontWeight: 'lighter'
|
26
40
|
},
|
27
41
|
envLabel: {
|
28
|
-
marginLeft:
|
42
|
+
marginLeft: 20,
|
43
|
+
backgroundColor: yellowA100
|
44
|
+
},
|
45
|
+
innerTitle: {
|
46
|
+
marginLeft: 10
|
47
|
+
},
|
48
|
+
menuInner: {
|
49
|
+
display: 'flex'
|
50
|
+
},
|
51
|
+
menuItem: {
|
52
|
+
color: grey500,
|
53
|
+
fontFamily: 'Roboto',
|
54
|
+
fontWeight: 'lighter'
|
29
55
|
}
|
30
56
|
}
|
31
57
|
|
@@ -37,15 +63,6 @@ export class Header extends Component {
|
|
37
63
|
showMenuIconButton={false}
|
38
64
|
style={style.bar}
|
39
65
|
titleStyle={style.title}
|
40
|
-
iconElementRight={
|
41
|
-
<IconMenu
|
42
|
-
iconButtonElement={<IconButton><MoreVertIcon /></IconButton>}
|
43
|
-
targetOrigin={{horizontal: 'right', vertical: 'top'}}
|
44
|
-
anchorOrigin={{horizontal: 'right', vertical: 'top'}}>
|
45
|
-
<MenuItem primaryText='Events' leftIcon={<ContentSend />} onTouchTap={() => this.props.navigateTo('/events')} />
|
46
|
-
<MenuItem primaryText='Errors' leftIcon={<ActionAssignment />} onTouchTap={() => this.props.navigateTo('/failures')} />
|
47
|
-
</IconMenu>
|
48
|
-
}
|
49
66
|
/>
|
50
67
|
)
|
51
68
|
}
|
@@ -53,11 +70,34 @@ export class Header extends Component {
|
|
53
70
|
logo () {
|
54
71
|
const { title, logo, env_label } = configs()
|
55
72
|
return (
|
56
|
-
<
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
73
|
+
<MuiThemeProvider muiTheme={muiTheme}>
|
74
|
+
<div className='header'>
|
75
|
+
<Link className='header--title' to='/'>
|
76
|
+
{logo && <img className='logo' src={logo} />}
|
77
|
+
<span className='title' style={style.innerTitle}>{title || DEFAULT_TITLE}</span>
|
78
|
+
<Chip className='env-label' style={style.envLabel}>{env_label}</Chip>
|
79
|
+
</Link>
|
80
|
+
<Menu
|
81
|
+
disableAutoFocus
|
82
|
+
value={this.props.routing.locationBeforeTransitions.pathname}
|
83
|
+
listStyle={style.menuInner}>
|
84
|
+
<MenuItem
|
85
|
+
value='/events'
|
86
|
+
style={style.menuItem}
|
87
|
+
primaryText='Events'
|
88
|
+
leftIcon={<EventsIcon />}
|
89
|
+
onTouchTap={() => this.props.navigateTo('/events')}
|
90
|
+
/>
|
91
|
+
<MenuItem
|
92
|
+
value='/failures'
|
93
|
+
style={style.menuItem}
|
94
|
+
primaryText='Failures'
|
95
|
+
leftIcon={<FailuresIcon />}
|
96
|
+
onTouchTap={() => this.props.navigateTo('/failures')}
|
97
|
+
/>
|
98
|
+
</Menu>
|
99
|
+
</div>
|
100
|
+
</MuiThemeProvider>
|
61
101
|
)
|
62
102
|
}
|
63
103
|
}
|
@@ -2,23 +2,21 @@ import {
|
|
2
2
|
EVENT_SHOW_RETRY,
|
3
3
|
EVENT_HIDE_RETRY,
|
4
4
|
EVENT_HIDE_OVERVIEW,
|
5
|
-
RECEIVE_EVENT_DETAILS
|
5
|
+
RECEIVE_EVENT_DETAILS,
|
6
|
+
REQUEST_EVENT_RETRY_FAILED
|
6
7
|
} from 'actions'
|
7
8
|
|
8
|
-
function patchEvent (state,
|
9
|
-
|
10
|
-
return Object.assign(state, params)
|
11
|
-
}
|
12
|
-
return state
|
9
|
+
function patchEvent (state, params) {
|
10
|
+
return {...state, ...params}
|
13
11
|
}
|
14
12
|
|
15
13
|
export default (state = {}, action) => {
|
16
14
|
switch (action.type) {
|
17
15
|
case EVENT_SHOW_RETRY:
|
18
|
-
return patchEvent(state,
|
16
|
+
return patchEvent(state, { retryVisible: true })
|
19
17
|
|
20
18
|
case EVENT_HIDE_RETRY:
|
21
|
-
return patchEvent(state,
|
19
|
+
return patchEvent(state, { retryVisible: false, error: null })
|
22
20
|
|
23
21
|
case EVENT_HIDE_OVERVIEW:
|
24
22
|
return {}
|
@@ -26,6 +24,9 @@ export default (state = {}, action) => {
|
|
26
24
|
case RECEIVE_EVENT_DETAILS:
|
27
25
|
return action.event
|
28
26
|
|
27
|
+
case REQUEST_EVENT_RETRY_FAILED:
|
28
|
+
return patchEvent(state, { error: action.error })
|
29
|
+
|
29
30
|
default:
|
30
31
|
return state
|
31
32
|
}
|
@@ -2,7 +2,8 @@ import {
|
|
2
2
|
EVENT_SHOW_RETRY,
|
3
3
|
EVENT_HIDE_RETRY,
|
4
4
|
EVENT_HIDE_OVERVIEW,
|
5
|
-
RECEIVE_EVENT_DETAILS
|
5
|
+
RECEIVE_EVENT_DETAILS,
|
6
|
+
REQUEST_EVENT_RETRY_FAILED
|
6
7
|
} from 'actions'
|
7
8
|
|
8
9
|
import reducer from 'reducers/event-details'
|
@@ -21,7 +22,7 @@ describe('reducers/events-details', () => {
|
|
21
22
|
it('sets retryVisible to false', () => {
|
22
23
|
const currentState = { id: 1 }
|
23
24
|
const action = { type: EVENT_HIDE_RETRY, event: { id: 1 } }
|
24
|
-
const expectedState = { id: 1, retryVisible: false }
|
25
|
+
const expectedState = { id: 1, retryVisible: false, error: null }
|
25
26
|
expect(reducer(currentState, action)).toEqual(expectedState)
|
26
27
|
})
|
27
28
|
})
|
@@ -44,6 +45,15 @@ describe('reducers/events-details', () => {
|
|
44
45
|
})
|
45
46
|
})
|
46
47
|
|
48
|
+
describe('for REQUEST_EVENT_RETRY_FAILED', () => {
|
49
|
+
it('replaces the state', () => {
|
50
|
+
const currentState = { id: 1 }
|
51
|
+
const action = { type: REQUEST_EVENT_RETRY_FAILED, error: 'an error', event: { id: 2 } }
|
52
|
+
const expectedState = { id: 1, error: 'an error' }
|
53
|
+
expect(reducer(currentState, action)).toEqual(expectedState)
|
54
|
+
})
|
55
|
+
})
|
56
|
+
|
47
57
|
describe('for default', () => {
|
48
58
|
it('returns the currentState', () => {
|
49
59
|
const currentState = { current: true }
|
@@ -2,23 +2,21 @@ import {
|
|
2
2
|
FAILURE_SHOW_RETRY,
|
3
3
|
FAILURE_HIDE_RETRY,
|
4
4
|
FAILURE_HIDE_OVERVIEW,
|
5
|
-
RECEIVE_FAILURE_DETAILS
|
5
|
+
RECEIVE_FAILURE_DETAILS,
|
6
|
+
REQUEST_EVENT_RETRY_FAILED
|
6
7
|
} from 'actions'
|
7
8
|
|
8
|
-
function patchFailure (state,
|
9
|
-
|
10
|
-
return Object.assign(state, params)
|
11
|
-
}
|
12
|
-
return state
|
9
|
+
function patchFailure (state, params) {
|
10
|
+
return { ...state, ...params }
|
13
11
|
}
|
14
12
|
|
15
13
|
export default (state = {}, action) => {
|
16
14
|
switch (action.type) {
|
17
15
|
case FAILURE_SHOW_RETRY:
|
18
|
-
return patchFailure(state,
|
16
|
+
return patchFailure(state, { retryVisible: true })
|
19
17
|
|
20
18
|
case FAILURE_HIDE_RETRY:
|
21
|
-
return patchFailure(state,
|
19
|
+
return patchFailure(state, { retryVisible: false, error: null })
|
22
20
|
|
23
21
|
case FAILURE_HIDE_OVERVIEW:
|
24
22
|
return {}
|
@@ -26,6 +24,9 @@ export default (state = {}, action) => {
|
|
26
24
|
case RECEIVE_FAILURE_DETAILS:
|
27
25
|
return action.failure
|
28
26
|
|
27
|
+
case REQUEST_EVENT_RETRY_FAILED:
|
28
|
+
return patchFailure(state, { error: action.error })
|
29
|
+
|
29
30
|
default:
|
30
31
|
return state
|
31
32
|
}
|
@@ -2,7 +2,8 @@ import {
|
|
2
2
|
FAILURE_SHOW_RETRY,
|
3
3
|
FAILURE_HIDE_RETRY,
|
4
4
|
FAILURE_HIDE_OVERVIEW,
|
5
|
-
RECEIVE_FAILURE_DETAILS
|
5
|
+
RECEIVE_FAILURE_DETAILS,
|
6
|
+
REQUEST_EVENT_RETRY_FAILED
|
6
7
|
} from 'actions'
|
7
8
|
|
8
9
|
import reducer from 'reducers/failures/details'
|
@@ -21,7 +22,7 @@ describe('reducers/failures/details', () => {
|
|
21
22
|
it('sets retryVisible to false', () => {
|
22
23
|
const currentState = { id: 1 }
|
23
24
|
const action = { type: FAILURE_HIDE_RETRY, failure: { id: 1 } }
|
24
|
-
const expectedState = { id: 1, retryVisible: false }
|
25
|
+
const expectedState = { id: 1, retryVisible: false, error: null }
|
25
26
|
expect(reducer(currentState, action)).toEqual(expectedState)
|
26
27
|
})
|
27
28
|
})
|
@@ -44,6 +45,15 @@ describe('reducers/failures/details', () => {
|
|
44
45
|
})
|
45
46
|
})
|
46
47
|
|
48
|
+
describe('for REQUEST_EVENT_RETRY_FAILED', () => {
|
49
|
+
it('replaces the state', () => {
|
50
|
+
const currentState = { id: 1 }
|
51
|
+
const action = { type: REQUEST_EVENT_RETRY_FAILED, error: 'an error', failure: { id: 2 } }
|
52
|
+
const expectedState = { id: 1, error: 'an error' }
|
53
|
+
expect(reducer(currentState, action)).toEqual(expectedState)
|
54
|
+
})
|
55
|
+
})
|
56
|
+
|
47
57
|
describe('for default', () => {
|
48
58
|
it('returns the currentState', () => {
|
49
59
|
const currentState = { current: true }
|
@@ -5,13 +5,13 @@ import {
|
|
5
5
|
FAILURE_SHOW_RETRY,
|
6
6
|
FAILURE_HIDE_RETRY,
|
7
7
|
RECEIVE_FAILURE_RETRY,
|
8
|
-
|
8
|
+
DELETE_FAILURE
|
9
9
|
} from 'actions'
|
10
10
|
|
11
11
|
function patchFailure (state, action, params) {
|
12
12
|
return state.map((failure) => {
|
13
13
|
if (failure.id === action.failure.id) {
|
14
|
-
return
|
14
|
+
return { ...failure, ...params }
|
15
15
|
}
|
16
16
|
return failure
|
17
17
|
})
|
@@ -39,8 +39,10 @@ export default (state = [], action) => {
|
|
39
39
|
case RECEIVE_FAILURE_RETRY:
|
40
40
|
return patchFailure(state, action, { acknowledged: action.acknowledged, error: null })
|
41
41
|
|
42
|
-
case
|
43
|
-
return
|
42
|
+
case DELETE_FAILURE:
|
43
|
+
return state.filter((failure) => {
|
44
|
+
return failure.id !== action.failure.id
|
45
|
+
})
|
44
46
|
|
45
47
|
default:
|
46
48
|
return state
|
@@ -5,7 +5,7 @@ import {
|
|
5
5
|
FAILURE_SHOW_RETRY,
|
6
6
|
FAILURE_HIDE_RETRY,
|
7
7
|
RECEIVE_FAILURE_RETRY,
|
8
|
-
|
8
|
+
DELETE_FAILURE
|
9
9
|
} from 'actions'
|
10
10
|
|
11
11
|
import reducer from 'reducers/failures'
|
@@ -76,11 +76,11 @@ describe('reducers/failures', () => {
|
|
76
76
|
})
|
77
77
|
})
|
78
78
|
|
79
|
-
describe('for
|
80
|
-
it('
|
79
|
+
describe('for DELETE_FAILURE', () => {
|
80
|
+
it('removes the given failure from state', () => {
|
81
81
|
const currentState = [{ id: 1 }, { id: 2 }, { id: 3 }]
|
82
|
-
const action = { type:
|
83
|
-
const expectedState = [{ id: 1 }, { id:
|
82
|
+
const action = { type: DELETE_FAILURE, failure: { id: 2 } }
|
83
|
+
const expectedState = [{ id: 1 }, { id: 3 }]
|
84
84
|
expect(reducer(currentState, action)).toEqual(expectedState)
|
85
85
|
})
|
86
86
|
})
|
@@ -9,6 +9,8 @@ import {
|
|
9
9
|
REQUEST_FAILURES_SEARCH_RESULTS_FAILED,
|
10
10
|
LOAD_MORE_FAILURES_SEARCH_RESULTS,
|
11
11
|
TRIGGER_FAILURES_SEARCH,
|
12
|
+
REQUEST_FAILURE_RETRY,
|
13
|
+
REQUEST_FAILURE_RETRY_FAILED,
|
12
14
|
REQUEST_EVENT_RETRY,
|
13
15
|
RECEIVE_EVENT_RETRY,
|
14
16
|
REQUEST_EVENT_RETRY_FAILED,
|
@@ -63,12 +65,14 @@ export default (state = initialState, action) => {
|
|
63
65
|
currentEventsOffset: action.offset
|
64
66
|
})
|
65
67
|
|
68
|
+
case REQUEST_FAILURE_RETRY:
|
66
69
|
case REQUEST_EVENT_RETRY:
|
67
70
|
return Object.assign({}, state, {
|
68
71
|
isRetryingEvent: true
|
69
72
|
})
|
70
73
|
|
71
74
|
case RECEIVE_EVENT_RETRY:
|
75
|
+
case REQUEST_FAILURE_RETRY_FAILED:
|
72
76
|
case REQUEST_EVENT_RETRY_FAILED:
|
73
77
|
return Object.assign({}, state, {
|
74
78
|
isRetryingEvent: false
|