Remove 'wc-admin' client/store implementation (https://github.com/woocommerce/woocommerce-admin/pull/1344)
This has been replaced by the `wc-api` store, under client/wc-api
This commit is contained in:
parent
7592dae4bb
commit
833345dfee
|
@ -10,7 +10,6 @@ import { Provider as SlotFillProvider } from 'react-slot-fill';
|
||||||
*/
|
*/
|
||||||
import './stylesheets/_embedded.scss';
|
import './stylesheets/_embedded.scss';
|
||||||
import { EmbedLayout } from './layout';
|
import { EmbedLayout } from './layout';
|
||||||
import 'store';
|
|
||||||
import 'wc-api/wp-data-store';
|
import 'wc-api/wp-data-store';
|
||||||
|
|
||||||
render(
|
render(
|
||||||
|
|
|
@ -10,7 +10,6 @@ import { Provider as SlotFillProvider } from 'react-slot-fill';
|
||||||
*/
|
*/
|
||||||
import './stylesheets/_index.scss';
|
import './stylesheets/_index.scss';
|
||||||
import { PageLayout } from './layout';
|
import { PageLayout } from './layout';
|
||||||
import 'store';
|
|
||||||
import 'wc-api/wp-data-store';
|
import 'wc-api/wp-data-store';
|
||||||
|
|
||||||
render(
|
render(
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
/** @format */
|
|
||||||
/**
|
|
||||||
* External dependencies
|
|
||||||
*/
|
|
||||||
import { combineReducers, registerStore } from '@wordpress/data';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import { applyMiddleware, addThunks } from './middleware';
|
|
||||||
import orders from 'store/orders';
|
|
||||||
import reports from 'store/reports';
|
|
||||||
import notes from 'store/notes';
|
|
||||||
|
|
||||||
const store = registerStore( 'wc-admin', {
|
|
||||||
reducer: combineReducers( {
|
|
||||||
orders: orders.reducer,
|
|
||||||
reports: reports.reducer,
|
|
||||||
notes: notes.reducer,
|
|
||||||
} ),
|
|
||||||
|
|
||||||
actions: {
|
|
||||||
...orders.actions,
|
|
||||||
...reports.actions,
|
|
||||||
...notes.actions,
|
|
||||||
},
|
|
||||||
|
|
||||||
selectors: {
|
|
||||||
...orders.selectors,
|
|
||||||
...reports.selectors,
|
|
||||||
...notes.selectors,
|
|
||||||
},
|
|
||||||
|
|
||||||
resolvers: {
|
|
||||||
...orders.resolvers,
|
|
||||||
...reports.resolvers,
|
|
||||||
...notes.resolvers,
|
|
||||||
},
|
|
||||||
} );
|
|
||||||
|
|
||||||
applyMiddleware( store, [ addThunks ] );
|
|
|
@ -1,16 +0,0 @@
|
||||||
/** @format */
|
|
||||||
|
|
||||||
export function applyMiddleware( store, middlewares ) {
|
|
||||||
middlewares = middlewares.slice();
|
|
||||||
middlewares.reverse();
|
|
||||||
let dispatch = store.dispatch;
|
|
||||||
middlewares.forEach( middleware => ( dispatch = middleware( store )( dispatch ) ) );
|
|
||||||
return Object.assign( store, { dispatch } );
|
|
||||||
}
|
|
||||||
|
|
||||||
export const addThunks = ( { getState } ) => next => action => {
|
|
||||||
if ( 'function' === typeof action ) {
|
|
||||||
return action( getState );
|
|
||||||
}
|
|
||||||
return next( action );
|
|
||||||
};
|
|
|
@ -1,17 +0,0 @@
|
||||||
/** @format */
|
|
||||||
|
|
||||||
export default {
|
|
||||||
setNotes( notes, query ) {
|
|
||||||
return {
|
|
||||||
type: 'SET_NOTES',
|
|
||||||
notes,
|
|
||||||
query: query || {},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
setNotesError( query ) {
|
|
||||||
return {
|
|
||||||
type: 'SET_NOTES_ERROR',
|
|
||||||
query: query || {},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -1,15 +0,0 @@
|
||||||
/** @format */
|
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import actions from './actions';
|
|
||||||
import reducer from './reducer';
|
|
||||||
import resolvers from './resolvers';
|
|
||||||
import selectors from './selectors';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
actions,
|
|
||||||
reducer,
|
|
||||||
resolvers,
|
|
||||||
selectors,
|
|
||||||
};
|
|
|
@ -1,31 +0,0 @@
|
||||||
/** @format */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* External dependencies
|
|
||||||
*/
|
|
||||||
import { merge } from 'lodash';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import { ERROR } from 'store/constants';
|
|
||||||
import { getJsonString } from 'store/utils';
|
|
||||||
|
|
||||||
const DEFAULT_STATE = {};
|
|
||||||
|
|
||||||
export default function notesReducer( state = DEFAULT_STATE, action ) {
|
|
||||||
const queryKey = getJsonString( action.query );
|
|
||||||
|
|
||||||
switch ( action.type ) {
|
|
||||||
case 'SET_NOTES':
|
|
||||||
return merge( {}, state, {
|
|
||||||
[ queryKey ]: action.notes,
|
|
||||||
} );
|
|
||||||
case 'SET_NOTES_ERROR':
|
|
||||||
return merge( {}, state, {
|
|
||||||
[ queryKey ]: ERROR,
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
|
|
||||||
return state;
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
/** @format */
|
|
||||||
/**
|
|
||||||
* External dependencies
|
|
||||||
*/
|
|
||||||
import { dispatch } from '@wordpress/data';
|
|
||||||
import apiFetch from '@wordpress/api-fetch';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* WooCommerce dependencies
|
|
||||||
*/
|
|
||||||
import { stringifyQuery } from '@woocommerce/navigation';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import { NAMESPACE } from 'store/constants';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
// TODO: Use controls data plugin or fresh-data instead of async
|
|
||||||
async getNotes( ...args ) {
|
|
||||||
// This is interim code to work with either 2.x or 3.x version of @wordpress/data
|
|
||||||
// TODO: Change to just `getNotes( query )` after Gutenberg plugin uses @wordpress/data 3+
|
|
||||||
const query = args.length === 1 ? args[ 0 ] : args[ 1 ];
|
|
||||||
|
|
||||||
try {
|
|
||||||
const notes = await apiFetch( { path: NAMESPACE + 'admin/notes' + stringifyQuery( query ) } );
|
|
||||||
dispatch( 'wc-admin' ).setNotes( notes, query );
|
|
||||||
} catch ( error ) {
|
|
||||||
dispatch( 'wc-admin' ).setNotesError( query );
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -1,49 +0,0 @@
|
||||||
/** @format */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* External dependencies
|
|
||||||
*/
|
|
||||||
import { get } from 'lodash';
|
|
||||||
import { select } from '@wordpress/data';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import { getJsonString } from 'store/utils';
|
|
||||||
import { ERROR } from 'store/constants';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns notes for a specific query.
|
|
||||||
*
|
|
||||||
* @param {Object} state Current state
|
|
||||||
* @param {Object} query Note query parameters
|
|
||||||
* @return {Array} Notes
|
|
||||||
*/
|
|
||||||
function getNotes( state, query = {} ) {
|
|
||||||
return get( state, [ 'notes', getJsonString( query ) ], [] );
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
getNotes,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if a query is pending.
|
|
||||||
*
|
|
||||||
* @param {Object} state Current state
|
|
||||||
* @return {Boolean} True if the `getNotes` request is pending, false otherwise
|
|
||||||
*/
|
|
||||||
isGetNotesRequesting( state, ...args ) {
|
|
||||||
return select( 'core/data' ).isResolving( 'wc-admin', 'getNotes', args );
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if a get notes request has returned an error.
|
|
||||||
*
|
|
||||||
* @param {Object} state Current state
|
|
||||||
* @param {Object} query Query parameters
|
|
||||||
* @return {Boolean} True if the `getNotes` request has failed, false otherwise
|
|
||||||
*/
|
|
||||||
isGetNotesError( state, query ) {
|
|
||||||
return ERROR === getNotes( state, query );
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -1,80 +0,0 @@
|
||||||
/**
|
|
||||||
* @format
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* External dependencies
|
|
||||||
*/
|
|
||||||
import deepFreeze from 'deep-freeze';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import { ERROR } from 'store/constants';
|
|
||||||
import notesReducer from '../reducer';
|
|
||||||
import { getJsonString } from 'store/utils';
|
|
||||||
|
|
||||||
describe( 'notesReducer()', () => {
|
|
||||||
it( 'returns an empty data object by default', () => {
|
|
||||||
const state = notesReducer( undefined, {} );
|
|
||||||
expect( state ).toEqual( {} );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns with received notes data', () => {
|
|
||||||
const originalState = deepFreeze( {} );
|
|
||||||
const query = {
|
|
||||||
page: 2,
|
|
||||||
};
|
|
||||||
const notes = [ { id: 1214 }, { id: 1215 }, { id: 1216 } ];
|
|
||||||
|
|
||||||
const state = notesReducer( originalState, {
|
|
||||||
type: 'SET_NOTES',
|
|
||||||
query,
|
|
||||||
notes,
|
|
||||||
} );
|
|
||||||
|
|
||||||
const queryKey = getJsonString( query );
|
|
||||||
expect( state[ queryKey ] ).toEqual( notes );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'tracks multiple queries in notes data', () => {
|
|
||||||
const otherQuery = {
|
|
||||||
page: 3,
|
|
||||||
};
|
|
||||||
const otherQueryKey = getJsonString( otherQuery );
|
|
||||||
const otherNotes = [ { id: 1 }, { id: 2 }, { id: 3 } ];
|
|
||||||
const otherQueryState = {
|
|
||||||
[ otherQueryKey ]: otherNotes,
|
|
||||||
};
|
|
||||||
const originalState = deepFreeze( otherQueryState );
|
|
||||||
const query = {
|
|
||||||
page: 2,
|
|
||||||
};
|
|
||||||
const notes = [ { id: 1214 }, { id: 1215 }, { id: 1216 } ];
|
|
||||||
|
|
||||||
const state = notesReducer( originalState, {
|
|
||||||
type: 'SET_NOTES',
|
|
||||||
query,
|
|
||||||
notes,
|
|
||||||
} );
|
|
||||||
|
|
||||||
const queryKey = getJsonString( query );
|
|
||||||
expect( state[ queryKey ] ).toEqual( notes );
|
|
||||||
expect( state[ otherQueryKey ] ).toEqual( otherNotes );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns with received error data', () => {
|
|
||||||
const originalState = deepFreeze( {} );
|
|
||||||
const query = {
|
|
||||||
page: 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
const state = notesReducer( originalState, {
|
|
||||||
type: 'SET_NOTES_ERROR',
|
|
||||||
query,
|
|
||||||
} );
|
|
||||||
|
|
||||||
const queryKey = getJsonString( query );
|
|
||||||
expect( state[ queryKey ] ).toEqual( ERROR );
|
|
||||||
} );
|
|
||||||
} );
|
|
|
@ -1,53 +0,0 @@
|
||||||
/*
|
|
||||||
* @format
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* External dependencies
|
|
||||||
*/
|
|
||||||
import apiFetch from '@wordpress/api-fetch';
|
|
||||||
import { dispatch } from '@wordpress/data';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import { NAMESPACE } from 'store/constants';
|
|
||||||
import resolvers from '../resolvers';
|
|
||||||
|
|
||||||
const { getNotes } = resolvers;
|
|
||||||
|
|
||||||
jest.mock( '@wordpress/data', () => ( {
|
|
||||||
dispatch: jest.fn().mockReturnValue( {
|
|
||||||
setNotes: jest.fn(),
|
|
||||||
} ),
|
|
||||||
} ) );
|
|
||||||
jest.mock( '@wordpress/api-fetch', () => jest.fn() );
|
|
||||||
|
|
||||||
describe( 'getNotes', () => {
|
|
||||||
const NOTES_1 = [ { id: 1214 }, { id: 1215 }, { id: 1216 } ];
|
|
||||||
|
|
||||||
const NOTES_2 = [ { id: 1 }, { id: 2 }, { id: 3 } ];
|
|
||||||
|
|
||||||
beforeAll( () => {
|
|
||||||
apiFetch.mockImplementation( options => {
|
|
||||||
if ( options.path === NAMESPACE + 'admin/notes' ) {
|
|
||||||
return Promise.resolve( NOTES_1 );
|
|
||||||
}
|
|
||||||
if ( options.path === NAMESPACE + 'admin/notes?page=2' ) {
|
|
||||||
return Promise.resolve( NOTES_2 );
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns requested data', async () => {
|
|
||||||
expect.assertions( 1 );
|
|
||||||
await getNotes();
|
|
||||||
expect( dispatch().setNotes ).toHaveBeenCalledWith( NOTES_1, undefined );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns requested data for a specific query', async () => {
|
|
||||||
expect.assertions( 1 );
|
|
||||||
await getNotes( { page: 2 } );
|
|
||||||
expect( dispatch().setNotes ).toHaveBeenCalledWith( NOTES_2, { page: 2 } );
|
|
||||||
} );
|
|
||||||
} );
|
|
|
@ -1,92 +0,0 @@
|
||||||
/*
|
|
||||||
* @format
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* External dependencies
|
|
||||||
*/
|
|
||||||
import deepFreeze from 'deep-freeze';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import { ERROR } from 'store/constants';
|
|
||||||
import selectors from '../selectors';
|
|
||||||
import { select } from '@wordpress/data';
|
|
||||||
import { getJsonString } from 'store/utils';
|
|
||||||
|
|
||||||
const { getNotes, isGetNotesRequesting, isGetNotesError } = selectors;
|
|
||||||
jest.mock( '@wordpress/data', () => ( {
|
|
||||||
...require.requireActual( '@wordpress/data' ),
|
|
||||||
select: jest.fn().mockReturnValue( {} ),
|
|
||||||
} ) );
|
|
||||||
|
|
||||||
const query = { page: 1 };
|
|
||||||
const queryKey = getJsonString( query );
|
|
||||||
|
|
||||||
describe( 'getNotes()', () => {
|
|
||||||
it( 'returns an empty array when no notes are available', () => {
|
|
||||||
const state = deepFreeze( {} );
|
|
||||||
expect( getNotes( state, query ) ).toEqual( [] );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns stored notes for current query', () => {
|
|
||||||
const notes = [ { id: 1214 }, { id: 1215 }, { id: 1216 } ];
|
|
||||||
const state = deepFreeze( {
|
|
||||||
notes: {
|
|
||||||
[ queryKey ]: notes,
|
|
||||||
},
|
|
||||||
} );
|
|
||||||
expect( getNotes( state, query ) ).toEqual( notes );
|
|
||||||
} );
|
|
||||||
} );
|
|
||||||
|
|
||||||
describe( 'isGetNotesRequesting()', () => {
|
|
||||||
beforeAll( () => {
|
|
||||||
select( 'core/data' ).isResolving = jest.fn().mockReturnValue( false );
|
|
||||||
} );
|
|
||||||
|
|
||||||
afterAll( () => {
|
|
||||||
select( 'core/data' ).isResolving.mockRestore();
|
|
||||||
} );
|
|
||||||
|
|
||||||
function setIsResolving( isResolving ) {
|
|
||||||
select( 'core/data' ).isResolving.mockImplementation(
|
|
||||||
( reducerKey, selectorName ) =>
|
|
||||||
isResolving && reducerKey === 'wc-admin' && selectorName === 'getNotes'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
it( 'returns false if never requested', () => {
|
|
||||||
const result = isGetNotesRequesting( query );
|
|
||||||
expect( result ).toBe( false );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns false if request finished', () => {
|
|
||||||
setIsResolving( false );
|
|
||||||
const result = isGetNotesRequesting( query );
|
|
||||||
expect( result ).toBe( false );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns true if requesting', () => {
|
|
||||||
setIsResolving( true );
|
|
||||||
const result = isGetNotesRequesting( query );
|
|
||||||
expect( result ).toBe( true );
|
|
||||||
} );
|
|
||||||
} );
|
|
||||||
|
|
||||||
describe( 'isGetNotesError()', () => {
|
|
||||||
it( 'returns false by default', () => {
|
|
||||||
const state = deepFreeze( {} );
|
|
||||||
expect( isGetNotesError( state, query ) ).toEqual( false );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns true if ERROR constant is found', () => {
|
|
||||||
const state = deepFreeze( {
|
|
||||||
notes: {
|
|
||||||
[ queryKey ]: ERROR,
|
|
||||||
},
|
|
||||||
} );
|
|
||||||
expect( isGetNotesError( state, query ) ).toEqual( true );
|
|
||||||
} );
|
|
||||||
} );
|
|
|
@ -1,17 +0,0 @@
|
||||||
/** @format */
|
|
||||||
|
|
||||||
export default {
|
|
||||||
setOrders( orders, query ) {
|
|
||||||
return {
|
|
||||||
type: 'SET_ORDERS',
|
|
||||||
orders,
|
|
||||||
query: query || {},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
setOrdersError( query ) {
|
|
||||||
return {
|
|
||||||
type: 'SET_ORDERS_ERROR',
|
|
||||||
query: query || {},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -1,15 +0,0 @@
|
||||||
/** @format */
|
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import actions from './actions';
|
|
||||||
import reducer from './reducer';
|
|
||||||
import resolvers from './resolvers';
|
|
||||||
import selectors from './selectors';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
actions,
|
|
||||||
reducer,
|
|
||||||
resolvers,
|
|
||||||
selectors,
|
|
||||||
};
|
|
|
@ -1,32 +0,0 @@
|
||||||
/** @format */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* External dependencies
|
|
||||||
*/
|
|
||||||
import { merge } from 'lodash';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import { ERROR } from 'store/constants';
|
|
||||||
import { getJsonString } from 'store/utils';
|
|
||||||
|
|
||||||
const DEFAULT_STATE = {};
|
|
||||||
|
|
||||||
export default function ordersReducer( state = DEFAULT_STATE, action ) {
|
|
||||||
const queryKey = getJsonString( action.query );
|
|
||||||
|
|
||||||
switch ( action.type ) {
|
|
||||||
case 'SET_ORDERS':
|
|
||||||
return merge( {}, state, {
|
|
||||||
[ queryKey ]: action.orders,
|
|
||||||
} );
|
|
||||||
|
|
||||||
case 'SET_ORDERS_ERROR':
|
|
||||||
return merge( {}, state, {
|
|
||||||
[ queryKey ]: ERROR,
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
|
|
||||||
return state;
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
/** @format */
|
|
||||||
/**
|
|
||||||
* External dependencies
|
|
||||||
*/
|
|
||||||
import { dispatch } from '@wordpress/data';
|
|
||||||
import apiFetch from '@wordpress/api-fetch';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* WooCommerce dependencies
|
|
||||||
*/
|
|
||||||
import { stringifyQuery } from '@woocommerce/navigation';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import { NAMESPACE } from 'store/constants';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
// TODO: Use controls data plugin or fresh-data instead of async
|
|
||||||
async getOrders( ...args ) {
|
|
||||||
// This is interim code to work with either 2.x or 3.x version of @wordpress/data
|
|
||||||
// TODO: Change to just `getNotes( query )` after Gutenberg plugin uses @wordpress/data 3+
|
|
||||||
const query = args.length === 1 ? args[ 0 ] : args[ 1 ];
|
|
||||||
|
|
||||||
try {
|
|
||||||
const orders = await apiFetch( { path: NAMESPACE + 'orders' + stringifyQuery( query ) } );
|
|
||||||
dispatch( 'wc-admin' ).setOrders( orders, query );
|
|
||||||
} catch ( error ) {
|
|
||||||
dispatch( 'wc-admin' ).setOrdersError( query );
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -1,49 +0,0 @@
|
||||||
/** @format */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* External dependencies
|
|
||||||
*/
|
|
||||||
import { get } from 'lodash';
|
|
||||||
import { select } from '@wordpress/data';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import { getJsonString } from 'store/utils';
|
|
||||||
import { ERROR } from 'store/constants';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns orders for a specific query.
|
|
||||||
*
|
|
||||||
* @param {Object} state Current state
|
|
||||||
* @param {Object} query Report query parameters
|
|
||||||
* @return {Array} Report details
|
|
||||||
*/
|
|
||||||
function getOrders( state, query = {} ) {
|
|
||||||
return get( state, [ 'orders', getJsonString( query ) ], [] );
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
getOrders,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if a getOrders request is pending.
|
|
||||||
*
|
|
||||||
* @param {Object} state Current state
|
|
||||||
* @return {Boolean} True if the `getOrders` request is pending, false otherwise
|
|
||||||
*/
|
|
||||||
isGetOrdersRequesting( state, ...args ) {
|
|
||||||
return select( 'core/data' ).isResolving( 'wc-admin', 'getOrders', args );
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if a getOrders request has returned an error.
|
|
||||||
*
|
|
||||||
* @param {Object} state Current state
|
|
||||||
* @param {Object} query Query parameters
|
|
||||||
* @return {Boolean} True if the `getOrders` request has failed, false otherwise
|
|
||||||
*/
|
|
||||||
isGetOrdersError( state, query ) {
|
|
||||||
return ERROR === getOrders( state, query );
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -1,80 +0,0 @@
|
||||||
/**
|
|
||||||
* @format
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* External dependencies
|
|
||||||
*/
|
|
||||||
import deepFreeze from 'deep-freeze';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import { ERROR } from 'store/constants';
|
|
||||||
import ordersReducer from '../reducer';
|
|
||||||
import { getJsonString } from 'store/utils';
|
|
||||||
|
|
||||||
describe( 'ordersReducer()', () => {
|
|
||||||
it( 'returns an empty data object by default', () => {
|
|
||||||
const state = ordersReducer( undefined, {} );
|
|
||||||
expect( state ).toEqual( {} );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns with received orders data', () => {
|
|
||||||
const originalState = deepFreeze( {} );
|
|
||||||
const query = {
|
|
||||||
orderby: 'date',
|
|
||||||
};
|
|
||||||
const orders = [ { id: 1214 }, { id: 1215 }, { id: 1216 } ];
|
|
||||||
|
|
||||||
const state = ordersReducer( originalState, {
|
|
||||||
type: 'SET_ORDERS',
|
|
||||||
query,
|
|
||||||
orders,
|
|
||||||
} );
|
|
||||||
|
|
||||||
const queryKey = getJsonString( query );
|
|
||||||
expect( state[ queryKey ] ).toEqual( orders );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'tracks multiple queries in orders data', () => {
|
|
||||||
const otherQuery = {
|
|
||||||
orderby: 'id',
|
|
||||||
};
|
|
||||||
const otherQueryKey = getJsonString( otherQuery );
|
|
||||||
const otherOrders = [ { id: 1 }, { id: 2 }, { id: 3 } ];
|
|
||||||
const otherQueryState = {
|
|
||||||
[ otherQueryKey ]: otherOrders,
|
|
||||||
};
|
|
||||||
const originalState = deepFreeze( otherQueryState );
|
|
||||||
const query = {
|
|
||||||
orderby: 'date',
|
|
||||||
};
|
|
||||||
const orders = [ { id: 1214 }, { id: 1215 }, { id: 1216 } ];
|
|
||||||
|
|
||||||
const state = ordersReducer( originalState, {
|
|
||||||
type: 'SET_ORDERS',
|
|
||||||
query,
|
|
||||||
orders,
|
|
||||||
} );
|
|
||||||
|
|
||||||
const queryKey = getJsonString( query );
|
|
||||||
expect( state[ queryKey ] ).toEqual( orders );
|
|
||||||
expect( state[ otherQueryKey ] ).toEqual( otherOrders );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns with received error data', () => {
|
|
||||||
const originalState = deepFreeze( {} );
|
|
||||||
const query = {
|
|
||||||
orderby: 'date',
|
|
||||||
};
|
|
||||||
|
|
||||||
const state = ordersReducer( originalState, {
|
|
||||||
type: 'SET_ORDERS_ERROR',
|
|
||||||
query,
|
|
||||||
} );
|
|
||||||
|
|
||||||
const queryKey = getJsonString( query );
|
|
||||||
expect( state[ queryKey ] ).toEqual( ERROR );
|
|
||||||
} );
|
|
||||||
} );
|
|
|
@ -1,53 +0,0 @@
|
||||||
/*
|
|
||||||
* @format
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* External dependencies
|
|
||||||
*/
|
|
||||||
import apiFetch from '@wordpress/api-fetch';
|
|
||||||
import { dispatch } from '@wordpress/data';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import { NAMESPACE } from 'store/constants';
|
|
||||||
import resolvers from '../resolvers';
|
|
||||||
|
|
||||||
const { getOrders } = resolvers;
|
|
||||||
|
|
||||||
jest.mock( '@wordpress/data', () => ( {
|
|
||||||
dispatch: jest.fn().mockReturnValue( {
|
|
||||||
setOrders: jest.fn(),
|
|
||||||
} ),
|
|
||||||
} ) );
|
|
||||||
jest.mock( '@wordpress/api-fetch', () => jest.fn() );
|
|
||||||
|
|
||||||
describe( 'getOrders', () => {
|
|
||||||
const ORDERS_1 = [ { id: 1214 }, { id: 1215 }, { id: 1216 } ];
|
|
||||||
|
|
||||||
const ORDERS_2 = [ { id: 1 }, { id: 2 }, { id: 3 } ];
|
|
||||||
|
|
||||||
beforeAll( () => {
|
|
||||||
apiFetch.mockImplementation( options => {
|
|
||||||
if ( options.path === NAMESPACE + 'orders' ) {
|
|
||||||
return Promise.resolve( ORDERS_1 );
|
|
||||||
}
|
|
||||||
if ( options.path === NAMESPACE + 'orders?orderby=id' ) {
|
|
||||||
return Promise.resolve( ORDERS_2 );
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns requested report data', async () => {
|
|
||||||
expect.assertions( 1 );
|
|
||||||
await getOrders();
|
|
||||||
expect( dispatch().setOrders ).toHaveBeenCalledWith( ORDERS_1, undefined );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns requested report data for a specific query', async () => {
|
|
||||||
expect.assertions( 1 );
|
|
||||||
await getOrders( { orderby: 'id' } );
|
|
||||||
expect( dispatch().setOrders ).toHaveBeenCalledWith( ORDERS_2, { orderby: 'id' } );
|
|
||||||
} );
|
|
||||||
} );
|
|
|
@ -1,92 +0,0 @@
|
||||||
/*
|
|
||||||
* @format
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* External dependencies
|
|
||||||
*/
|
|
||||||
import deepFreeze from 'deep-freeze';
|
|
||||||
import { select } from '@wordpress/data';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import { ERROR } from 'store/constants';
|
|
||||||
import selectors from '../selectors';
|
|
||||||
import { getJsonString } from 'store/utils';
|
|
||||||
|
|
||||||
const { getOrders, isGetOrdersRequesting, isGetOrdersError } = selectors;
|
|
||||||
jest.mock( '@wordpress/data', () => ( {
|
|
||||||
...require.requireActual( '@wordpress/data' ),
|
|
||||||
select: jest.fn().mockReturnValue( {} ),
|
|
||||||
} ) );
|
|
||||||
|
|
||||||
const query = { orderby: 'date' };
|
|
||||||
const queryKey = getJsonString( query );
|
|
||||||
|
|
||||||
describe( 'getOrders()', () => {
|
|
||||||
it( 'returns an empty array when no orders are available', () => {
|
|
||||||
const state = deepFreeze( {} );
|
|
||||||
expect( getOrders( state, query ) ).toEqual( [] );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns stored orders for current query', () => {
|
|
||||||
const orders = [ { id: 1214 }, { id: 1215 }, { id: 1216 } ];
|
|
||||||
const state = deepFreeze( {
|
|
||||||
orders: {
|
|
||||||
[ queryKey ]: orders,
|
|
||||||
},
|
|
||||||
} );
|
|
||||||
expect( getOrders( state, query ) ).toEqual( orders );
|
|
||||||
} );
|
|
||||||
} );
|
|
||||||
|
|
||||||
describe( 'isGetOrdersRequesting()', () => {
|
|
||||||
beforeAll( () => {
|
|
||||||
select( 'core/data' ).isResolving = jest.fn().mockReturnValue( false );
|
|
||||||
} );
|
|
||||||
|
|
||||||
afterAll( () => {
|
|
||||||
select( 'core/data' ).isResolving.mockRestore();
|
|
||||||
} );
|
|
||||||
|
|
||||||
function setIsResolving( isResolving ) {
|
|
||||||
select( 'core/data' ).isResolving.mockImplementation(
|
|
||||||
( reducerKey, selectorName ) =>
|
|
||||||
isResolving && reducerKey === 'wc-admin' && selectorName === 'getOrders'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
it( 'returns false if never requested', () => {
|
|
||||||
const result = isGetOrdersRequesting( query );
|
|
||||||
expect( result ).toBe( false );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns false if request finished', () => {
|
|
||||||
setIsResolving( false );
|
|
||||||
const result = isGetOrdersRequesting( query );
|
|
||||||
expect( result ).toBe( false );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns true if requesting', () => {
|
|
||||||
setIsResolving( true );
|
|
||||||
const result = isGetOrdersRequesting( query );
|
|
||||||
expect( result ).toBe( true );
|
|
||||||
} );
|
|
||||||
} );
|
|
||||||
|
|
||||||
describe( 'isGetOrdersError()', () => {
|
|
||||||
it( 'returns false by default', () => {
|
|
||||||
const state = deepFreeze( {} );
|
|
||||||
expect( isGetOrdersError( state, query ) ).toEqual( false );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns true if ERROR constant is found', () => {
|
|
||||||
const state = deepFreeze( {
|
|
||||||
orders: {
|
|
||||||
[ queryKey ]: ERROR,
|
|
||||||
},
|
|
||||||
} );
|
|
||||||
expect( isGetOrdersError( state, query ) ).toEqual( true );
|
|
||||||
} );
|
|
||||||
} );
|
|
|
@ -1,31 +0,0 @@
|
||||||
/** @format */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* External dependencies
|
|
||||||
*/
|
|
||||||
import { combineReducers } from '@wordpress/data';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import items from './items';
|
|
||||||
import stats from './stats';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
reducer: combineReducers( {
|
|
||||||
items: items.reducer,
|
|
||||||
stats: stats.reducer,
|
|
||||||
} ),
|
|
||||||
actions: {
|
|
||||||
...items.actions,
|
|
||||||
...stats.actions,
|
|
||||||
},
|
|
||||||
selectors: {
|
|
||||||
...items.selectors,
|
|
||||||
...stats.selectors,
|
|
||||||
},
|
|
||||||
resolvers: {
|
|
||||||
...items.resolvers,
|
|
||||||
...stats.resolvers,
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -1,20 +0,0 @@
|
||||||
/** @format */
|
|
||||||
|
|
||||||
export default {
|
|
||||||
setReportItems( endpoint, query, data, totalCount ) {
|
|
||||||
return {
|
|
||||||
type: 'SET_REPORT_ITEMS',
|
|
||||||
endpoint,
|
|
||||||
query: query || {},
|
|
||||||
data,
|
|
||||||
totalCount,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
setReportItemsError( endpoint, query ) {
|
|
||||||
return {
|
|
||||||
type: 'SET_REPORT_ITEMS_ERROR',
|
|
||||||
endpoint,
|
|
||||||
query: query || {},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -1,15 +0,0 @@
|
||||||
/** @format */
|
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import actions from './actions';
|
|
||||||
import reducer from './reducer';
|
|
||||||
import resolvers from './resolvers';
|
|
||||||
import selectors from './selectors';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
actions,
|
|
||||||
reducer,
|
|
||||||
resolvers,
|
|
||||||
selectors,
|
|
||||||
};
|
|
|
@ -1,39 +0,0 @@
|
||||||
/** @format */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* External dependencies
|
|
||||||
*/
|
|
||||||
import { merge } from 'lodash';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import { ERROR } from 'store/constants';
|
|
||||||
import { getJsonString } from 'store/utils';
|
|
||||||
|
|
||||||
const DEFAULT_STATE = {};
|
|
||||||
|
|
||||||
export default function reportItemsReducer( state = DEFAULT_STATE, action ) {
|
|
||||||
const queryKey = getJsonString( action.query );
|
|
||||||
|
|
||||||
switch ( action.type ) {
|
|
||||||
case 'SET_REPORT_ITEMS':
|
|
||||||
return merge( {}, state, {
|
|
||||||
[ action.endpoint ]: {
|
|
||||||
[ queryKey ]: {
|
|
||||||
data: action.data,
|
|
||||||
totalCount: action.totalCount,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} );
|
|
||||||
|
|
||||||
case 'SET_REPORT_ITEMS_ERROR':
|
|
||||||
return merge( {}, state, {
|
|
||||||
[ action.endpoint ]: {
|
|
||||||
[ queryKey ]: ERROR,
|
|
||||||
},
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
|
|
||||||
return state;
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
/** @format */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* External dependencies
|
|
||||||
*/
|
|
||||||
import apiFetch from '@wordpress/api-fetch';
|
|
||||||
import { dispatch } from '@wordpress/data';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* WooCommerce dependencies
|
|
||||||
*/
|
|
||||||
import { stringifyQuery } from '@woocommerce/navigation';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import { NAMESPACE } from 'store/constants';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
async getReportItems( ...args ) {
|
|
||||||
const [ endpoint, query ] = args.slice( -2 );
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await apiFetch( {
|
|
||||||
parse: false,
|
|
||||||
path: NAMESPACE + 'reports/' + endpoint + stringifyQuery( query ),
|
|
||||||
} );
|
|
||||||
|
|
||||||
const itemsData = await response.json();
|
|
||||||
const totalCount = parseInt( response.headers.get( 'x-wp-total' ) );
|
|
||||||
dispatch( 'wc-admin' ).setReportItems( endpoint, query, itemsData, totalCount );
|
|
||||||
} catch ( error ) {
|
|
||||||
dispatch( 'wc-admin' ).setReportItemsError( endpoint, query );
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -1,51 +0,0 @@
|
||||||
/** @format */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* External dependencies
|
|
||||||
*/
|
|
||||||
import { get } from 'lodash';
|
|
||||||
import { select } from '@wordpress/data';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import { ERROR } from 'store/constants';
|
|
||||||
import { getJsonString } from 'store/utils';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns report items for a specific endpoint query.
|
|
||||||
*
|
|
||||||
* @param {Object} state Current state
|
|
||||||
* @param {String} endpoint Stats endpoint
|
|
||||||
* @param {Object} query Report query parameters
|
|
||||||
* @return {Object} Report details
|
|
||||||
*/
|
|
||||||
function getReportItems( state, endpoint, query = {} ) {
|
|
||||||
return get( state, [ 'reports', 'items', endpoint, getJsonString( query ) ], { data: [] } );
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
getReportItems,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if a getReportItems request is pending.
|
|
||||||
*
|
|
||||||
* @param {Object} state Current state
|
|
||||||
* @return {Boolean} True if the `getReportItems` request is pending, false otherwise
|
|
||||||
*/
|
|
||||||
isGetReportItemsRequesting( state, ...args ) {
|
|
||||||
return select( 'core/data' ).isResolving( 'wc-admin', 'getReportItems', args );
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if a getReportItems request has returned an error.
|
|
||||||
*
|
|
||||||
* @param {Object} state Current state
|
|
||||||
* @param {String} endpoint Items endpoint
|
|
||||||
* @param {Object} query Report query parameters
|
|
||||||
* @return {Boolean} True if the `getReportItems` request has failed, false otherwise
|
|
||||||
*/
|
|
||||||
isGetReportItemsError( state, endpoint, query ) {
|
|
||||||
return ERROR === getReportItems( state, endpoint, query );
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -1,104 +0,0 @@
|
||||||
/**
|
|
||||||
* @format
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* External dependencies
|
|
||||||
*/
|
|
||||||
import deepFreeze from 'deep-freeze';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import { ERROR } from 'store/constants';
|
|
||||||
import reportItemsReducer from '../reducer';
|
|
||||||
import { getJsonString } from 'store/utils';
|
|
||||||
|
|
||||||
describe( 'reportItemsReducer()', () => {
|
|
||||||
const endpoint = 'coupons';
|
|
||||||
|
|
||||||
it( 'returns an empty object by default', () => {
|
|
||||||
const state = reportItemsReducer( undefined, {} );
|
|
||||||
expect( state ).toEqual( {} );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns with received items data', () => {
|
|
||||||
const originalState = deepFreeze( {} );
|
|
||||||
const query = {
|
|
||||||
orderby: 'orders_count',
|
|
||||||
};
|
|
||||||
const itemsData = [ { id: 1214 }, { id: 1215 }, { id: 1216 } ];
|
|
||||||
const itemsTotalCount = 50;
|
|
||||||
|
|
||||||
const state = reportItemsReducer( originalState, {
|
|
||||||
type: 'SET_REPORT_ITEMS',
|
|
||||||
endpoint,
|
|
||||||
query,
|
|
||||||
data: itemsData,
|
|
||||||
totalCount: itemsTotalCount,
|
|
||||||
} );
|
|
||||||
|
|
||||||
const queryKey = getJsonString( query );
|
|
||||||
expect( state[ endpoint ][ queryKey ] ).toEqual( {
|
|
||||||
data: itemsData,
|
|
||||||
totalCount: itemsTotalCount,
|
|
||||||
} );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'tracks multiple queries in items data', () => {
|
|
||||||
const otherQuery = {
|
|
||||||
orderby: 'id',
|
|
||||||
};
|
|
||||||
const otherQueryKey = getJsonString( otherQuery );
|
|
||||||
const otherItemsData = [ { id: 1 }, { id: 2 }, { id: 3 } ];
|
|
||||||
const otherItemsTotalCount = 70;
|
|
||||||
const otherQueryState = {
|
|
||||||
[ endpoint ]: {
|
|
||||||
[ otherQueryKey ]: {
|
|
||||||
data: otherItemsData,
|
|
||||||
totalCount: otherItemsTotalCount,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const originalState = deepFreeze( otherQueryState );
|
|
||||||
const query = {
|
|
||||||
orderby: 'orders_count',
|
|
||||||
};
|
|
||||||
const itemsData = [ { id: 1214 }, { id: 1215 }, { id: 1216 } ];
|
|
||||||
const itemsTotalCount = 50;
|
|
||||||
|
|
||||||
const state = reportItemsReducer( originalState, {
|
|
||||||
type: 'SET_REPORT_ITEMS',
|
|
||||||
endpoint,
|
|
||||||
query,
|
|
||||||
data: itemsData,
|
|
||||||
totalCount: itemsTotalCount,
|
|
||||||
} );
|
|
||||||
|
|
||||||
const queryKey = getJsonString( query );
|
|
||||||
expect( state[ endpoint ][ queryKey ] ).toEqual( {
|
|
||||||
data: itemsData,
|
|
||||||
totalCount: itemsTotalCount,
|
|
||||||
} );
|
|
||||||
expect( state[ endpoint ][ otherQueryKey ] ).toEqual( {
|
|
||||||
data: otherItemsData,
|
|
||||||
totalCount: otherItemsTotalCount,
|
|
||||||
} );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns with received error data', () => {
|
|
||||||
const originalState = deepFreeze( {} );
|
|
||||||
const query = {
|
|
||||||
orderby: 'orders_count',
|
|
||||||
};
|
|
||||||
|
|
||||||
const state = reportItemsReducer( originalState, {
|
|
||||||
type: 'SET_REPORT_ITEMS_ERROR',
|
|
||||||
endpoint,
|
|
||||||
query,
|
|
||||||
} );
|
|
||||||
|
|
||||||
const queryKey = getJsonString( query );
|
|
||||||
expect( state[ endpoint ][ queryKey ] ).toEqual( ERROR );
|
|
||||||
} );
|
|
||||||
} );
|
|
|
@ -1,74 +0,0 @@
|
||||||
/*
|
|
||||||
* @format
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* External dependencies
|
|
||||||
*/
|
|
||||||
import apiFetch from '@wordpress/api-fetch';
|
|
||||||
import { dispatch } from '@wordpress/data';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import resolvers from '../resolvers';
|
|
||||||
|
|
||||||
const { getReportItems } = resolvers;
|
|
||||||
|
|
||||||
jest.mock( '@wordpress/data', () => ( {
|
|
||||||
dispatch: jest.fn().mockReturnValue( {
|
|
||||||
setReportItems: jest.fn(),
|
|
||||||
} ),
|
|
||||||
} ) );
|
|
||||||
jest.mock( '@wordpress/api-fetch', () => jest.fn() );
|
|
||||||
|
|
||||||
describe( 'getReportItems', () => {
|
|
||||||
const ITEMS_1 = [ { id: 1214 }, { id: 1215 }, { id: 1216 } ];
|
|
||||||
const ITEMS_1_COUNT = 50;
|
|
||||||
const ITEMS_2 = [ { id: 1 }, { id: 2 }, { id: 3 } ];
|
|
||||||
const ITEMS_2_COUNT = 75;
|
|
||||||
const endpoint = 'products';
|
|
||||||
|
|
||||||
beforeAll( () => {
|
|
||||||
apiFetch.mockImplementation( options => {
|
|
||||||
if ( options.path === `/wc/v4/reports/${ endpoint }` ) {
|
|
||||||
return Promise.resolve( {
|
|
||||||
headers: {
|
|
||||||
get: () => ITEMS_1_COUNT,
|
|
||||||
},
|
|
||||||
json: () => Promise.resolve( ITEMS_1 ),
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
if ( options.path === `/wc/v4/reports/${ endpoint }?orderby=id` ) {
|
|
||||||
return Promise.resolve( {
|
|
||||||
headers: {
|
|
||||||
get: () => ITEMS_2_COUNT,
|
|
||||||
},
|
|
||||||
json: () => Promise.resolve( ITEMS_2 ),
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns requested report data', async () => {
|
|
||||||
expect.assertions( 1 );
|
|
||||||
await getReportItems( endpoint );
|
|
||||||
expect( dispatch().setReportItems ).toHaveBeenCalledWith(
|
|
||||||
endpoint,
|
|
||||||
undefined,
|
|
||||||
ITEMS_1,
|
|
||||||
ITEMS_1_COUNT
|
|
||||||
);
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns requested report data for a specific query', async () => {
|
|
||||||
expect.assertions( 1 );
|
|
||||||
await getReportItems( endpoint, { orderby: 'id' } );
|
|
||||||
expect( dispatch().setReportItems ).toHaveBeenCalledWith(
|
|
||||||
endpoint,
|
|
||||||
{ orderby: 'id' },
|
|
||||||
ITEMS_2,
|
|
||||||
ITEMS_2_COUNT
|
|
||||||
);
|
|
||||||
} );
|
|
||||||
} );
|
|
|
@ -1,106 +0,0 @@
|
||||||
/*
|
|
||||||
* @format
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* External dependencies
|
|
||||||
*/
|
|
||||||
import deepFreeze from 'deep-freeze';
|
|
||||||
import { select } from '@wordpress/data';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import { ERROR } from 'store/constants';
|
|
||||||
import { getJsonString } from 'store/utils';
|
|
||||||
import selectors from '../selectors';
|
|
||||||
|
|
||||||
const { getReportItems, isGetReportItemsRequesting, isGetReportItemsError } = selectors;
|
|
||||||
jest.mock( '@wordpress/data', () => ( {
|
|
||||||
...require.requireActual( '@wordpress/data' ),
|
|
||||||
select: jest.fn().mockReturnValue( {} ),
|
|
||||||
} ) );
|
|
||||||
|
|
||||||
const query = { orderby: 'date' };
|
|
||||||
const queryKey = getJsonString( query );
|
|
||||||
const endpoint = 'coupons';
|
|
||||||
|
|
||||||
describe( 'getReportItems()', () => {
|
|
||||||
it( 'returns an empty object when no items are available', () => {
|
|
||||||
const state = deepFreeze( {} );
|
|
||||||
expect( getReportItems( state, endpoint, query ) ).toEqual( { data: [] } );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns stored items for current query', () => {
|
|
||||||
const itemsData = [ { id: 1214 }, { id: 1215 }, { id: 1216 } ];
|
|
||||||
const itemsTotalCount = 50;
|
|
||||||
const queryState = {
|
|
||||||
data: itemsData,
|
|
||||||
totalCount: itemsTotalCount,
|
|
||||||
};
|
|
||||||
const state = deepFreeze( {
|
|
||||||
reports: {
|
|
||||||
items: {
|
|
||||||
[ endpoint ]: {
|
|
||||||
[ queryKey ]: queryState,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} );
|
|
||||||
expect( getReportItems( state, endpoint, query ) ).toEqual( queryState );
|
|
||||||
} );
|
|
||||||
} );
|
|
||||||
|
|
||||||
describe( 'isGetReportItemsRequesting()', () => {
|
|
||||||
beforeAll( () => {
|
|
||||||
select( 'core/data' ).isResolving = jest.fn().mockReturnValue( false );
|
|
||||||
} );
|
|
||||||
|
|
||||||
afterAll( () => {
|
|
||||||
select( 'core/data' ).isResolving.mockRestore();
|
|
||||||
} );
|
|
||||||
|
|
||||||
function setIsResolving( isResolving ) {
|
|
||||||
select( 'core/data' ).isResolving.mockImplementation(
|
|
||||||
( reducerKey, selectorName ) =>
|
|
||||||
isResolving && reducerKey === 'wc-admin' && selectorName === 'getReportItems'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
it( 'returns false if never requested', () => {
|
|
||||||
const result = isGetReportItemsRequesting( endpoint );
|
|
||||||
expect( result ).toBe( false );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns false if request finished', () => {
|
|
||||||
setIsResolving( false );
|
|
||||||
const result = isGetReportItemsRequesting( endpoint );
|
|
||||||
expect( result ).toBe( false );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns true if requesting', () => {
|
|
||||||
setIsResolving( true );
|
|
||||||
const result = isGetReportItemsRequesting( endpoint );
|
|
||||||
expect( result ).toBe( true );
|
|
||||||
} );
|
|
||||||
} );
|
|
||||||
|
|
||||||
describe( 'isGetReportItemsError()', () => {
|
|
||||||
it( 'returns false by default', () => {
|
|
||||||
const state = deepFreeze( {} );
|
|
||||||
expect( isGetReportItemsError( state, endpoint, query ) ).toEqual( false );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns true if ERROR constant is found', () => {
|
|
||||||
const state = deepFreeze( {
|
|
||||||
reports: {
|
|
||||||
items: {
|
|
||||||
[ endpoint ]: {
|
|
||||||
[ queryKey ]: ERROR,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} );
|
|
||||||
expect( isGetReportItemsError( state, endpoint, query ) ).toEqual( true );
|
|
||||||
} );
|
|
||||||
} );
|
|
|
@ -1,21 +0,0 @@
|
||||||
/** @format */
|
|
||||||
|
|
||||||
export default {
|
|
||||||
setReportStats( endpoint, report, query, totalResults, totalPages ) {
|
|
||||||
return {
|
|
||||||
type: 'SET_REPORT_STATS',
|
|
||||||
endpoint,
|
|
||||||
report,
|
|
||||||
totalResults,
|
|
||||||
totalPages,
|
|
||||||
query: query || {},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
setReportStatsError( endpoint, query ) {
|
|
||||||
return {
|
|
||||||
type: 'SET_REPORT_STATS_ERROR',
|
|
||||||
endpoint,
|
|
||||||
query: query || {},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -1,16 +0,0 @@
|
||||||
/** @format */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import actions from './actions';
|
|
||||||
import reducer from './reducer';
|
|
||||||
import resolvers from './resolvers';
|
|
||||||
import selectors from './selectors';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
actions,
|
|
||||||
reducer,
|
|
||||||
resolvers,
|
|
||||||
selectors,
|
|
||||||
};
|
|
|
@ -1,40 +0,0 @@
|
||||||
/** @format */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* External dependencies
|
|
||||||
*/
|
|
||||||
import { merge } from 'lodash';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import { ERROR } from 'store/constants';
|
|
||||||
import { getJsonString } from 'store/utils';
|
|
||||||
|
|
||||||
const DEFAULT_STATE = {};
|
|
||||||
|
|
||||||
export default function reportStatsReducer( state = DEFAULT_STATE, action ) {
|
|
||||||
if ( 'SET_REPORT_STATS' === action.type ) {
|
|
||||||
const queryKey = getJsonString( action.query );
|
|
||||||
return merge( {}, state, {
|
|
||||||
[ action.endpoint ]: {
|
|
||||||
[ queryKey ]: {
|
|
||||||
data: action.report,
|
|
||||||
totalResults: action.totalResults,
|
|
||||||
totalPages: action.totalPages,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( 'SET_REPORT_STATS_ERROR' === action.type ) {
|
|
||||||
const queryKey = getJsonString( action.query );
|
|
||||||
return merge( {}, state, {
|
|
||||||
[ action.endpoint ]: {
|
|
||||||
[ queryKey ]: ERROR,
|
|
||||||
},
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
|
|
||||||
return state;
|
|
||||||
}
|
|
|
@ -1,63 +0,0 @@
|
||||||
/** @format */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* External dependencies
|
|
||||||
*/
|
|
||||||
import apiFetch from '@wordpress/api-fetch';
|
|
||||||
import { dispatch } from '@wordpress/data';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* WooCommerce dependencies
|
|
||||||
*/
|
|
||||||
import { stringifyQuery } from '@woocommerce/navigation';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import { NAMESPACE, SWAGGERNAMESPACE } from 'store/constants';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
// TODO: Use controls data plugin or fresh-data instead of async
|
|
||||||
async getReportStats( ...args ) {
|
|
||||||
// This is interim code to work with either 2.x or 3.x version of @wordpress/data
|
|
||||||
// TODO: Change to just `getNotes( endpoint, query )`
|
|
||||||
// after Gutenberg plugin uses @wordpress/data 3+
|
|
||||||
const [ endpoint, query ] = args.length === 2 ? args : args.slice( 1, 3 );
|
|
||||||
const statEndpoints = [ 'orders', 'revenue', 'products', 'taxes' ];
|
|
||||||
|
|
||||||
let apiPath = endpoint + stringifyQuery( query );
|
|
||||||
|
|
||||||
// TODO: Remove once swagger endpoints are phased out.
|
|
||||||
const swaggerEndpoints = [ 'categories' ];
|
|
||||||
if ( swaggerEndpoints.indexOf( endpoint ) >= 0 ) {
|
|
||||||
apiPath = SWAGGERNAMESPACE + 'reports/' + endpoint + '/stats' + stringifyQuery( query );
|
|
||||||
try {
|
|
||||||
const response = await fetch( apiPath );
|
|
||||||
|
|
||||||
const report = await response.json();
|
|
||||||
dispatch( 'wc-admin' ).setReportStats( endpoint, report, query );
|
|
||||||
} catch ( error ) {
|
|
||||||
dispatch( 'wc-admin' ).setReportStatsError( endpoint, query );
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( statEndpoints.indexOf( endpoint ) >= 0 ) {
|
|
||||||
apiPath = NAMESPACE + 'reports/' + endpoint + '/stats' + stringifyQuery( query );
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await apiFetch( {
|
|
||||||
path: apiPath,
|
|
||||||
parse: false,
|
|
||||||
} );
|
|
||||||
|
|
||||||
const report = await response.json();
|
|
||||||
const totalResults = parseInt( response.headers.get( 'x-wp-total' ) );
|
|
||||||
const totalPages = parseInt( response.headers.get( 'x-wp-totalpages' ) );
|
|
||||||
dispatch( 'wc-admin' ).setReportStats( endpoint, report, query, totalResults, totalPages );
|
|
||||||
} catch ( error ) {
|
|
||||||
dispatch( 'wc-admin' ).setReportStatsError( endpoint, query );
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -1,52 +0,0 @@
|
||||||
/** @format */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* External dependencies
|
|
||||||
*/
|
|
||||||
import { get } from 'lodash';
|
|
||||||
import { select } from '@wordpress/data';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import { ERROR } from 'store/constants';
|
|
||||||
import { getJsonString } from 'store/utils';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns report stats details for a specific endpoint query.
|
|
||||||
*
|
|
||||||
* @param {Object} state Current state
|
|
||||||
* @param {String} endpoint Stats endpoint
|
|
||||||
* @param {Object} query Report query parameters
|
|
||||||
* @return {Object} Report details
|
|
||||||
*/
|
|
||||||
function getReportStats( state, endpoint, query = {} ) {
|
|
||||||
const queries = get( state, [ 'reports', 'stats', endpoint ], {} );
|
|
||||||
return queries[ getJsonString( query ) ] || null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
getReportStats,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if a stats query is pending.
|
|
||||||
*
|
|
||||||
* @param {Object} state Current state
|
|
||||||
* @return {Boolean} True if the `getReportStats` request is pending, false otherwise
|
|
||||||
*/
|
|
||||||
isReportStatsRequesting( state, ...args ) {
|
|
||||||
return select( 'core/data' ).isResolving( 'wc-admin', 'getReportStats', args );
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if a report stat request has returned an error.
|
|
||||||
*
|
|
||||||
* @param {Object} state Current state
|
|
||||||
* @param {String} endpoint Stats endpoint
|
|
||||||
* @param {Object} query Report query parameters
|
|
||||||
* @return {Boolean} True if the `getReportStats` request has failed, false otherwise
|
|
||||||
*/
|
|
||||||
isReportStatsError( state, endpoint, query ) {
|
|
||||||
return ERROR === getReportStats( state, endpoint, query );
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -1,164 +0,0 @@
|
||||||
/**
|
|
||||||
* @format
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* External dependencies
|
|
||||||
*/
|
|
||||||
import deepFreeze from 'deep-freeze';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import { ERROR } from 'store/constants';
|
|
||||||
import reportStatsReducer from '../reducer';
|
|
||||||
import { getJsonString } from 'store/utils';
|
|
||||||
|
|
||||||
describe( 'reportStatsReducer()', () => {
|
|
||||||
it( 'returns an empty data object by default', () => {
|
|
||||||
const state = reportStatsReducer( undefined, {} );
|
|
||||||
expect( state ).toEqual( {} );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns with received report data', () => {
|
|
||||||
const originalState = deepFreeze( {} );
|
|
||||||
const query = {
|
|
||||||
after: '2018-01-04T00:00:00+00:00',
|
|
||||||
before: '2018-07-14T00:00:00+00:00',
|
|
||||||
interval: 'day',
|
|
||||||
};
|
|
||||||
const report = {
|
|
||||||
totals: {
|
|
||||||
orders_count: 10,
|
|
||||||
num_items_sold: 9,
|
|
||||||
},
|
|
||||||
interval: [ 0, 1, 2 ],
|
|
||||||
};
|
|
||||||
const endpoint = 'revenue';
|
|
||||||
|
|
||||||
const state = reportStatsReducer( originalState, {
|
|
||||||
type: 'SET_REPORT_STATS',
|
|
||||||
endpoint,
|
|
||||||
query,
|
|
||||||
report,
|
|
||||||
totalResults: 3,
|
|
||||||
totalPages: 1,
|
|
||||||
} );
|
|
||||||
|
|
||||||
const queryKey = getJsonString( query );
|
|
||||||
expect( state[ endpoint ][ queryKey ] ).toEqual( {
|
|
||||||
data: { ...report },
|
|
||||||
totalResults: 3,
|
|
||||||
totalPages: 1,
|
|
||||||
} );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'tracks multiple queries per endpoint in report data', () => {
|
|
||||||
const otherQuery = {
|
|
||||||
after: '2018-01-04T00:00:00+00:00',
|
|
||||||
before: '2018-07-14T00:00:00+00:00',
|
|
||||||
interval: 'week',
|
|
||||||
};
|
|
||||||
const otherQueryKey = getJsonString( otherQuery );
|
|
||||||
const otherQueryState = {
|
|
||||||
revenue: {
|
|
||||||
[ otherQueryKey ]: { data: { totals: 1000 } },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const originalState = deepFreeze( otherQueryState );
|
|
||||||
const query = {
|
|
||||||
after: '2018-01-04T00:00:00+00:00',
|
|
||||||
before: '2018-07-14T00:00:00+00:00',
|
|
||||||
interval: 'day',
|
|
||||||
};
|
|
||||||
const report = {
|
|
||||||
totals: {
|
|
||||||
orders_count: 10,
|
|
||||||
num_items_sold: 9,
|
|
||||||
},
|
|
||||||
interval: [ 0, 1, 2 ],
|
|
||||||
};
|
|
||||||
const endpoint = 'revenue';
|
|
||||||
|
|
||||||
const state = reportStatsReducer( originalState, {
|
|
||||||
type: 'SET_REPORT_STATS',
|
|
||||||
endpoint,
|
|
||||||
query,
|
|
||||||
report,
|
|
||||||
totalResults: 3,
|
|
||||||
totalPages: 1,
|
|
||||||
} );
|
|
||||||
|
|
||||||
const queryKey = getJsonString( query );
|
|
||||||
expect( state[ endpoint ][ queryKey ] ).toEqual( {
|
|
||||||
data: { ...report },
|
|
||||||
totalResults: 3,
|
|
||||||
totalPages: 1,
|
|
||||||
} );
|
|
||||||
expect( state[ endpoint ][ otherQueryKey ].data.totals ).toEqual( 1000 );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'tracks multiple endpoints in report data', () => {
|
|
||||||
const productsQuery = {
|
|
||||||
after: '2018-01-04T00:00:00+00:00',
|
|
||||||
before: '2018-07-14T00:00:00+00:00',
|
|
||||||
interval: 'week',
|
|
||||||
};
|
|
||||||
const productsQueryKey = getJsonString( productsQuery );
|
|
||||||
const productsQueryState = {
|
|
||||||
products: {
|
|
||||||
[ productsQueryKey ]: { data: { totals: 1999 } },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const originalState = deepFreeze( productsQueryState );
|
|
||||||
const query = {
|
|
||||||
after: '2018-01-04T00:00:00+00:00',
|
|
||||||
before: '2018-07-14T00:00:00+00:00',
|
|
||||||
interval: 'day',
|
|
||||||
};
|
|
||||||
const report = {
|
|
||||||
totals: {
|
|
||||||
orders_count: 10,
|
|
||||||
num_items_sold: 9,
|
|
||||||
},
|
|
||||||
interval: [ 0, 1, 2 ],
|
|
||||||
};
|
|
||||||
const endpoint = 'revenue';
|
|
||||||
|
|
||||||
const state = reportStatsReducer( originalState, {
|
|
||||||
type: 'SET_REPORT_STATS',
|
|
||||||
endpoint,
|
|
||||||
query,
|
|
||||||
report,
|
|
||||||
totalResults: 3,
|
|
||||||
totalPages: 1,
|
|
||||||
} );
|
|
||||||
|
|
||||||
const queryKey = getJsonString( query );
|
|
||||||
expect( state[ endpoint ][ queryKey ] ).toEqual( {
|
|
||||||
data: { ...report },
|
|
||||||
totalResults: 3,
|
|
||||||
totalPages: 1,
|
|
||||||
} );
|
|
||||||
expect( state.products[ productsQueryKey ].data.totals ).toEqual( 1999 );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns with received error data', () => {
|
|
||||||
const originalState = deepFreeze( {} );
|
|
||||||
const query = {
|
|
||||||
after: '2018-01-04T00:00:00+00:00',
|
|
||||||
before: '2018-07-14T00:00:00+00:00',
|
|
||||||
interval: 'day',
|
|
||||||
};
|
|
||||||
const endpoint = 'revenue';
|
|
||||||
|
|
||||||
const state = reportStatsReducer( originalState, {
|
|
||||||
type: 'SET_REPORT_STATS_ERROR',
|
|
||||||
endpoint,
|
|
||||||
query,
|
|
||||||
} );
|
|
||||||
|
|
||||||
const queryKey = getJsonString( query );
|
|
||||||
expect( state[ endpoint ][ queryKey ] ).toEqual( ERROR );
|
|
||||||
} );
|
|
||||||
} );
|
|
|
@ -1,107 +0,0 @@
|
||||||
/*
|
|
||||||
* @format
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* External dependencies
|
|
||||||
*/
|
|
||||||
import apiFetch from '@wordpress/api-fetch';
|
|
||||||
import { dispatch } from '@wordpress/data';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import resolvers from '../resolvers';
|
|
||||||
|
|
||||||
const { getReportStats } = resolvers;
|
|
||||||
|
|
||||||
jest.mock( '@wordpress/data', () => ( {
|
|
||||||
dispatch: jest.fn().mockReturnValue( {
|
|
||||||
setReportStats: jest.fn(),
|
|
||||||
} ),
|
|
||||||
} ) );
|
|
||||||
jest.mock( '@wordpress/api-fetch', () => jest.fn() );
|
|
||||||
|
|
||||||
describe( 'getReportStats', () => {
|
|
||||||
const REPORT_1 = {
|
|
||||||
totals: {
|
|
||||||
orders_count: 10,
|
|
||||||
num_items_sold: 9,
|
|
||||||
},
|
|
||||||
interval: [ 0, 1, 2 ],
|
|
||||||
};
|
|
||||||
const REPORT_1_TOTALS = {
|
|
||||||
'x-wp-total': 10,
|
|
||||||
'x-wp-totalpages': 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
const REPORT_2 = {
|
|
||||||
totals: {
|
|
||||||
orders_count: 5,
|
|
||||||
items_sold: 5,
|
|
||||||
gross_revenue: 999.99,
|
|
||||||
},
|
|
||||||
intervals: [
|
|
||||||
{
|
|
||||||
interval: 'week',
|
|
||||||
subtotals: {},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
const REPORT_2_TOTALS = {
|
|
||||||
'x-wp-total': 20,
|
|
||||||
'x-wp-totalpages': 4,
|
|
||||||
};
|
|
||||||
|
|
||||||
beforeAll( () => {
|
|
||||||
apiFetch.mockImplementation( options => {
|
|
||||||
if ( options.path === '/wc/v4/reports/revenue/stats' ) {
|
|
||||||
return Promise.resolve( {
|
|
||||||
headers: {
|
|
||||||
get: header => REPORT_1_TOTALS[ header ],
|
|
||||||
},
|
|
||||||
json: () => Promise.resolve( REPORT_1 ),
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
if ( options.path === '/wc/v4/reports/products/stats?interval=week' ) {
|
|
||||||
return Promise.resolve( {
|
|
||||||
headers: {
|
|
||||||
get: header => REPORT_2_TOTALS[ header ],
|
|
||||||
},
|
|
||||||
json: () => Promise.resolve( REPORT_2 ),
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns requested report data', async () => {
|
|
||||||
expect.assertions( 1 );
|
|
||||||
const endpoint = 'revenue';
|
|
||||||
|
|
||||||
await getReportStats( endpoint, undefined );
|
|
||||||
|
|
||||||
expect( dispatch().setReportStats ).toHaveBeenCalledWith(
|
|
||||||
endpoint,
|
|
||||||
REPORT_1,
|
|
||||||
undefined,
|
|
||||||
REPORT_1_TOTALS[ 'x-wp-total' ],
|
|
||||||
REPORT_1_TOTALS[ 'x-wp-totalpages' ]
|
|
||||||
);
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns requested report data for a specific query', async () => {
|
|
||||||
expect.assertions( 1 );
|
|
||||||
const endpoint = 'products';
|
|
||||||
const query = { interval: 'week' };
|
|
||||||
|
|
||||||
await getReportStats( endpoint, query );
|
|
||||||
|
|
||||||
expect( dispatch().setReportStats ).toHaveBeenCalledWith(
|
|
||||||
endpoint,
|
|
||||||
REPORT_2,
|
|
||||||
query,
|
|
||||||
REPORT_2_TOTALS[ 'x-wp-total' ],
|
|
||||||
REPORT_2_TOTALS[ 'x-wp-totalpages' ]
|
|
||||||
);
|
|
||||||
} );
|
|
||||||
} );
|
|
|
@ -1,102 +0,0 @@
|
||||||
/*
|
|
||||||
* @format
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* External dependencies
|
|
||||||
*/
|
|
||||||
import deepFreeze from 'deep-freeze';
|
|
||||||
import { select } from '@wordpress/data';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import { ERROR } from 'store/constants';
|
|
||||||
import selectors from '../selectors';
|
|
||||||
|
|
||||||
const { getReportStats, isReportStatsRequesting, isReportStatsError } = selectors;
|
|
||||||
jest.mock( '@wordpress/data', () => ( {
|
|
||||||
...require.requireActual( '@wordpress/data' ),
|
|
||||||
select: jest.fn().mockReturnValue( {} ),
|
|
||||||
} ) );
|
|
||||||
|
|
||||||
const endpointName = 'revenue';
|
|
||||||
|
|
||||||
describe( 'getReportStats()', () => {
|
|
||||||
it( 'returns null when no report data is available', () => {
|
|
||||||
const state = deepFreeze( {} );
|
|
||||||
expect( getReportStats( state, endpointName ) ).toEqual( null );
|
|
||||||
} );
|
|
||||||
it( 'returns stored report information by endpoint and query combination', () => {
|
|
||||||
const report = {
|
|
||||||
totals: {
|
|
||||||
orders_count: 10,
|
|
||||||
num_items_sold: 9,
|
|
||||||
},
|
|
||||||
interval: [ 0, 1, 2 ],
|
|
||||||
};
|
|
||||||
const state = deepFreeze( {
|
|
||||||
reports: {
|
|
||||||
stats: {
|
|
||||||
revenue: {
|
|
||||||
'{}': { ...report },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} );
|
|
||||||
expect( getReportStats( state, endpointName ) ).toEqual( report );
|
|
||||||
} );
|
|
||||||
} );
|
|
||||||
|
|
||||||
describe( 'isReportStatsRequesting()', () => {
|
|
||||||
beforeAll( () => {
|
|
||||||
select( 'core/data' ).isResolving = jest.fn().mockReturnValue( false );
|
|
||||||
} );
|
|
||||||
|
|
||||||
afterAll( () => {
|
|
||||||
select( 'core/data' ).isResolving.mockRestore();
|
|
||||||
} );
|
|
||||||
|
|
||||||
function setIsResolving( isResolving ) {
|
|
||||||
select( 'core/data' ).isResolving.mockImplementation(
|
|
||||||
( reducerKey, selectorName ) =>
|
|
||||||
isResolving && reducerKey === 'wc-admin' && selectorName === 'getReportStats'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
it( 'returns false if never requested', () => {
|
|
||||||
const result = isReportStatsRequesting( endpointName );
|
|
||||||
expect( result ).toBe( false );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns false if request finished', () => {
|
|
||||||
setIsResolving( false );
|
|
||||||
const result = isReportStatsRequesting( endpointName );
|
|
||||||
expect( result ).toBe( false );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns true if requesting', () => {
|
|
||||||
setIsResolving( true );
|
|
||||||
const result = isReportStatsRequesting( endpointName );
|
|
||||||
expect( result ).toBe( true );
|
|
||||||
} );
|
|
||||||
} );
|
|
||||||
|
|
||||||
describe( 'isReportStatsError()', () => {
|
|
||||||
it( 'returns false by default', () => {
|
|
||||||
const state = deepFreeze( {} );
|
|
||||||
expect( isReportStatsError( state, endpointName ) ).toEqual( false );
|
|
||||||
} );
|
|
||||||
it( 'returns true if ERROR constant is found', () => {
|
|
||||||
const state = deepFreeze( {
|
|
||||||
reports: {
|
|
||||||
stats: {
|
|
||||||
revenue: {
|
|
||||||
'{}': ERROR,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} );
|
|
||||||
expect( isReportStatsError( state, endpointName ) ).toEqual( true );
|
|
||||||
} );
|
|
||||||
} );
|
|
|
@ -1,598 +0,0 @@
|
||||||
/*
|
|
||||||
* @format
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import {
|
|
||||||
isReportDataEmpty,
|
|
||||||
getReportChartData,
|
|
||||||
getSummaryNumbers,
|
|
||||||
getFilterQuery,
|
|
||||||
getReportTableData,
|
|
||||||
timeStampFilterDates,
|
|
||||||
} from '../utils';
|
|
||||||
import * as ordersConfig from 'analytics/report/orders/config';
|
|
||||||
|
|
||||||
jest.mock( '../utils', () => ( {
|
|
||||||
...require.requireActual( '../utils' ),
|
|
||||||
getReportTableQuery: () => ( {
|
|
||||||
after: '2018-10-10',
|
|
||||||
before: '2018-10-10',
|
|
||||||
} ),
|
|
||||||
} ) );
|
|
||||||
|
|
||||||
describe( 'isReportDataEmpty()', () => {
|
|
||||||
it( 'returns false if report is valid', () => {
|
|
||||||
const report = {
|
|
||||||
data: {
|
|
||||||
totals: {
|
|
||||||
orders_count: 10,
|
|
||||||
num_items_sold: 9,
|
|
||||||
},
|
|
||||||
intervals: [ 0, 1, 2 ],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
expect( isReportDataEmpty( report ) ).toEqual( false );
|
|
||||||
} );
|
|
||||||
it( 'returns true if report object is undefined', () => {
|
|
||||||
expect( isReportDataEmpty( undefined ) ).toEqual( true );
|
|
||||||
} );
|
|
||||||
it( 'returns true if data response object is missing', () => {
|
|
||||||
expect( isReportDataEmpty( {} ) ).toEqual( true );
|
|
||||||
} );
|
|
||||||
it( 'returns true if totals response object is missing', () => {
|
|
||||||
expect( isReportDataEmpty( { data: {} } ) ).toEqual( true );
|
|
||||||
} );
|
|
||||||
it( 'returns true if intervals response object is empty', () => {
|
|
||||||
expect( isReportDataEmpty( { data: { intervals: [], totals: 2 } } ) ).toEqual( true );
|
|
||||||
} );
|
|
||||||
} );
|
|
||||||
|
|
||||||
describe( 'getReportChartData()', () => {
|
|
||||||
const select = jest.fn().mockReturnValue( {} );
|
|
||||||
const response = {
|
|
||||||
isEmpty: false,
|
|
||||||
isError: false,
|
|
||||||
isRequesting: false,
|
|
||||||
data: {
|
|
||||||
totals: null,
|
|
||||||
intervals: [],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
beforeAll( () => {
|
|
||||||
select( 'wc-api' ).getReportStats = jest.fn().mockReturnValue( {} );
|
|
||||||
select( 'wc-api' ).isReportStatsRequesting = jest.fn().mockReturnValue( false );
|
|
||||||
select( 'wc-api' ).getReportStatsError = jest.fn().mockReturnValue( false );
|
|
||||||
} );
|
|
||||||
|
|
||||||
afterAll( () => {
|
|
||||||
select( 'wc-api' ).getReportStats.mockRestore();
|
|
||||||
select( 'wc-api' ).isReportStatsRequesting.mockRestore();
|
|
||||||
select( 'wc-api' ).getReportStatsError.mockRestore();
|
|
||||||
} );
|
|
||||||
|
|
||||||
function setGetReportStats( func ) {
|
|
||||||
select( 'wc-api' ).getReportStats.mockImplementation( ( ...args ) => func( ...args ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
function setIsReportStatsRequesting( func ) {
|
|
||||||
select( 'wc-api' ).isReportStatsRequesting.mockImplementation( ( ...args ) => func( ...args ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
function setGetReportStatsError( func ) {
|
|
||||||
select( 'wc-api' ).getReportStatsError.mockImplementation( ( ...args ) => func( ...args ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
it( 'returns isRequesting if first request is in progress', () => {
|
|
||||||
setIsReportStatsRequesting( () => {
|
|
||||||
return true;
|
|
||||||
} );
|
|
||||||
const result = getReportChartData( 'revenue', 'primary', {}, select );
|
|
||||||
expect( result ).toEqual( { ...response, isRequesting: true } );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns isError if first request errors', () => {
|
|
||||||
setIsReportStatsRequesting( () => {
|
|
||||||
return false;
|
|
||||||
} );
|
|
||||||
setGetReportStatsError( () => {
|
|
||||||
return { error: 'Error' };
|
|
||||||
} );
|
|
||||||
const result = getReportChartData( 'revenue', 'primary', {}, select );
|
|
||||||
expect( result ).toEqual( { ...response, isError: true } );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns results after single page of data', () => {
|
|
||||||
const data = {
|
|
||||||
totals: {
|
|
||||||
orders_count: 115,
|
|
||||||
gross_revenue: 13966.92,
|
|
||||||
},
|
|
||||||
intervals: [
|
|
||||||
{
|
|
||||||
interval: 'day',
|
|
||||||
date_start: '2018-07-01 00:00:00',
|
|
||||||
subtotals: {
|
|
||||||
orders_count: 115,
|
|
||||||
gross_revenue: 13966.92,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
setIsReportStatsRequesting( () => {
|
|
||||||
return false;
|
|
||||||
} );
|
|
||||||
setGetReportStatsError( () => {
|
|
||||||
return undefined;
|
|
||||||
} );
|
|
||||||
setGetReportStats( () => {
|
|
||||||
return {
|
|
||||||
totalResults: 1,
|
|
||||||
data,
|
|
||||||
};
|
|
||||||
} );
|
|
||||||
|
|
||||||
const result = getReportChartData( 'revenue', 'primary', {}, select );
|
|
||||||
expect( result ).toEqual( { ...response, data: { ...data } } );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns combined results for multiple pages of data', () => {
|
|
||||||
const totalResults = 110;
|
|
||||||
const orders_count = 115;
|
|
||||||
const gross_revenue = 13966.92;
|
|
||||||
const intervals = [];
|
|
||||||
for ( let i = 0; i < totalResults; i++ ) {
|
|
||||||
intervals.push( {
|
|
||||||
interval: 'day',
|
|
||||||
date_start: '2018-07-01 00:00:00',
|
|
||||||
subtotals: { orders_count, gross_revenue },
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
const totals = {
|
|
||||||
orders_count: orders_count * totalResults,
|
|
||||||
gross_revenue: gross_revenue * totalResults,
|
|
||||||
};
|
|
||||||
|
|
||||||
setIsReportStatsRequesting( () => {
|
|
||||||
return false;
|
|
||||||
} );
|
|
||||||
setGetReportStatsError( () => {
|
|
||||||
return undefined;
|
|
||||||
} );
|
|
||||||
setGetReportStats( ( endpoint, query ) => {
|
|
||||||
if ( 2 === query.page ) {
|
|
||||||
return {
|
|
||||||
totalResults,
|
|
||||||
data: {
|
|
||||||
totals,
|
|
||||||
intervals: intervals.slice( 100, 110 ),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
totalResults,
|
|
||||||
data: {
|
|
||||||
totals,
|
|
||||||
intervals: intervals.slice( 0, 100 ),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
} );
|
|
||||||
|
|
||||||
const actualResponse = getReportChartData( 'revenue', 'primary', {}, select );
|
|
||||||
const expectedResponse = {
|
|
||||||
...response,
|
|
||||||
data: {
|
|
||||||
totals,
|
|
||||||
intervals,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
expect( actualResponse ).toEqual( expectedResponse );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns isRequesting if additional requests are in progress', () => {
|
|
||||||
setIsReportStatsRequesting( ( endpoint, query ) => {
|
|
||||||
if ( 2 === query.page ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
} );
|
|
||||||
setGetReportStatsError( () => {
|
|
||||||
return undefined;
|
|
||||||
} );
|
|
||||||
|
|
||||||
const result = getReportChartData( 'revenue', 'primary', {}, select );
|
|
||||||
expect( result ).toEqual( { ...response, isRequesting: true } );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns isError if additional requests return an error', () => {
|
|
||||||
setIsReportStatsRequesting( () => {
|
|
||||||
return false;
|
|
||||||
} );
|
|
||||||
setGetReportStatsError( ( endpoint, query ) => {
|
|
||||||
if ( 2 === query.page ) {
|
|
||||||
return { error: 'Error' };
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
} );
|
|
||||||
const result = getReportChartData( 'revenue', 'primary', {}, select );
|
|
||||||
expect( result ).toEqual( { ...response, isError: true } );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns empty state if a query returns no data', () => {
|
|
||||||
setIsReportStatsRequesting( () => {
|
|
||||||
return false;
|
|
||||||
} );
|
|
||||||
setGetReportStatsError( () => {
|
|
||||||
return undefined;
|
|
||||||
} );
|
|
||||||
setGetReportStats( () => {
|
|
||||||
return {
|
|
||||||
totalResults: undefined,
|
|
||||||
data: {},
|
|
||||||
};
|
|
||||||
} );
|
|
||||||
|
|
||||||
const result = getReportChartData( 'revenue', 'primary', {}, select );
|
|
||||||
expect( result ).toEqual( { ...response, isEmpty: true } );
|
|
||||||
} );
|
|
||||||
} );
|
|
||||||
|
|
||||||
describe( 'getSummaryNumbers()', () => {
|
|
||||||
const select = jest.fn().mockReturnValue( {} );
|
|
||||||
const response = {
|
|
||||||
isError: false,
|
|
||||||
isRequesting: false,
|
|
||||||
totals: {
|
|
||||||
primary: null,
|
|
||||||
secondary: null,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const query = {
|
|
||||||
after: '2018-10-10',
|
|
||||||
before: '2018-10-10',
|
|
||||||
period: 'custom',
|
|
||||||
compare: 'previous_period',
|
|
||||||
};
|
|
||||||
|
|
||||||
beforeAll( () => {
|
|
||||||
select( 'wc-api' ).getReportStats = jest.fn().mockReturnValue( {} );
|
|
||||||
select( 'wc-api' ).isReportStatsRequesting = jest.fn().mockReturnValue( false );
|
|
||||||
select( 'wc-api' ).getReportStatsError = jest.fn().mockReturnValue( false );
|
|
||||||
} );
|
|
||||||
|
|
||||||
afterAll( () => {
|
|
||||||
select( 'wc-api' ).getReportStats.mockRestore();
|
|
||||||
select( 'wc-api' ).isReportStatsRequesting.mockRestore();
|
|
||||||
select( 'wc-api' ).getReportStatsError.mockRestore();
|
|
||||||
} );
|
|
||||||
|
|
||||||
function setGetReportStats( func ) {
|
|
||||||
select( 'wc-api' ).getReportStats.mockImplementation( ( ...args ) => func( ...args ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
function setIsReportStatsRequesting( func ) {
|
|
||||||
select( 'wc-api' ).isReportStatsRequesting.mockImplementation( ( ...args ) => func( ...args ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
function setGetReportStatsError( func ) {
|
|
||||||
select( 'wc-api' ).getReportStatsError.mockImplementation( ( ...args ) => func( ...args ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
it( 'returns isRequesting if a request is in progress', () => {
|
|
||||||
setIsReportStatsRequesting( () => {
|
|
||||||
return true;
|
|
||||||
} );
|
|
||||||
const result = getSummaryNumbers( 'revenue', query, select );
|
|
||||||
expect( result ).toEqual( { ...response, isRequesting: true } );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns isError if request errors', () => {
|
|
||||||
setIsReportStatsRequesting( () => {
|
|
||||||
return false;
|
|
||||||
} );
|
|
||||||
setGetReportStatsError( () => {
|
|
||||||
return { error: 'Error' };
|
|
||||||
} );
|
|
||||||
const result = getSummaryNumbers( 'revenue', query, select );
|
|
||||||
expect( result ).toEqual( { ...response, isError: true } );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns results after queries finish', () => {
|
|
||||||
const totals = {
|
|
||||||
primary: {
|
|
||||||
orders_count: 115,
|
|
||||||
gross_revenue: 13966.92,
|
|
||||||
},
|
|
||||||
secondary: {
|
|
||||||
orders_count: 85,
|
|
||||||
gross_revenue: 10406.1,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
setIsReportStatsRequesting( () => {
|
|
||||||
return false;
|
|
||||||
} );
|
|
||||||
setGetReportStatsError( () => {
|
|
||||||
return undefined;
|
|
||||||
} );
|
|
||||||
setGetReportStats( () => {
|
|
||||||
return {
|
|
||||||
totals,
|
|
||||||
};
|
|
||||||
} );
|
|
||||||
|
|
||||||
setGetReportStats( ( endpoint, _query ) => {
|
|
||||||
if ( '2018-10-10T00:00:00+00:00' === _query.after ) {
|
|
||||||
return {
|
|
||||||
data: {
|
|
||||||
totals: totals.primary,
|
|
||||||
intervals: [],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
data: {
|
|
||||||
totals: totals.secondary,
|
|
||||||
intervals: [],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
} );
|
|
||||||
|
|
||||||
const result = getSummaryNumbers( 'revenue', query, select );
|
|
||||||
expect( result ).toEqual( { ...response, totals } );
|
|
||||||
} );
|
|
||||||
} );
|
|
||||||
|
|
||||||
describe( 'getFilterQuery', () => {
|
|
||||||
/**
|
|
||||||
* Mock the orders config
|
|
||||||
*/
|
|
||||||
const filters = [
|
|
||||||
{
|
|
||||||
param: 'filter',
|
|
||||||
filters: [
|
|
||||||
{ value: 'top_meal', query: { lunch: 'burritos' } },
|
|
||||||
{ value: 'top_dessert', query: { dinner: 'ice_cream' } },
|
|
||||||
{ value: 'compare-cuisines', settings: { param: 'region' } },
|
|
||||||
{
|
|
||||||
value: 'food_destination',
|
|
||||||
subFilters: [
|
|
||||||
{ value: 'choose_a_european_city', settings: { param: 'european_cities' } },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const advancedFilters = {
|
|
||||||
filters: {
|
|
||||||
mexican: {
|
|
||||||
rules: [ { value: 'is' }, { value: 'is_not' } ],
|
|
||||||
},
|
|
||||||
french: {
|
|
||||||
rules: [ { value: 'includes' }, { value: 'excludes' } ],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
ordersConfig.filters = filters;
|
|
||||||
ordersConfig.advancedFilters = advancedFilters;
|
|
||||||
|
|
||||||
it( 'should return an empty object if no filter param is given', () => {
|
|
||||||
const query = {};
|
|
||||||
const filterQuery = getFilterQuery( 'orders', query );
|
|
||||||
|
|
||||||
expect( filterQuery ).toEqual( {} );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'should return an empty object if filter parameter is not in configs', () => {
|
|
||||||
const query = { filter: 'canned_meat' };
|
|
||||||
const filterQuery = getFilterQuery( 'orders', query );
|
|
||||||
|
|
||||||
expect( filterQuery ).toEqual( {} );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'should return the query for an advanced filter', () => {
|
|
||||||
const query = { filter: 'advanced', mexican_is: 'delicious' };
|
|
||||||
const filterQuery = getFilterQuery( 'orders', query );
|
|
||||||
|
|
||||||
expect( filterQuery ).toEqual( { mexican_is: 'delicious', match: 'all' } );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'should ignore other queries not defined by filter configs', () => {
|
|
||||||
const query = {
|
|
||||||
filter: 'advanced',
|
|
||||||
mexican_is_not: 'healthy',
|
|
||||||
orderby: 'calories',
|
|
||||||
topping: 'salsa-verde',
|
|
||||||
};
|
|
||||||
const filterQuery = getFilterQuery( 'orders', query );
|
|
||||||
|
|
||||||
expect( filterQuery ).toEqual( { mexican_is_not: 'healthy', match: 'all' } );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'should apply the match parameter advanced filters', () => {
|
|
||||||
const query = {
|
|
||||||
filter: 'advanced',
|
|
||||||
french_includes: 'le-fromage',
|
|
||||||
match: 'any',
|
|
||||||
};
|
|
||||||
const filterQuery = getFilterQuery( 'orders', query );
|
|
||||||
|
|
||||||
expect( filterQuery ).toEqual( { french_includes: 'le-fromage', match: 'any' } );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'should return the query for compare filters', () => {
|
|
||||||
const query = { filter: 'compare-cuisines', region: 'vietnam,malaysia,thailand' };
|
|
||||||
const filterQuery = getFilterQuery( 'orders', query );
|
|
||||||
|
|
||||||
expect( filterQuery ).toEqual( { region: 'vietnam,malaysia,thailand' } );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'should return the query for subFilters', () => {
|
|
||||||
const query = { filter: 'choose_a_european_city', european_cities: 'paris,rome,barcelona' };
|
|
||||||
const filterQuery = getFilterQuery( 'orders', query );
|
|
||||||
|
|
||||||
expect( filterQuery ).toEqual( { european_cities: 'paris,rome,barcelona' } );
|
|
||||||
} );
|
|
||||||
} );
|
|
||||||
|
|
||||||
describe( 'getReportTableData()', () => {
|
|
||||||
const select = jest.fn().mockReturnValue( {} );
|
|
||||||
const response = {
|
|
||||||
isError: false,
|
|
||||||
isRequesting: false,
|
|
||||||
items: {
|
|
||||||
data: [],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const query = {
|
|
||||||
after: '2018-10-10',
|
|
||||||
before: '2018-10-10',
|
|
||||||
};
|
|
||||||
|
|
||||||
beforeAll( () => {
|
|
||||||
select( 'wc-api' ).getReportItems = jest.fn().mockReturnValue( {} );
|
|
||||||
select( 'wc-api' ).isReportItemsRequesting = jest.fn().mockReturnValue( false );
|
|
||||||
select( 'wc-api' ).getReportItemsError = jest.fn().mockReturnValue( undefined );
|
|
||||||
} );
|
|
||||||
|
|
||||||
afterAll( () => {
|
|
||||||
select( 'wc-api' ).getReportItems.mockRestore();
|
|
||||||
select( 'wc-api' ).isReportItemsRequesting.mockRestore();
|
|
||||||
select( 'wc-api' ).getReportItemsError.mockRestore();
|
|
||||||
} );
|
|
||||||
|
|
||||||
function setGetReportItems( func ) {
|
|
||||||
select( 'wc-api' ).getReportItems.mockImplementation( ( ...args ) => func( ...args ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
function setIsReportItemsRequesting( func ) {
|
|
||||||
select( 'wc-api' ).isReportItemsRequesting.mockImplementation( ( ...args ) => func( ...args ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
function setGetReportItemsError( func ) {
|
|
||||||
select( 'wc-api' ).getReportItemsError.mockImplementation( ( ...args ) => func( ...args ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
it( 'returns isRequesting if a request is in progress', () => {
|
|
||||||
setIsReportItemsRequesting( () => true );
|
|
||||||
|
|
||||||
const result = getReportTableData( 'coupons', query, select );
|
|
||||||
|
|
||||||
expect( result ).toEqual( { ...response, query, isRequesting: true } );
|
|
||||||
expect( select( 'wc-api' ).getReportItems ).toHaveBeenLastCalledWith( 'coupons', query );
|
|
||||||
expect( select( 'wc-api' ).isReportItemsRequesting ).toHaveBeenLastCalledWith(
|
|
||||||
'coupons',
|
|
||||||
query
|
|
||||||
);
|
|
||||||
expect( select( 'wc-api' ).getReportItemsError ).toHaveBeenCalledTimes( 0 );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns isError if request errors', () => {
|
|
||||||
setIsReportItemsRequesting( () => false );
|
|
||||||
setGetReportItemsError( () => ( { error: 'Error' } ) );
|
|
||||||
|
|
||||||
const result = getReportTableData( 'coupons', query, select );
|
|
||||||
|
|
||||||
expect( result ).toEqual( { ...response, query, isError: true } );
|
|
||||||
expect( select( 'wc-api' ).getReportItems ).toHaveBeenLastCalledWith( 'coupons', query );
|
|
||||||
expect( select( 'wc-api' ).isReportItemsRequesting ).toHaveBeenLastCalledWith(
|
|
||||||
'coupons',
|
|
||||||
query
|
|
||||||
);
|
|
||||||
expect( select( 'wc-api' ).getReportItemsError ).toHaveBeenLastCalledWith( 'coupons', query );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'returns results after queries finish', () => {
|
|
||||||
const items = [ { id: 1 }, { id: 2 }, { id: 3 } ];
|
|
||||||
setIsReportItemsRequesting( () => false );
|
|
||||||
setGetReportItemsError( () => undefined );
|
|
||||||
setGetReportItems( () => items );
|
|
||||||
|
|
||||||
const result = getReportTableData( 'coupons', query, select );
|
|
||||||
|
|
||||||
expect( result ).toEqual( { ...response, query, items } );
|
|
||||||
expect( select( 'wc-api' ).getReportItems ).toHaveBeenLastCalledWith( 'coupons', query );
|
|
||||||
expect( select( 'wc-api' ).isReportItemsRequesting ).toHaveBeenLastCalledWith(
|
|
||||||
'coupons',
|
|
||||||
query
|
|
||||||
);
|
|
||||||
expect( select( 'wc-api' ).getReportItemsError ).toHaveBeenLastCalledWith( 'coupons', query );
|
|
||||||
} );
|
|
||||||
} );
|
|
||||||
|
|
||||||
describe( 'timeStampFilterDates', () => {
|
|
||||||
const advancedFilters = {
|
|
||||||
filters: {
|
|
||||||
city: {
|
|
||||||
input: { component: 'Search' },
|
|
||||||
},
|
|
||||||
my_date: {
|
|
||||||
input: { component: 'Date' },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
it( 'should not change activeFilters not using the Date component', () => {
|
|
||||||
const activeFilter = {
|
|
||||||
key: 'name',
|
|
||||||
rule: 'is',
|
|
||||||
value: 'New York',
|
|
||||||
};
|
|
||||||
const timeStampedActiveFilter = timeStampFilterDates( advancedFilters, activeFilter );
|
|
||||||
|
|
||||||
expect( timeStampedActiveFilter ).toMatchObject( activeFilter );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'should append timestamps to activeFilters using the Date component', () => {
|
|
||||||
const activeFilter = {
|
|
||||||
key: 'my_date',
|
|
||||||
rule: 'after',
|
|
||||||
value: '2018-04-04',
|
|
||||||
};
|
|
||||||
const timeStampedActiveFilter = timeStampFilterDates( advancedFilters, activeFilter );
|
|
||||||
|
|
||||||
expect( timeStampedActiveFilter.value ).toBe( '2018-04-04T00:00:00+00:00' );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'should append start of day for "after" rule', () => {
|
|
||||||
const activeFilter = {
|
|
||||||
key: 'my_date',
|
|
||||||
rule: 'after',
|
|
||||||
value: '2018-04-04',
|
|
||||||
};
|
|
||||||
const timeStampedActiveFilter = timeStampFilterDates( advancedFilters, activeFilter );
|
|
||||||
expect( timeStampedActiveFilter.value ).toBe( '2018-04-04T00:00:00+00:00' );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'should append end of day for "before" rule', () => {
|
|
||||||
const activeFilter = {
|
|
||||||
key: 'my_date',
|
|
||||||
rule: 'before',
|
|
||||||
value: '2018-04-04',
|
|
||||||
};
|
|
||||||
const timeStampedActiveFilter = timeStampFilterDates( advancedFilters, activeFilter );
|
|
||||||
expect( timeStampedActiveFilter.value ).toBe( '2018-04-04T23:59:59+00:00' );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'should handle "between" values', () => {
|
|
||||||
const activeFilter = {
|
|
||||||
key: 'my_date',
|
|
||||||
rule: 'before',
|
|
||||||
value: [ '2018-04-04', '2018-04-10' ],
|
|
||||||
};
|
|
||||||
const timeStampedActiveFilter = timeStampFilterDates( advancedFilters, activeFilter );
|
|
||||||
expect( Array.isArray( timeStampedActiveFilter.value ) ).toBe( true );
|
|
||||||
expect( timeStampedActiveFilter.value ).toHaveLength( 2 );
|
|
||||||
expect( timeStampedActiveFilter.value[ 0 ] ).toContain( 'T00:00:00+00:00' );
|
|
||||||
expect( timeStampedActiveFilter.value[ 1 ] ).toContain( 'T23:59:59+00:00' );
|
|
||||||
} );
|
|
||||||
} );
|
|
Loading…
Reference in New Issue