示例#1
0
	describe( 'noticesMiddleware()', () => {
		let store;
		useSandbox( ( sandbox ) => {
			store = createStore( () => 'Hello' );
			sandbox.spy( store, 'dispatch' );
		} );

		before( () => {
			handlers.DUMMY_TYPE = ( dispatch, action, getState ) => {
				dispatch( successNotice( `${ getState() } ${ action.target }` ) );
			};
		} );

		after( () => {
			delete handlers.DUMMY_TYPE;
		} );

		it( 'should trigger the observer corresponding to the dispatched action type', () => {
			noticesMiddleware( store )( noop )( { type: 'DUMMY_TYPE', target: 'World' } );

			expect( store.dispatch ).to.have.been.calledWithMatch( {
				type: NOTICE_CREATE,
				notice: {
					text: 'Hello World'
				}
			} );
		} );
	} );
示例#2
0
describe( 'SearchUrl', () => {
	let onSearch, onReplace, onPage;

	useSandbox( sandbox => {
		onSearch = sandbox.stub();
		onReplace = sandbox.stub( page, 'replace' );
		onPage = sandbox.stub( page, 'show' );
	} );

	test( 'should call onSearch if provided', () => {
		searchUrl( SEARCH_KEYWORD, '', onSearch );

		expect( onSearch ).to.have.been.calledWith( SEARCH_KEYWORD );
	} );

	test( 'should replace existing search keyword', () => {
		global.window = { location: { href: 'http://example.com/cat' } };

		searchUrl( SEARCH_KEYWORD, 'existing' );

		expect( onReplace ).to.have.been.calledWith( '/cat?s=' + SEARCH_KEYWORD );
	} );

	test( 'should set page URL if no existing keyword', () => {
		global.window = { location: { href: 'http://example.com/cat' } };

		searchUrl( SEARCH_KEYWORD );

		expect( onPage ).to.have.been.calledWith( '/cat?s=' + SEARCH_KEYWORD );
	} );
} );
示例#3
0
describe( 'wrap-es6-functions', () => {
	function assertCall( obj, args, key ) {
		test( key, () => {
			if ( isFunction( obj[ key ] ) ) {
				obj[ key ].apply( obj, args );
				assert( console.error.calledOnce ); // eslint-disable-line no-console
			}
		} );
	}

	useSandbox( sandbox => {
		sandbox.stub( console, 'error' );

		fromPairs(
			[
				[ Array, [ 'keys', 'entries', 'values', 'findIndex', 'fill', 'find', 'includes' ] ],
				[ String, [ 'codePointAt', 'normalize', 'repeat', 'startsWith', 'endsWith', 'includes' ] ],
			],
			( object, keys ) => {
				keys.forEach( key => {
					if ( isFunction( object.prototype[ key ] ) ) {
						sandbox.spy( object.prototype, key );
					}
				} );
			}
		);

		require( '../' )();
	} );

	describe( 'Array', () => {
		[ 'keys', 'entries', 'values', 'includes' ].forEach(
			partial( assertCall, Array.prototype, [] )
		);
		[ 'findIndex', 'find' ].forEach( partial( assertCall, Array.prototype, [ () => true ] ) );
		[ 'fill' ].forEach( partial( assertCall, Array.prototype, [ 1 ] ) );
	} );

	describe( 'String', () => {
		[ 'codePointAt', 'repeat' ].forEach( partial( assertCall, 'hello', [ 1 ] ) );
		[ 'startsWith', 'endsWith', 'includes' ].forEach( partial( assertCall, 'hello', [ 'a' ] ) );
		[ 'normalize' ].forEach( partial( assertCall, 'hello', [] ) );
	} );
} );
示例#4
0
	context( 'utility', () => {
		let dispatch;
		useSandbox( ( sandbox ) => {
			dispatch = sandbox.spy();
		} );

		describe( 'dispatchSuccess()', () => {
			it( 'should return a function which upon being called dispatches the specified success message', () => {
				dispatchSuccess( 'Success!' )( dispatch );

				expect( dispatch ).to.have.been.calledWithMatch( {
					type: NOTICE_CREATE,
					notice: {
						status: 'is-success',
						text: 'Success!'
					}
				} );
			} );
		} );
	} );
示例#5
0
describe( 'reducer', () => {
	useSandbox( ( sandbox ) => {
		sandbox.stub( console, 'warn' );
	} );

	it( 'should include expected keys in return value', () => {
		expect( reducer( undefined, {} ) ).to.have.keys( [
			'id',
			'currencyCode',
			'capabilities'
		] );
	} );

	describe( '#id()', () => {
		it( 'should default to null', () => {
			const state = id( undefined, {} );

			expect( state ).to.be.null;
		} );

		it( 'should set the current user ID', () => {
			const state = id( null, {
				type: CURRENT_USER_ID_SET,
				userId: 73705554
			} );

			expect( state ).to.equal( 73705554 );
		} );

		it( 'should validate ID is positive', () => {
			const state = id( -1, {
				type: DESERIALIZE
			} );

			expect( state ).to.equal( null );
		} );

		it( 'should validate ID is a number', () => {
			const state = id( 'foobar', {
				type: DESERIALIZE
			} );

			expect( state ).to.equal( null );
		} );

		it( 'returns valid ID', () => {
			const state = id( 73705554, {
				type: DESERIALIZE
			} );

			expect( state ).to.equal( 73705554 );
		} );

		it( 'will SERIALIZE current user', () => {
			const state = id( 73705554, {
				type: SERIALIZE
			} );

			expect( state ).to.equal( 73705554 );
		} );
	} );

	describe( '#currencyCode()', () => {
		it( 'should default to null', () => {
			const state = currencyCode( undefined, {} );
			expect( state ).to.equal( null );
		} );
		it( 'should set currency code when plans are received', () => {
			const state = currencyCode( undefined, {
				type: PLANS_RECEIVE,
				plans: [
					{
						product_id: 1001,
						currency_code: 'USD'
					}
				]
			} );
			expect( state ).to.equal( 'USD' );
		} );
		it( 'should return current state when we have empty plans', () => {
			const state = currencyCode( 'USD', {
				type: PLANS_RECEIVE,
				plans: []
			} );
			expect( state ).to.equal( 'USD' );
		} );
		it( 'should update current state when we receive new plans', () => {
			const state = currencyCode( 'USD', {
				type: PLANS_RECEIVE,
				plans: [
					{
						product_id: 1001,
						currency_code: 'EUR'
					}
				]
			} );
			expect( state ).to.equal( 'EUR' );
		} );
		it( 'should return current state when we have empty site plans', () => {
			const state = currencyCode( 'USD', {
				type: SITE_PLANS_FETCH_COMPLETED,
				plans: []
			} );
			expect( state ).to.equal( 'USD' );
		} );
		it( 'should set currency code when site plans are received', () => {
			const state = currencyCode( undefined, {
				type: SITE_PLANS_FETCH_COMPLETED,
				plans: [
					{
						productName: 'Free',
						currencyCode: 'USD'
					}
				]
			} );
			expect( state ).to.equal( 'USD' );
		} );
		it( 'should update currency code when site plans are received', () => {
			const state = currencyCode( 'USD', {
				type: SITE_PLANS_FETCH_COMPLETED,
				plans: [
					{
						productName: 'Free',
						currencyCode: 'CAD'
					}
				]
			} );
			expect( state ).to.equal( 'CAD' );
		} );
		it( 'should persist state', () => {
			const original = 'JPY';
			const state = currencyCode( original, {
				type: SERIALIZE
			} );
			expect( state ).to.equal( original );
		} );
		it( 'should restore valid persisted state', () => {
			const original = 'JPY';
			const state = currencyCode( original, {
				type: DESERIALIZE
			} );
			expect( state ).to.equal( original );
		} );
		it( 'should ignore invalid persisted state', () => {
			const original = 1234;
			const state = currencyCode( original, {
				type: DESERIALIZE
			} );
			expect( state ).to.equal( null );
		} );
	} );

	describe( 'capabilities()', () => {
		it( 'should default to an empty object', () => {
			const state = capabilities( undefined, {} );
			expect( state ).to.eql( {} );
		} );

		it( 'should track capabilities by single received site', () => {
			const state = capabilities( undefined, {
				type: SITE_RECEIVE,
				site: {
					ID: 2916284,
					capabilities: {
						manage_options: false
					}
				}
			} );

			expect( state ).to.eql( {
				2916284: {
					manage_options: false
				}
			} );
		} );

		it( 'should accumulate capabilities by received site', () => {
			const original = deepFreeze( {
				2916284: {
					manage_options: false
				}
			} );
			const state = capabilities( original, {
				type: SITE_RECEIVE,
				site: {
					ID: 77203074,
					capabilities: {
						manage_options: true
					}
				}
			} );

			expect( state ).to.eql( {
				2916284: {
					manage_options: false
				},
				77203074: {
					manage_options: true
				}
			} );
		} );

		it( 'should ignore received site if missing capabilities', () => {
			const state = capabilities( undefined, {
				type: SITE_RECEIVE,
				site: {
					ID: 2916284
				}
			} );

			expect( state ).to.eql( {} );
		} );

		it( 'should track capabilities by multiple received sites', () => {
			const state = capabilities( undefined, {
				type: SITES_RECEIVE,
				sites: [ {
					ID: 2916284,
					capabilities: {
						manage_options: false
					}
				} ]
			} );

			expect( state ).to.eql( {
				2916284: {
					manage_options: false
				}
			} );
		} );

		it( 'should ignore received sites if missing capabilities', () => {
			const state = capabilities( undefined, {
				type: SITES_RECEIVE,
				sites: [ {
					ID: 2916284
				} ]
			} );

			expect( state ).to.eql( {} );
		} );

		it( 'should persist state', () => {
			const original = deepFreeze( {
				2916284: {
					manage_options: false
				}
			} );
			const state = capabilities( original, {
				type: SERIALIZE
			} );

			expect( state ).to.equal( original );
		} );

		it( 'should restore valid persisted state', () => {
			const original = deepFreeze( {
				2916284: {
					manage_options: false
				}
			} );
			const state = capabilities( original, {
				type: DESERIALIZE
			} );

			expect( state ).to.equal( original );
		} );

		it( 'should not restore invalid persisted state', () => {
			const original = deepFreeze( {
				BAD2916284: {
					manage_options: false
				}
			} );
			const state = capabilities( original, {
				type: DESERIALIZE
			} );

			expect( state ).to.eql( {} );
		} );
	} );
} );
示例#6
0
describe( 'actions', () => {
	let sandbox, spy;

	useSandbox( newSandbox => {
		sandbox = newSandbox;
		spy = sandbox.spy();
	} );

	describe( '#receiveMediaStorage()', () => {
		it( 'should return an action object', () => {
			const siteId = 2916284;
			const mediaStorage = {
				max_storage_bytes: -1,
				storage_used_bytes: -1
			};
			const action = receiveMediaStorage( mediaStorage, 2916284 );
			expect( action ).to.eql( {
				type: SITE_MEDIA_STORAGE_RECEIVE,
				siteId,
				mediaStorage
			} );
		} );
	} );

	describe( '#receiveMediaStorage()', () => {
		before( () => {
			nock( 'https://public-api.wordpress.com:443' )
				.persist()
				.get( '/rest/v1.1/sites/2916284/media-storage' )
				.reply( 200, {
					max_storage_bytes: 3221225472,
					storage_used_bytes: 323506
				} )
				.get( '/rest/v1.1/sites/77203074/media-storage' )
				.reply( 403, {
					error: 'authorization_required',
					message: 'An active access token must be used to access media-storage.'
				} );
		} );

		after( () => {
			nock.cleanAll();
		} );

		it( 'should dispatch fetch action when thunk triggered', () => {
			requestMediaStorage( 2916284 )( spy );
			expect( spy ).to.have.been.calledWith( {
				type: SITE_MEDIA_STORAGE_REQUEST,
				siteId: 2916284
			} );
		} );

		it( 'should dispatch receive action when request completes', () => {
			return requestMediaStorage( 2916284 )( spy ).then( () => {
				expect( spy ).to.have.been.calledWith( {
					type: SITE_MEDIA_STORAGE_RECEIVE,
					mediaStorage: {
						max_storage_bytes: 3221225472,
						storage_used_bytes: 323506
					},
					siteId: 2916284
				} );
			} );
		} );

		it( 'should dispatch success action when request completes', () => {
			return requestMediaStorage( 2916284 )( spy ).then( () => {
				expect( spy ).to.have.been.calledWith( {
					type: SITE_MEDIA_STORAGE_REQUEST_SUCCESS,
					siteId: 2916284
				} );
			} );
		} );

		it( 'should dispatch fail action when request fails', () => {
			return requestMediaStorage( 77203074 )( spy ).then( () => {
				expect( spy ).to.have.been.calledWith( {
					type: SITE_MEDIA_STORAGE_REQUEST_FAILURE,
					siteId: 77203074,
					error: sandbox.match( { message: 'An active access token must be used to access media-storage.' } )
				} );
			} );
		} );
	} );
} );
示例#7
0
describe( 'reducer', () => {
	useSandbox( ( sandbox ) => {
		sandbox.stub( console, 'warn' );
	} );

	it( 'should export expected reducer keys', () => {
		expect( reducer( undefined, {} ) ).to.have.keys( [
			'jetpackConnectSite',
			'jetpackConnectAuthorize',
			'jetpackConnectSessions',
			'jetpackSSO',
			'jetpackSSOSessions'
		] );
	} );

	describe( '#jetpackConnectSessions()', () => {
		it( 'should default to an empty object', () => {
			const state = jetpackConnectSessions( undefined, {} );
			expect( state ).to.eql( {} );
		} );

		it( 'should add the url slug as a new property when checking a new url', () => {
			const state = jetpackConnectSessions( undefined, {
				type: JETPACK_CONNECT_CHECK_URL,
				url: 'https://website.com'
			} );

			expect( state ).to.have.property( 'website.com' ).to.be.a( 'object' );
		} );

		it( 'should store a timestamp when checking a new url', () => {
			const nowTime = ( new Date() ).getTime();
			const state = jetpackConnectSessions( undefined, {
				type: JETPACK_CONNECT_CHECK_URL,
				url: 'https://website.com'
			} );

			expect( state[ 'website.com' ] ).to.have.property( 'timestamp' )
				.to.be.at.least( nowTime );
		} );

		it( 'should update the timestamp when checking an existent url', () => {
			const nowTime = ( new Date() ).getTime();
			const state = jetpackConnectSessions( { 'website.com': { timestamp: 1 } }, {
				type: JETPACK_CONNECT_CHECK_URL,
				url: 'https://website.com'
			} );

			expect( state[ 'website.com' ] ).to.have.property( 'timestamp' )
				.to.be.at.least( nowTime );
		} );

		it( 'should not restore a state with a property without a timestamp', () => {
			const state = jetpackConnectSessions( { 'website.com': {} }, {
				type: DESERIALIZE
			} );

			expect( state ).to.be.eql( {} );
		} );

		it( 'should not restore a state with a property with a non-integer timestamp', () => {
			const state = jetpackConnectSessions( { 'website.com': { timestamp: '1' } }, {
				type: DESERIALIZE
			} );

			expect( state ).to.be.eql( {} );
		} );

		it( 'should not restore a state with a session stored with extra properties', () => {
			const state = jetpackConnectSessions( { 'website.com': { timestamp: 1, foo: 'bar' } }, {
				type: DESERIALIZE
			} );

			expect( state ).to.be.eql( {} );
		} );

		it( 'should restore a valid state', () => {
			const state = jetpackConnectSessions( { 'website.com': { timestamp: 1 } }, {
				type: DESERIALIZE
			} );

			expect( state ).to.be.eql( { 'website.com': { timestamp: 1 } } );
		} );

		it( 'should restore a valid state including dashes, slashes and semicolons', () => {
			const state = jetpackConnectSessions( { 'https://website.com:3000/test-one': { timestamp: 1 } }, {
				type: DESERIALIZE
			} );

			expect( state ).to.be.eql( { 'https://website.com:3000/test-one': { timestamp: 1 } } );
		} );
	} );

	describe( '#jetpackSSOSessions()', () => {
		it( 'should default to an empty object', () => {
			const state = jetpackConnectAuthorize( undefined, {} );
			expect( state ).to.eql( {} );
		} );

		it( 'should store an integer timestamp when creating new session', () => {
			const nowTime = ( new Date() ).getTime();
			const state = jetpackSSOSessions( undefined, {
				type: JETPACK_CONNECT_SSO_AUTHORIZE_SUCCESS,
				ssoUrl: 'https://website.com?action=jetpack-sso&result=success&sso_nonce={$nonce}&user_id={$user_id}'
			} );

			expect( state ).to.have.property( 'website.com' )
				.to.be.a( 'object' );
			expect( state[ 'website.com' ] ).to.have.property( 'timestamp' )
				.to.be.at.least( nowTime );
		} );
	} );

	describe( '#jetpackConnectAuthorize()', () => {
		it( 'should default to an empty object', () => {
			const state = jetpackConnectAuthorize( undefined, {} );
			expect( state ).to.eql( {} );
		} );
	} );

	describe( '#jetpackSSO()', () => {
		it( 'should default to an empty object', () => {
			const state = jetpackSSO( undefined, {} );
			expect( state ).to.eql( {} );
		} );

		it( 'should not persist state', () => {
			const original = deepFreeze( {
				isAuthorizing: false,
				site_id: 0,
				authorizationError: false,
				ssoUrl: 'http://website.com'
			} );

			const state = jetpackSSO( original, { type: SERIALIZE } );

			expect( state ).to.eql( {} );
		} );

		it( 'should set isValidating to true when validating', () => {
			const state = jetpackSSO( undefined, {
				type: JETPACK_CONNECT_SSO_VALIDATION_REQUEST
			} );

			expect( state ).to.have.property( 'isValidating', true );
		} );

		it( 'should set isAuthorizing to true when authorizing', () => {
			const state = jetpackSSO( undefined, {
				type: JETPACK_CONNECT_SSO_AUTHORIZE_REQUEST
			} );

			expect( state ).to.have.property( 'isAuthorizing', true );
		} );

		it( 'should set isValidating to false after validation', () => {
			const actions = [
				successfulSSOValidation,
				{
					type: JETPACK_CONNECT_SSO_VALIDATION_ERROR,
					error: {
						statusCode: 400
					}
				}
			];

			actions.forEach( ( action ) => {
				const state = jetpackSSO( undefined, action );
				expect( state ).to.have.property( 'isValidating', false );
			} );
		} );

		it( 'should store boolean nonceValid after validation', () => {
			const actions = [
				successfulSSOValidation,
				falseSSOValidation
			];

			actions.forEach( ( action ) => {
				const originalAction = deepFreeze( action );
				const state = jetpackSSO( undefined, originalAction );
				expect( state ).to.have.property( 'nonceValid', originalAction.success );
			} );
		} );

		it( 'should store blog details after successful validation', () => {
			const successState = jetpackSSO( undefined, successfulSSOValidation );
			expect( successState ).to.have.property( 'blogDetails' )
				.to.be.eql( successfulSSOValidation.blogDetails );
		} );

		it( 'should store empty object in blog_details when validation is false', () => {
			const failedState = jetpackSSO( undefined, falseSSOValidation );
			expect( failedState ).to.have.property( 'blogDetails' )
				.to.be.eql( {} );
		} );

		it( 'should set isAuthorizing to false after authorization', () => {
			const actions = [
				{
					type: JETPACK_CONNECT_SSO_AUTHORIZE_SUCCESS,
					ssoUrl: 'http://website.com'
				},
				{
					type: JETPACK_CONNECT_SSO_AUTHORIZE_ERROR,
					error: {
						statusCode: 400
					},
				}
			];

			actions.forEach( ( action ) => {
				const state = jetpackSSO( undefined, action );
				expect( state ).to.have.property( 'isAuthorizing', false );
			} );
		} );

		it( 'should store sso_url after authorization', () => {
			const action = deepFreeze( {
				type: JETPACK_CONNECT_SSO_AUTHORIZE_SUCCESS,
				ssoUrl: 'http://website.com'
			} );

			const state = jetpackSSO( undefined, action );

			expect( state ).to.have.property( 'ssoUrl', action.sso_url );
		} );
	} );
} );
示例#8
0
describe( 'actions', () => {
	let spy;

	useSandbox( sandbox => ( spy = sandbox.spy() ) );

	const siteId = 123456;
	const failedSiteId = 456789;
	const plugins = {
		data: {
			is_cache_enabled: true,
			is_super_cache_enabled: true,
		},
	};

	describe( '#receivePlugins()', () => {
		test( 'should return an action object', () => {
			const action = receivePlugins( siteId, plugins.data );

			expect( action ).to.eql( {
				type: WP_SUPER_CACHE_RECEIVE_PLUGINS,
				plugins: plugins.data,
				siteId,
			} );
		} );
	} );

	describe( '#requestPlugins()', () => {
		useNock( nock => {
			nock( 'https://public-api.wordpress.com' )
				.persist()
				.get( `/rest/v1.1/jetpack-blogs/${ siteId }/rest-api/` )
				.query( { path: '/wp-super-cache/v1/plugins' } )
				.reply( 200, plugins )
				.get( `/rest/v1.1/jetpack-blogs/${ failedSiteId }/rest-api/` )
				.query( { path: '/wp-super-cache/v1/plugins' } )
				.reply( 403, {
					error: 'authorization_required',
					message: 'User cannot access this private blog.',
				} );
		} );

		test( 'should dispatch fetch action when thunk triggered', () => {
			requestPlugins( siteId )( spy );

			expect( spy ).to.have.been.calledWith( {
				type: WP_SUPER_CACHE_REQUEST_PLUGINS,
				siteId,
			} );
		} );

		test( 'should dispatch receive action when request completes', () => {
			return requestPlugins( siteId )( spy ).then( () => {
				expect( spy ).to.have.been.calledWith( receivePlugins( siteId, plugins.data ) );
			} );
		} );

		test( 'should dispatch request success action when request completes', () => {
			return requestPlugins( siteId )( spy ).then( () => {
				expect( spy ).to.have.been.calledWith( {
					type: WP_SUPER_CACHE_REQUEST_PLUGINS_SUCCESS,
					siteId,
				} );
			} );
		} );

		test( 'should dispatch fail action when request fails', () => {
			return requestPlugins( failedSiteId )( spy ).then( () => {
				expect( spy ).to.have.been.calledWith( {
					type: WP_SUPER_CACHE_REQUEST_PLUGINS_FAILURE,
					siteId: failedSiteId,
					error: sinon.match( { message: 'User cannot access this private blog.' } ),
				} );
			} );
		} );
	} );

	describe( 'togglePlugin()', () => {
		const plugin = 'no_adverts_for_friends';
		const apiResponse = {
			data: {
				updated: true,
			},
		};

		useNock( nock => {
			nock( 'https://public-api.wordpress.com' )
				.persist()
				.post( `/rest/v1.1/jetpack-blogs/${ siteId }/rest-api/` )
				.query( { path: '/wp-super-cache/v1/plugins' } )
				.reply( 200, apiResponse )
				.post( `/rest/v1.1/jetpack-blogs/${ failedSiteId }/rest-api/` )
				.query( { path: '/wp-super-cache/v1/plugins' } )
				.reply( 403, {
					error: 'authorization_required',
					message: 'User cannot access this private blog.',
				} );
		} );

		test( 'should dispatch toggle action when thunk triggered', () => {
			togglePlugin( siteId, plugin )( spy );

			expect( spy ).to.have.been.calledWith( {
				type: WP_SUPER_CACHE_TOGGLE_PLUGIN,
				siteId,
				plugin,
			} );
		} );

		test( 'should dispatch receive action when request completes', () => {
			return togglePlugin( siteId, plugin )( spy ).then( () => {
				expect( spy ).to.have.been.calledWith( receivePlugins( siteId, apiResponse.data ) );
			} );
		} );

		test( 'should dispatch save success action when request completes', () => {
			return togglePlugin( siteId, plugin )( spy ).then( () => {
				expect( spy ).to.have.been.calledWith( {
					type: WP_SUPER_CACHE_TOGGLE_PLUGIN_SUCCESS,
					plugin,
					siteId,
				} );
			} );
		} );

		test( 'should dispatch fail action when request fails', () => {
			return togglePlugin( failedSiteId, plugin )( spy ).then( () => {
				expect( spy ).to.have.been.calledWith( {
					type: WP_SUPER_CACHE_TOGGLE_PLUGIN_FAILURE,
					siteId: failedSiteId,
					plugin,
					error: sinon.match( { message: 'User cannot access this private blog.' } ),
				} );
			} );
		} );
	} );
} );
示例#9
0
describe( 'reducer', () => {
	useSandbox( sandbox => {
		sandbox.stub( console, 'warn' );
	} );

	test( 'should include expected keys in return value', () => {
		expect( reducer( undefined, {} ) ).to.have.keys( [ 'requesting', 'items' ] );
	} );

	describe( '#requesting()', () => {
		test( 'should default to an empty object', () => {
			const state = requesting( undefined, {} );

			expect( state ).to.eql( {} );
		} );

		test( 'should set shortcode of that site ID to true value if a request is initiated', () => {
			const state = requesting(
				{},
				{
					type: SHORTCODE_REQUEST,
					siteId: 12345678,
					shortcode: 'test_shortcode',
				}
			);

			expect( state ).to.eql( {
				12345678: {
					test_shortcode: true,
				},
			} );
		} );

		test( 'should store the requested site IDs faultlessly if the site previously had no shortcodes', () => {
			const state = requesting(
				deepFreeze( {
					12345678: {},
				} ),
				{
					type: SHORTCODE_REQUEST,
					siteId: 12345678,
					shortcode: 'another_shortcode',
				}
			);

			expect( state ).to.eql( {
				12345678: {
					another_shortcode: true,
				},
			} );
		} );

		test( 'should accumulate the requested site IDs', () => {
			const state = requesting(
				deepFreeze( {
					12345678: {
						test_shortcode: true,
					},
				} ),
				{
					type: SHORTCODE_REQUEST,
					siteId: 87654321,
					shortcode: 'another_shortcode',
				}
			);

			expect( state ).to.eql( {
				12345678: {
					test_shortcode: true,
				},
				87654321: {
					another_shortcode: true,
				},
			} );
		} );

		test( 'should accumulate the requested shortcodes of given site IDs', () => {
			const state = requesting(
				deepFreeze( {
					12345678: {
						test_shortcode: false,
					},
					87654321: {
						another_shortcode: true,
					},
				} ),
				{
					type: SHORTCODE_REQUEST,
					siteId: 12345678,
					shortcode: 'some_shortcode',
				}
			);

			expect( state ).to.eql( {
				12345678: {
					test_shortcode: false,
					some_shortcode: true,
				},
				87654321: {
					another_shortcode: true,
				},
			} );
		} );

		test( 'should set shortcode of that site ID to false if request finishes successfully', () => {
			const state = requesting(
				deepFreeze( {
					12345678: {
						test_shortcode: true,
						another_shortcode: true,
					},
					87654321: {
						test_shortcode: true,
					},
				} ),
				{
					type: SHORTCODE_REQUEST_SUCCESS,
					siteId: 12345678,
					shortcode: 'test_shortcode',
				}
			);

			expect( state ).to.eql( {
				12345678: {
					test_shortcode: false,
					another_shortcode: true,
				},
				87654321: {
					test_shortcode: true,
				},
			} );
		} );

		test( 'should set shortcode of that site ID to false if request finishes unsuccessfully', () => {
			const state = requesting(
				deepFreeze( {
					12345678: {
						test_shortcode: true,
						another_shortcode: true,
					},
					87654321: {
						test_shortcode: true,
					},
				} ),
				{
					type: SHORTCODE_REQUEST_FAILURE,
					siteId: 12345678,
					shortcode: 'test_shortcode',
					error: 'The requested shortcode does not exist.',
				}
			);

			expect( state ).to.eql( {
				12345678: {
					test_shortcode: false,
					another_shortcode: true,
				},
				87654321: {
					test_shortcode: true,
				},
			} );
		} );

		test( 'should not persist state', () => {
			const state = requesting(
				deepFreeze( {
					12345678: {
						test_shortcode: true,
					},
				} ),
				{
					type: SERIALIZE,
				}
			);

			expect( state ).to.be.undefined;
		} );

		test( 'should not load persisted state', () => {
			const state = requesting(
				deepFreeze( {
					12345678: {
						test_shortcode: true,
					},
				} ),
				{
					type: DESERIALIZE,
				}
			);

			expect( state ).to.eql( {} );
		} );
	} );

	describe( '#items()', () => {
		const shortcodeData = {
			result: '<html></html>',
			shortcode: '[gallery ids="1,2,3"]',
			scripts: {},
			styles: {},
		};

		test( 'should default to an empty object', () => {
			const state = items( undefined, {} );

			expect( state ).to.eql( {} );
		} );

		test( 'should index shortcodes by site ID', () => {
			const state = items(
				{},
				{
					type: SHORTCODE_RECEIVE,
					siteId: 12345678,
					shortcode: 'test_shortcode',
					data: shortcodeData,
				}
			);

			expect( state ).to.eql( {
				12345678: {
					test_shortcode: shortcodeData,
				},
			} );
		} );

		test( 'should index shortcodes by site ID faultlessly if the site previously had no shortcodes', () => {
			const state = items(
				{
					12345678: {},
				},
				{
					type: SHORTCODE_RECEIVE,
					siteId: 12345678,
					shortcode: 'test_shortcode',
					data: shortcodeData,
				}
			);

			expect( state ).to.eql( {
				12345678: {
					test_shortcode: shortcodeData,
				},
			} );
		} );

		test( 'should accumulate sites', () => {
			const state = items(
				deepFreeze( {
					12345678: {
						test_shortcode: shortcodeData,
					},
				} ),
				{
					type: SHORTCODE_RECEIVE,
					siteId: 87654321,
					shortcode: 'test_shortcode',
					data: { ...shortcodeData, result: '<html></html>' },
				}
			);

			expect( state ).to.eql( {
				12345678: {
					test_shortcode: shortcodeData,
				},
				87654321: {
					test_shortcode: { ...shortcodeData, result: '<html></html>' },
				},
			} );
		} );

		test( 'should accumulate shortcodes in sites', () => {
			const state = items(
				deepFreeze( {
					12345678: {
						test_shortcode: shortcodeData,
					},
					87654321: {
						test_shortcode: { ...shortcodeData, result: '<html></html>' },
					},
				} ),
				{
					type: SHORTCODE_RECEIVE,
					siteId: 12345678,
					shortcode: 'another_shortcode',
					data: { ...shortcodeData, result: '<html><head></head></html>' },
				}
			);

			expect( state ).to.eql( {
				12345678: {
					test_shortcode: shortcodeData,
					another_shortcode: { ...shortcodeData, result: '<html><head></head></html>' },
				},
				87654321: {
					test_shortcode: { ...shortcodeData, result: '<html></html>' },
				},
			} );
		} );

		test( 'should override previous shortcodes of same site ID', () => {
			const state = items(
				deepFreeze( {
					12345678: {
						test_shortcode: shortcodeData,
					},
					87654321: {
						test_shortcode: { ...shortcodeData, result: '<html></html>' },
					},
				} ),
				{
					type: SHORTCODE_RECEIVE,
					siteId: 87654321,
					shortcode: 'test_shortcode',
					data: shortcodeData,
				}
			);

			expect( state ).to.eql( {
				12345678: {
					test_shortcode: shortcodeData,
				},
				87654321: {
					test_shortcode: shortcodeData,
				},
			} );
		} );

		test( 'should forget gallery shortcodes when receiving a MEDIA ITEM and the id matches', () => {
			const state = items(
				deepFreeze( {
					12345678: {
						test_shortcode: shortcodeData,
					},
					87654321: {
						test_shortcode: { ...shortcodeData, result: '<html></html>' },
					},
				} ),
				{
					type: 'FLUX_RECEIVE_MEDIA_ITEM',
					siteId: 87654321,
					data: {
						ID: 1,
					},
				}
			);

			expect( state ).to.eql( {
				12345678: {
					test_shortcode: shortcodeData,
				},
				87654321: {},
			} );
		} );

		test( 'should forget gallery shortcodes when receiving MEDIA ITEMS the ids match', () => {
			const state = items(
				deepFreeze( {
					12345678: {
						test_shortcode: shortcodeData,
					},
					87654321: {
						test_shortcode: { ...shortcodeData, result: '<html></html>' },
					},
				} ),
				{
					type: 'FLUX_RECEIVE_MEDIA_ITEMS',
					siteId: 87654321,
					data: {
						media: [ { ID: 1 }, { ID: 2 } ],
					},
				}
			);

			expect( state ).to.eql( {
				12345678: {
					test_shortcode: shortcodeData,
				},
				87654321: {},
			} );
		} );

		test( 'should persist state', () => {
			const state = items(
				deepFreeze( {
					12345678: {
						test_shortcode: shortcodeData,
					},
					87654321: {
						test_shortcode: { ...shortcodeData, result: '<html></html>' },
					},
				} ),
				{
					type: SERIALIZE,
				}
			);

			expect( state ).to.eql( {
				12345678: {
					test_shortcode: shortcodeData,
				},
				87654321: {
					test_shortcode: { ...shortcodeData, result: '<html></html>' },
				},
			} );
		} );

		test( 'should load valid persisted state', () => {
			const state = items(
				deepFreeze( {
					12345678: {
						test_shortcode: shortcodeData,
					},
					87654321: {
						test_shortcode: { ...shortcodeData, result: '<html></html>' },
					},
				} ),
				{
					type: DESERIALIZE,
				}
			);

			expect( state ).to.eql( {
				12345678: {
					test_shortcode: shortcodeData,
				},
				87654321: {
					test_shortcode: { ...shortcodeData, result: '<html></html>' },
				},
			} );
		} );

		test( 'should not load invalid persisted state', () => {
			const state = items(
				deepFreeze( {
					1234567: 'test_shortcode',
				} ),
				{
					type: DESERIALIZE,
				}
			);

			expect( state ).to.eql( {} );
		} );
	} );
} );
示例#10
0
describe( 'actions', () => {
	let spy;
	useSandbox( ( sandbox ) => spy = sandbox.spy() );

	describe( '#receiveCountryStates()', () => {
		it( 'should return an action object', () => {
			const action = receiveCountryStates( [
				{ code: 'AK', name: 'Alaska' },
				{ code: 'AS', name: 'American Samoa' }
			], 'US' );

			expect( action ).to.eql( {
				type: COUNTRY_STATES_RECEIVE,
				countryCode: 'us',
				countryStates: [
					{ code: 'AK', name: 'Alaska' },
					{ code: 'AS', name: 'American Samoa' }
				]
			} );
		} );
	} );

	describe( '#requestCountryStates()', () => {
		useNock( ( nock ) => {
			nock( 'https://public-api.wordpress.com:443' )
				.persist()
				.get( '/rest/v1.1/domains/supported-states/us' )
				.reply( 200, [
					{ code: 'AK', name: 'Alaska' },
					{ code: 'AS', name: 'American Samoa' }
				] )
				.get( '/rest/v1.1/domains/supported-states/ca' )
				.reply( 500, {
					error: 'server_error',
					message: 'A server error occurred',
				} );
		} );

		it( 'should dispatch fetch action when thunk triggered', () => {
			requestCountryStates( 'us' )( spy );

			expect( spy ).to.have.been.calledWith( {
				type: COUNTRY_STATES_REQUEST,
				countryCode: 'us'
			} );
		} );

		it( 'should dispatch country states receive action when request completes', () => {
			return requestCountryStates( 'us' )( spy ).then( () => {
				expect( spy ).to.have.been.calledWith( {
					type: COUNTRY_STATES_RECEIVE,
					countryCode: 'us',
					countryStates: [
						{ code: 'AK', name: 'Alaska' },
						{ code: 'AS', name: 'American Samoa' }
					]
				} );
			} );
		} );

		it( 'should dispatch country states request success action when request completes', () => {
			return requestCountryStates( 'us' )( spy ).then( () => {
				expect( spy ).to.have.been.calledWith( {
					type: COUNTRY_STATES_REQUEST_SUCCESS,
					countryCode: 'us'
				} );
			} );
		} );

		it( 'should dispatch fail action when request fails', () => {
			return requestCountryStates( 'ca' )( spy ).then( () => {
				expect( spy ).to.have.been.calledWith( {
					type: COUNTRY_STATES_REQUEST_FAILURE,
					countryCode: 'ca',
					error: sinon.match( { message: 'A server error occurred' } )
				} );
			} );
		} );
	} );
} );
示例#11
0
describe( 'reducer', () => {
	let sandbox;

	useSandbox( newSandbox => {
		sandbox = newSandbox;
		// mute off console warn
		sandbox.stub( console, 'warn' );
	} );

	test( 'should export expected reducer keys', () => {
		expect( plansReducer( undefined, {} ) ).to.have.keys( [ 'items', 'requesting', 'error' ] );
	} );

	describe( '#items()', () => {
		test( 'should default to an empty Array', () => {
			expect( itemsReducer( undefined, [] ) ).to.eql( [] );
		} );

		test( 'should index items state', () => {
			const initialState = undefined;
			const plans = WPCOM_RESPONSE;
			const action = plansReceiveAction( plans );
			const expectedState = plans;
			deepFreeze( expectedState );

			const newState = itemsReducer( initialState, action );

			expect( newState ).to.eql( expectedState );
		} );

		test( 'should override plans', () => {
			const plans = WPCOM_RESPONSE;
			const initialState = plans;
			const action = plansReceiveAction( plans );
			const expectedState = plans;

			deepFreeze( initialState );
			deepFreeze( expectedState );

			const newState = itemsReducer( initialState, action );

			expect( newState ).to.eql( expectedState );
		} );

		test( 'should persist state', () => {
			const plans = WPCOM_RESPONSE;
			const initialState = plans;
			const action = { type: 'SERIALIZE' };
			const expectedState = plans;

			deepFreeze( initialState );
			deepFreeze( expectedState );

			const newState = itemsReducer( initialState, action );

			expect( newState ).to.eql( expectedState );
		} );

		test( 'should load persisted state', () => {
			const plans = WPCOM_RESPONSE;
			const initialState = plans;
			const action = { type: 'DESERIALIZE' };
			const expectedState = plans;
			deepFreeze( initialState );
			deepFreeze( expectedState );

			const newState = itemsReducer( initialState, action );

			expect( newState ).to.eql( expectedState );
		} );

		test( 'should not load invalid persisted state', () => {
			// product_id should be `Number`
			const plans = [ { product_id: '234234' } ];
			const initialState = plans;
			const action = { type: 'DESERIALIZE' };
			deepFreeze( initialState );
			const expectedState = [];
			deepFreeze( expectedState );

			const newState = itemsReducer( initialState, action );

			expect( newState ).to.eql( expectedState );
		} );
	} );

	describe( '#requesting()', () => {
		test( 'should return FALSE when initial state is undefined and action is unknown', () => {
			expect( requestReducer( undefined, {} ) ).to.eql( false );
		} );

		test( 'should return TRUE when initial state is undefined and action is REQUEST', () => {
			const initialState = undefined;
			const action = requestPlans();
			const expectedState = true;
			deepFreeze( expectedState );

			const newState = requestReducer( initialState, action );

			expect( newState ).to.eql( expectedState );
		} );

		test( 'should update `requesting` state on SUCCESS', () => {
			const initialState = true;
			const action = plansRequestSuccessAction();
			const expectedState = false;

			deepFreeze( initialState );
			deepFreeze( expectedState );

			const newState = requestReducer( initialState, action );

			expect( newState ).to.eql( expectedState );
		} );

		test( 'should update `requesting` state on FAILURE', () => {
			const initialState = true;
			const action = plansRequestFailureAction();
			const expectedState = false;

			deepFreeze( initialState );
			deepFreeze( expectedState );

			const newState = requestReducer( initialState, action );

			expect( newState ).to.eql( expectedState );
		} );
	} );

	describe( '#errors()', () => {
		test( 'should return FALSE when initial state is undefined and action is unknown', () => {
			expect( errorReducer( undefined, {} ) ).to.eql( false );
		} );

		test( 'should set `error` state to TRUE on FAILURE', () => {
			const initialState = undefined;
			const action = plansRequestFailureAction();
			const expectedState = true;

			deepFreeze( expectedState );

			const newState = errorReducer( initialState, action );

			expect( newState ).to.eql( expectedState );
		} );

		test( 'should set `error` state to FALSE on REQUEST', () => {
			const initialState = true;
			const action = requestPlans();
			const expectedState = false;

			deepFreeze( initialState );
			deepFreeze( expectedState );

			const newState = errorReducer( initialState, action );

			expect( newState ).to.eql( expectedState );
		} );

		test( 'should set `error` state to FALSE on SUCCESS', () => {
			const initialState = true;
			const action = plansRequestSuccessAction();
			const expectedState = false;

			deepFreeze( initialState );
			deepFreeze( expectedState );

			const newState = errorReducer( initialState, action );

			expect( newState ).to.eql( expectedState );
		} );
	} );
} );
示例#12
0
describe( 'reducer', () => {
	useSandbox( sandbox => {
		sandbox.stub( console, 'warn' );
	} );

	test( 'should include expected keys in return value', () => {
		expect( reducer( undefined, {} ) ).to.have.keys( [ 'requests', 'items' ] );
	} );

	describe( 'requests()', () => {
		test( 'should default to an empty object', () => {
			const state = requests( undefined, {} );

			expect( state ).to.eql( {} );
		} );

		test( 'should track stats list request fetching', () => {
			const state = requests( undefined, {
				type: SITE_STATS_REQUEST,
				siteId: 2916284,
				statType: 'statsStreak',
				query: streakQuery,
			} );

			expect( state ).to.eql( {
				2916284: {
					statsStreak: {
						'[["endDate","2016-06-01"],["startDate","2015-06-01"]]': {
							requesting: true,
							status: 'pending',
						},
					},
				},
			} );
		} );

		test( 'should accumulate queries', () => {
			const original = deepFreeze( {
				2916284: {
					statsStreak: {
						'[["endDate","2016-07-01"],["startDate","2016-06-01"]]': {
							requesting: true,
							status: 'pending',
						},
					},
				},
			} );

			const state = requests( original, {
				type: SITE_STATS_REQUEST,
				siteId: 2916284,
				statType: 'statsStreak',
				query: streakQueryDos,
			} );

			expect( state ).to.eql( {
				2916284: {
					statsStreak: {
						'[["endDate","2016-07-01"],["startDate","2016-06-01"]]': {
							requesting: true,
							status: 'pending',
						},
						'[["endDate","2015-06-01"],["startDate","2014-06-01"]]': {
							requesting: true,
							status: 'pending',
						},
					},
				},
			} );
		} );

		test( 'should track stats request success', () => {
			const today = new Date();
			const state = requests( undefined, {
				type: SITE_STATS_RECEIVE,
				siteId: 2916284,
				statType: 'statsStreak',
				query: streakQuery,
				data: streakResponse,
				date: today,
			} );

			expect( state ).to.eql( {
				2916284: {
					statsStreak: {
						'[["endDate","2016-06-01"],["startDate","2015-06-01"]]': {
							requesting: false,
							status: 'success',
							date: today,
						},
					},
				},
			} );
		} );

		test( 'should track stats request failure', () => {
			const state = requests( undefined, {
				type: SITE_STATS_REQUEST_FAILURE,
				siteId: 2916284,
				statType: 'statsStreak',
				query: streakQuery,
				error: new Error(),
			} );

			expect( state ).to.eql( {
				2916284: {
					statsStreak: {
						'[["endDate","2016-06-01"],["startDate","2015-06-01"]]': {
							requesting: false,
							status: 'error',
						},
					},
				},
			} );
		} );

		test( 'should not persist state', () => {
			const original = deepFreeze( {
				2916284: {
					statsStreak: {
						'[["endDate","2016-07-01"],["startDate","2016-06-01"]]': {
							requesting: true,
							status: 'pending',
						},
					},
				},
			} );

			const state = requests( original, { type: SERIALIZE } );

			expect( state ).to.be.undefined;
		} );

		test( 'should not load persisted state', () => {
			const original = deepFreeze( {
				2916284: {
					statsStreak: {
						'[["endDate","2016-07-01"],["startDate","2016-06-01"]]': {
							requesting: true,
							status: 'pending',
						},
					},
				},
			} );

			const state = requests( original, { type: DESERIALIZE } );

			expect( state ).to.eql( {} );
		} );
	} );

	describe( 'items()', () => {
		test( 'should persist state', () => {
			const original = deepFreeze( {
				2916284: {
					statsStreak: {
						'[["endDate","2016-07-01"],["startDate","2016-06-01"]]': streakResponse,
					},
				},
			} );
			const state = items( original, { type: SERIALIZE } );

			expect( state ).to.eql( original );
		} );

		test( 'should load valid persisted state', () => {
			const original = deepFreeze( {
				2916284: {
					statsStreak: {
						'[["endDate","2016-07-01"],["startDate","2016-06-01"]]': streakResponse,
					},
				},
			} );
			const state = items( original, { type: DESERIALIZE } );

			expect( state ).to.eql( original );
		} );

		test( 'should not load invalid persisted state', () => {
			const original = deepFreeze( {
				2916284: {
					'[["endDate","2016-07-01"],["startDate","2016-06-01"]]': streakResponse,
				},
			} );
			const state = items( original, { type: DESERIALIZE } );

			expect( state ).to.eql( {} );
		} );

		test( 'should default to an empty object', () => {
			const state = items( undefined, {} );

			expect( state ).to.eql( {} );
		} );

		test( 'should add received stats', () => {
			const state = items( undefined, {
				type: SITE_STATS_RECEIVE,
				siteId: 2916284,
				statType: 'statsStreak',
				query: streakQuery,
				data: streakResponse,
			} );

			expect( state ).to.eql( {
				2916284: {
					statsStreak: {
						'[["endDate","2016-06-01"],["startDate","2015-06-01"]]': streakResponse,
					},
				},
			} );
		} );

		test( 'should accumulate received stats by statType', () => {
			const original = deepFreeze( {
				2916284: {
					statsStreak: {
						'[["endDate","2016-07-01"],["startDate","2016-06-01"]]': streakResponse,
					},
				},
			} );

			const state = items( original, {
				type: SITE_STATS_RECEIVE,
				siteId: 2916284,
				statType: 'statsStreak',
				query: streakQueryDos,
				data: streakResponseDos,
			} );

			expect( state ).to.eql( {
				2916284: {
					statsStreak: {
						'[["endDate","2016-07-01"],["startDate","2016-06-01"]]': streakResponse,
						'[["endDate","2015-06-01"],["startDate","2014-06-01"]]': streakResponseDos,
					},
				},
			} );
		} );

		test( 'should change root site property when received stats by statType', () => {
			const original = deepFreeze( {
				2916284: {
					statsStreak: {
						'[["endDate","2016-07-01"],["startDate","2016-06-01"]]': streakResponse,
					},
				},
			} );

			const state = items( original, {
				type: SITE_STATS_RECEIVE,
				siteId: 2916284,
				statType: 'statsStreak',
				query: streakQueryDos,
				data: streakResponseDos,
			} );

			expect( state[ 2916284 ] ).to.not.equal( original[ 2916284 ] );
		} );

		test( 'should add additional statTypes', () => {
			const original = deepFreeze( {
				2916284: {
					statsStreak: {
						'[["endDate","2016-07-01"],["startDate","2016-06-01"]]': streakResponse,
					},
				},
			} );

			const state = items( original, {
				type: SITE_STATS_RECEIVE,
				siteId: 2916284,
				statType: 'statsCountryViews',
				query: streakQuery,
				data: {},
			} );

			expect( state ).to.eql( {
				2916284: {
					statsStreak: {
						'[["endDate","2016-07-01"],["startDate","2016-06-01"]]': streakResponse,
					},
					statsCountryViews: {
						'[["endDate","2016-06-01"],["startDate","2015-06-01"]]': {},
					},
				},
			} );
		} );

		test( 'should should not change another statTypes property', () => {
			const original = deepFreeze( {
				2916284: {
					statsStreak: {
						'[["endDate","2016-07-01"],["startDate","2016-06-01"]]': streakResponse,
					},
				},
			} );

			const state = items( original, {
				type: SITE_STATS_RECEIVE,
				siteId: 2916284,
				statType: 'statsCountryViews',
				query: streakQuery,
				data: {},
			} );

			expect( state[ 2916284 ].statsStreak ).to.equal( original[ 2916284 ].statsStreak );
		} );

		test( 'should not change another site property', () => {
			const original = deepFreeze( {
				2916284: {
					statsStreak: {
						'[["endDate","2016-07-01"],["startDate","2016-06-01"]]': streakResponse,
					},
				},
			} );

			const state = items( original, {
				type: SITE_STATS_RECEIVE,
				siteId: 3916284,
				statType: 'statsCountryViews',
				query: streakQuery,
				data: {},
			} );

			expect( state[ 2916284 ].statsStreak ).to.equal( original[ 2916284 ].statsStreak );
		} );
	} );
} );
示例#13
0
describe( 'reducer', () => {
	useSandbox( ( sandbox ) => {
		sandbox.stub( console, 'warn' );
	} );

	it( 'should include expected keys in return value', () => {
		expect( reducer( undefined, {} ) ).to.have.keys( [
			'requesting',
			'items'
		] );
	} );

	describe( '#requesting()', () => {
		it( 'should default to an false', () => {
			const state = requesting( undefined, {} );

			expect( state ).to.be.false;
		} );

		it( 'should set requesting to true value if a request is initiated', () => {
			const state = requesting( undefined, {
				type: BILLING_TRANSACTIONS_REQUEST,
			} );

			expect( state ).to.be.true;
		} );

		it( 'should set requesting to false if request finishes successfully', () => {
			const state = requesting( true, {
				type: BILLING_TRANSACTIONS_REQUEST_SUCCESS,
			} );

			expect( state ).to.eql( false );
		} );

		it( 'should set requesting to false if request finishes unsuccessfully', () => {
			const state = requesting( true, {
				type: BILLING_TRANSACTIONS_REQUEST_FAILURE,
			} );

			expect( state ).to.eql( false );
		} );

		it( 'should not persist state', () => {
			const state = requesting( true, {
				type: SERIALIZE
			} );

			expect( state ).to.eql( false );
		} );

		it( 'should not load persisted state', () => {
			const state = requesting( true, {
				type: DESERIALIZE
			} );

			expect( state ).to.eql( false );
		} );
	} );

	describe( '#items()', () => {
		const billingTransactions = {
			past: [
				{
					id: '12345678',
					amount: '$1.23',
				}
			],
			upcoming: [
				{
					id: '87654321',
					amount: '$4.56',
				}
			]
		};

		it( 'should default to empty object', () => {
			const state = items( undefined, {} );

			expect( state ).to.eql( {} );
		} );

		it( 'should store the billing transactions properly', () => {
			const state = items( null, {
				type: BILLING_TRANSACTIONS_RECEIVE,
				...billingTransactions
			} );

			expect( state ).to.eql( billingTransactions );
		} );

		it( 'should override previous billing transactions', () => {
			const state = items( deepFreeze( {
				past: [
					{
						id: '11223344',
						amount: '$3.43',
						desc: 'test'
					}
				],
				upcoming: [
					{
						id: '88776655',
						amount: '$1.11',
						product: 'example'
					}
				]
			} ), {
				type: BILLING_TRANSACTIONS_RECEIVE,
				...billingTransactions
			} );

			expect( state ).to.eql( billingTransactions );
		} );

		it( 'should persist state', () => {
			const state = items( deepFreeze( billingTransactions ), {
				type: SERIALIZE
			} );

			expect( state ).to.eql( billingTransactions );
		} );

		it( 'should load valid persisted state', () => {
			const state = items( deepFreeze( billingTransactions ), {
				type: DESERIALIZE
			} );

			expect( state ).to.eql( billingTransactions );
		} );

		it( 'should not load invalid persisted state', () => {
			const state = items( deepFreeze( {
				example: 'test'
			} ), {
				type: DESERIALIZE
			} );

			expect( state ).to.eql( {} );
		} );
	} );
} );
示例#14
0
describe( 'PreferencesActions', function() {
	let sandbox, PreferencesActions, getSettings, postSettings;
	const store = { get: noop, set: noop };
	const Dispatcher = { handleViewAction: noop, handleServerAction: noop };

	useSandbox( ( _sandbox ) => sandbox = _sandbox );
	useMockery();
	useNock();

	before( function() {
		mockery.registerMock( 'lib/user/utils', { isLoggedIn: () => true } );
		mockery.registerMock( 'store', store );
		mockery.registerMock( 'dispatcher', Dispatcher );
		mockery.registerMock( 'lib/wp', {
			undocumented: function() {
				return {
					me: function() {
						return {
							settings: function() {
								return {
									get: getSettings,
									update: postSettings
								};
							}
						};
					}
				};
			}
		} );

		PreferencesActions = require( '../actions' );
	} );

	beforeEach( function() {
		sandbox.restore();
		sandbox.stub( store, 'get' );
		sandbox.stub( store, 'set' );
		sandbox.stub( Dispatcher, 'handleViewAction' );
		sandbox.stub( Dispatcher, 'handleServerAction' );

		getSettings = sandbox.stub().callsArgWithAsync( 0, null, {
			[ USER_SETTING_KEY ]: DUMMY_PERSISTED_PREFERENCES
		} );
		postSettings = sandbox.stub().callsArgAsync( 1 );
	} );

	describe( '#fetch()', function() {
		it( 'should retrieve from localStorage and trigger a request to the REST API', function( done ) {
			store.get.restore();
			sandbox.stub( store, 'get' ).returns( DUMMY_PERSISTED_PREFERENCES );

			PreferencesActions.fetch();

			expect( store.get ).to.have.been.calledWith( LOCALSTORAGE_KEY );
			expect( Dispatcher.handleServerAction ).to.have.been.calledWithMatch( {
				type: 'RECEIVE_ME_SETTINGS',
				data: {
					[ USER_SETTING_KEY ]: DUMMY_PERSISTED_PREFERENCES
				}
			} );

			process.nextTick( function() {
				expect( Dispatcher.handleServerAction ).to.have.been.calledTwice;
				expect( store.set ).to.have.been.calledWith( LOCALSTORAGE_KEY, DUMMY_PERSISTED_PREFERENCES );
				done();
			} );
		} );

		it( 'should not persist to localStorage from remote request if error occurs', function( done ) {
			sandbox.stub( PreferencesActions, 'mergePreferencesToLocalStorage' );

			getSettings = sandbox.stub().callsArgWithAsync( 0, true );

			PreferencesActions.fetch();
			process.nextTick( function() {
				expect( PreferencesActions.mergePreferencesToLocalStorage ).to.not.have.been.called;
				done();
			} );
		} );

		it( 'should not dispatch an empty local store', function( done ) {
			store.get.restore();
			sandbox.stub( store, 'get' ).returns( undefined );

			PreferencesActions.fetch();

			expect( store.get ).to.have.been.calledWith( LOCALSTORAGE_KEY );
			expect( Dispatcher.handleServerAction ).to.not.have.been.called;

			process.nextTick( function() {
				expect( Dispatcher.handleServerAction ).to.have.been.calledOnce;
				expect( store.set ).to.have.been.calledWith(
					LOCALSTORAGE_KEY,
					DUMMY_PERSISTED_PREFERENCES
				);
				done();
			} );
		} );
	} );

	describe( '#set()', function() {
		it( 'should save to localStorage and trigger a request to the REST API', function( done ) {
			PreferencesActions.set( 'one', 1 );

			expect( store.set ).to.have.been.calledWith( LOCALSTORAGE_KEY, { one: 1 } );
			expect( Dispatcher.handleViewAction ).to.have.been.calledWithMatch( {
				type: 'UPDATE_ME_SETTINGS'
			} );
			expect( postSettings ).to.have.been.calledWithMatch( JSON.stringify( {
				[ USER_SETTING_KEY ]: { one: 1 }
			} ) );

			process.nextTick( function() {
				expect( Dispatcher.handleServerAction ).to.have.been.calledWithMatch( {
					type: 'RECEIVE_ME_SETTINGS'
				} );
				done();
			} );
		} );

		it( 'should add to, not replace, existing values', function() {
			store.get.restore();
			sandbox.stub( store, 'get' ).returns( { one: 1 } );
			PreferencesActions.set( 'two', 2 );

			expect( store.set ).to.have.been.calledWith( LOCALSTORAGE_KEY, { one: 1, two: 2 } );
			expect( Dispatcher.handleViewAction ).to.have.been.calledWithMatch( {
				type: 'UPDATE_ME_SETTINGS',
				data: {
					[ USER_SETTING_KEY ]: { two: 2 }
				}
			} );
		} );

		it( 'should assume a null value is to be removed', function() {
			PreferencesActions.set( 'one', 1 );
			PreferencesActions.set( 'one', null );

			expect( store.set ).to.have.been.calledWith( LOCALSTORAGE_KEY, { one: 1 } );
			expect( store.set ).to.have.been.calledWith( LOCALSTORAGE_KEY, {} );
			expect( Dispatcher.handleViewAction ).to.have.been.calledWithMatch( {
				type: 'UPDATE_ME_SETTINGS',
				data: {
					[ USER_SETTING_KEY ]: { one: null }
				}
			} );
		} );

		it( 'should only dispatch a receive after all pending updates have finished', function( done ) {
			PreferencesActions.set( 'one', 1 );
			PreferencesActions.set( 'one', null );

			process.nextTick( function() {
				expect( postSettings ).to.have.been.calledTwice;
				expect( Dispatcher.handleServerAction ).to.have.been.calledOnce;
				expect( Dispatcher.handleServerAction ).to.have.been.calledWithMatch( { type: 'RECEIVE_ME_SETTINGS' } );
				done();
			} );
		} );
	} );

	describe( '#remove()', function() {
		it( 'should remove from localStorage and trigger a request to the REST API', function( done ) {
			PreferencesActions.set( 'one', 1 );
			PreferencesActions.remove( 'one' );

			expect( store.set ).to.have.been.calledWith( LOCALSTORAGE_KEY, {} );
			expect( Dispatcher.handleViewAction ).to.have.been.calledWithMatch( {
				type: 'UPDATE_ME_SETTINGS',
				data: {
					[ USER_SETTING_KEY ]: { one: 1 }
				}
			} );
			expect( postSettings ).to.have.been.calledWithMatch( JSON.stringify( {
				[ USER_SETTING_KEY ]: { one: 1 }
			} ) );

			process.nextTick( function() {
				expect( Dispatcher.handleServerAction ).to.have.been.calledWithMatch( {
					type: 'RECEIVE_ME_SETTINGS'
				} );

				done();
			} );
		} );
	} );
} );
示例#15
0
	context( 'handlers', () => {
		let dispatch;
		useSandbox( ( sandbox ) => {
			dispatch = sandbox.spy();
		} );

		describe( 'onPostDeleteFailure()', () => {
			it( 'should dispatch error notice with truncated title if known', () => {
				onPostDeleteFailure( dispatch, {
					type: POST_DELETE_FAILURE,
					siteId: 2916284,
					postId: 841
				}, () => ( {
					posts: {
						queries: {
							2916284: new PostQueryManager( {
								items: {
									841: {
										ID: 841,
										site_ID: 2916284,
										global_ID: '3d097cb7c5473c169bba0eb8e3c6cb64',
										title: 'Hello World, This Should Be Truncated'
									}
								}
							} )
						}
					}
				} ) );

				expect( dispatch ).to.have.been.calledWithMatch( {
					type: NOTICE_CREATE,
					notice: {
						status: 'is-error',
						text: 'An error occurred while deleting "Hello World, This Sho..."'
					}
				} );
			} );

			it( 'should dispatch error notice with unknown title', () => {
				onPostDeleteFailure( dispatch, {
					type: POST_DELETE_FAILURE,
					siteId: 2916284,
					postId: 841
				}, () => ( {
					posts: {
						queries: {}
					}
				} ) );

				expect( dispatch ).to.have.been.calledWithMatch( {
					type: NOTICE_CREATE,
					notice: {
						status: 'is-error',
						text: 'An error occurred while deleting the post'
					}
				} );
			} );
		} );

		describe( 'onPostRestoreFailure()', () => {
			it( 'should dispatch error notice with truncated title if known', () => {
				onPostRestoreFailure( dispatch, {
					type: POST_RESTORE_FAILURE,
					siteId: 2916284,
					postId: 841
				}, () => ( {
					posts: {
						queries: {
							2916284: new PostQueryManager( {
								items: {
									841: {
										ID: 841,
										site_ID: 2916284,
										global_ID: '3d097cb7c5473c169bba0eb8e3c6cb64',
										title: 'Hello World, This Should Be Truncated'
									}
								}
							} )
						}
					}
				} ) );

				expect( dispatch ).to.have.been.calledWithMatch( {
					type: NOTICE_CREATE,
					notice: {
						status: 'is-error',
						text: 'An error occurred while restoring "Hello World, This Sho..."'
					}
				} );
			} );

			it( 'should dispatch error notice with unknown title', () => {
				onPostRestoreFailure( dispatch, {
					type: POST_RESTORE_FAILURE,
					siteId: 2916284,
					postId: 841
				}, () => ( {
					posts: {
						queries: {}
					}
				} ) );

				expect( dispatch ).to.have.been.calledWithMatch( {
					type: NOTICE_CREATE,
					notice: {
						status: 'is-error',
						text: 'An error occurred while restoring the post'
					}
				} );
			} );
		} );

		describe( 'onPostSaveSuccess()', () => {
			it( 'should not dispatch if status has no corresponding text', () => {
				onPostSaveSuccess( dispatch, {
					type: POST_SAVE_SUCCESS,
					post: {
						title: 'Hello World',
						status: 'invalid'
					}
				} );

				expect( dispatch ).to.not.have.been.calledWithMatch( {
					type: NOTICE_CREATE
				} );
			} );

			it( 'should dispatch success notice for trash', () => {
				onPostSaveSuccess( dispatch, {
					type: POST_SAVE_SUCCESS,
					post: { status: 'trash' }
				} );

				expect( dispatch ).to.have.been.calledWithMatch( {
					type: NOTICE_CREATE,
					notice: {
						status: 'is-success',
						text: 'Post successfully moved to trash'
					}
				} );
			} );

			it( 'should dispatch success notice for publish', () => {
				onPostSaveSuccess( dispatch, {
					type: POST_SAVE_SUCCESS,
					post: { status: 'publish' }
				} );

				expect( dispatch ).to.have.been.calledWithMatch( {
					type: NOTICE_CREATE,
					notice: {
						status: 'is-success',
						text: 'Post successfully published'
					}
				} );
			} );
		} );
	} );
示例#16
0
describe( 'reducer', () => {
	const primarySiteId = 123456;
	const secondarySiteId = 456789;

	useSandbox( sandbox => {
		sandbox.stub( console, 'warn' );
	} );

	describe( 'deleteStatus()', () => {
		const previousState = deepFreeze( {
			deleteStatus: {
				[ primarySiteId ]: {
					deleting: true,
					status: 'pending',
				},
			},
		} );

		test( 'should default to an empty object', () => {
			const state = reducer( undefined, {} );

			expect( state.deleteStatus ).to.eql( {} );
		} );

		test( 'should set request to true if request in progress', () => {
			const state = reducer( undefined, {
				type: WP_SUPER_CACHE_DELETE_CACHE,
				siteId: primarySiteId,
			} );

			expect( state.deleteStatus ).to.eql( {
				[ primarySiteId ]: {
					deleting: true,
					status: 'pending',
				},
			} );
		} );

		test( 'should accumulate requesting values', () => {
			const state = reducer( previousState, {
				type: WP_SUPER_CACHE_DELETE_CACHE,
				siteId: secondarySiteId,
			} );

			expect( state.deleteStatus ).to.eql( {
				[ primarySiteId ]: {
					deleting: true,
					status: 'pending',
				},
				[ secondarySiteId ]: {
					deleting: true,
					status: 'pending',
				},
			} );
		} );

		test( 'should set request to false if request finishes successfully', () => {
			const state = reducer( previousState, {
				type: WP_SUPER_CACHE_DELETE_CACHE_SUCCESS,
				siteId: primarySiteId,
			} );

			expect( state.deleteStatus ).to.eql( {
				[ primarySiteId ]: {
					deleting: false,
					status: 'success',
				},
			} );
		} );

		test( 'should set request to false if request finishes with failure', () => {
			const state = reducer( previousState, {
				type: WP_SUPER_CACHE_DELETE_CACHE_FAILURE,
				siteId: primarySiteId,
			} );

			expect( state.deleteStatus ).to.eql( {
				[ primarySiteId ]: {
					deleting: false,
					status: 'error',
				},
			} );
		} );

		test( 'should not persist state', () => {
			const state = reducer( previousState, {
				type: SERIALIZE,
			} );

			expect( state ).to.be.undefined;
		} );

		test( 'should not load persisted state', () => {
			const state = reducer( previousState, {
				type: DESERIALIZE,
			} );

			expect( state.deleteStatus ).to.eql( {} );
		} );
	} );

	describe( 'testing()', () => {
		const previousState = deepFreeze( {
			testing: {
				[ primarySiteId ]: true,
			},
		} );

		test( 'should default to an empty object', () => {
			const state = reducer( undefined, {} );

			expect( state.testing ).to.eql( {} );
		} );

		test( 'should set testing value to true if request in progress', () => {
			const state = reducer( undefined, {
				type: WP_SUPER_CACHE_TEST_CACHE,
				siteId: primarySiteId,
			} );

			expect( state.testing ).to.eql( {
				[ primarySiteId ]: true,
			} );
		} );

		test( 'should accumulate testing values', () => {
			const state = reducer( previousState, {
				type: WP_SUPER_CACHE_TEST_CACHE,
				siteId: secondarySiteId,
			} );

			expect( state.testing ).to.eql( {
				[ primarySiteId ]: true,
				[ secondarySiteId ]: true,
			} );
		} );

		test( 'should set testing value to false if request finishes successfully', () => {
			const state = reducer( previousState, {
				type: WP_SUPER_CACHE_TEST_CACHE_SUCCESS,
				siteId: primarySiteId,
			} );

			expect( state.testing ).to.eql( {
				[ primarySiteId ]: false,
			} );
		} );

		test( 'should set testing value to false if request finishes with failure', () => {
			const state = reducer( previousState, {
				type: WP_SUPER_CACHE_TEST_CACHE_FAILURE,
				siteId: primarySiteId,
			} );

			expect( state.testing ).to.eql( {
				[ primarySiteId ]: false,
			} );
		} );

		test( 'should not persist state', () => {
			const state = reducer( previousState, {
				type: SERIALIZE,
			} );

			expect( state ).to.be.undefined;
		} );

		test( 'should not load persisted state', () => {
			const state = reducer( previousState, {
				type: DESERIALIZE,
			} );

			expect( state.testing ).to.eql( {} );
		} );
	} );

	describe( 'preloading()', () => {
		const previousState = deepFreeze( {
			preloading: {
				[ primarySiteId ]: true,
			},
		} );

		test( 'should default to an empty object', () => {
			const state = reducer( undefined, {} );

			expect( state.preloading ).to.eql( {} );
		} );

		test( 'should set preloading value to true if request in progress', () => {
			const state = reducer( undefined, {
				type: WP_SUPER_CACHE_PRELOAD_CACHE,
				siteId: primarySiteId,
			} );

			expect( state.preloading ).to.eql( {
				[ primarySiteId ]: true,
			} );
		} );

		test( 'should accumulate preloading values', () => {
			const state = reducer( previousState, {
				type: WP_SUPER_CACHE_PRELOAD_CACHE,
				siteId: secondarySiteId,
			} );

			expect( state.preloading ).to.eql( {
				[ primarySiteId ]: true,
				[ secondarySiteId ]: true,
			} );
		} );

		test( 'should set preloading value to false if request finishes successfully', () => {
			const state = reducer( previousState, {
				type: WP_SUPER_CACHE_PRELOAD_CACHE_SUCCESS,
				siteId: primarySiteId,
			} );

			expect( state.preloading ).to.eql( {
				[ primarySiteId ]: false,
			} );
		} );

		test( 'should set preloading value to false if request finishes with failure', () => {
			const state = reducer( previousState, {
				type: WP_SUPER_CACHE_PRELOAD_CACHE_FAILURE,
				siteId: primarySiteId,
			} );

			expect( state.preloading ).to.eql( {
				[ primarySiteId ]: false,
			} );
		} );

		test( 'should not persist state', () => {
			const state = reducer( previousState, {
				type: SERIALIZE,
			} );

			expect( state ).to.be.undefined;
		} );

		test( 'should not load persisted state', () => {
			const state = reducer( previousState, {
				type: DESERIALIZE,
			} );

			expect( state.preloading ).to.eql( {} );
		} );
	} );

	describe( 'items()', () => {
		const primaryResults = {
			attempts: {
				first: {
					status: 'OK',
				},
			},
		};
		const secondaryResults = {
			attempts: {
				second: {
					status: 'FAILED',
				},
			},
		};
		const previousState = deepFreeze( {
			items: {
				[ primarySiteId ]: primaryResults,
			},
		} );

		test( 'should default to an empty object', () => {
			const state = reducer( undefined, {} );

			expect( state.items ).to.eql( {} );
		} );

		test( 'should index cache test results by site ID', () => {
			const state = reducer( undefined, {
				type: WP_SUPER_CACHE_TEST_CACHE_SUCCESS,
				siteId: primarySiteId,
				data: primaryResults,
			} );

			expect( state.items ).to.eql( {
				[ primarySiteId ]: primaryResults,
			} );
		} );

		test( 'should accumulate cache test results', () => {
			const state = reducer( previousState, {
				type: WP_SUPER_CACHE_TEST_CACHE_SUCCESS,
				siteId: secondarySiteId,
				data: secondaryResults,
			} );

			expect( state.items ).to.eql( {
				[ primarySiteId ]: primaryResults,
				[ secondarySiteId ]: secondaryResults,
			} );
		} );

		test( 'should override previous cache test results of same site ID', () => {
			const state = reducer( previousState, {
				type: WP_SUPER_CACHE_TEST_CACHE_SUCCESS,
				siteId: primarySiteId,
				data: secondaryResults,
			} );

			expect( state.items ).to.eql( {
				[ primarySiteId ]: secondaryResults,
			} );
		} );

		test( 'should accumulate new cache test results and overwrite existing ones for the same site ID', () => {
			const newResults = {
				attempts: {
					first: {
						status: 'OK',
					},
					second: {
						status: 'FAILED',
					},
				},
			};
			const state = reducer( previousState, {
				type: WP_SUPER_CACHE_TEST_CACHE_SUCCESS,
				siteId: primarySiteId,
				data: newResults,
			} );

			expect( state.items ).to.eql( {
				[ primarySiteId ]: newResults,
			} );
		} );

		test( 'should not persist state', () => {
			const state = reducer( previousState, {
				type: SERIALIZE,
			} );

			expect( state ).to.be.undefined;
		} );

		test( 'should not load persisted state', () => {
			const state = reducer( previousState, {
				type: DESERIALIZE,
			} );

			expect( state.items ).to.eql( {} );
		} );
	} );
} );
示例#17
0
describe( 'reducer', () => {
	useSandbox( ( sandbox ) => sandbox.stub( console, 'warn' ) );

	it( 'should include expected keys in return value', () => {
		expect( reducer( undefined, {} ) ).to.have.keys( [
			'requesting',
			'items'
		] );
	} );

	describe( 'requesting()', () => {
		it( 'should default to an empty object', () => {
			const state = requesting( undefined, {} );

			expect( state ).to.eql( {} );
		} );

		it( 'should set site ID to true value if request in progress', () => {
			const state = requesting( undefined, {
				type: PAGE_TEMPLATES_REQUEST,
				siteId: 2916284
			} );

			expect( state ).to.eql( {
				2916284: true
			} );
		} );

		it( 'should accumulate requesting values', () => {
			const original = deepFreeze( {
				2916284: true
			} );
			const state = requesting( original, {
				type: PAGE_TEMPLATES_REQUEST,
				siteId: 77203074
			} );

			expect( state ).to.eql( {
				2916284: true,
				77203074: true
			} );
		} );

		it( 'should set site ID to false if request finishes successfully', () => {
			const original = deepFreeze( {
				2916284: true
			} );
			const state = requesting( original, {
				type: PAGE_TEMPLATES_REQUEST_SUCCESS,
				siteId: 2916284
			} );

			expect( state ).to.eql( {
				2916284: false
			} );
		} );

		it( 'should set site ID to false if request finishes with failure', () => {
			const original = deepFreeze( {
				2916284: true
			} );
			const state = requesting( original, {
				type: PAGE_TEMPLATES_REQUEST_FAILURE,
				siteId: 2916284
			} );

			expect( state ).to.eql( {
				2916284: false
			} );
		} );

		it( 'should not persist state', () => {
			const original = deepFreeze( {
				2916284: true
			} );
			const state = requesting( original, {
				type: SERIALIZE
			} );

			expect( state ).to.eql( {} );
		} );

		it( 'should not load persisted state', () => {
			const original = deepFreeze( {
				2916284: true
			} );
			const state = requesting( original, {
				type: DESERIALIZE
			} );

			expect( state ).to.eql( {} );
		} );
	} );

	describe( 'items()', () => {
		it( 'should default to an empty object', () => {
			const state = requesting( undefined, {} );

			expect( state ).to.eql( {} );
		} );

		it( 'should track page templates by site ID', () => {
			const state = items( null, {
				type: PAGE_TEMPLATES_RECEIVE,
				siteId: 2916284,
				templates: [
					{ label: 'Full Width, No Sidebar', file: 'fullwidth-page.php' },
					{ label: 'Portfolio Page Template', file: 'portfolio-page.php' }
				]
			} );

			expect( state ).to.eql( {
				2916284: [
					{ label: 'Full Width, No Sidebar', file: 'fullwidth-page.php' },
					{ label: 'Portfolio Page Template', file: 'portfolio-page.php' }
				]
			} );
		} );

		it( 'should accumulate sites', () => {
			const original = deepFreeze( {
				2916284: [
					{ label: 'Full Width, No Sidebar', file: 'fullwidth-page.php' },
					{ label: 'Portfolio Page Template', file: 'portfolio-page.php' }
				]
			} );
			const state = items( original, {
				type: PAGE_TEMPLATES_RECEIVE,
				siteId: 77203074,
				templates: [
					{ label: 'Full Width', file: 'fullwidth.php' }
				]
			} );

			expect( state ).to.eql( {
				2916284: [
					{ label: 'Full Width, No Sidebar', file: 'fullwidth-page.php' },
					{ label: 'Portfolio Page Template', file: 'portfolio-page.php' }
				],
				77203074: [
					{ label: 'Full Width', file: 'fullwidth.php' },
				]
			} );
		} );

		it( 'should override previous page templates of same site ID', () => {
			const original = deepFreeze( {
				2916284: [
					{ label: 'Full Width, No Sidebar', file: 'fullwidth-page.php' },
					{ label: 'Portfolio Page Template', file: 'portfolio-page.php' }
				]
			} );
			const state = items( original, {
				type: PAGE_TEMPLATES_RECEIVE,
				siteId: 2916284,
				templates: [
					{ label: 'Full Width', file: 'fullwidth.php' }
				]
			} );

			expect( state ).to.eql( {
				2916284: [
					{ label: 'Full Width', file: 'fullwidth.php' },
				]
			} );
		} );

		it( 'should persist state', () => {
			const original = deepFreeze( {
				2916284: [
					{ label: 'Full Width', file: 'fullwidth.php' },
				]
			} );
			const state = items( original, { type: SERIALIZE } );

			expect( state ).to.eql( {
				2916284: [
					{ label: 'Full Width', file: 'fullwidth.php' },
				]
			} );
		} );

		it( 'should load valid persisted state', () => {
			const original = deepFreeze( {
				2916284: [
					{ label: 'Full Width', file: 'fullwidth.php' },
				]
			} );
			const state = items( original, { type: DESERIALIZE } );

			expect( state ).to.eql( {
				2916284: [
					{ label: 'Full Width', file: 'fullwidth.php' },
				]
			} );
		} );

		it( 'should not load invalid persisted state', () => {
			const original = deepFreeze( {
				2916284: [
					{ label: 'Full Width' },
				]
			} );
			const state = items( original, { type: DESERIALIZE } );

			expect( state ).to.eql( {} );
			expect( console.warn ).to.have.been.calledTwice; // eslint-disable-line no-console
		} );
	} );
} );
示例#18
0
describe( 'actions', () => {
	let spy;
	useSandbox( ( sandbox ) => spy = sandbox.spy() );

	describe( '#requestPostFormats()', () => {
		useNock( ( nock ) => {
			nock( 'https://public-api.wordpress.com:443' )
				.persist()
				.get( '/rest/v1.1/sites/12345678/post-formats' )
				.reply( 200, {
					formats: {
						image: 'Image',
						video: 'Video',
						link: 'Link'
					}
				} )
				.get( '/rest/v1.1/sites/87654321/post-formats' )
				.reply( 403, {
					error: 'authorization_required',
					message: 'User cannot access this private blog.'
				} );
		} );

		it( 'should dispatch fetch action when thunk triggered', () => {
			requestPostFormats( 12345678 )( spy );

			expect( spy ).to.have.been.calledWith( {
				type: POST_FORMATS_REQUEST,
				siteId: 12345678
			} );
		} );

		it( 'should dispatch receive action when request completes', () => {
			return requestPostFormats( 12345678 )( spy ).then( () => {
				expect( spy ).to.have.been.calledWith( {
					type: POST_FORMATS_RECEIVE,
					siteId: 12345678,
					formats: {
						image: 'Image',
						video: 'Video',
						link: 'Link'
					}
				} );
			} );
		} );

		it( 'should dispatch request success action when request completes', () => {
			return requestPostFormats( 12345678 )( spy ).then( () => {
				expect( spy ).to.have.been.calledWith( {
					type: POST_FORMATS_REQUEST_SUCCESS,
					siteId: 12345678
				} );
			} );
		} );

		it( 'should dispatch request failure action when request fails', () => {
			return requestPostFormats( 87654321 )( spy ).then( () => {
				expect( spy ).to.have.been.calledWith( {
					type: POST_FORMATS_REQUEST_FAILURE,
					siteId: 87654321,
					error: sinon.match( {
						message: 'User cannot access this private blog.'
					} )
				} );
			} );
		} );
	} );
} );
示例#19
0
describe( 'api', () => {
	let app, config, localRequest, sandbox;

	useSandbox( newSandbox => ( sandbox = newSandbox ) );

	beforeAll( () => {
		config = require( 'config' );
		sandbox
			.stub( config, 'isEnabled' )
			.withArgs( 'oauth' )
			.returns( true );
		app = require( '../' )();
		localRequest = supertest( app );
	} );

	afterEach( () => {
		sandbox.restore();
	} );

	test( 'should return package version', () => {
		const version = require( '../../../package.json' ).version;

		return localRequest.get( '/version' ).then( ( { body, status } ) => {
			expect( status ).toBe( 200 );
			expect( body ).toEqual( { version } );
		} );
	} );

	test( 'should clear oauth cookie and redirect to login_url', () => {
		return localRequest
			.get( '/logout' )
			.redirects( 0 )
			.set( 'cookie', 'wpcom_token=test' )
			.then( ( { header, status } ) => {
				expect( status ).toBe( 302 );
				expect( header.location ).toBe( config( 'login_url' ) );
				expect( header[ 'set-cookie' ] ).toEqual( [
					'wpcom_token=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT',
				] );
			} );
	} );

	let maybeIt = it;
	if ( unmodifiedConfig( 'env_id' ) !== 'desktop' ) {
		maybeIt = maybeIt.skip;
	}

	maybeIt( 'should handle incomplete login details', function( done ) {
		const end = sandbox.stub( request.Request.prototype, 'end' );

		end.callsArgWithAsync( 0, { status: 400 }, { body: { error: 'invalid_request' } } );

		localRequest.post( '/oauth' ).end( function( err, res ) {
			expect( res.body.error ).toBe( 'invalid_request' );
			expect( res.status ).toBe( 400 );
			done();
		} );
	} );

	maybeIt( 'should return a login error with a bad login', function( done ) {
		const end = sandbox.stub( request.Request.prototype, 'end' ),
			response = { error: 'invalid_request' };

		end.callsArgWithAsync( 0, { status: 400 }, { body: response } );

		localRequest
			.post( '/oauth' )
			.send( { username: '******', password: '******' } )
			.expect( 400, response, done );
	} );

	maybeIt( 'should return a 400 needs_2fa if the user has 2FA enabled', function( done ) {
		const response = {
			error: 'needs_2fa',
			error_description: 'Please enter the verification code generated by your authenticator app.',
		};
		const end = sandbox.stub( request.Request.prototype, 'end' );

		end.callsArgWithAsync( 0, { status: 400 }, { body: response } );

		localRequest
			.post( '/oauth' )
			.send( { username: '******', password: '******' } )
			.expect( 400, response, done );
	} );

	maybeIt( 'should return a successful login', function( done ) {
		const response = { access_token: '1234' },
			end = sandbox.stub( request.Request.prototype, 'end' );

		end.callsArgWithAsync( 0, null, { body: response } );

		localRequest
			.post( '/oauth' )
			.send( { username: '******', password: '******', auth_code: '123456' } )
			.expect( 200, response, done );
	} );

	maybeIt( 'should return a 408 with no connection', function( done ) {
		const response = {
			error: 'invalid_request',
			error_description:
				'The request to localhost failed (code 12345), please check your internet connection and try again.',
		};
		const end = sandbox.stub( request.Request.prototype, 'end' );

		end.callsArgWithAsync( 0, { host: 'localhost', code: '12345' }, undefined );

		localRequest
			.post( '/oauth' )
			.send( { username: '******', password: '******' } )
			.expect( 408, response, done );
	} );
} );
示例#20
0
describe( 'actions', () => {
	let spy;
	useSandbox( sandbox => ( spy = sandbox.spy() ) );

	describe( '#fetchShortcode()', () => {
		const siteId = 12345678;
		const shortcode = '[gallery ids="1,2,3"]';

		describe( 'success', () => {
			useNock( nock => {
				nock( 'https://public-api.wordpress.com' )
					.persist()
					.get( `/rest/v1.1/sites/${ siteId }/shortcodes/render` )
					.query( {
						shortcode,
					} )
					.reply( 200, {
						result: '<html></html>',
						shortcode: '[gallery ids="1,2,3"]',
						scripts: {},
						styles: {},
					} );
			} );

			test( 'should return a fetch action object when called', () => {
				return fetchShortcode( siteId, shortcode )( spy ).then( () => {
					expect( spy ).to.have.been.calledWith( {
						type: SHORTCODE_REQUEST,
						siteId,
						shortcode,
					} );
				} );
			} );

			test( 'should return a receive action when request successfully completes', () => {
				return fetchShortcode( siteId, shortcode )( spy ).then( () => {
					expect( spy ).to.have.been.calledWith( {
						type: SHORTCODE_REQUEST_SUCCESS,
						siteId,
						shortcode,
					} );

					expect( spy ).to.have.been.calledWith( {
						type: SHORTCODE_RECEIVE,
						siteId,
						shortcode,
						data: {
							result: '<html></html>',
							shortcode: '[gallery ids="1,2,3"]',
							scripts: {},
							styles: {},
						},
					} );
				} );
			} );
		} );

		describe( 'failure', () => {
			useNock( nock => {
				nock( 'https://public-api.wordpress.com' )
					.persist()
					.get( `/rest/v1.1/sites/${ siteId }/shortcodes/render` )
					.query( {
						shortcode,
					} )
					.reply( 400, {
						error: 'The requested shortcode does not exist.',
					} );
			} );

			test( 'should return a receive action when an error occurs', () => {
				return fetchShortcode( siteId, shortcode )( spy ).catch( () => {
					expect( spy ).to.have.been.calledWith( {
						type: SHORTCODE_REQUEST_FAILURE,
						siteId,
						shortcode,
						error: 'The requested shortcode does not exist.',
					} );
				} );
			} );
		} );
	} );
} );
示例#21
0
describe( 'actions', () => {
	let spy;

	useSandbox( ( sandbox ) => spy = sandbox.spy() );

	const siteId = 123456;
	const failedSiteId = 456789;
	const url = 'wordpress.com/test';
	const stats = {
		data: {
			generated: 1493997829,
			supercache: {
				cached: 1,
				cached_list: [ {
					lower_age: 180347,
					files: 2,
					upper_age: 183839,
					dir: 'wordpress.com/test'
				} ],
				expired: 0,
				expired_list: [],
				fsize: 59573,
			},
			wpcache: {
				cached: 0,
				cached_list: [],
				expired: 1,
				expired_list: [ {
					lower_age: 180347,
					files: 2,
					upper_age: 183839,
					dir: 'wordpress.com/test'
				} ],
				fsize: 59573,
			}
		}
	};

	describe( '#generateStats()', () => {
		useNock( nock => {
			nock( 'https://public-api.wordpress.com' )
				.persist()
				.get( `/rest/v1.1/jetpack-blogs/${ siteId }/rest-api/` )
				.query( { path: '/wp-super-cache/v1/stats' } )
				.reply( 200, stats )
				.get( `/rest/v1.1/jetpack-blogs/${ failedSiteId }/rest-api/` )
				.query( { path: '/wp-super-cache/v1/stats' } )
				.reply( 403, {
					error: 'authorization_required',
					message: 'User cannot access this private blog.'
				} );
		} );

		it( 'should dispatch fetch action when thunk triggered', () => {
			generateStats( siteId )( spy );

			expect( spy ).to.have.been.calledWith( {
				type: WP_SUPER_CACHE_GENERATE_STATS,
				siteId,
			} );
		} );

		it( 'should dispatch request success action when request completes', () => {
			return generateStats( siteId )( spy ).then( () => {
				expect( spy ).to.have.been.calledWith( {
					type: WP_SUPER_CACHE_GENERATE_STATS_SUCCESS,
					stats: stats.data,
					siteId,
				} );
			} );
		} );

		it( 'should dispatch fail action when request fails', () => {
			return generateStats( failedSiteId )( spy ).then( () => {
				expect( spy ).to.have.been.calledWith( {
					type: WP_SUPER_CACHE_GENERATE_STATS_FAILURE,
					siteId: failedSiteId,
				} );
			} );
		} );
	} );

	describe( '#deleteFile()', () => {
		useNock( nock => {
			nock( 'https://public-api.wordpress.com' )
				.persist()
				.post( `/rest/v1.1/jetpack-blogs/${ siteId }/rest-api/` )
				.query( { path: '/wp-super-cache/v1/cache' } )
				.reply( 200, { 'Cache Cleared': true } )
				.post( `/rest/v1.1/jetpack-blogs/${ failedSiteId }/rest-api/` )
				.query( { path: '/wp-super-cache/v1/cache' } )
				.reply( 403, {
					error: 'authorization_required',
					message: 'User cannot access this private blog.'
				} );
		} );

		it( 'should dispatch fetch action when thunk triggered', () => {
			deleteFile( siteId, url, true, false )( spy );

			expect( spy ).to.have.been.calledWith( {
				type: WP_SUPER_CACHE_DELETE_FILE,
				siteId,
			} );
		} );

		it( 'should dispatch request success action when request completes', () => {
			return deleteFile( siteId, url, true, false )( spy ).then( () => {
				expect( spy ).to.have.been.calledWith( {
					type: WP_SUPER_CACHE_DELETE_FILE_SUCCESS,
					isSupercache: true,
					isCached: false,
					siteId,
					url,
				} );
			} );
		} );

		it( 'should dispatch fail action when request fails', () => {
			return deleteFile( failedSiteId, url, true, false )( spy ).then( () => {
				expect( spy ).to.have.been.calledWith( {
					type: WP_SUPER_CACHE_DELETE_FILE_FAILURE,
					siteId: failedSiteId,
				} );
			} );
		} );
	} );
} );
示例#22
0
describe( 'reducer', () => {
	useSandbox( ( sandbox ) => {
		sandbox.stub( console, 'warn' );
	} );

	it( 'should include expected keys in return value', () => {
		expect( reducer( undefined, {} ) ).to.have.keys( [
			'queries',
			'queryRequests'
		] );
	} );

	describe( 'queryRequests()', () => {
		it( 'should default to an empty object', () => {
			const state = queryRequests( undefined, {} );

			expect( state ).to.eql( {} );
		} );

		it( 'should track term query request fetching', () => {
			const state = queryRequests( undefined, {
				type: TERMS_REQUEST,
				siteId: 2916284,
				query: { search: 'Ribs' },
				taxonomy: 'category'
			} );

			expect( state ).to.eql( {
				2916284: {
					category: {
						'{"search":"ribs"}': true
					}
				}
			} );
		} );

		it( 'should accumulate queries', () => {
			const original = deepFreeze( {
				2916284: {
					category: {
						'{"search":"ribs"}': true
					}
				}
			} );

			const state = queryRequests( original, {
				type: TERMS_REQUEST,
				siteId: 2916284,
				query: { search: 'AND Chicken' },
				taxonomy: 'category'
			} );

			expect( state ).to.eql( {
				2916284: {
					category: {
						'{"search":"ribs"}': true,
						'{"search":"and chicken"}': true
					}
				}
			} );
		} );

		it( 'should track term query request success', () => {
			const state = queryRequests( undefined, {
				type: TERMS_REQUEST_SUCCESS,
				siteId: 2916284,
				query: { search: 'Ribs' },
				found: testTerms.length,
				terms: testTerms,
				taxonomy: 'category'
			} );

			expect( state ).to.eql( {
				2916284: {
					category: {
						'{"search":"ribs"}': false
					}
				}
			} );
		} );

		it( 'should track term query request failure', () => {
			const state = queryRequests( undefined, {
				type: TERMS_REQUEST_FAILURE,
				siteId: 2916284,
				query: { search: 'Ribs' },
				error: new Error(),
				taxonomy: 'category'
			} );

			expect( state ).to.eql( {
				2916284: {
					category: {
						'{"search":"ribs"}': false
					}
				}
			} );
		} );
	} );

	describe( 'queries()', () => {
		it( 'should default to an empty object', () => {
			const state = queries( undefined, {} );

			expect( state ).to.eql( {} );
		} );

		it( 'should track term query request success', () => {
			const query = { search: 'i' };
			const state = queries( undefined, {
				type: TERMS_RECEIVE,
				siteId: 2916284,
				found: 2,
				terms: testTerms,
				taxonomy: 'category',
				query
			} );

			expect( state ).to.have.keys( [ '2916284' ] );
			expect( state[ 2916284 ] ).to.have.keys( 'category' );
			expect( state[ 2916284 ].category ).to.be.an.instanceof( TermQueryManager );
			expect( state[ 2916284 ].category.getItems( query ) ).to.eql( testTerms );
			expect( state[ 2916284 ].category.getFound( query ) ).to.equal( 2 );
		} );

		it( 'should track items even if no query is specified', () => {
			const state = queries( undefined, {
				type: TERMS_RECEIVE,
				siteId: 2916284,
				terms: testTerms,
				taxonomy: 'category'
			} );

			expect( state ).to.have.keys( [ '2916284' ] );
			expect( state[ 2916284 ] ).to.have.keys( 'category' );
			expect( state[ 2916284 ].category ).to.be.an.instanceof( TermQueryManager );
			expect( state[ 2916284 ].category.getItems() ).to.eql( testTerms );
		} );

		it( 'should return the same state if no changes to received items', () => {
			const action = {
				type: TERMS_RECEIVE,
				siteId: 2916284,
				found: 2,
				terms: testTerms,
				taxonomy: 'category',
				query: { search: 'i' }
			};

			const original = deepFreeze( queries( undefined, action ) );
			const state = queries( original, action );

			expect( state ).to.equal( original );
		} );

		it( 'should accumulate query request success', () => {
			const original = deepFreeze( queries( undefined, {
				type: TERMS_RECEIVE,
				siteId: 2916284,
				found: 2,
				terms: testTerms,
				taxonomy: 'category',
				query: { search: 'i' }
			} ) );

			const state = queries( original, {
				type: TERMS_RECEIVE,
				siteId: 2916284,
				query: { search: 'nom' },
				found: 1,
				terms: [ { ID: 777, name: 'Noms' } ],
				taxonomy: 'post_tag'
			} );

			expect( state ).to.have.keys( [ '2916284' ] );
			expect( state[ 2916284 ] ).to.have.keys( [ 'category', 'post_tag' ] );
		} );

		it( 'should omit removed term', () => {
			const original = deepFreeze( queries( undefined, {
				type: TERMS_RECEIVE,
				siteId: 2916284,
				terms: testTerms,
				taxonomy: 'category'
			} ) );

			const state = queries( original, {
				type: TERM_REMOVE,
				siteId: 2916284,
				taxonomy: 'category',
				termId: testTerms[ 0 ].ID
			} );

			expect( state ).to.have.keys( [ '2916284' ] );
			expect( state[ 2916284 ] ).to.have.keys( 'category' );
			expect( state[ 2916284 ].category.getItems() ).to.have.length( testTerms.length - 1 );
			expect( state[ 2916284 ].category.getItem( testTerms[ 0 ].ID ) ).to.be.undefined;
		} );

		it( 'should persist state', () => {
			const original = deepFreeze( queries( undefined, {
				type: TERMS_RECEIVE,
				siteId: 2916284,
				found: 2,
				terms: testTerms,
				taxonomy: 'category',
				query: { search: 'i' }
			} ) );

			const state = queries( original, { type: SERIALIZE } );

			expect( state ).to.have.keys( [ '2916284' ] );
			expect( state[ 2916284 ] ).to.have.keys( [ 'category' ] );
			expect( state[ 2916284 ].category ).to.have.keys( [ 'data', 'options' ] );
		} );

		it( 'should load persisted state', () => {
			const original = deepFreeze( queries( undefined, {
				type: TERMS_RECEIVE,
				siteId: 2916284,
				found: 2,
				terms: testTerms,
				taxonomy: 'category',
				query: { search: 'i' }
			} ) );

			const serialized = queries( original, { type: SERIALIZE } );
			const state = queries( serialized, { type: DESERIALIZE } );

			expect( state ).to.eql( original );
		} );

		it( 'should not load invalid persisted state', () => {
			const state = queries( {
				2916284: {
					category: '{~!--BROKEN'
				}
			}, { type: DESERIALIZE } );

			expect( state ).to.eql( {} );
		} );
	} );
} );
示例#23
0
describe( 'actions', () => {
	let sandbox, spy;

	useSandbox( newSandbox => {
		sandbox = newSandbox;
		spy = sandbox.spy();
	} );

	describe( 'creators functions', () => {
		it( '#plansReceiveAction()', () => {
			const plans = wpcomResponse;
			const action = plansReceiveAction( plans );
			expect( action ).to.eql( ACTION_PLANS_RECEIVE );
		} );

		it( '#plansRequestAction()', () => {
			const action = plansRequestAction();
			expect( action ).to.eql( ACTION_PLANS_REQUEST );
		} );

		it( '#plansRequestSuccessAction()', () => {
			const action = plansRequestSuccessAction();
			expect( action ).to.eql( ACTION_PLANS_REQUEST_SUCCESS );
		} );

		it( '#plansRequestFailureAction()', () => {
			const action = plansRequestFailureAction( errorResponse );
			expect( action ).to.eql( ACTION_PLANS_REQUEST_FAILURE );
		} );
	} );

	describe( '#requestPlans() - success', () => {
		before( () => {
			nock( 'https://public-api.wordpress.com:443' )
				.persist()
				.get( '/rest/v1.4/plans' )
				.reply( 200, wpcomResponse );
		} );

		after( () => {
			nock.cleanAll();
		} );

		it( 'should dispatch REQUEST action when thunk triggered', () => {
			const action = plansRequestAction();
			requestPlans()( spy );
			expect( spy ).to.have.been.calledWith( action );
		} );

		it( 'should dispatch RECEIVE action when request completes', () => {
			const plans = wpcomResponse;
			const action_request = plansRequestAction();
			const action_receive = plansReceiveAction( plans );
			const promise = requestPlans()( spy );

			expect( spy ).to.have.been.calledWith( action_request );

			return promise.then( () => {
				expect( spy ).to.have.been.calledWith( action_receive );
			} );
		} );
	} );
} );
示例#24
0
describe( 'reducer', () => {
	useSandbox( sandbox => {
		sandbox.stub( console, 'warn' );
	} );

	test( 'should export expected reducer keys', () => {
		expect( reducer( undefined, {} ) ).to.have.keys( [ 'items', 'requesting' ] );
	} );

	describe( '#items()', () => {
		test( 'should default to an empty object', () => {
			const state = items( undefined, {} );

			expect( state ).to.eql( {} );
		} );

		test( 'should store connection status when received', () => {
			const state = items( undefined, {
				type: SITE_CONNECTION_STATUS_RECEIVE,
				siteId: 2916284,
				status: true,
			} );

			expect( state ).to.eql( {
				2916284: true,
			} );
		} );

		test( 'should accumulate connection statuses when receiving for new sites', () => {
			const original = deepFreeze( {
				2916284: true,
			} );
			const state = items( original, {
				type: SITE_CONNECTION_STATUS_RECEIVE,
				siteId: 77203074,
				status: false,
			} );

			expect( state ).to.eql( {
				2916284: true,
				77203074: false,
			} );
		} );

		test( 'should overwrite connection status when receiving for an existing site', () => {
			const original = deepFreeze( {
				2916284: true,
				77203074: false,
			} );
			const state = items( original, {
				type: SITE_CONNECTION_STATUS_RECEIVE,
				siteId: 2916284,
				status: false,
			} );

			expect( state ).to.eql( {
				2916284: false,
				77203074: false,
			} );
		} );

		test( 'should not persist state', () => {
			const original = deepFreeze( {
				2916284: true,
			} );
			const state = items( original, { type: SERIALIZE } );

			expect( state ).to.be.undefined;
		} );

		test( 'should not load persisted state', () => {
			const original = deepFreeze( {
				2916284: true,
			} );
			const state = items( original, { type: DESERIALIZE } );

			expect( state ).to.eql( {} );
		} );
	} );

	describe( 'requesting()', () => {
		test( 'should default to an empty object', () => {
			const state = requesting( undefined, {} );

			expect( state ).to.eql( {} );
		} );

		test( 'should track connection status request when started', () => {
			const state = requesting( undefined, {
				type: SITE_CONNECTION_STATUS_REQUEST,
				siteId: 2916284,
			} );

			expect( state ).to.eql( {
				2916284: true,
			} );
		} );

		test( 'should accumulate connection status requests when started', () => {
			const original = deepFreeze( {
				2916284: true,
			} );
			const state = requesting( original, {
				type: SITE_CONNECTION_STATUS_REQUEST,
				siteId: 77203074,
			} );

			expect( state ).to.eql( {
				2916284: true,
				77203074: true,
			} );
		} );

		test( 'should track connection status request when succeeded', () => {
			const original = deepFreeze( {
				2916284: true,
				77203074: true,
			} );
			const state = requesting( original, {
				type: SITE_CONNECTION_STATUS_REQUEST_SUCCESS,
				siteId: 2916284,
			} );

			expect( state ).to.eql( {
				2916284: false,
				77203074: true,
			} );
		} );

		test( 'should track connection status request when failed', () => {
			const original = deepFreeze( {
				2916284: false,
				77203074: true,
			} );
			const state = requesting( original, {
				type: SITE_CONNECTION_STATUS_REQUEST_FAILURE,
				siteId: 77203074,
			} );

			expect( state ).to.eql( {
				2916284: false,
				77203074: false,
			} );
		} );

		test( 'should not persist state', () => {
			const original = deepFreeze( {
				2916284: true,
			} );
			const state = requesting( original, { type: SERIALIZE } );

			expect( state ).to.be.undefined;
		} );

		test( 'should not load persisted state', () => {
			const original = deepFreeze( {
				2916284: true,
			} );
			const state = requesting( original, { type: DESERIALIZE } );

			expect( state ).to.eql( {} );
		} );
	} );
} );
示例#25
0
describe( 'reducer', () => {
	useSandbox( ( sandbox ) => {
		sandbox.stub( console, 'warn' );
	} );

	it( 'should include expected keys in return value', () => {
		expect( reducer( undefined, {} ) ).to.have.keys( [
			'items'
		] );
	} );

	describe( '#items()', () => {
		it( 'should persist state', () => {
			const original = deepFreeze( {
				2916284: {
					'jetpack-portfolio': keyedTestTerms
				}
			} );
			const state = items( original, { type: SERIALIZE } );

			expect( state ).to.eql( original );
		} );

		it( 'should load valid persisted state', () => {
			const original = deepFreeze( {
				2916284: {
					'jetpack-portfolio': keyedTestTerms
				}
			} );
			const state = items( original, { type: DESERIALIZE } );

			expect( state ).to.eql( original );
		} );

		it( 'should not load invalid persisted state', () => {
			const original = deepFreeze( {
				2916284: {
					'jetpack-portfolio': {
						111: {}
					}
				}
			} );
			const state = items( original, { type: DESERIALIZE } );

			expect( state ).to.eql( {} );
		} );

		it( 'should default to an empty object', () => {
			const state = items( undefined, {} );

			expect( state ).to.eql( {} );
		} );

		it( 'should add received terms', () => {
			const state = items( undefined, {
				type: TERMS_RECEIVE,
				siteId: 2916284,
				taxonomy: 'jetpack-portfolio',
				terms: testTerms
			} );

			expect( state ).to.eql( {
				2916284: {
					'jetpack-portfolio': keyedTestTerms
				}
			} );
		} );

		it( 'should accumulate received terms by taxonomy', () => {
			const original = deepFreeze( {
				2916284: {
					'jetpack-portfolio': keyedTestTerms
				}
			} );

			const state = items( original, {
				type: TERMS_RECEIVE,
				siteId: 2916284,
				taxonomy: 'jetpack-portfolio',
				terms: moreTerms
			} );

			const expectedTerms = merge( {}, keyedTestTerms, keyedMoreTerms );

			expect( state ).to.eql( {
				2916284: {
					'jetpack-portfolio': expectedTerms
				}
			} );
		} );

		it( 'should add additional terms', () => {
			const original = deepFreeze( {
				2916284: {
					'jetpack-portfolio': keyedTestTerms
				}
			} );

			const state = items( original, {
				type: TERMS_RECEIVE,
				siteId: 2916284,
				taxonomy: 'amazing-taxonomy',
				terms: moreTerms
			} );

			expect( state ).to.eql( {
				2916284: {
					'amazing-taxonomy': keyedMoreTerms,
					'jetpack-portfolio': keyedTestTerms
				}
			} );
		} );
	} );
} );
示例#26
0
describe( 'reducer', () => {
	useSandbox( ( sandbox ) => sandbox.stub( console, 'warn' ) );

	it( 'should include expected keys in return value', () => {
		expect( reducer( undefined, {} ) ).to.have.keys( [
			'requesting',
			'items'
		] );
	} );

	describe( 'requesting()', () => {
		it( 'should default to false', () => {
			const isRequestingHappinessEngineers = requesting( undefined, {} );

			expect( isRequestingHappinessEngineers ).to.be.false;
		} );

		it( 'should return true if request is in progress', () => {
			const isRequestingHappinessEngineers = requesting( undefined, {
				type: HAPPINESS_ENGINEERS_FETCH
			} );

			expect( isRequestingHappinessEngineers ).to.be.true;
		} );

		it( 'should return false if request was successful', () => {
			const isRequestingHappinessEngineers = requesting( undefined, {
				type: HAPPINESS_ENGINEERS_FETCH_SUCCESS
			} );

			expect( isRequestingHappinessEngineers ).to.be.false;
		} );

		it( 'should return false if request failed', () => {
			const isRequestingHappinessEngineers = requesting( undefined, {
				type: HAPPINESS_ENGINEERS_FETCH_FAILURE
			} );

			expect( isRequestingHappinessEngineers ).to.be.false;
		} );
	} );

	describe( 'items()', () => {
		it( 'should default to null', () => {
			const state = items( undefined, {} );

			expect( state ).to.eql( null );
		} );

		it( 'should save the received happiness engineers', () => {
			const state = items( null, {
				type: HAPPINESS_ENGINEERS_RECEIVE,
				happinessEngineers: [
					{ avatar_URL: 'test 1' },
					{ avatar_URL: 'test 2' }
				]
			} );

			expect( state ).to.eql( [ 'test 1', 'test 2' ] );
		} );

		it( 'should rewrite old state with received', () => {
			const original = deepFreeze( {
				'test 1': { avatar_URL: 'test 1' },
				'test 2': { avatar_URL: 'test 2' }
			} );

			const state = items( original, {
				type: HAPPINESS_ENGINEERS_RECEIVE,
				happinessEngineers: [
					{ avatar_URL: 'test 3' }
				]
			} );

			expect( state ).to.eql( [ 'test 3' ] );
		} );

		it( 'should persist state', () => {
			const original = deepFreeze( [ 'test 3' ] );
			const state = items( original, { type: SERIALIZE } );

			expect( state ).to.eql( [ 'test 3' ] );
		} );

		it( 'should load valid persisted state', () => {
			const original = deepFreeze( [ 'test 3' ] );
			const state = items( original, { type: DESERIALIZE } );

			expect( state ).to.eql( [ 'test 3' ] );
		} );

		it( 'should not load invalid persisted state', () => {
			const original = deepFreeze( {
				'test 3': { URL: 'test 3' }
			} );
			const state = items( original, { type: DESERIALIZE } );

			expect( state ).to.eql( null );
		} );
	} );
} );
示例#27
0
describe( 'actions', () => {
	let sandbox, spy;

	useSandbox( newSandbox => {
		sandbox = newSandbox;
		spy = sandbox.spy();
	} );

	describe( '#dismissWordAdsError()', () => {
		test( 'should return a dismiss error action', () => {
			expect( dismissWordAdsError( 2916284 ) ).to.eql( {
				type: WORDADS_SITE_APPROVE_REQUEST_DISMISS_ERROR,
				siteId: 2916284,
			} );
		} );
	} );

	describe( '#dismissWordAdsSuccess()', () => {
		test( 'should return a dismiss Success action', () => {
			expect( dismissWordAdsSuccess( 2916284 ) ).to.eql( {
				type: WORDADS_SITE_APPROVE_REQUEST_DISMISS_SUCCESS,
				siteId: 2916284,
			} );
		} );
	} );

	describe( '#requestWordAdsApproval()', () => {
		useNock( nock => {
			nock( 'https://public-api.wordpress.com:443' )
				.persist()
				.post( '/rest/v1.1/sites/2916284/wordads/approve' )
				.reply( 200, {
					approved: true,
				} )
				.post( '/rest/v1.1/sites/77203074/wordads/approve' )
				.reply( 403, {
					error: 'authorization_required',
					message: 'An active access token must be used to approve wordads.',
				} );
		} );

		test( 'should dispatch fetch action when thunk triggered', () => {
			requestWordAdsApproval( 2916284 )( spy );
			expect( spy ).to.have.been.calledWith( {
				type: WORDADS_SITE_APPROVE_REQUEST,
				siteId: 2916284,
			} );
		} );

		test( 'should dispatch success action when request completes', () => {
			return requestWordAdsApproval( 2916284 )( spy ).then( () => {
				expect( spy ).to.have.been.calledWith( {
					type: WORDADS_SITE_APPROVE_REQUEST_SUCCESS,
					approved: true,
					siteId: 2916284,
				} );
			} );
		} );

		test( 'should dispatch fail action when request fails', () => {
			return requestWordAdsApproval( 77203074 )( spy ).then( () => {
				expect( spy ).to.have.been.calledWith( {
					type: WORDADS_SITE_APPROVE_REQUEST_FAILURE,
					siteId: 77203074,
					error: sandbox.match( 'An active access token must be used to approve wordads.' ),
				} );
			} );
		} );
	} );
} );
示例#28
0
describe( 'actions', () => {
	let sandbox, spy;

	useSandbox( newSandbox => {
		sandbox = newSandbox;
		spy = sandbox.spy();
	} );
	const responseShape = {
		[ USER_SETTING_KEY ]: DEFAULT_PREFERENCES
	};

	describe( 'receivePreferences()', () => {
		it( 'should return an action object', () => {
			const action = receivePreferences( { foo: 'bar' } );

			expect( action ).to.eql( {
				type: PREFERENCES_RECEIVE,
				values: {
					foo: 'bar'
				}
			} );
		} );
	} );

	describe( 'fetchPreferences()', () => {
		useNock( ( nock ) => {
			nock( 'https://public-api.wordpress.com:443' )
				.persist()
				.get( '/rest/v1.1/me/settings' )
				.reply( 200, responseShape );
		} );

		it( 'should dispatch fetch action when thunk triggered', () => {
			fetchPreferences()( spy );
			expect( spy ).to.have.been.calledWith( {
				type: PREFERENCES_FETCH
			} );
		} );

		it( 'should dispatch success action when request completes', () => {
			return fetchPreferences()( spy ).then( () => {
				expect( spy ).to.have.been.calledWithMatch( {
					type: PREFERENCES_FETCH_SUCCESS,
					values: responseShape[ USER_SETTING_KEY ],
				} );
			} );
		} );
	} );

	describe( 'fetchPreferences()', () => {
		useNock( ( nock ) => {
			nock( 'https://public-api.wordpress.com:443' )
				.persist()
				.get( '/rest/v1.1/me/settings' )
				.reply( 404 );
		} );

		it( 'should dispatch fail action when request fails', () => {
			return fetchPreferences()( spy ).then( () => {
				expect( spy ).to.have.been.calledWithMatch( {
					type: PREFERENCES_FETCH_FAILURE
				} );
			} );
		} );
	} );

	describe( 'setPreference()', () => {
		it( 'should return PREFERENCES_SET with correct payload', () => {
			expect( setPreference( 'preferenceKey', 'preferenceValue' ) ).to.deep.equal( {
				type: PREFERENCES_SET,
				key: 'preferenceKey',
				value: 'preferenceValue'
			} );
		} );
	} );

	describe( 'savePreference()', () => {
		useNock( ( nock ) => {
			nock( 'https://public-api.wordpress.com:443' )
				.persist()
				.post( '/rest/v1.1/me/settings/', {
					[ USER_SETTING_KEY ]: { preferenceKey: 'preferenceValue' }
				} )
				.reply( 200, responseShape );

			nock( 'https://public-api.wordpress.com:443' )
				.persist()
				.post( '/rest/v1.1/me/settings/', {
					[ USER_SETTING_KEY ]: { loggedOut: true }
				} )
				.reply( 403, {
					error: 'authorization_required',
					message: 'An active access token must be used to query information about the current user.'
				} );
		} );

		it( 'should dispatch PREFERENCES_SET action when thunk triggered', () => {
			savePreference( 'preferenceKey', 'preferenceValue' )( spy );
			expect( spy ).to.have.been.calledWithMatch( {
				type: PREFERENCES_SET,
				key: 'preferenceKey',
				value: 'preferenceValue'
			} );
		} );

		it( 'should dispatch PREFERENCES_SAVE action when thunk triggered', () => {
			savePreference( 'preferenceKey', 'preferenceValue' )( spy );
			expect( spy ).to.have.been.calledWithMatch( {
				type: PREFERENCES_SAVE,
				key: 'preferenceKey',
				value: 'preferenceValue'
			} );
		} );

		it( 'should dispatch PREFERENCES_RECEIVE action when request completes', () => {
			return savePreference( 'preferenceKey', 'preferenceValue' )( spy ).then( () => {
				expect( spy ).to.have.been.calledWithMatch( {
					type: PREFERENCES_RECEIVE,
					values: responseShape[ USER_SETTING_KEY ]
				} );
			} );
		} );

		it( 'should dispatch PREFERENCES_SAVE_FAILURE action when request fails', () => {
			return savePreference( 'loggedOut', true )( spy ).then( () => {
				expect( spy ).to.have.been.calledWithMatch( {
					type: PREFERENCES_SAVE_FAILURE,
					error: sinon.match( {
						message: 'An active access token must be used to query information about the current user.'
					} )
				} );
			} );
		} );

		it( 'should dispatch PREFERENCES_SAVE_SUCCESS action when request completes', () => {
			return savePreference( 'preferenceKey', 'preferenceValue' )( spy ).then( () => {
				expect( spy ).to.have.been.calledWithMatch( {
					type: PREFERENCES_SAVE_SUCCESS,
					key: 'preferenceKey',
					value: 'preferenceValue'
				} );
			} );
		} );
	} );
} );
示例#29
0
describe( 'reducer', () => {
	useSandbox( sandbox => {
		sandbox.stub( console, 'warn' );
	} );

	describe( '#requesting()', () => {
		test( 'should default to an empty object', () => {
			const state = requesting( undefined, {} );

			expect( state ).to.eql( {} );
		} );

		test( 'should set requesting value to true if request in progress', () => {
			const state = requesting( undefined, {
				type: POST_STATS_REQUEST,
				siteId: 2916284,
				postId: 2454,
				fields: [ 'views', 'years' ],
			} );

			expect( state ).to.eql( {
				2916284: {
					2454: {
						'views,years': true,
					},
				},
			} );
		} );

		test( 'should accumulate requesting values (stat)', () => {
			const previousState = deepFreeze( {
				2916284: {
					2454: { views: true },
				},
			} );
			const state = requesting( previousState, {
				type: POST_STATS_REQUEST,
				siteId: 2916284,
				postId: 2454,
				fields: [ 'countComments' ],
			} );

			expect( state ).to.eql( {
				2916284: {
					2454: {
						views: true,
						countComments: true,
					},
				},
			} );
		} );

		test( 'should accumulate requesting values (postId)', () => {
			const previousState = deepFreeze( {
				2916284: {
					2454: { views: true },
				},
			} );
			const state = requesting( previousState, {
				type: POST_STATS_REQUEST,
				siteId: 2916284,
				postId: 2455,
				fields: [ 'views' ],
			} );

			expect( state ).to.eql( {
				2916284: {
					2454: { views: true },
					2455: { views: true },
				},
			} );
		} );

		test( 'should accumulate requesting values (siteId)', () => {
			const previousState = deepFreeze( {
				2916284: {
					2454: { views: true },
				},
			} );
			const state = requesting( previousState, {
				type: POST_STATS_REQUEST,
				siteId: 2916285,
				postId: 2454,
				fields: [ 'views' ],
			} );

			expect( state ).to.eql( {
				2916284: {
					2454: { views: true },
				},
				2916285: {
					2454: { views: true },
				},
			} );
		} );

		test( 'should set request to false if request finishes successfully', () => {
			const previousState = deepFreeze( {
				2916284: {
					2454: { views: true },
				},
			} );
			const state = requesting( previousState, {
				type: POST_STATS_REQUEST_SUCCESS,
				siteId: 2916284,
				postId: 2454,
				fields: [ 'views' ],
			} );

			expect( state ).to.eql( {
				2916284: {
					2454: { views: false },
				},
			} );
		} );

		test( 'should set request to false if request finishes with failure', () => {
			const previousState = deepFreeze( {
				2916284: {
					2454: { views: true },
				},
			} );
			const state = requesting( previousState, {
				type: POST_STATS_REQUEST_FAILURE,
				siteId: 2916284,
				postId: 2454,
				fields: [ 'views' ],
			} );

			expect( state ).to.eql( {
				2916284: {
					2454: { views: false },
				},
			} );
		} );
	} );

	describe( '#items()', () => {
		test( 'should default to an empty object', () => {
			const state = items( undefined, {} );

			expect( state ).to.eql( {} );
		} );

		test( 'should index post stats by site ID, post id and stat', () => {
			const state = items( null, {
				type: POST_STATS_RECEIVE,
				siteId: 2916284,
				postId: 2454,
				stats: { views: 2, years: [] },
			} );

			expect( state ).to.eql( {
				2916284: {
					2454: { views: 2, years: [] },
				},
			} );
		} );

		test( 'should accumulate stats', () => {
			const previousState = deepFreeze( {
				2916284: {
					2454: { views: 2 },
				},
			} );
			const state = items( previousState, {
				type: POST_STATS_RECEIVE,
				siteId: 2916284,
				postId: 2454,
				stats: { countComments: 3 },
			} );

			expect( state ).to.eql( {
				2916284: {
					2454: {
						views: 2,
						countComments: 3,
					},
				},
			} );
		} );

		test( 'should accumulate post IDs', () => {
			const previousState = deepFreeze( {
				2916284: {
					2454: { views: 2 },
				},
			} );
			const state = items( previousState, {
				type: POST_STATS_RECEIVE,
				siteId: 2916284,
				postId: 2455,
				stats: { views: 3 },
			} );

			expect( state ).to.eql( {
				2916284: {
					2454: { views: 2 },
					2455: { views: 3 },
				},
			} );
		} );

		test( 'should accumulate site IDs', () => {
			const previousState = deepFreeze( {
				2916284: {
					2454: { views: 2 },
				},
			} );
			const state = items( previousState, {
				type: POST_STATS_RECEIVE,
				siteId: 2916285,
				postId: 2454,
				stats: { views: 3 },
			} );

			expect( state ).to.eql( {
				2916284: {
					2454: { views: 2 },
				},
				2916285: {
					2454: { views: 3 },
				},
			} );
		} );

		test( 'should override previous stat value of same site ID, post ID and stat key', () => {
			const previousState = deepFreeze( {
				2916284: {
					2454: { views: 2 },
				},
			} );
			const state = items( previousState, {
				type: POST_STATS_RECEIVE,
				siteId: 2916284,
				postId: 2454,
				stats: { views: 3 },
			} );

			expect( state ).to.eql( {
				2916284: {
					2454: { views: 3 },
				},
			} );
		} );

		test( 'should persist state', () => {
			const previousState = deepFreeze( {
				2916284: {
					2454: { views: 2 },
				},
			} );
			const state = items( previousState, { type: SERIALIZE } );

			expect( state ).to.eql( {
				2916284: {
					2454: { views: 2 },
				},
			} );
		} );

		test( 'should load valid persisted state', () => {
			const previousState = deepFreeze( {
				2916284: {
					2454: { views: 2 },
				},
			} );
			const state = items( previousState, { type: DESERIALIZE } );

			expect( state ).to.eql( {
				2916284: {
					2454: { views: 2 },
				},
			} );
		} );

		test( 'should not load invalid persisted state', () => {
			const previousInvalidState = deepFreeze( {
				2454: { views: 2 },
			} );
			const state = items( previousInvalidState, { type: DESERIALIZE } );

			expect( state ).to.eql( {} );
		} );
	} );
} );
示例#30
0
describe( 'actions', () => {
	let spy;
	useSandbox( ( sandbox ) => spy = sandbox.spy() );

	describe( '#fetchConnections()', () => {
		useNock( ( nock ) => {
			nock( 'https://public-api.wordpress.com:443' )
				.persist()
				.get( '/rest/v1.1/sites/2916284/publicize-connections' )
				.reply( 200, {
					connections: [
						{ ID: 2, site_ID: 2916284 }
					]
				} )
				.get( '/rest/v1.1/sites/77203074/publicize-connections' )
				.reply( 403, {
					error: 'authorization_required',
					message: 'An active access token must be used to access publicize connections.'
				} );
		} );

		it( 'should dispatch fetch action when thunk triggered', () => {
			fetchConnections( 2916284 )( spy );

			expect( spy ).to.have.been.calledWith( {
				type: PUBLICIZE_CONNECTIONS_REQUEST,
				siteId: 2916284
			} );
		} );

		it( 'should dispatch receive action when request completes', ( done ) => {
			fetchConnections( 2916284 )( spy ).then( () => {
				expect( spy ).to.have.been.calledThrice;

				const action1 = spy.getCall( 1 ).args[ 0 ];
				expect( action1.type ).to.equal( PUBLICIZE_CONNECTIONS_RECEIVE );
				expect( action1.siteId ).to.equal( 2916284 );
				expect( action1.data.connections ).to.eql( [ { ID: 2, site_ID: 2916284 } ] );

				const action2 = spy.getCall( 2 ).args[ 0 ];
				expect( action2.type ).to.equal( PUBLICIZE_CONNECTIONS_REQUEST_SUCCESS );
				expect( action2.siteId ).to.equal( 2916284 );

				done();
			} ).catch( done );
		} );

		it( 'should dispatch fail action when request fails', ( done ) => {
			fetchConnections( 77203074 )( spy ).then( () => {
				expect( spy ).to.have.been.calledTwice;

				const action = spy.getCall( 1 ).args[ 0 ];
				expect( action.type ).to.equal( PUBLICIZE_CONNECTIONS_REQUEST_FAILURE );
				expect( action.siteId ).to.equal( 77203074 );
				expect( action.error.message ).to.equal( 'An active access token must be used to access publicize connections.' );

				done();
			} ).catch( done );
		} );
	} );

	describe( 'fetchConnection()', () => {
		useNock( ( nock ) => {
			nock( 'https://public-api.wordpress.com:443' )
				.persist()
				.get( '/rest/v1.1/sites/2916284/publicize-connections/2' )
				.reply( 200, { ID: 2, site_ID: 2916284 } )
				.get( '/rest/v1.1/sites/77203074/publicize-connections/2' )
				.reply( 403, {
					error: 'authorization_required',
					message: 'An active access token must be used to access publicize connections.'
				} );
		} );

		it( 'should dispatch fetch action when thunk triggered', () => {
			fetchConnection( 2916284, 2 )( spy );

			expect( spy ).to.have.been.calledWith( {
				type: PUBLICIZE_CONNECTION_REQUEST,
				connectionId: 2,
				siteId: 2916284,
			} );
		} );

		it( 'should dispatch receive action when request completes', ( done ) => {
			fetchConnection( 2916284, 2 )( spy ).then( () => {
				expect( spy ).to.have.been.calledThrice;

				const action1 = spy.getCall( 1 ).args[ 0 ];
				expect( action1.type ).to.equal( PUBLICIZE_CONNECTION_RECEIVE );
				expect( action1.siteId ).to.equal( 2916284 );
				expect( action1.connection ).to.eql( { ID: 2, site_ID: 2916284 } );

				const action2 = spy.getCall( 2 ).args[ 0 ];
				expect( action2.type ).to.equal( PUBLICIZE_CONNECTION_REQUEST_SUCCESS );
				expect( action2.connectionId ).to.equal( 2 );
				expect( action2.siteId ).to.equal( 2916284 );
				done();
			} ).catch( done );
		} );

		it( 'should dispatch fail action when request fails', ( done ) => {
			fetchConnection( 77203074, 2 )( spy ).then( () => {
				expect( spy ).to.have.been.calledTwice;

				const action = spy.getCall( 1 ).args[ 0 ];
				expect( action.type ).to.equal( PUBLICIZE_CONNECTION_REQUEST_FAILURE );
				expect( action.connectionId ).to.equal( 2 );
				expect( action.error.message ).to.equal( 'An active access token must be used to access publicize connections.' );
				expect( action.siteId ).to.equal( 77203074 );

				done();
			} ).catch( done );
		} );
	} );

	describe( 'createSiteConnection()', () => {
		useNock( ( nock ) => {
			nock( 'https://public-api.wordpress.com:443' )
				.post( '/rest/v1.1/sites/2916284/publicize-connections/new', {
					external_user_ID: 1,
					keyring_connection_ID: 2,
					shared: false,
				} )
				.reply( 200, {
					ID: 2,
					site_ID: 2916284,
				} )
				.post( '/rest/v1.1/sites/77203074/publicize-connections/new', {
					external_user_ID: 1,
					keyring_connection_ID: 2,
					shared: false,
				} )
				.reply( 403, {
					error: 'authorization_required',
					message: 'An active access token must be used to access publicize connections.'
				} );
		} );

		it( 'should dispatch create action when request completes', () => {
			createSiteConnection( 2916284, 2, 1 )( spy ).then( () => {
				const action = spy.getCall( 0 ).args[ 0 ];

				expect( action.type ).to.equal( PUBLICIZE_CONNECTION_CREATE );
				expect( action.connection ).to.eql( { ID: 2, site_ID: 2916284 } );
			} );
		} );

		it( 'should dispatch fail action when request fails', () => {
			createSiteConnection( 77203074, 2, 1 )( spy ).then( () => {
				expect( spy ).to.have.been.calledWith( {
					type: PUBLICIZE_CONNECTION_CREATE_FAILURE,
					error: sinon.match( { message: 'An active access token must be used to access publicize connections.' } )
				} );
			} );
		} );
	} );

	describe( 'updateSiteConnection()', () => {
		const attributes = { shared: true };

		useNock( ( nock ) => {
			nock( 'https://public-api.wordpress.com:443' )
				.post( '/rest/v1.1/sites/2916284/publicize-connections/2', {
					shared: true,
				} )
				.reply( 200, {
					ID: 2,
					site_ID: 2916284,
				} )
				.post( '/rest/v1.1/sites/77203074/publicize-connections/2', {
					shared: true,
				} )
				.reply( 403, {
					error: 'authorization_required',
					message: 'An active access token must be used to access publicize connections.'
				} );
		} );

		it( 'should dispatch update action when request completes', () => {
			updateSiteConnection( { ID: 2, site_ID: 2916284, label: 'Facebook' }, attributes )( spy ).then( () => {
				const action = spy.getCall( 0 ).args[ 0 ];

				expect( action.type ).to.equal( PUBLICIZE_CONNECTION_UPDATE );
				expect( action.connection ).to.eql( { ID: 2, site_ID: 2916284 } );
			} );
		} );

		it( 'should dispatch fail action when request fails', () => {
			updateSiteConnection( { ID: 2, site_ID: 77203074, label: 'Facebook' }, attributes )( spy ).then( () => {
				expect( spy ).to.have.been.calledWith( {
					type: PUBLICIZE_CONNECTION_UPDATE_FAILURE,
					error: sinon.match( { message: 'An active access token must be used to access publicize connections.' } )
				} );
			} );
		} );
	} );

	describe( 'deleteSiteConnection()', () => {
		useNock( ( nock ) => {
			nock( 'https://public-api.wordpress.com:443' )
				.post( '/rest/v1.1/sites/2916284/publicize-connections/2/delete' )
				.reply( 200, {
					ID: 2,
					deleted: true,
				} )
				.post( '/rest/v1.1/sites/77203074/publicize-connections/2/delete' )
				.reply( 403, {
					error: 'authorization_required',
					message: 'An active access token must be used to access publicize connections.'
				} );
		} );

		it( 'should dispatch delete action when request completes', () => {
			deleteSiteConnection( { ID: 2, site_ID: 2916284 } )( spy ).then( () => {
				expect( spy ).to.have.been.calledWith( {
					type: PUBLICIZE_CONNECTION_DELETE,
					connection: {
						ID: 2,
						site_ID: 2916284,
					},
				} );
			} );
		} );

		it( 'should dispatch fail action when request fails', () => {
			deleteSiteConnection( { ID: 2, site_ID: 77203074 } )( spy ).then( () => {
				expect( spy ).to.have.been.calledWith( {
					type: PUBLICIZE_CONNECTION_DELETE_FAILURE,
					error: sinon.match( { message: 'An active access token must be used to access publicize connections.' } )
				} );
			} );
		} );
	} );

	describe( 'deleteConnections()', () => {
		it( 'should return an action object', () => {
			const action = deleteConnection( { ID: 2, site_ID: 2916284 } );

			expect( action ).to.eql( {
				type: PUBLICIZE_CONNECTION_DELETE,
				connection: {
					ID: 2,
					site_ID: 2916284,
				},
			} );
		} );
	} );

	describe( 'failCreateConnection()', () => {
		it( 'should return an action object', () => {
			const action = failCreateConnection( { message: 'An error occurred' } );

			expect( action ).to.eql( {
				type: PUBLICIZE_CONNECTION_CREATE_FAILURE,
				error: {
					message: 'An error occurred',
				},
			} );
		} );
	} );

	describe( '#receiveConnections()', () => {
		it( 'should return an action object', () => {
			const data = { connections: [ { ID: 2, site_ID: 2916284 } ] };
			const action = receiveConnections( 2916284, data );

			expect( action ).to.eql( {
				type: PUBLICIZE_CONNECTIONS_RECEIVE,
				siteId: 2916284,
				data
			} );
		} );
	} );
} );