UNPKG

vue-instantsearch

Version:

👀 Lightning-fast Algolia search for Vue apps

618 lines (510 loc) • 13 kB
import { mount } from '../../../test/utils'; import { __setState } from '../../mixins/widget'; import Menu from '../Menu.vue'; jest.mock('../../mixins/widget'); jest.mock('../../mixins/panel'); const apple = { value: 'Apple', label: 'Apple', count: 50, isRefined: false, }; const samsung = { value: 'Samsung', label: 'Samsung', count: 25, isRefined: false, }; const microsoft = { value: 'Microsoft', label: 'Microsoft', count: 12, isRefined: false, }; const defaultState = { items: [apple, samsung, microsoft], canRefine: true, canToggleShowMore: false, isShowingMore: false, refine: () => {}, createURL: () => {}, toggleShowMore: () => {}, }; const defaultProps = { attribute: 'brand', }; it('accepts an attribute prop', () => { __setState({ ...defaultState, }); const props = { ...defaultProps, }; const wrapper = mount(Menu, { propsData: props, }); expect(wrapper.vm.widgetParams.attribute).toBe('brand'); }); it('accepts a limit prop', () => { __setState({ ...defaultState, }); const props = { ...defaultProps, limit: 5, }; const wrapper = mount(Menu, { propsData: props, }); expect(wrapper.vm.widgetParams.limit).toBe(5); }); it('accepts a showMoreLimit prop', () => { __setState({ ...defaultState, }); const props = { ...defaultProps, showMoreLimit: 10, }; const wrapper = mount(Menu, { propsData: props, }); expect(wrapper.vm.widgetParams.showMoreLimit).toBe(10); }); it('accepts a sortBy prop', () => { __setState({ ...defaultState, }); const props = { ...defaultProps, sortBy: ['name:desc'], }; const wrapper = mount(Menu, { propsData: props, }); expect(wrapper.vm.widgetParams.sortBy).toEqual(['name:desc']); }); it('accepts a transformItems prop', () => { __setState({ ...defaultState, }); const transformItems = () => {}; const props = { ...defaultProps, transformItems, }; const wrapper = mount(Menu, { propsData: props, }); expect(wrapper.vm.widgetParams.transformItems).toBe(transformItems); }); describe('default render', () => { it('renders correctly', () => { __setState({ ...defaultState }); const wrapper = mount(Menu, { propsData: defaultProps, }); expect(wrapper.html()).toMatchSnapshot(); }); it('renders correctly without refinement', () => { __setState({ ...defaultState, items: [], canRefine: false, }); const wrapper = mount(Menu, { propsData: defaultProps, }); expect(wrapper.findAll('.ais-Menu--noRefinement')).toHaveLength(1); expect(wrapper.html()).toMatchSnapshot(); }); it('renders correctly with a selected item', () => { __setState({ ...defaultState, items: [ apple, { ...samsung, isRefined: true, }, microsoft, ], }); const wrapper = mount(Menu, { propsData: defaultProps, }); expect(wrapper.findAll('.ais-Menu-item--selected')).toHaveLength(1); expect(wrapper.find('.ais-Menu-item--selected .ais-Menu-link').html()) .toMatchInlineSnapshot(` <a class="ais-Menu-link"> <span class="ais-Menu-label"> Samsung </span> <span class="ais-Menu-count"> 25 </span> </a> `); expect(wrapper.html()).toMatchSnapshot(); }); it('renders correctly with a URL for the href', () => { __setState({ ...defaultState, createURL: value => `/brand/${value}`, }); const wrapper = mount(Menu, { propsData: defaultProps, }); expect(wrapper.find('.ais-Menu-link').attributes().href).toBe( '/brand/Apple' ); expect(wrapper.html()).toMatchSnapshot(); }); it('renders correctly with show more button', () => { __setState({ ...defaultState }); const wrapper = mount(Menu, { propsData: { ...defaultProps, showMore: true, }, }); expect(wrapper.findAll('.ais-Menu-showMore')).toHaveLength(1); expect(wrapper.find('.ais-Menu-showMore').text()).toBe('Show more'); expect(wrapper.htmlCompat()).toMatchSnapshot(); }); it('renders correctly with show more button toggled', () => { __setState({ ...defaultState, isShowingMore: true, }); const wrapper = mount(Menu, { propsData: { ...defaultProps, showMore: true, }, }); expect(wrapper.find('.ais-Menu-showMore').text()).toBe('Show less'); expect(wrapper.htmlCompat()).toMatchSnapshot(); }); it('renders correctly with a disabled show more button', () => { __setState({ ...defaultState, canToggleShowMore: false, }); const wrapper = mount(Menu, { propsData: { ...defaultProps, showMore: true, }, }); const showMoreWrapper = wrapper.find('.ais-Menu-showMore'); expect(wrapper.findAll('.ais-Menu-showMore')).toHaveLength(1); expect(showMoreWrapper.classes()).toContain('ais-Menu-showMore--disabled'); expect(showMoreWrapper).toBeDisabled(); expect(wrapper.htmlCompat()).toMatchSnapshot(); }); it('renders correctly without a show more button (canRefine)', () => { __setState({ ...defaultState, items: [], canRefine: false, }); const wrapper = mount(Menu, { propsData: { ...defaultProps, showMore: true, }, }); expect(wrapper.findAll('.ais-Menu-showMore')).toHaveLength(0); expect(wrapper.html()).toMatchSnapshot(); }); it('renders correctly without a show more button (showMore)', () => { __setState({ ...defaultState }); const wrapper = mount(Menu, { propsData: { ...defaultProps, showMore: false, }, }); expect(wrapper.findAll('.ais-Menu-showMore')).toHaveLength(0); expect(wrapper.html()).toMatchSnapshot(); }); it('calls refine on link click', async () => { const refine = jest.fn(); __setState({ ...defaultState, refine, }); const wrapper = mount(Menu, { propsData: defaultProps, }); await wrapper.find('.ais-Menu-link').trigger('click'); expect(refine).toHaveBeenCalledTimes(1); expect(refine).toHaveBeenCalledWith('Apple'); }); it('calls toggleShowMore on button click', async () => { const toggleShowMore = jest.fn(); __setState({ ...defaultState, canToggleShowMore: true, toggleShowMore, }); const wrapper = mount(Menu, { propsData: { ...defaultProps, showMore: true, }, }); await wrapper.find('.ais-Menu-showMore').trigger('click'); expect(toggleShowMore).toHaveBeenCalledTimes(1); }); }); it('calls the Panel mixin with `canRefine`', async () => { __setState({ ...defaultState }); const wrapper = mount(Menu, { propsData: defaultProps, }); const mapStateToCanRefine = () => wrapper.vm.mapStateToCanRefine(wrapper.vm.state); expect(mapStateToCanRefine()).toBe(true); await wrapper.setData({ state: { canRefine: false, }, }); expect(mapStateToCanRefine()).toBe(false); expect(wrapper.vm.mapStateToCanRefine({})).toBe(false); }); it('exposes send-event method for insights middleware', async () => { const sendEvent = jest.fn(); __setState({ ...defaultState, sendEvent, }); const wrapper = mount({ components: { Menu }, data() { return { props: defaultProps }; }, template: ` <Menu v-bind="props"> <template v-slot="{ sendEvent }"> <div> <button @click="sendEvent()">Send Event</button> </div> </template> </Menu> `, }); await wrapper.find('button').trigger('click'); expect(sendEvent).toHaveBeenCalledTimes(1); }); describe('custom default render', () => { const defaultSlot = ` <template v-slot="state"> <div :class="[!state.canRefine && 'no-refinement']"> <ol> <li v-for="item in state.items" :key="item.value" > <a :href="state.createURL(item.value)" @click.prevent="state.refine(item.value)" > {{item.label}} - {{item.count}} </a> </li> </ol> <button :disabled="!state.canToggleShowMore" @click.prevent="state.toggleShowMore" > {{ state.isShowingMore ? 'Show less' : 'Show more' }} </button> </div> </template> `; it('renders correctly', () => { __setState({ ...defaultState }); const wrapper = mount({ components: { Menu }, data() { return { props: defaultProps }; }, template: ` <Menu v-bind="props"> ${defaultSlot} </Menu> `, }); expect(wrapper.htmlCompat()).toMatchSnapshot(); }); it('renders correctly without refinement', () => { __setState({ ...defaultState, items: [], canRefine: false, }); const wrapper = mount({ components: { Menu }, data() { return { props: defaultProps }; }, template: ` <Menu v-bind="props"> ${defaultSlot} </Menu> `, }); expect(wrapper.htmlCompat()).toMatchSnapshot(); }); it('renders correctly with an URL for the href', () => { __setState({ ...defaultState, createURL: value => `/brand/${value}`, }); const wrapper = mount({ components: { Menu }, data() { return { props: defaultProps }; }, template: ` <Menu v-bind="props"> ${defaultSlot} </Menu> `, }); expect(wrapper.htmlCompat()).toMatchSnapshot(); }); it('renders correctly with a show more button toggled', () => { __setState({ ...defaultState, isShowingMore: true, }); const wrapper = mount({ components: { Menu }, data() { return { props: defaultProps }; }, template: ` <Menu v-bind="props"> ${defaultSlot} </Menu> `, }); expect(wrapper.htmlCompat()).toMatchSnapshot(); }); it('renders correctly with a disabled show more button', () => { __setState({ ...defaultState, canToggleShowMore: false, }); const wrapper = mount({ components: { Menu }, data() { return { props: defaultProps }; }, template: ` <Menu v-bind="props"> ${defaultSlot} </Menu> `, }); expect(wrapper.htmlCompat()).toMatchSnapshot(); }); it('calls refine on link click', async () => { const refine = jest.fn(); __setState({ ...defaultState, refine, }); const wrapper = mount({ components: { Menu }, data() { return { props: defaultProps }; }, template: ` <Menu v-bind="props"> ${defaultSlot} </Menu> `, }); await wrapper.find('a').trigger('click'); expect(refine).toHaveBeenCalledTimes(1); expect(refine).toHaveBeenCalledWith('Apple'); }); it('calls toggleShowMore on button click', async () => { const toggleShowMore = jest.fn(); __setState({ ...defaultState, canToggleShowMore: true, toggleShowMore, }); const wrapper = mount({ components: { Menu }, data() { return { props: defaultProps }; }, template: ` <Menu v-bind="props"> ${defaultSlot} </Menu> `, }); await wrapper.find('button').trigger('click'); expect(toggleShowMore).toHaveBeenCalledTimes(1); }); }); describe('custom showMoreLabel render', () => { const showMoreLabelSlot = ` <template v-slot:showMoreLabel="{ isShowingMore }"> <span> {{ isShowingMore ? 'Voir moins' : 'Voir plus' }} </span> </template> `; it('renders correctly with a custom show more label', () => { __setState({ ...defaultState }); const props = { ...defaultProps, showMore: true, }; const wrapper = mount({ components: { Menu }, data() { return { props }; }, template: ` <Menu v-bind="props"> ${showMoreLabelSlot} </Menu> `, }); expect(wrapper.find('.ais-Menu-showMore').text()).toBe('Voir plus'); expect(wrapper.htmlCompat()).toMatchSnapshot(); }); it('renders correctly with a custom show more label toggled', () => { __setState({ ...defaultState, isShowingMore: true, }); const props = { ...defaultProps, showMore: true, }; const wrapper = mount({ components: { Menu }, data() { return { props }; }, template: ` <Menu v-bind="props"> ${showMoreLabelSlot} </Menu> `, }); expect(wrapper.find('.ais-Menu-showMore').text()).toBe('Voir moins'); expect(wrapper.htmlCompat()).toMatchSnapshot(); }); });