Skip to content
This repository was archived by the owner on Feb 23, 2024. It is now read-only.

Commit 72adf29

Browse files
mikejolleynerrad
andauthored
Remove API summaries in favour of client side code (#2387)
* Remove summary from API * Add wordCountType to assets * Update packages * Remove summary from test data * Featured product uses short desc * Pass description instead of summary * Use new Summary Component * Component and tests * Increased versititilty of methods * Update assets/js/base/components/cart-checkout/product-summary/index.js Co-authored-by: Darren Ethier <[email protected]> * Extra tests for html tags Co-authored-by: Darren Ethier <[email protected]>
1 parent 854d258 commit 72adf29

File tree

21 files changed

+357
-223
lines changed

21 files changed

+357
-223
lines changed

assets/js/atomic/components/product/summary/index.js

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,30 @@
44
import PropTypes from 'prop-types';
55
import classnames from 'classnames';
66
import { useProductLayoutContext } from '@woocommerce/base-context';
7+
import Summary from '@woocommerce/base-components/summary';
8+
import { getSetting } from '@woocommerce/settings';
79

810
const ProductSummary = ( { className, product } ) => {
911
const { layoutStyleClassPrefix } = useProductLayoutContext();
10-
if ( ! product.summary ) {
12+
const source = product.short_description
13+
? product.short_description
14+
: product.description;
15+
16+
if ( ! source ) {
1117
return null;
1218
}
1319

20+
const countType = getSetting( 'wordCountType', 'words' );
21+
1422
return (
15-
<div
23+
<Summary
1624
className={ classnames(
1725
className,
1826
`${ layoutStyleClassPrefix }__product-summary`
1927
) }
20-
dangerouslySetInnerHTML={ {
21-
__html: product.summary,
22-
} }
28+
source={ source }
29+
maxLength={ 150 }
30+
countType={ countType }
2331
/>
2432
);
2533
};

assets/js/base/components/cart-checkout/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export { default as PlaceOrderButton } from './place-order-button';
66
export { default as Policies } from './policies';
77
export { default as ProductImage } from './product-image';
88
export { default as ProductLowStockBadge } from './product-low-stock-badge';
9+
export { default as ProductSummary } from './product-summary';
910
export { default as ProductMetadata } from './product-metadata';
1011
export { default as ProductName } from './product-name';
1112
export { default as ProductPrice } from './product-price';

assets/js/base/components/cart-checkout/product-metadata/index.js

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,34 @@
11
/**
22
* External dependencies
33
*/
4-
import { RawHTML } from '@wordpress/element';
54
import PropTypes from 'prop-types';
65

76
/**
87
* Internal dependencies
98
*/
109
import ProductVariationData from '../product-variation-data';
10+
import ProductSummary from '../product-summary';
1111
import './style.scss';
1212

13-
const ProductMetadata = ( { summary, variation } ) => {
13+
const ProductMetadata = ( {
14+
shortDescription = '',
15+
fullDescription = '',
16+
variation = [],
17+
} ) => {
1418
return (
1519
<div className="wc-block-product-metadata">
16-
{ summary && <RawHTML>{ summary }</RawHTML> }
17-
{ variation && <ProductVariationData variation={ variation } /> }
20+
<ProductSummary
21+
shortDescription={ shortDescription }
22+
fullDescription={ fullDescription }
23+
/>
24+
<ProductVariationData variation={ variation } />
1825
</div>
1926
);
2027
};
2128

2229
ProductMetadata.propTypes = {
23-
summary: PropTypes.string,
30+
shortDescription: PropTypes.string,
31+
fullDescription: PropTypes.string,
2432
variation: PropTypes.array,
2533
};
2634

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/**
2+
* External dependencies
3+
*/
4+
import PropTypes from 'prop-types';
5+
import Summary from '@woocommerce/base-components/summary';
6+
import { getSetting } from '@woocommerce/settings';
7+
8+
/**
9+
* Returns an element containing a summary of the product.
10+
*/
11+
const ProductSummary = ( { shortDescription = '', fullDescription = '' } ) => {
12+
const source = shortDescription ? shortDescription : fullDescription;
13+
14+
if ( ! source ) {
15+
return null;
16+
}
17+
18+
return (
19+
<Summary source={ source } maxLength={ 15 } countType={ getSetting( 'wordCountType', 'words' ) } />
20+
);
21+
};
22+
23+
ProductSummary.propTypes = {
24+
shortDescription: PropTypes.string,
25+
fullDescription: PropTypes.string,
26+
};
27+
28+
export default ProductSummary;

assets/js/base/components/cart-checkout/product-variation-data/index.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@ import PropTypes from 'prop-types';
77
/**
88
* Returns a formatted element containing variation details.
99
*/
10-
const ProductVariationData = ( { variation } ) => {
10+
const ProductVariationData = ( { variation = [] } ) => {
11+
if ( ! variation ) {
12+
return null;
13+
}
14+
1115
const variationsText = variation
1216
.map( ( v ) => {
1317
if ( v.attribute ) {
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/**
2+
* External dependencies
3+
*/
4+
import { RawHTML, useMemo } from '@wordpress/element';
5+
6+
/**
7+
* Internal dependencies
8+
*/
9+
import { generateSummary } from './utils';
10+
11+
/**
12+
* Summary component.
13+
*
14+
* @param {Object} props Component props.
15+
* @param {string} props.source Source text.
16+
* @param {number} props.maxLength Max length of the summary, using countType.
17+
* @param {string} props.countType One of words, characters_excluding_spaces, or characters_including_spaces.
18+
* @param {string} props.className Class name for rendered component.
19+
*/
20+
export const Summary = ( {
21+
source,
22+
maxLength = 15,
23+
countType = 'words',
24+
className = '',
25+
} ) => {
26+
const summaryText = useMemo( () => {
27+
return generateSummary( source, maxLength, countType );
28+
}, [ source, maxLength, countType ] );
29+
30+
return <RawHTML className={ className }>{ summaryText }</RawHTML>;
31+
};
32+
33+
export default Summary;
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/**
2+
* Internal dependencies
3+
*/
4+
import { generateSummary } from '../utils';
5+
6+
describe( 'Summary Component', () => {
7+
describe( 'Test the generateSummary utility', () => {
8+
const testContent =
9+
'<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p><p>Ut enim ad minim veniam, quis <strong>nostrud</strong> exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p><p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p><p>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>';
10+
11+
it( 'Default', async () => {
12+
const result = generateSummary( testContent );
13+
14+
expect( result.trim() ).toEqual(
15+
'<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore&hellip;</p>'
16+
);
17+
} );
18+
it( 'No max words - return full description', async () => {
19+
const result = generateSummary( testContent, 100000 );
20+
21+
expect( result.trim() ).toEqual(
22+
'<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>\n<p>Ut enim ad minim veniam, quis <strong>nostrud</strong> exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>\n<p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p>\n<p>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>'
23+
);
24+
} );
25+
it( 'Limit to 3 words', async () => {
26+
const result = generateSummary( testContent, 3 );
27+
28+
expect( result.trim() ).toEqual(
29+
'<p>Lorem ipsum dolor&hellip;</p>'
30+
);
31+
} );
32+
it( 'Limit to 1 word', async () => {
33+
const result = generateSummary( testContent, 1 );
34+
35+
expect( result.trim() ).toEqual( '<p>Lorem&hellip;</p>' );
36+
} );
37+
it( 'Limit to 15 characters, including spaces.', async () => {
38+
const result = generateSummary(
39+
testContent,
40+
15,
41+
'characters_including_spaces'
42+
);
43+
44+
expect( result.trim() ).toEqual( '<p>Lorem ipsum dol&hellip;</p>' );
45+
} );
46+
it( 'Limit to 15 characters, excluding spaces.', async () => {
47+
const result = generateSummary(
48+
testContent,
49+
15,
50+
'characters_excluding_spaces'
51+
);
52+
53+
expect( result.trim() ).toEqual(
54+
'<p>Lorem ipsum dolor&hellip;</p>'
55+
);
56+
} );
57+
} );
58+
describe( 'Test the generateSummary utility with HTML tags in strings', () => {
59+
const testContent =
60+
'<p>Lorem <strong class="classname">ipsum</strong> dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor.</p>';
61+
62+
it( 'Limit string to 10 characters', async () => {
63+
const result = generateSummary(
64+
testContent,
65+
10,
66+
'characters_excluding_spaces'
67+
);
68+
69+
expect( result.trim() ).toEqual( '<p>Lorem ipsum&hellip;</p>' );
70+
} );
71+
it( 'Limit string to 5 words', async () => {
72+
const result = generateSummary( testContent, 5, 'words' );
73+
74+
expect( result.trim() ).toEqual(
75+
'<p>Lorem ipsum dolor sit amet&hellip;</p>'
76+
);
77+
} );
78+
it( 'First paragraph only - tags are not stripped.', async () => {
79+
const result = generateSummary( testContent, 9999, 'words' );
80+
81+
expect( result.trim() ).toEqual(
82+
'<p>Lorem <strong class="classname">ipsum</strong> dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor.</p>'
83+
);
84+
} );
85+
} );
86+
describe( 'Test the generateSummary utility with special chars', () => {
87+
const testContent =
88+
'<p>我不知道这是否行得通。</p><p>我是用中文写的说明,因此我们可以测试如何修剪产品摘要中的单词。</p>';
89+
90+
it( 'Default', async () => {
91+
const result = generateSummary(
92+
testContent,
93+
15,
94+
'characters_excluding_spaces'
95+
);
96+
97+
expect( result.trim() ).toEqual( '<p>我不知道这是否行得通。</p>' );
98+
} );
99+
it( 'Limit to 3 words', async () => {
100+
const result = generateSummary(
101+
testContent,
102+
3,
103+
'characters_excluding_spaces'
104+
);
105+
106+
expect( result.trim() ).toEqual( '<p>我不知&hellip;</p>' );
107+
} );
108+
} );
109+
} );

0 commit comments

Comments
 (0)