Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Themes, Actions: Install WP.com theme on Jetpack action. #9924

Merged
merged 24 commits into from
Dec 19, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
a410e51
Action implementation.
budzanowski Dec 9, 2016
930c1d9
Tracking reducer implementation.
budzanowski Dec 9, 2016
f77b40e
Add -wpcom suffix to theme name.
budzanowski Dec 9, 2016
b968043
Correct args order.
budzanowski Dec 9, 2016
75a7454
Add tests.
budzanowski Dec 9, 2016
bbbe06c
Add reducer tests.
budzanowski Dec 9, 2016
7aa4881
Change implementation to use wpcom suffixed theme as param.
budzanowski Dec 11, 2016
8383169
Implement review findings.
budzanowski Dec 12, 2016
b20388b
Adjust tests.
budzanowski Dec 12, 2016
7b62f5c
Adjust after review/discussion.
budzanowski Dec 12, 2016
6b9f117
Fix reducer
ockham Dec 16, 2016
c91357a
s/THEME_INSTALL_ON_JETPACK_REQUEST/THEME_INSTALL/g
ockham Dec 16, 2016
8636394
state/themes/actions: Alphabetize imports
ockham Dec 16, 2016
bcd17c4
state/themes/reducer: Rename installThemeOnJetpackRequests to themeIn…
ockham Dec 16, 2016
12e07c4
Fix test
ockham Dec 16, 2016
8388019
More installThemeOnJetpackRequests -> themeInstalls renaming
ockham Dec 16, 2016
c180a5f
Alphabetize more
ockham Dec 16, 2016
d6bf171
s/installWpcomThemeOnJetpack/installTheme/g
ockham Dec 16, 2016
6247c43
state/themes/test/actions: Use site IDs instead of slugs
ockham Dec 16, 2016
a3ea52e
state/themes/actions: Change arg order
ockham Dec 16, 2016
93f8e82
s/wpcomThemeId/themeId/g
ockham Dec 16, 2016
8c5a262
Update JSDoc
ockham Dec 16, 2016
12c6d10
More wpcomThemeId -> themeId renaming
ockham Dec 16, 2016
dbf0a0a
state/themes/test/reducer: Use site IDs instead of slugs
ockham Dec 16, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions client/state/action-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,9 @@ export const THEME_ACTIVATE_REQUEST_FAILURE = 'THEME_ACTIVATE_REQUEST_FAILURE';
export const THEME_REQUEST = 'THEME_REQUEST';
export const THEME_REQUEST_FAILURE = 'THEME_REQUEST_FAILURE';
export const THEME_REQUEST_SUCCESS = 'THEME_REQUEST_SUCCESS';
export const THEME_INSTALL = 'THEME_INSTALL';
export const THEME_INSTALL_SUCCESS = 'THEME_INSTALL_SUCCESS';
export const THEME_INSTALL_FAILURE = 'THEME_INSTALL_FAILURE';
export const THEME_BACK_PATH_SET = 'THEME_BACK_PATH_SET';
export const THEME_CLEAR_ACTIVATED = 'THEME_CLEAR_ACTIVATED';
export const THEME_UPLOAD_CLEAR = 'THEME_UPLOAD_CLEAR';
Expand Down
64 changes: 52 additions & 12 deletions client/state/themes/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,29 +13,32 @@ import {
ACTIVE_THEME_REQUEST,
ACTIVE_THEME_REQUEST_SUCCESS,
ACTIVE_THEME_REQUEST_FAILURE,
THEME_REQUEST,
THEME_REQUEST_SUCCESS,
THEME_REQUEST_FAILURE,
THEMES_RECEIVE,
THEMES_REQUEST,
THEMES_REQUEST_SUCCESS,
THEMES_REQUEST_FAILURE,
THEME_ACTIVATE_REQUEST,
THEME_ACTIVATE_REQUEST_SUCCESS,
THEME_ACTIVATE_REQUEST_FAILURE,
THEME_BACK_PATH_SET,
THEME_CLEAR_ACTIVATED,
THEME_UPLOAD_START,
THEME_UPLOAD_SUCCESS,
THEME_UPLOAD_FAILURE,
THEME_UPLOAD_CLEAR,
THEME_UPLOAD_PROGRESS,
THEME_INSTALL,
THEME_INSTALL_SUCCESS,
THEME_INSTALL_FAILURE,
THEME_REQUEST,
THEME_REQUEST_SUCCESS,
THEME_REQUEST_FAILURE,
THEME_TRANSFER_INITIATE_FAILURE,
THEME_TRANSFER_INITIATE_PROGRESS,
THEME_TRANSFER_INITIATE_REQUEST,
THEME_TRANSFER_INITIATE_SUCCESS,
THEME_TRANSFER_STATUS_FAILURE,
THEME_TRANSFER_STATUS_RECEIVE,
THEME_UPLOAD_START,
THEME_UPLOAD_SUCCESS,
THEME_UPLOAD_FAILURE,
THEME_UPLOAD_CLEAR,
THEME_UPLOAD_PROGRESS,
THEMES_RECEIVE,
THEMES_REQUEST,
THEMES_REQUEST_SUCCESS,
THEMES_REQUEST_FAILURE,
} from 'state/action-types';
import {
recordTracksEvent,
Expand Down Expand Up @@ -349,6 +352,43 @@ export function themeActivated( themeStylesheet, siteId, source = 'unknown', pur
return themeActivatedThunk; // it is named function just for testing purposes
}

/**
* Triggers a network request to install a WordPress.org or WordPress.com theme on a Jetpack site.
* To install a theme from WordPress.com, suffix the theme name with '-wpcom'. Note that this options
* requires Jetpack 4.4
*
* @param {String} themeId Theme ID. If suffixed with '-wpcom', install from WordPress.com
* @param {String} siteId Jetpack Site ID
* @return {Function} Action thunk
*/
export function installTheme( themeId, siteId ) {
return ( dispatch ) => {
dispatch( {
type: THEME_INSTALL,
siteId,
themeId
} );

return wpcom.undocumented().installThemeOnJetpack( siteId, themeId )
.then( ( theme ) => {
dispatch( receiveTheme( theme ) );
dispatch( {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could dispatch receiveTheme with the API result here if we want.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am adding it but It looks like we do only receive limited subset of theme data from the endpoint.

type: THEME_INSTALL_SUCCESS,
siteId,
themeId
} );
} )
.catch( ( error ) => {
dispatch( {
type: THEME_INSTALL_FAILURE,
siteId,
themeId,
error
} );
} );
};
}

/**
* Returns an action object to be used in signalling that theme activated status
* for site should be cleared
Expand Down
52 changes: 42 additions & 10 deletions client/state/themes/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,26 @@ import { mapValues, omit } from 'lodash';
*/
import ThemeQueryManager from 'lib/query-manager/theme';
import {
ACTIVE_THEME_REQUEST,
ACTIVE_THEME_REQUEST_SUCCESS,
ACTIVE_THEME_REQUEST_FAILURE,
DESERIALIZE,
SERIALIZE,
SERVER_DESERIALIZE,
THEME_ACTIVATE_REQUEST,
THEME_ACTIVATE_REQUEST_SUCCESS,
THEME_ACTIVATE_REQUEST_FAILURE,
THEME_CLEAR_ACTIVATED,
THEME_INSTALL,
THEME_INSTALL_SUCCESS,
THEME_INSTALL_FAILURE,
THEME_REQUEST,
THEME_REQUEST_SUCCESS,
THEME_REQUEST_FAILURE,
THEMES_RECEIVE,
THEMES_REQUEST,
THEMES_REQUEST_SUCCESS,
THEMES_REQUEST_FAILURE,
THEME_ACTIVATE_REQUEST,
THEME_ACTIVATE_REQUEST_SUCCESS,
THEME_ACTIVATE_REQUEST_FAILURE,
THEME_CLEAR_ACTIVATED,
ACTIVE_THEME_REQUEST,
ACTIVE_THEME_REQUEST_SUCCESS,
ACTIVE_THEME_REQUEST_FAILURE,
SERIALIZE,
DESERIALIZE,
SERVER_DESERIALIZE,
} from 'state/action-types';
import {
getSerializedThemesQuery,
Expand Down Expand Up @@ -159,6 +162,34 @@ export function themeRequests( state = {}, action ) {
return state;
}

/**
* Returns the updated Jetpack site wpcom theme install requests state after an action has been
* dispatched. The state reflects a mapping of site ID, theme ID pairing to a
* boolean reflecting whether a request for the theme install is in progress.
*
* @param {Object} state Current state
* @param {Object} action Action payload
* @return {Object} Updated state
*/
export function themeInstalls( state = {}, action ) {
switch ( action.type ) {
case THEME_INSTALL:
case THEME_INSTALL_SUCCESS:
case THEME_INSTALL_FAILURE:
return Object.assign( {}, state, {
[ action.siteId ]: Object.assign( {}, state[ action.siteId ], {
[ action.themeId ]: THEME_INSTALL === action.type
} )
} );

case SERIALIZE:
case DESERIALIZE:
return {};
}

return state;
}

/**
* Returns the updated site theme requests error state after an action has been
* dispatched. The state reflects a mapping of site ID, theme ID pairing to a
Expand Down Expand Up @@ -314,6 +345,7 @@ export default combineReducers( {
queryRequests,
queryRequestErrors,
lastQuery,
themeInstalls,
themeRequests,
themeRequestErrors,
activeThemes,
Expand Down
102 changes: 97 additions & 5 deletions client/state/themes/test/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,21 @@ import {
THEME_ACTIVATE_REQUEST_SUCCESS,
THEME_ACTIVATE_REQUEST_FAILURE,
THEME_CLEAR_ACTIVATED,
THEME_INSTALL,
THEME_INSTALL_SUCCESS,
THEME_INSTALL_FAILURE,
THEME_REQUEST,
THEME_REQUEST_SUCCESS,
THEME_REQUEST_FAILURE,
THEME_TRANSFER_INITIATE_FAILURE,
THEME_TRANSFER_INITIATE_REQUEST,
THEME_TRANSFER_INITIATE_SUCCESS,
THEME_TRANSFER_STATUS_FAILURE,
THEME_TRANSFER_STATUS_RECEIVE,
THEMES_RECEIVE,
THEMES_REQUEST,
THEMES_REQUEST_SUCCESS,
THEMES_REQUEST_FAILURE,
THEME_TRANSFER_STATUS_RECEIVE,
THEME_TRANSFER_STATUS_FAILURE,
THEME_TRANSFER_INITIATE_REQUEST,
THEME_TRANSFER_INITIATE_SUCCESS,
THEME_TRANSFER_INITIATE_FAILURE,
} from 'state/action-types';
import {
themeActivated,
Expand All @@ -40,6 +43,7 @@ import {
requestTheme,
pollThemeTransferStatus,
initiateThemeTransfer,
installTheme
} from '../actions';
import useNock from 'test/helpers/use-nock';

Expand Down Expand Up @@ -809,4 +813,92 @@ describe( 'actions', () => {
} );
} );
} );

describe( '#installTheme', () => {
const successResponse = {
id: 'karuna-wpcom',
screenshot: '//i0.wp.com/budzanowski.wpsandbox.me/wp-content/themes/karuna-wpcom/screenshot.png',
active: false,
name: 'Karuna',
theme_uri: 'https://wordpress.com/themes/karuna/',
description: 'Karuna is a clean business theme designed with health and wellness-focused sites in mind.' +
' With bright, bold colors, prominent featured images, and support for customer testimonials',
author: 'Automattic',
author_uri: 'http://wordpress.com/themes/',
version: '1.1.0',
autoupdate: false,
log: [
[
'Unpacking the package…',
'Installing the theme…',
'Theme installed successfully.'
]
]
};

const downloadFailureResponse = {
status: 400,
code: 'problem_fetching_theme',
message: 'Problem downloading theme'
};

const alreadyInstalledFailureResponse = {
status: 400,
code: 'theme_already_installed',
message: 'The theme is already installed'
};

useNock( ( nock ) => {
nock( 'https://public-api.wordpress.com:443' )
.persist()
.post( '/rest/v1.1/sites/2211667/themes/karuna-wpcom/install' )
.reply( 200, successResponse )
.post( '/rest/v1.1/sites/2211667/themes/typist-wpcom/install' )
.reply( 400, downloadFailureResponse )
.post( '/rest/v1.1/sites/2211667/themes/pinboard-wpcom/install' )
.reply( 400, alreadyInstalledFailureResponse );
} );

it( 'should dispatch install theme request action when triggered', () => {
installTheme( 'karuna-wpcom', 2211667 )( spy );

expect( spy ).to.have.been.calledWith( {
type: THEME_INSTALL,
siteId: 2211667,
themeId: 'karuna-wpcom'
} );
} );

it( 'should dispatch wpcom theme install request success action when request completes', () => {
return installTheme( 'karuna-wpcom', 2211667 )( spy ).then( () => {
expect( spy ).to.have.been.calledWith( {
type: THEME_INSTALL_SUCCESS,
siteId: 2211667,
themeId: 'karuna-wpcom',
} );
} );
} );

it( 'should dispatch wpcom theme install request failure action when theme was not found', () => {
return installTheme( 'typist-wpcom', 2211667 )( spy ).then( () => {
expect( spy ).to.have.been.calledWith( {
type: THEME_INSTALL_FAILURE,
siteId: 2211667,
themeId: 'typist-wpcom',
error: sinon.match( { message: 'Problem downloading theme' } ),
} );
} );
} );

it( 'should dispatch wpcom theme install request failure action when theme is already installed', () => {
return installTheme( 'pinboard-wpcom', 2211667 )( spy ).then( () => {
expect( spy ).to.have.been.calledWith( {
type: THEME_INSTALL_FAILURE,
siteId: 2211667,
themeId: 'pinboard-wpcom',
error: sinon.match( { message: 'The theme is already installed' } ),
} );
} );
} );
} );
} );
Loading