-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #538 from shopgate/PWA-1628-product-card-render-props
Added missing props to the ProductCard from the themeApi
- Loading branch information
Showing
16 changed files
with
10,854 additions
and
34 deletions.
There are no files selected for viewing
896 changes: 896 additions & 0 deletions
896
themes/theme-gmd/themeApi/ProductCard/__snapshots__/index.spec.jsx.snap
Large diffs are not rendered by default.
Oops, something went wrong.
4,293 changes: 4,293 additions & 0 deletions
4,293
themes/theme-gmd/themeApi/ProductCard/components/Render/__snapshots__/index.spec.jsx.snap
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
105 changes: 105 additions & 0 deletions
105
themes/theme-gmd/themeApi/ProductCard/components/Render/index.spec.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
import React from 'react'; | ||
import { mount } from 'enzyme'; | ||
import { Provider } from 'react-redux'; | ||
import configureStore from 'redux-mock-store'; | ||
import mockRenderOptions from '@shopgate/pwa-common/helpers/mocks/mockRenderOptions'; | ||
import { mockProductId, mockProduct } from '../../mock'; | ||
import ProductCardRender from './index'; | ||
|
||
const defaultProps = { | ||
url: '/some/url', | ||
productId: mockProductId, | ||
product: mockProduct, | ||
}; | ||
|
||
/** | ||
* @param {Object} additionalProps Additional component props | ||
* @param {Object} state Redux state. | ||
* @returns {JSX} | ||
*/ | ||
const renderComponent = (additionalProps = {}) => { | ||
const props = { | ||
...defaultProps, | ||
...additionalProps, | ||
}; | ||
|
||
const store = configureStore()(); | ||
return mount( | ||
<Provider store={store}> | ||
<ProductCardRender {...props} /> | ||
</Provider>, | ||
mockRenderOptions | ||
); | ||
}; | ||
|
||
describe('<ProductCardRender />', () => { | ||
it('should render as expected', () => { | ||
const wrapper = renderComponent(); | ||
expect(wrapper).toMatchSnapshot(); | ||
expect(wrapper.find('Portal').length).toBe(6); | ||
expect(wrapper.find('Link').prop('href')).toEqual(defaultProps.url); | ||
expect(wrapper.find('ProductCardBadge').exists()).toBe(true); | ||
expect(wrapper.find('ProductCardBadge').text()).toEqual(`-${mockProduct.price.discount}%`); | ||
expect(wrapper.find('RatingStars').exists()).toBe(true); | ||
expect(wrapper.find('RatingStars').prop('value')).toBe(mockProduct.rating.average); | ||
expect(wrapper.find('ProductCardTitle').exists()).toBe(true); | ||
expect(wrapper.find('ProductCardTitle').text()).toBe(mockProduct.name); | ||
expect(wrapper.find('ProductCardTitle').prop('rows')).toBe(ProductCardRender.defaultProps.titleRows); | ||
const productCardPrice = wrapper.find('ProductCardPrice'); | ||
expect(productCardPrice.exists()).toBe(true); | ||
expect(productCardPrice.find('ProductGridPrice').prop('price')).toEqual(mockProduct.price); | ||
}); | ||
|
||
it('should render without name', () => { | ||
const wrapper = renderComponent({ hideName: true }); | ||
expect(wrapper).toMatchSnapshot(); | ||
expect(wrapper.find('ProductCardTitle').exists()).toBe(false); | ||
}); | ||
|
||
it('should render without rating', () => { | ||
const wrapper = renderComponent({ hideRating: true }); | ||
expect(wrapper).toMatchSnapshot(); | ||
expect(wrapper.find('RatingStars').exists()).toBe(false); | ||
}); | ||
|
||
it('should render without prices', () => { | ||
const wrapper = renderComponent({ hidePrice: true }); | ||
expect(wrapper).toMatchSnapshot(); | ||
expect(wrapper.find('ProductCardBadge').exists()).toBe(false); | ||
expect(wrapper.find('ProductCardPrice').exists()).toBe(false); | ||
}); | ||
|
||
it('should render with one row for the product name', () => { | ||
const wrapper = renderComponent({ titleRows: 1 }); | ||
expect(wrapper).toMatchSnapshot(); | ||
expect(wrapper.find('ProductCardTitle').find('Ellipsis').prop('rows')).toBe(1); | ||
}); | ||
|
||
it('should not render the discount badge when the is no discount', () => { | ||
const wrapper = renderComponent({ | ||
product: { | ||
...mockProduct, | ||
price: { | ||
...mockProduct.price, | ||
discount: 0, | ||
}, | ||
}, | ||
}); | ||
expect(wrapper).toMatchSnapshot(); | ||
expect(wrapper.find('ProductCardBadge').exists()).toBe(false); | ||
}); | ||
|
||
it('should not render the rating stars when there is no average rating', () => { | ||
const wrapper = renderComponent({ | ||
product: { | ||
...mockProduct, | ||
rating: { | ||
...mockProduct.rating, | ||
average: 0, | ||
}, | ||
}, | ||
}); | ||
expect(wrapper).toMatchSnapshot(); | ||
expect(wrapper.find('RatingStars').exists()).toBe(false); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import React from 'react'; | ||
import { mount } from 'enzyme'; | ||
import { Provider } from 'react-redux'; | ||
import configureStore from 'redux-mock-store'; | ||
import { bin2hex } from '@shopgate/pwa-common/helpers/data'; | ||
import { ITEM_PATH } from '@shopgate/pwa-common-commerce/product/constants'; | ||
import mockRenderOptions from '@shopgate/pwa-common/helpers/mocks/mockRenderOptions'; | ||
import { mockProductId, mockProduct } from './mock'; | ||
import ProductCard, { ProductCardUnwrapped } from './index'; | ||
|
||
/** | ||
* Creates a state for a mocked store. | ||
* @param {Object} product A product. | ||
* @param {string} productId The id for the product. | ||
* @returns {Object} | ||
*/ | ||
export const createMockState = (product = mockProduct) => ({ | ||
product: { | ||
productsById: { | ||
[product.id]: { | ||
productData: product, | ||
}, | ||
}, | ||
}, | ||
}); | ||
|
||
/** | ||
* @param {Object} props Component props. | ||
* @param {Object} state Redux state. | ||
* @returns {JSX} | ||
*/ | ||
const renderComponent = (props = {}, state = createMockState()) => { | ||
const store = configureStore()(state); | ||
return mount( | ||
<Provider store={store}> | ||
<ProductCard {...props} /> | ||
</Provider>, | ||
mockRenderOptions | ||
); | ||
}; | ||
|
||
describe('<ProductCard />', () => { | ||
it('should not render when no product could be found', () => { | ||
const wrapper = renderComponent(); | ||
expect(wrapper).toMatchSnapshot(); | ||
expect(wrapper.find(ProductCardUnwrapped).isEmptyRender()).toBe(true); | ||
}); | ||
|
||
it('should render as expected', () => { | ||
const wrapper = renderComponent({ productId: mockProductId }); | ||
expect(wrapper).toMatchSnapshot(); | ||
|
||
const renderWrapper = wrapper.find('ProductCardRender'); | ||
expect(renderWrapper.prop('url')).toBe(`${ITEM_PATH}/${bin2hex(mockProductId)}`); | ||
expect(renderWrapper.prop('product')).toBe(mockProduct); | ||
}); | ||
|
||
it('should render with a custom render prop', () => { | ||
const text = 'Custom Output'; | ||
|
||
/** | ||
* @returns {JSX} | ||
*/ | ||
const render = () => ( | ||
<div>{text}</div> | ||
); | ||
|
||
const wrapper = renderComponent({ productId: mockProductId, render }); | ||
expect(wrapper).toMatchSnapshot(); | ||
expect(wrapper.text()).toBe(text); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
export const mockProductId = 'PR0DUCTID'; | ||
export const mockProduct = { | ||
id: mockProductId, | ||
name: 'Product Name', | ||
featuredImageUrl: null, | ||
price: { | ||
currency: 'EUR', | ||
unitPrice: 5, | ||
unitPriceStriked: 10, | ||
discount: 50, | ||
info: 'Price Info', | ||
}, | ||
rating: { | ||
count: 4, | ||
average: 80, | ||
reviewCount: 3, | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.