-
Notifications
You must be signed in to change notification settings - Fork 798
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
JITMs: add redux structure and REST API client method to be used by t…
…he JITM component of the Jetpack Dashboard (Spin-off of #10759). (#10818) This PR is an extract of #10759 in order to simplify that PR and scope it to UI changes. Author: @jeherve #### Changes proposed in this Pull Request: * Introduces `_inc/client/state/jitm` and files for reducer, actions and tests. * Introduces method `fetchJitm` in the REST API client. #### Testing instructions: * Checkout this branch * Run `yarn test-client _inc/client/state/jitm/test/*` * Confirm tests pass #### Proposed changelog entry for your changes: None needed
- Loading branch information
Showing
8 changed files
with
287 additions
and
3 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,56 @@ | ||
/** | ||
* Internal dependencies | ||
*/ | ||
import { | ||
JITM_FETCH, | ||
JITM_FETCH_RECEIVE, | ||
JITM_FETCH_FAIL, | ||
JITM_DISMISS, | ||
JITM_DISMISS_SUCCESS, | ||
JITM_DISMISS_FAIL, | ||
} from 'state/action-types'; | ||
import restApi from 'rest-api'; | ||
|
||
export const fetchJitm = ( message_path = '', query_url = 'page=jetpack' ) => { | ||
return dispatch => { | ||
dispatch( { | ||
type: JITM_FETCH | ||
} ); | ||
return restApi | ||
.fetchJitm( message_path, query_url ) | ||
.then( message => { | ||
dispatch( { | ||
type: JITM_FETCH_RECEIVE, | ||
message: message | ||
} ); | ||
} ) | ||
.catch( error => { | ||
dispatch( { | ||
type: JITM_FETCH_FAIL, | ||
error: error | ||
} ); | ||
} ); | ||
}; | ||
}; | ||
|
||
export const getJitmDismissalResponse = ( id, feature_class ) => { | ||
return dispatch => { | ||
dispatch( { | ||
type: JITM_DISMISS | ||
} ); | ||
return restApi | ||
.dismissJitm( id, feature_class ) | ||
.then( response => { | ||
dispatch( { | ||
type: JITM_DISMISS_SUCCESS, | ||
response: response | ||
} ); | ||
} ) | ||
.catch( error => { | ||
dispatch( { | ||
type: JITM_DISMISS_FAIL, | ||
error: error | ||
} ); | ||
} ); | ||
}; | ||
}; |
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,9 @@ | ||
/** | ||
* Internal dependencies | ||
*/ | ||
import * as reducer from './reducer'; | ||
import * as actions from './actions'; | ||
|
||
const all = { ...reducer, ...actions }; | ||
|
||
export default all; |
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,102 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { combineReducers } from 'redux'; | ||
import get from 'lodash/get'; | ||
import assign from 'lodash/assign'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import { | ||
JITM_FETCH, | ||
JITM_FETCH_RECEIVE, | ||
JITM_FETCH_FAIL, | ||
JITM_DISMISS, | ||
JITM_DISMISS_SUCCESS, | ||
JITM_DISMISS_FAIL | ||
} from 'state/action-types'; | ||
|
||
export const data = ( state = {}, action ) => { | ||
switch ( action.type ) { | ||
case JITM_FETCH_RECEIVE: | ||
return assign( {}, state, { message: action.message } ); | ||
case JITM_DISMISS_SUCCESS: | ||
return assign( {}, state, { response: action.response } ); | ||
default: | ||
return state; | ||
} | ||
}; | ||
|
||
export const initialRequestsState = { | ||
isFetchingJitm: false, | ||
isDismissingJitm: false, | ||
}; | ||
|
||
export const requests = ( state = initialRequestsState, action ) => { | ||
switch ( action.type ) { | ||
case JITM_FETCH: | ||
return assign( {}, state, { | ||
isFetchingJitm: true | ||
} ); | ||
case JITM_FETCH_RECEIVE: | ||
case JITM_FETCH_FAIL: | ||
return assign( {}, state, { | ||
isFetchingJitm: false | ||
} ); | ||
case JITM_DISMISS: | ||
return assign( {}, state, { | ||
isDismissingJitm: true | ||
} ); | ||
case JITM_DISMISS_SUCCESS: | ||
case JITM_DISMISS_FAIL: | ||
return assign( {}, state, { | ||
isDismissingJitm: false | ||
} ); | ||
default: | ||
return state; | ||
} | ||
}; | ||
|
||
export const reducer = combineReducers( { | ||
data, | ||
requests | ||
} ); | ||
|
||
/** | ||
* Returns true if currently requesting a JITM message. Otherwise false. | ||
* | ||
* @param {Object} state Global state tree | ||
* @return {Boolean} Whether a JITM is being requested | ||
*/ | ||
export function isFetchingJitm( state ) { | ||
return !! state.jetpack.jitm.requests.isFetchingJitm; | ||
} | ||
|
||
/** | ||
* Returns true if currently requesting the dismissal of a JITM message. Otherwise false. | ||
* | ||
* @param {Object} state Global state tree | ||
* @return {Boolean} Whether a JITM is being dismissed. | ||
*/ | ||
export function isDismissingJitm( state ) { | ||
return !! state.jetpack.jitm.requests.isDismissingJitm; | ||
} | ||
|
||
/** | ||
* Returns the current JITM message | ||
* @param {Object} state Global state tree | ||
* @return {Object} Features | ||
*/ | ||
export function getJitm( state ) { | ||
return get( state.jetpack.jitm, [ 'data', 'message' ], {} ); | ||
} | ||
|
||
/** | ||
* Dismiss the current JITM message | ||
* @param {Object} state Global state tree | ||
* @return {Object} Response | ||
*/ | ||
export function getJitmDismissalResponse( state ) { | ||
return get( state.jetpack.jitm, [ 'data', 'response' ], {} ); | ||
} |
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,50 @@ | ||
import { expect } from 'chai'; | ||
|
||
import { | ||
data as dataReducer, | ||
requests as requestsReducer, | ||
initialRequestsState | ||
} from '../reducer'; | ||
|
||
describe( 'data reducer', () => { | ||
it( 'data state should default to empty object', () => { | ||
const state = dataReducer( undefined, {} ); | ||
expect( state ).to.eql( {} ); | ||
} ); | ||
} ); | ||
|
||
describe( 'requests reducer', () => { | ||
it( 'requests state should default to empty object', () => { | ||
const state = requestsReducer( undefined, {} ); | ||
expect( state ).to.eql( initialRequestsState ); | ||
} ); | ||
|
||
describe( '#fetchJitm', () => { | ||
it( 'should set isFetchingJitm to true when fetching JITMs', () => { | ||
const stateIn = {}; | ||
const action = { | ||
type: 'JITM_FETCH' | ||
}; | ||
let stateOut = requestsReducer( stateIn, action ); | ||
expect( stateOut.isFetchingJitm ).to.be.true; | ||
} ); | ||
|
||
it( 'should set isFetchingJitm to false when JITM fetch succeeds', () => { | ||
const stateIn = {}; | ||
const action = { | ||
type: 'JITM_FETCH_RECEIVE' | ||
}; | ||
let stateOut = requestsReducer( stateIn, action ); | ||
expect( stateOut.isFetchingJitm ).to.be.false; | ||
} ); | ||
|
||
it( 'should set isFetchingJitm to false when fetching JITMs fails', () => { | ||
const stateIn = {}; | ||
const action = { | ||
type: 'JITM_FETCH_FAIL' | ||
}; | ||
let stateOut = requestsReducer( stateIn, action ); | ||
expect( stateOut.isFetchingJitm ).to.be.false; | ||
} ); | ||
} ); | ||
} ); |
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,38 @@ | ||
import { expect } from 'chai'; | ||
|
||
import { | ||
fetchJitm, | ||
getJitm, | ||
isFetchingJitm, | ||
} from '../reducer'; | ||
|
||
let state = { | ||
jetpack: { | ||
jitm: { | ||
data: { | ||
message: 'Hi' | ||
}, | ||
requests: { | ||
isFetchingJitm: true | ||
} | ||
} | ||
} | ||
}; | ||
|
||
describe( 'status selectors', () => { | ||
describe( '#getJitm', () => { | ||
it( 'should return state.jetpack.jitm.data.message', () => { | ||
const stateIn = state; | ||
const output = getJitm( stateIn ); | ||
expect( output ).to.equal( state.jetpack.jitm.data.message ); | ||
} ); | ||
} ); | ||
|
||
describe( '#isFetchingJitm', () => { | ||
it( 'should return state.jetpack.jitm.requests.isFetchingJim', () => { | ||
const stateIn = state; | ||
const output = isFetchingJitm( stateIn ); | ||
expect( output ).to.equal( state.jetpack.jitm.requests.isFetchingJitm ); | ||
} ); | ||
} ); | ||
} ) |
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