khaihihi
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { sortBy, map } from 'lodash';
|
||||
|
||||
/**
|
||||
* Given a query object, removes an attribute filter by a single slug.
|
||||
* @param {Array} query Current query object.
|
||||
* @param {Function} setQuery Callback to update the current query object.
|
||||
* @param {Object} attribute An attribute object.
|
||||
* @param {string} slug Term slug to remove.
|
||||
*/
|
||||
export const removeAttributeFilterBySlug = (
|
||||
query = [],
|
||||
setQuery = () => {},
|
||||
attribute,
|
||||
slug = ''
|
||||
) => {
|
||||
// Get current filter for provided attribute.
|
||||
const foundQuery = query.filter(
|
||||
( item ) => item.attribute === attribute.taxonomy
|
||||
);
|
||||
|
||||
const currentQuery = foundQuery.length ? foundQuery[ 0 ] : null;
|
||||
|
||||
if (
|
||||
! currentQuery ||
|
||||
! currentQuery.slug ||
|
||||
! Array.isArray( currentQuery.slug ) ||
|
||||
! currentQuery.slug.includes( slug )
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
const newSlugs = currentQuery.slug.filter( ( item ) => item !== slug );
|
||||
|
||||
// Remove current attribute filter from query.
|
||||
const returnQuery = query.filter(
|
||||
( item ) => item.attribute !== attribute.taxonomy
|
||||
);
|
||||
|
||||
// Add a new query for selected terms, if provided.
|
||||
if ( newSlugs.length > 0 ) {
|
||||
currentQuery.slug = newSlugs.sort();
|
||||
returnQuery.push( currentQuery );
|
||||
}
|
||||
|
||||
setQuery( sortBy( returnQuery, 'attribute' ) );
|
||||
};
|
||||
|
||||
/**
|
||||
* Given a query object, sets the query up to filter by a given attribute and attribute terms.
|
||||
* @param {Array} query Current query object.
|
||||
* @param {Function} setQuery Callback to update the current query object.
|
||||
* @param {Object} attribute An attribute object.
|
||||
* @param {Array} attributeTerms Array of term objects.
|
||||
* @param {string} operator Operator for the filter. Valid values: in, and.
|
||||
*/
|
||||
export const updateAttributeFilter = (
|
||||
query = [],
|
||||
setQuery = () => {},
|
||||
attribute,
|
||||
attributeTerms = [],
|
||||
operator = 'in'
|
||||
) => {
|
||||
const returnQuery = query.filter(
|
||||
( item ) => item.attribute !== attribute.taxonomy
|
||||
);
|
||||
|
||||
if ( attributeTerms.length === 0 ) {
|
||||
setQuery( returnQuery );
|
||||
} else {
|
||||
returnQuery.push( {
|
||||
attribute: attribute.taxonomy,
|
||||
operator,
|
||||
slug: map( attributeTerms, 'slug' ).sort(),
|
||||
} );
|
||||
setQuery( sortBy( returnQuery, 'attribute' ) );
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { ATTRIBUTES } from '@woocommerce/block-settings';
|
||||
|
||||
/**
|
||||
* Format an attribute from the settings into an object with standardized keys.
|
||||
* @param {Object} The attribute object.
|
||||
*/
|
||||
const attributeSettingToObject = ( attribute ) => {
|
||||
if ( ! attribute || ! attribute.attribute_name ) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
id: parseInt( attribute.attribute_id, 10 ),
|
||||
name: attribute.attribute_name,
|
||||
taxonomy: 'pa_' + attribute.attribute_name,
|
||||
label: attribute.attribute_label,
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Format all attribute settings into objects.
|
||||
*/
|
||||
const attributeObjects = ATTRIBUTES.reduce( ( acc, current ) => {
|
||||
const attributeObject = attributeSettingToObject( current );
|
||||
|
||||
if ( attributeObject.id ) {
|
||||
acc.push( attributeObject );
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, [] );
|
||||
|
||||
/**
|
||||
* Get attribute data by taxonomy.
|
||||
*
|
||||
* @param {number} attributeId The attribute ID.
|
||||
* @return {Object|undefined} The attribute object if it exists.
|
||||
*/
|
||||
export const getAttributeFromID = ( attributeId ) => {
|
||||
if ( ! attributeId ) {
|
||||
return;
|
||||
}
|
||||
return attributeObjects.find( ( attribute ) => {
|
||||
return attribute.id === attributeId;
|
||||
} );
|
||||
};
|
||||
|
||||
/**
|
||||
* Get attribute data by taxonomy.
|
||||
*
|
||||
* @param {string} taxonomy The attribute taxonomy name e.g. pa_color.
|
||||
* @return {Object|undefined} The attribute object if it exists.
|
||||
*/
|
||||
export const getAttributeFromTaxonomy = ( taxonomy ) => {
|
||||
if ( ! taxonomy ) {
|
||||
return;
|
||||
}
|
||||
return attributeObjects.find( ( attribute ) => {
|
||||
return attribute.taxonomy === taxonomy;
|
||||
} );
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the taxonomy of an attribute by Attribute ID.
|
||||
*
|
||||
* @param {number} attributeId The attribute ID.
|
||||
* @return {string} The taxonomy name.
|
||||
*/
|
||||
export const getTaxonomyFromAttributeId = ( attributeId ) => {
|
||||
if ( ! attributeId ) {
|
||||
return null;
|
||||
}
|
||||
const attribute = getAttributeFromID( attributeId );
|
||||
return attribute ? attribute.taxonomy : null;
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import classnames from 'classnames';
|
||||
import { RawHTML } from '@wordpress/element';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import getShortcode from './get-shortcode';
|
||||
|
||||
/**
|
||||
* Return a save function using the blockType to generate the correct shortcode.
|
||||
*/
|
||||
export const deprecatedConvertToShortcode = ( blockType ) => {
|
||||
return function( props ) {
|
||||
const { align, contentVisibility } = props.attributes;
|
||||
const classes = classnames( align ? `align${ align }` : '', {
|
||||
'is-hidden-title': ! contentVisibility.title,
|
||||
'is-hidden-price': ! contentVisibility.price,
|
||||
'is-hidden-rating': ! contentVisibility.rating,
|
||||
'is-hidden-button': ! contentVisibility.button,
|
||||
} );
|
||||
return (
|
||||
<RawHTML className={ classes }>
|
||||
{ getShortcode( props, blockType ) }
|
||||
</RawHTML>
|
||||
);
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { min } from 'lodash';
|
||||
import { DEFAULT_COLUMNS, DEFAULT_ROWS } from '@woocommerce/block-settings';
|
||||
|
||||
export default function getQuery( blockAttributes, name ) {
|
||||
const {
|
||||
attributes,
|
||||
attrOperator,
|
||||
categories,
|
||||
catOperator,
|
||||
tags,
|
||||
tagOperator,
|
||||
orderby,
|
||||
products,
|
||||
} = blockAttributes;
|
||||
const columns = blockAttributes.columns || DEFAULT_COLUMNS;
|
||||
const rows = blockAttributes.rows || DEFAULT_ROWS;
|
||||
const apiMax = Math.floor( 100 / columns ) * columns; // Prevent uneven final row.
|
||||
|
||||
const query = {
|
||||
status: 'publish',
|
||||
per_page: min( [ rows * columns, apiMax ] ),
|
||||
catalog_visibility: 'visible',
|
||||
};
|
||||
|
||||
if ( categories && categories.length ) {
|
||||
query.category = categories.join( ',' );
|
||||
if ( catOperator && catOperator === 'all' ) {
|
||||
query.category_operator = 'and';
|
||||
}
|
||||
}
|
||||
|
||||
if ( tags && tags.length > 0 ) {
|
||||
query.tag = tags.join( ',' );
|
||||
if ( tagOperator && tagOperator === 'all' ) {
|
||||
query.tag_operator = 'and';
|
||||
}
|
||||
}
|
||||
|
||||
if ( orderby ) {
|
||||
if ( orderby === 'price_desc' ) {
|
||||
query.orderby = 'price';
|
||||
query.order = 'desc';
|
||||
} else if ( orderby === 'price_asc' ) {
|
||||
query.orderby = 'price';
|
||||
query.order = 'asc';
|
||||
} else if ( orderby === 'title' ) {
|
||||
query.orderby = 'title';
|
||||
query.order = 'asc';
|
||||
} else if ( orderby === 'menu_order' ) {
|
||||
query.orderby = 'menu_order';
|
||||
query.order = 'asc';
|
||||
} else {
|
||||
query.orderby = orderby;
|
||||
}
|
||||
}
|
||||
|
||||
if ( attributes && attributes.length > 0 ) {
|
||||
query.attribute_term = attributes.map( ( { id } ) => id ).join( ',' );
|
||||
query.attribute = attributes[ 0 ].attr_slug;
|
||||
|
||||
if ( attrOperator ) {
|
||||
query.attribute_operator = attrOperator === 'all' ? 'and' : 'in';
|
||||
}
|
||||
}
|
||||
|
||||
// Toggle query parameters depending on block type.
|
||||
switch ( name ) {
|
||||
case 'woocommerce/product-best-sellers':
|
||||
query.orderby = 'popularity';
|
||||
break;
|
||||
case 'woocommerce/product-top-rated':
|
||||
query.orderby = 'rating';
|
||||
break;
|
||||
case 'woocommerce/product-on-sale':
|
||||
query.on_sale = 1;
|
||||
break;
|
||||
case 'woocommerce/product-new':
|
||||
query.orderby = 'date';
|
||||
break;
|
||||
case 'woocommerce/handpicked-products':
|
||||
query.include = products;
|
||||
query.per_page = products.length;
|
||||
break;
|
||||
}
|
||||
|
||||
return query;
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { DEFAULT_COLUMNS, DEFAULT_ROWS } from '@woocommerce/block-settings';
|
||||
|
||||
export default function getShortcode( props, name ) {
|
||||
const blockAttributes = props.attributes;
|
||||
const {
|
||||
attributes,
|
||||
attrOperator,
|
||||
categories,
|
||||
catOperator,
|
||||
orderby,
|
||||
products,
|
||||
} = blockAttributes;
|
||||
const columns = blockAttributes.columns || DEFAULT_COLUMNS;
|
||||
const rows = blockAttributes.rows || DEFAULT_ROWS;
|
||||
|
||||
const shortcodeAtts = new Map();
|
||||
shortcodeAtts.set( 'limit', rows * columns );
|
||||
shortcodeAtts.set( 'columns', columns );
|
||||
|
||||
if ( categories && categories.length ) {
|
||||
shortcodeAtts.set( 'category', categories.join( ',' ) );
|
||||
if ( catOperator && catOperator === 'all' ) {
|
||||
shortcodeAtts.set( 'cat_operator', 'AND' );
|
||||
}
|
||||
}
|
||||
|
||||
if ( attributes && attributes.length ) {
|
||||
shortcodeAtts.set(
|
||||
'terms',
|
||||
attributes.map( ( { id } ) => id ).join( ',' )
|
||||
);
|
||||
shortcodeAtts.set( 'attribute', attributes[ 0 ].attr_slug );
|
||||
if ( attrOperator && attrOperator === 'all' ) {
|
||||
shortcodeAtts.set( 'terms_operator', 'AND' );
|
||||
}
|
||||
}
|
||||
|
||||
if ( orderby ) {
|
||||
if ( orderby === 'price_desc' ) {
|
||||
shortcodeAtts.set( 'orderby', 'price' );
|
||||
shortcodeAtts.set( 'order', 'DESC' );
|
||||
} else if ( orderby === 'price_asc' ) {
|
||||
shortcodeAtts.set( 'orderby', 'price' );
|
||||
shortcodeAtts.set( 'order', 'ASC' );
|
||||
} else if ( orderby === 'date' ) {
|
||||
shortcodeAtts.set( 'orderby', 'date' );
|
||||
shortcodeAtts.set( 'order', 'DESC' );
|
||||
} else {
|
||||
shortcodeAtts.set( 'orderby', orderby );
|
||||
}
|
||||
}
|
||||
|
||||
// Toggle shortcode atts depending on block type.
|
||||
switch ( name ) {
|
||||
case 'woocommerce/product-best-sellers':
|
||||
shortcodeAtts.set( 'best_selling', '1' );
|
||||
break;
|
||||
case 'woocommerce/product-top-rated':
|
||||
shortcodeAtts.set( 'orderby', 'rating' );
|
||||
break;
|
||||
case 'woocommerce/product-on-sale':
|
||||
shortcodeAtts.set( 'on_sale', '1' );
|
||||
break;
|
||||
case 'woocommerce/product-new':
|
||||
shortcodeAtts.set( 'orderby', 'date' );
|
||||
shortcodeAtts.set( 'order', 'DESC' );
|
||||
break;
|
||||
case 'woocommerce/handpicked-products':
|
||||
if ( ! products.length ) {
|
||||
return '';
|
||||
}
|
||||
shortcodeAtts.set( 'ids', products.join( ',' ) );
|
||||
shortcodeAtts.set( 'limit', products.length );
|
||||
break;
|
||||
case 'woocommerce/product-category':
|
||||
if ( ! categories || ! categories.length ) {
|
||||
return '';
|
||||
}
|
||||
break;
|
||||
case 'woocommerce/products-by-attribute':
|
||||
if ( ! attributes || ! attributes.length ) {
|
||||
return '';
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Build the shortcode string out of the set shortcode attributes.
|
||||
let shortcode = '[products';
|
||||
for ( const [ key, value ] of shortcodeAtts ) {
|
||||
/* eslint-disable-line */
|
||||
shortcode += ' ' + key + '="' + value + '"';
|
||||
}
|
||||
shortcode += ']';
|
||||
|
||||
return shortcode;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Get the src of the first image attached to a product (the featured image).
|
||||
*
|
||||
* @param {Object} product The product object to get the images from.
|
||||
* @param {Array} product.images The array of images, destructured from the product object.
|
||||
* @return {string} The full URL to the image.
|
||||
*/
|
||||
export function getImageSrcFromProduct( product ) {
|
||||
if ( ! product || ! product.images || ! product.images.length ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return product.images[ 0 ].src || '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ID of the first image attached to a product (the featured image).
|
||||
*
|
||||
* @param {Object} product The product object to get the images from.
|
||||
* @param {Array} product.images The array of images, destructured from the product object.
|
||||
* @return {number} The ID of the image.
|
||||
*/
|
||||
export function getImageIdFromProduct( product ) {
|
||||
if ( ! product || ! product.images || ! product.images.length ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return product.images[ 0 ].id || 0;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { render } from 'react-dom';
|
||||
import BlockErrorBoundary from '@woocommerce/base-components/block-error-boundary';
|
||||
|
||||
/**
|
||||
* Renders a block component in the place of a specified set of selectors.
|
||||
*
|
||||
* @param {string} selector CSS selector to match the elements to replace.
|
||||
* @param {Function} Block React block to use as a replacement.
|
||||
* @param {Function} [getProps] Function to generate the props object for the
|
||||
* block.
|
||||
*/
|
||||
export default ( selector, Block, getProps = () => {} ) => {
|
||||
const containers = document.querySelectorAll( selector );
|
||||
|
||||
if ( containers.length ) {
|
||||
// Use Array.forEach for IE11 compatibility.
|
||||
Array.prototype.forEach.call( containers, ( el, i ) => {
|
||||
const props = getProps( el, i );
|
||||
const attributes = {
|
||||
...el.dataset,
|
||||
...props.attributes,
|
||||
};
|
||||
|
||||
el.classList.remove( 'is-loading' );
|
||||
|
||||
render(
|
||||
<BlockErrorBoundary>
|
||||
<Block { ...props } attributes={ attributes } />
|
||||
</BlockErrorBoundary>,
|
||||
el
|
||||
);
|
||||
} );
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { DEFAULT_COLUMNS, DEFAULT_ROWS } from '@woocommerce/block-settings';
|
||||
|
||||
export const sharedAttributeBlockTypes = [
|
||||
'woocommerce/product-best-sellers',
|
||||
'woocommerce/product-category',
|
||||
'woocommerce/product-new',
|
||||
'woocommerce/product-on-sale',
|
||||
'woocommerce/product-top-rated',
|
||||
];
|
||||
|
||||
export default {
|
||||
/**
|
||||
* Number of columns.
|
||||
*/
|
||||
columns: {
|
||||
type: 'number',
|
||||
default: DEFAULT_COLUMNS,
|
||||
},
|
||||
|
||||
/**
|
||||
* Number of rows.
|
||||
*/
|
||||
rows: {
|
||||
type: 'number',
|
||||
default: DEFAULT_ROWS,
|
||||
},
|
||||
|
||||
/**
|
||||
* How to align cart buttons.
|
||||
*/
|
||||
alignButtons: {
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
|
||||
/**
|
||||
* Product category, used to display only products in the given categories.
|
||||
*/
|
||||
categories: {
|
||||
type: 'array',
|
||||
default: [],
|
||||
},
|
||||
|
||||
/**
|
||||
* Product category operator, used to restrict to products in all or any selected categories.
|
||||
*/
|
||||
catOperator: {
|
||||
type: 'string',
|
||||
default: 'any',
|
||||
},
|
||||
|
||||
/**
|
||||
* Content visibility setting
|
||||
*/
|
||||
contentVisibility: {
|
||||
type: 'object',
|
||||
default: {
|
||||
title: true,
|
||||
price: true,
|
||||
rating: true,
|
||||
button: true,
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* Are we previewing?
|
||||
*/
|
||||
isPreview: {
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,142 @@
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import getQuery from '../get-query';
|
||||
|
||||
describe( 'getQuery', () => {
|
||||
describe( 'per_page calculations', () => {
|
||||
test( 'should set per_page as a result of row * col', () => {
|
||||
let query = getQuery( {
|
||||
columns: 4,
|
||||
rows: 3,
|
||||
} );
|
||||
expect( query.per_page ).toBe( 12 );
|
||||
|
||||
query = getQuery( {
|
||||
columns: 1,
|
||||
rows: 3,
|
||||
} );
|
||||
expect( query.per_page ).toBe( 3 );
|
||||
|
||||
query = getQuery( {
|
||||
columns: 4,
|
||||
rows: 1,
|
||||
} );
|
||||
expect( query.per_page ).toBe( 4 );
|
||||
} );
|
||||
|
||||
test( 'should restrict per_page to under 100', () => {
|
||||
let query = getQuery( {
|
||||
columns: 4,
|
||||
rows: 30,
|
||||
} );
|
||||
expect( query.per_page ).toBe( 100 );
|
||||
|
||||
query = getQuery( {
|
||||
columns: 3,
|
||||
rows: 87,
|
||||
} );
|
||||
expect( query.per_page ).toBe( 99 );
|
||||
} );
|
||||
} );
|
||||
|
||||
describe( 'for different query orders', () => {
|
||||
const attributes = {
|
||||
columns: 4,
|
||||
rows: 3,
|
||||
orderby: 'date',
|
||||
};
|
||||
test( 'should order by date when using "date"', () => {
|
||||
const query = getQuery( attributes );
|
||||
expect( query.orderby ).toBe( 'date' );
|
||||
expect( query.order ).toBeUndefined();
|
||||
} );
|
||||
|
||||
test( 'should order by price, DESC when "price_desc"', () => {
|
||||
attributes.orderby = 'price_desc';
|
||||
const query = getQuery( attributes );
|
||||
expect( query.orderby ).toBe( 'price' );
|
||||
expect( query.order ).toBe( 'desc' );
|
||||
} );
|
||||
|
||||
test( 'should order by price, ASC when "price_asc"', () => {
|
||||
attributes.orderby = 'price_asc';
|
||||
const query = getQuery( attributes );
|
||||
expect( query.orderby ).toBe( 'price' );
|
||||
expect( query.order ).toBe( 'asc' );
|
||||
} );
|
||||
|
||||
test( 'should order by title, ASC when "title"', () => {
|
||||
attributes.orderby = 'title';
|
||||
const query = getQuery( attributes );
|
||||
expect( query.orderby ).toBe( 'title' );
|
||||
expect( query.order ).toBe( 'asc' );
|
||||
} );
|
||||
|
||||
test( 'should order by menu_order, ASC when "menu_order"', () => {
|
||||
attributes.orderby = 'menu_order';
|
||||
const query = getQuery( attributes );
|
||||
expect( query.orderby ).toBe( 'menu_order' );
|
||||
expect( query.order ).toBe( 'asc' );
|
||||
} );
|
||||
|
||||
test( 'should order by popularity when "popularity"', () => {
|
||||
attributes.orderby = 'popularity';
|
||||
const query = getQuery( attributes );
|
||||
expect( query.orderby ).toBe( 'popularity' );
|
||||
expect( query.order ).toBeUndefined();
|
||||
} );
|
||||
} );
|
||||
|
||||
describe( 'for category queries', () => {
|
||||
const attributes = {
|
||||
columns: 4,
|
||||
rows: 3,
|
||||
orderby: 'date',
|
||||
};
|
||||
test( 'should return a general query with no category', () => {
|
||||
const query = getQuery( attributes );
|
||||
expect( query ).toEqual( {
|
||||
catalog_visibility: 'visible',
|
||||
orderby: 'date',
|
||||
per_page: 12,
|
||||
status: 'publish',
|
||||
} );
|
||||
} );
|
||||
|
||||
test( 'should return an empty category query', () => {
|
||||
attributes.categories = [];
|
||||
const query = getQuery( attributes );
|
||||
expect( query ).toEqual( {
|
||||
catalog_visibility: 'visible',
|
||||
orderby: 'date',
|
||||
per_page: 12,
|
||||
status: 'publish',
|
||||
} );
|
||||
} );
|
||||
|
||||
test( 'should return a category query with one category', () => {
|
||||
attributes.categories = [ 1 ];
|
||||
const query = getQuery( attributes );
|
||||
expect( query ).toEqual( {
|
||||
catalog_visibility: 'visible',
|
||||
category: '1',
|
||||
orderby: 'date',
|
||||
per_page: 12,
|
||||
status: 'publish',
|
||||
} );
|
||||
} );
|
||||
|
||||
test( 'should return a category query with two categories', () => {
|
||||
attributes.categories = [ 1, 2 ];
|
||||
const query = getQuery( attributes );
|
||||
expect( query ).toEqual( {
|
||||
catalog_visibility: 'visible',
|
||||
category: '1,2',
|
||||
orderby: 'date',
|
||||
per_page: 12,
|
||||
status: 'publish',
|
||||
} );
|
||||
} );
|
||||
} );
|
||||
} );
|
||||
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { getImageSrcFromProduct, getImageIdFromProduct } from '../products';
|
||||
|
||||
describe( 'getImageSrcFromProduct', () => {
|
||||
test( 'returns first image src', () => {
|
||||
const imageSrc = getImageSrcFromProduct( {
|
||||
images: [ { src: 'foo.jpg' } ],
|
||||
} );
|
||||
|
||||
expect( imageSrc ).toBe( 'foo.jpg' );
|
||||
} );
|
||||
|
||||
test( 'returns empty string if no product was provided', () => {
|
||||
const imageSrc = getImageSrcFromProduct();
|
||||
|
||||
expect( imageSrc ).toBe( '' );
|
||||
} );
|
||||
|
||||
test( 'returns empty string if product is empty', () => {
|
||||
const imageSrc = getImageSrcFromProduct( {} );
|
||||
|
||||
expect( imageSrc ).toBe( '' );
|
||||
} );
|
||||
|
||||
test( 'returns empty string if product has no images', () => {
|
||||
const imageSrc = getImageSrcFromProduct( { images: null } );
|
||||
|
||||
expect( imageSrc ).toBe( '' );
|
||||
} );
|
||||
|
||||
test( 'returns empty string if product has 0 images', () => {
|
||||
const imageSrc = getImageSrcFromProduct( { images: [] } );
|
||||
|
||||
expect( imageSrc ).toBe( '' );
|
||||
} );
|
||||
|
||||
test( 'returns empty string if product image has no src attribute', () => {
|
||||
const imageSrc = getImageSrcFromProduct( { images: [ {} ] } );
|
||||
|
||||
expect( imageSrc ).toBe( '' );
|
||||
} );
|
||||
} );
|
||||
|
||||
describe( 'getImageIdFromProduct', () => {
|
||||
test( 'returns first image id', () => {
|
||||
const imageUrl = getImageIdFromProduct( {
|
||||
images: [ { id: 123 } ],
|
||||
} );
|
||||
|
||||
expect( imageUrl ).toBe( 123 );
|
||||
} );
|
||||
|
||||
test( 'returns 0 if no product was provided', () => {
|
||||
const imageUrl = getImageIdFromProduct();
|
||||
|
||||
expect( imageUrl ).toBe( 0 );
|
||||
} );
|
||||
|
||||
test( 'returns 0 if product is empty', () => {
|
||||
const imageUrl = getImageIdFromProduct( {} );
|
||||
|
||||
expect( imageUrl ).toBe( 0 );
|
||||
} );
|
||||
|
||||
test( 'returns 0 if product has no images', () => {
|
||||
const imageUrl = getImageIdFromProduct( { images: null } );
|
||||
|
||||
expect( imageUrl ).toBe( 0 );
|
||||
} );
|
||||
|
||||
test( 'returns 0 if product has 0 images', () => {
|
||||
const imageUrl = getImageIdFromProduct( { images: [] } );
|
||||
|
||||
expect( imageUrl ).toBe( 0 );
|
||||
} );
|
||||
|
||||
test( 'returns 0 if product image has no src attribute', () => {
|
||||
const imageUrl = getImageIdFromProduct( { images: [ {} ] } );
|
||||
|
||||
expect( imageUrl ).toBe( 0 );
|
||||
} );
|
||||
} );
|
||||
Reference in New Issue
Block a user