import { mount } from '@vue/test-utils' import Vuex from 'vuex' import Vue from 'vue' import SearchableInput from './SearchableInput' import { searchResults } from '~/components/generic/SearchableInput/SearchableInput.story' const localVue = global.localVue localVue.filter('truncate', () => 'truncated string') localVue.filter('dateTime', () => Date.now) const stubs = { 'nuxt-link': true, 'client-only': true, } describe('SearchableInput.vue', () => { let mocks, propsData, getters, wrapper beforeEach(() => { propsData = {} mocks = { $router: { push: jest.fn(), }, $t: jest.fn((string) => string), } getters = { 'auth/isModerator': () => false } wrapper = Wrapper() }) const Wrapper = () => { const store = new Vuex.Store({ getters, }) return mount(SearchableInput, { mocks, localVue, propsData, store, stubs }) } describe('mount', () => { let select beforeEach(() => { select = wrapper.find('.ds-select') select.trigger('focus') select.element.value = 'abcd' }) it('opens the dropdown when focused', () => { expect(wrapper.find('.ds-select-dropdown').isVisible()).toBe(true) }) it('closes the dropdown when blurred', () => { select.trigger('blur') expect(wrapper.find('.ds-select-is-open').exists()).toBe(false) }) it('closes the dropdown when cleared with esc key', () => { select.trigger('input') select.trigger('keyup.esc') expect(wrapper.find('.ds-select-is-open').exists()).toBe(false) }) it('changes the unprocessedSearchInput as the value changes', () => { select.trigger('input') expect(select.element.value).toBe('abcd') }) describe('navigating to resource', () => { beforeEach(() => { propsData = { options: searchResults } wrapper = Wrapper() select = wrapper.find('.ds-select') select.trigger('focus') }) it('pushes to post page', async () => { select.element.value = 'Post' select.trigger('input') const post = wrapper.find('.search-post') post.trigger('click') await Vue.nextTick() expect(mocks.$router.push).toHaveBeenCalledWith({ name: 'post-id-slug', params: { id: 'post-by-jenny', slug: 'user-post-by-jenny' }, }) }) it("pushes to user's profile", async () => { select.element.value = 'Bob' select.trigger('input') const users = wrapper.findAll('.slug') const bob = users.filter((item) => item.text().match(/@bob-der-baumeister/)) bob.trigger('click') await Vue.nextTick() expect(mocks.$router.push).toHaveBeenCalledWith({ name: 'profile-id-slug', params: { id: 'u2', slug: 'bob-der-baumeister' }, }) }) it('pushes hashtag query params', async () => { select.element.value = 'Hash' select.trigger('input') const tags = wrapper.findAll('.hc-hashtag') const tag = tags.filter((item) => item.text().match(/#Hashtag/)) tag.trigger('click') await Vue.nextTick() expect(mocks.$router.push).toHaveBeenCalledWith('?hashtag=Hashtag') }) }) it('opens the search result page when enter is pressed', async () => { select.element.value = 'ab' select.trigger('input') select.trigger('keyup.enter') expect(mocks.$router.push).toHaveBeenCalledWith({ path: '/search/search-results', query: { search: 'ab' }, }) }) it('replaces irregular whitespace with a single space', async () => { select.element.value = 'peter lustig' select.trigger('input') select.trigger('keyup.enter') expect(mocks.$router.push).toHaveBeenCalledWith({ path: '/search/search-results', query: { search: 'peter lustig' }, }) }) }) })