2019-09-04 16:07:00 +00:00
|
|
|
/**
|
|
|
|
* External dependencies
|
|
|
|
*/
|
|
|
|
import TestRenderer from 'react-test-renderer';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Internal dependencies
|
|
|
|
*/
|
|
|
|
import withAttributes from '../with-attributes';
|
|
|
|
import * as mockUtils from '../../components/utils';
|
|
|
|
import * as mockBaseUtils from '../../base/utils/errors';
|
|
|
|
|
|
|
|
jest.mock( '../../components/utils', () => ( {
|
|
|
|
getAttributes: jest.fn(),
|
|
|
|
getTerms: jest.fn(),
|
|
|
|
} ) );
|
|
|
|
|
|
|
|
jest.mock( '../../base/utils/errors', () => ( {
|
|
|
|
formatError: jest.fn(),
|
|
|
|
} ) );
|
|
|
|
|
|
|
|
jest.mock( 'lodash', () => ( {
|
|
|
|
...jest.requireActual( 'lodash' ),
|
|
|
|
debounce: ( func ) => func,
|
|
|
|
} ) );
|
|
|
|
|
2019-09-05 15:09:31 +00:00
|
|
|
const mockAttributes = [
|
|
|
|
{ id: 1, name: 'Color', slug: 'color' },
|
|
|
|
{ id: 2, name: 'Size', slug: 'size' },
|
|
|
|
];
|
|
|
|
const mockAttributesWithParent = [
|
|
|
|
{ id: 1, name: 'Color', slug: 'color', parent: 0 },
|
|
|
|
{ id: 2, name: 'Size', slug: 'size', parent: 0 },
|
|
|
|
];
|
2019-09-04 16:07:00 +00:00
|
|
|
const selected = [ { id: 11, attr_slug: 'color' } ];
|
|
|
|
const TestComponent = withAttributes( ( props ) => {
|
2019-09-05 15:09:31 +00:00
|
|
|
return (
|
|
|
|
<div
|
|
|
|
attributes={ props.attributes }
|
|
|
|
error={ props.error }
|
|
|
|
expandedAttribute={ props.expandedAttribute }
|
|
|
|
onExpandAttribute={ props.onExpandAttribute }
|
|
|
|
isLoading={ props.isLoading }
|
|
|
|
termsAreLoading={ props.termsAreLoading }
|
|
|
|
termsList={ props.termsList }
|
|
|
|
/>
|
|
|
|
);
|
2019-09-04 16:07:00 +00:00
|
|
|
} );
|
|
|
|
|
|
|
|
describe( 'withAttributes Component', () => {
|
|
|
|
afterEach( () => {
|
|
|
|
mockUtils.getAttributes.mockReset();
|
|
|
|
mockUtils.getTerms.mockReset();
|
|
|
|
mockBaseUtils.formatError.mockReset();
|
|
|
|
} );
|
|
|
|
|
|
|
|
describe( 'lifecycle events', () => {
|
|
|
|
let getAttributesPromise;
|
|
|
|
|
|
|
|
beforeEach( () => {
|
|
|
|
getAttributesPromise = Promise.resolve( mockAttributes );
|
2020-03-30 18:32:28 +00:00
|
|
|
mockUtils.getAttributes.mockReturnValue( getAttributesPromise );
|
|
|
|
mockUtils.getTerms.mockResolvedValue( [] );
|
2019-09-04 16:07:00 +00:00
|
|
|
} );
|
|
|
|
|
|
|
|
it( 'getAttributes is called on mount', () => {
|
2019-09-05 15:09:31 +00:00
|
|
|
TestRenderer.create( <TestComponent /> );
|
2019-09-04 16:07:00 +00:00
|
|
|
const { getAttributes } = mockUtils;
|
|
|
|
|
|
|
|
expect( getAttributes ).toHaveBeenCalledTimes( 1 );
|
|
|
|
} );
|
|
|
|
|
|
|
|
it( 'getTerms is called on component update', () => {
|
2019-09-05 15:09:31 +00:00
|
|
|
const renderer = TestRenderer.create( <TestComponent /> );
|
2019-09-04 16:07:00 +00:00
|
|
|
let props = renderer.root.findByType( 'div' ).props;
|
|
|
|
|
|
|
|
props.onExpandAttribute( 1 );
|
|
|
|
|
|
|
|
const { getTerms } = mockUtils;
|
|
|
|
props = renderer.root.findByType( 'div' ).props;
|
|
|
|
|
|
|
|
expect( getTerms ).toHaveBeenCalledWith( 1 );
|
|
|
|
expect( getTerms ).toHaveBeenCalledTimes( 1 );
|
|
|
|
expect( props.expandedAttribute ).toBe( 1 );
|
|
|
|
} );
|
|
|
|
|
2019-12-10 17:17:46 +00:00
|
|
|
it( 'getTerms is called on mount if there was an attribute selected', async () => {
|
2019-09-04 16:07:00 +00:00
|
|
|
const renderer = TestRenderer.create(
|
|
|
|
<TestComponent selected={ selected } />
|
|
|
|
);
|
|
|
|
|
2019-12-10 17:17:46 +00:00
|
|
|
await getAttributesPromise;
|
2019-09-04 16:07:00 +00:00
|
|
|
|
2019-12-10 17:17:46 +00:00
|
|
|
const { getTerms } = mockUtils;
|
|
|
|
const props = renderer.root.findByType( 'div' ).props;
|
|
|
|
|
|
|
|
expect( getTerms ).toHaveBeenCalledWith( 1 );
|
|
|
|
expect( getTerms ).toHaveBeenCalledTimes( 1 );
|
|
|
|
expect( props.expandedAttribute ).toBe( 1 );
|
2019-09-04 16:07:00 +00:00
|
|
|
} );
|
|
|
|
} );
|
|
|
|
|
|
|
|
describe( 'when the API returns attributes data', () => {
|
|
|
|
let renderer;
|
|
|
|
|
|
|
|
beforeEach( () => {
|
2020-03-30 18:32:28 +00:00
|
|
|
mockUtils.getAttributes.mockResolvedValue( mockAttributes );
|
2019-09-05 15:09:31 +00:00
|
|
|
renderer = TestRenderer.create( <TestComponent /> );
|
2019-09-04 16:07:00 +00:00
|
|
|
} );
|
|
|
|
|
|
|
|
it( 'sets the attributes props', () => {
|
|
|
|
const props = renderer.root.findByType( 'div' ).props;
|
|
|
|
|
|
|
|
expect( props.error ).toBeNull();
|
|
|
|
expect( props.isLoading ).toBe( false );
|
|
|
|
expect( props.attributes ).toEqual( mockAttributesWithParent );
|
|
|
|
} );
|
|
|
|
} );
|
|
|
|
|
|
|
|
describe( 'when the API returns an error', () => {
|
|
|
|
const error = { message: 'There was an error.' };
|
|
|
|
const getAttributesPromise = Promise.reject( error );
|
|
|
|
const formattedError = { message: 'There was an error.', type: 'api' };
|
|
|
|
let renderer;
|
|
|
|
|
|
|
|
beforeEach( () => {
|
2020-03-30 18:32:28 +00:00
|
|
|
mockUtils.getAttributes.mockReturnValue( getAttributesPromise );
|
|
|
|
mockBaseUtils.formatError.mockReturnValue( formattedError );
|
2019-09-05 15:09:31 +00:00
|
|
|
renderer = TestRenderer.create( <TestComponent /> );
|
2019-09-04 16:07:00 +00:00
|
|
|
} );
|
|
|
|
|
2019-12-10 17:17:46 +00:00
|
|
|
test( 'sets the error prop', async () => {
|
|
|
|
await expect( () => getAttributesPromise() ).toThrow();
|
|
|
|
|
2019-09-04 16:07:00 +00:00
|
|
|
const { formatError } = mockBaseUtils;
|
2019-12-10 17:17:46 +00:00
|
|
|
const props = renderer.root.findByType( 'div' ).props;
|
|
|
|
|
|
|
|
expect( formatError ).toHaveBeenCalledWith( error );
|
|
|
|
expect( formatError ).toHaveBeenCalledTimes( 1 );
|
|
|
|
expect( props.error ).toEqual( formattedError );
|
|
|
|
expect( props.isLoading ).toBe( false );
|
|
|
|
expect( props.attributes ).toEqual( [] );
|
2019-09-04 16:07:00 +00:00
|
|
|
} );
|
|
|
|
} );
|
|
|
|
} );
|