UNPKG

@shopgate/pwa-common

Version:

Common library for the Shopgate Connect PWA.

234 lines (226 loc) • 7.32 kB
import React from 'react'; import { mount } from 'enzyme'; import { ThemeResourcesProvider } from '@shopgate/engage/core/providers'; import Widgets from "./index"; import { jsx as _jsx } from "react/jsx-runtime"; jest.useFakeTimers(); jest.mock('@shopgate/pwa-common/context', () => ({ ThemeContext: { Provider: ({ children }) => children } })); /** * A mock Image component. * @returns {JSX} */ const Image = () => /*#__PURE__*/_jsx("img", { alt: "" }); /* eslint-disable react/prop-types */ /** * A mock WidgetGrid component. * @param {Array} children Array of children. * @returns {JSX} */ const WidgetGrid = ({ children }) => /*#__PURE__*/_jsx("div", { className: "widget-grid", children: children }); /* eslint-enable react/prop-types */ const components = { v1: { '@shopgate/commerce-widgets/image': Image, '@shopgate/commerce-widgets/widget-grid': WidgetGrid } }; /** * @param {Object[]} widgets Widgets to be rendered. * @returns {JSX.Element} */ const createWrapper = widgets => mount(/*#__PURE__*/_jsx(ThemeResourcesProvider, { widgets: components, components: {}, children: /*#__PURE__*/_jsx(Widgets, { widgets: widgets }) })); describe('<Widgets />', () => { it('should render a grid if height is defined', () => { const widgets = [{ col: 0, row: 0, width: 12, height: 3, settings: { id: 83535, image: 'https://data.shopgate.com/shop_widget_images/23836/92204c0f264ac30d6836994c2fb64eb1.min.jpeg' }, type: '@shopgate/commerce-widgets/image' }]; const wrapper = createWrapper(widgets); expect(wrapper.find('WidgetGrid').exists()).toBe(true); }); it('should not wrap a widget which is not a grid and has no height', () => { const widgets = [{ col: 0, row: 0, width: 12, settings: { id: 83535, image: 'https://data.shopgate.com/shop_widget_images/23836/92204c0f264ac30d6836994c2fb64eb1.min.jpeg' }, type: '@shopgate/commerce-widgets/image' }]; const wrapper = createWrapper(widgets); expect(wrapper).toMatchSnapshot(); expect(wrapper.find('WidgetGrid').exists()).toBe(false); }); it('should render a grid if the widget is of type grid', () => { const widgets = [{ type: '@shopgate/commerce-widgets/widget-grid', settings: { widgets: [{ col: 0, row: 0, width: 12, height: 5, settings: { id: '84961', alt: '', image: 'https://data.shopgate.com/shop_widget_images/23836/aedc545959f55e3f73851eca0ed40a75.min.jpeg', link: '/category/' }, type: '@shopgate/commerce-widgets/image' }] } }]; const wrapper = createWrapper(widgets); expect(wrapper).toMatchSnapshot(); expect(wrapper.find('WidgetGrid').exists()).toBe(true); }); it('should render only one widget when the second one is not published and third one is invalid', () => { const widgets = [{ col: 0, row: 0, width: 12, settings: { id: 835351, image: 'https://data.shopgate.com/shop_widget_images/23836/92204c0f264ac30d6836994c2fb64eb1.min.jpeg' }, type: '@shopgate/commerce-widgets/image' }, { col: 0, row: 0, width: 12, settings: { id: 835352, image: 'https://data.shopgate.com/shop_widget_images/23836/92204c0f264ac30d6836994c2fb64eb1.min.jpeg' }, type: '@shopgate/commerce-widgets/imagefoo' }, { col: 0, row: 0, width: 12, settings: { published: false, id: 835353, image: 'https://data.shopgate.com/shop_widget_images/23836/92204c0f264ac30d6836994c2fb64eb1.min.jpeg' }, type: '@shopgate/commerce-widgets/image' }]; const wrapper = createWrapper(widgets); expect(wrapper).toMatchSnapshot(); expect(wrapper.find('img').length).toBe(1); }); it('should schedule a re-render when widget is scheduled', () => { // Use a fixed point in time so "next full hour" is deterministic. // Pick a time that's not exactly on the hour. const base = new Date('2023-01-01T10:37:00.000Z'); jest.setSystemTime(base); const minutesToNextFullHour = 60 - base.getMinutes(); // 23 const msToNextFullHour = minutesToNextFullHour * 60000; // 23 * 60_000 const scheduledFromMs = Date.now() + msToNextFullHour - 1; const scheduledToMs = Date.now() + minutesToNextFullHour + 1000; const widgets = [{ col: 0, row: 0, width: 12, settings: { id: 835351, image: 'https://data.shopgate.com/shop_widget_images/23836/92204c0f264ac30d6836994c2fb64eb1.min.jpeg', published: true, plan: true, planDate: { valid_from: new Date(scheduledFromMs).toISOString(), valid_to: new Date(scheduledToMs).toISOString() } }, type: '@shopgate/commerce-widgets/image' }]; const wrapper = createWrapper(widgets); const instance = wrapper.find('Widgets').instance(); const clearSpy = jest.spyOn(global, 'clearTimeout'); instance.forceUpdate = jest.fn(); // Before the schedule hits, the image should not render yet. expect(wrapper.find(Image).exists()).toBe(false); // 1) Advance to the next full hour -> first forced update. jest.advanceTimersByTime(msToNextFullHour); expect(instance.forceUpdate).toHaveBeenCalledTimes(1); // 2) The component should schedule the next tick for +60 min. jest.advanceTimersByTime(60 * 60000); expect(instance.forceUpdate).toHaveBeenCalledTimes(2); // Unmount triggers cleanup of any pending timeouts. wrapper.unmount(); expect(clearSpy).toHaveBeenCalled(); clearSpy.mockRestore(); }); it('should render only wrapper when widgets array is empty', () => { const widgets = []; const wrapper = createWrapper(widgets); expect(wrapper.find('Image').exists()).toBe(false); }); it('should render null when no widgets are passed', () => { const wrapper = createWrapper(undefined); expect(wrapper.find('Widgets').html()).toBe(null); }); it('should check settings of child widgets inside widget-grid', () => { const widgets = [{ height: 2, id: 'index-5-@shopgate/commerce-widgets/widget-grid', type: '@shopgate/commerce-widgets/widget-grid', settings: { widgets: [{ col: 0, row: 0, height: 2, width: 2, settings: { id: 835351, image: 'https://data.shopgate.com/shop_widget_images/23836/92204c0f264ac30d6836994c2fb64eb1.min.jpeg', published: true, plan: false }, type: '@shopgate/commerce-widgets/image' }, { col: 2, row: 0, height: 2, width: 2, settings: { id: 835352, image: 'https://data.shopgate.com/shop_widget_images/23836/92204c0f264ac30d6836994c2fb64eb1.min.jpeg', published: false, plan: false }, type: '@shopgate/commerce-widgets/image' }] } }]; const wrapper = createWrapper(widgets); expect(wrapper.find('img').length).toBe(1); }); });