UNPKG

@davidrouyer/vue-instantsearch

Version:

👀 Lightning-fast Algolia search for Vue apps

317 lines (258 loc) • 7.99 kB
import Vue from 'vue'; import { mount } from '@vue/test-utils'; import instantsearch from 'instantsearch.js/es'; import InstantSearch from '../InstantSearch'; import { version } from '../../../package.json'; beforeEach(() => jest.clearAllMocks()); it('passes props to InstantSearch.js', () => { const searchClient = {}; const insightsClient = jest.fn(); const searchFunction = helper => helper.search(); mount(InstantSearch, { propsData: { searchClient, insightsClient, indexName: 'something', routing: { router: {}, stateMapping: {}, }, stalledSearchDelay: 250, searchFunction, }, }); expect(instantsearch).toHaveBeenCalledWith({ indexName: 'something', routing: { router: {}, stateMapping: {}, }, searchClient, insightsClient, searchFunction, stalledSearchDelay: 250, }); }); it('throws on usage of appId or apiKey', () => { global.console.warn = jest.fn(); global.console.error = jest.fn(); mount(InstantSearch, { propsData: { searchClient: {}, apiKey: 'bla', appId: 'blabla', indexName: 'something', }, }); expect(global.console.warn.mock.calls[0][0]).toMatchInlineSnapshot(` "Vue InstantSearch: You used the prop api-key or app-id. These have been replaced by search-client. See more info here: https://www.algolia.com/doc/api-reference/widgets/instantsearch/vue/#widget-param-search-client" `); expect(global.console.error.mock.calls[0][0]).toMatchInlineSnapshot(` "[Vue warn]: Invalid prop: custom validator check failed for prop \\"apiKey\\". found in ---> <AisInstantSearch> <Root>" `); expect(global.console.error.mock.calls[1][0]).toMatchInlineSnapshot(` "[Vue warn]: Invalid prop: custom validator check failed for prop \\"appId\\". found in ---> <AisInstantSearch> <Root>" `); }); it('calls `start` on the next tick', async () => { const wrapper = mount(InstantSearch, { propsData: { searchClient: {}, indexName: 'something', }, }); await Vue.nextTick(); expect(wrapper.vm.instantSearchInstance.start).toHaveBeenCalledTimes(1); }); it('renders correctly (empty)', () => { const wrapper = mount(InstantSearch, { propsData: { searchClient: {}, indexName: 'bla', }, }); expect(wrapper.html()).toMatchSnapshot(); }); it('renders correctly (with slot used)', () => { const wrapper = mount(InstantSearch, { propsData: { searchClient: {}, indexName: 'bla', }, slots: { default: '<div>Hi there, this is the main slot</div>', }, }); expect(wrapper.html()).toMatchSnapshot(); }); it('Allows a change in `index-name`', () => { const wrapper = mount(InstantSearch, { propsData: { searchClient: {}, indexName: 'bla', }, }); wrapper.setProps({ indexName: 'doggie_bowl', }); const helper = wrapper.vm.instantSearchInstance.helper; expect(helper.setIndex).toHaveBeenCalledTimes(1); expect(helper.setIndex).toHaveBeenCalledWith('doggie_bowl'); expect(helper.search).toHaveBeenCalledTimes(1); }); it('Allows a change in `search-client`', () => { const wrapper = mount(InstantSearch, { propsData: { searchClient: {}, indexName: 'bla', }, }); const newClient = { cats: 'rule', dogs: 'drool' }; wrapper.setProps({ searchClient: newClient, }); const helper = wrapper.vm.instantSearchInstance.helper; expect(helper.setClient).toHaveBeenCalledTimes(1); expect(helper.setClient).toHaveBeenCalledWith(newClient); expect(helper.search).toHaveBeenCalledTimes(1); }); it('Allows a change in `search-function`', () => { const oldValue = () => {}; const newValue = () => {}; const wrapper = mount(InstantSearch, { propsData: { searchClient: {}, indexName: 'bla', searchFunction: oldValue, }, }); expect(wrapper.vm.instantSearchInstance._searchFunction).toEqual(oldValue); wrapper.setProps({ searchFunction: newValue, }); expect(wrapper.vm.instantSearchInstance._searchFunction).toEqual(newValue); }); it('Allows a change in `stalled-search-delay`', () => { const wrapper = mount(InstantSearch, { propsData: { searchClient: {}, indexName: 'bla', searchFunction: () => {}, stalledSearchDelay: 200, }, }); expect(wrapper.vm.instantSearchInstance._stalledSearchDelay).toEqual(200); wrapper.setProps({ stalledSearchDelay: 50, }); expect(wrapper.vm.instantSearchInstance._stalledSearchDelay).toEqual(50); }); it('does not allow `routing` to be a boolean', () => { global.console.error = jest.fn(); global.console.warn = jest.fn(); mount(InstantSearch, { propsData: { searchClient: {}, indexName: 'bla', routing: true, }, }); expect(global.console.error.mock.calls[0][0]).toMatchInlineSnapshot(` "[Vue warn]: Invalid prop: custom validator check failed for prop \\"routing\\". found in ---> <AisInstantSearch> <Root>" `); expect(global.console.warn.mock.calls[0][0]).toMatchInlineSnapshot( `"routing should be an object, with \`router\` and \`stateMapping\`. See https://www.algolia.com/doc/api-reference/widgets/instantsearch/vue/#widget-param-routing"` ); }); it('Does not allow a change in `routing`', () => { global.console.error = jest.fn(); const wrapper = mount(InstantSearch, { propsData: { searchClient: {}, indexName: 'bla', }, }); wrapper.setProps({ routing: false, }); // Vue catches this error and throws it to the console expect(global.console.error.mock.calls[0][0]).toMatchInlineSnapshot(` [Error: routing configuration can not be changed dynamically at this point. Please open a new issue: https://github.com/algolia/vue-instantsearch/issues/new?template=feature.md] `); }); it('will call client.addAlgoliaAgent if present', () => { const client = { addAlgoliaAgent: jest.fn() }; mount(InstantSearch, { propsData: { searchClient: client, indexName: 'bla', }, }); expect(client.addAlgoliaAgent).toHaveBeenCalledTimes(2); expect(client.addAlgoliaAgent).toHaveBeenCalledWith(`Vue (${Vue.version})`); expect(client.addAlgoliaAgent).toHaveBeenCalledWith( `Vue InstantSearch (${version})` ); }); it('will not call client.addAlgoliaAgent if not function (so nothing to assert)', () => { expect(() => mount(InstantSearch, { propsData: { searchClient: { addAlgoliaAgent: true }, indexName: 'bla', }, }) ).not.toThrow(); }); it('disposes the instantsearch instance on unmount', async () => { const wrapper = mount(InstantSearch, { propsData: { searchClient: {}, indexName: 'something', }, }); await Vue.nextTick(); expect(wrapper.vm.instantSearchInstance.started).toBe(true); wrapper.destroy(); expect(wrapper.vm.instantSearchInstance.started).toBe(false); expect(wrapper.vm.instantSearchInstance.dispose).toHaveBeenCalledTimes(1); }); it('provides the instantsearch instance', done => { Vue.config.errorHandler = done; const ChildComponent = { inject: ['$_ais_instantSearchInstance'], mounted() { this.$nextTick(() => { expect(typeof this.$_ais_instantSearchInstance).toBe('object'); expect(wrapper.vm.instantSearchInstance).toBe( this.$_ais_instantSearchInstance ); done(); }); }, render() { return null; }, }; const wrapper = mount(InstantSearch, { propsData: { searchClient: {}, indexName: 'something', }, slots: { default: ChildComponent, }, }); });