2025-07-02 12:20:21 +00:00

132 lines
3.8 KiB
JavaScript

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('.name')
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' },
})
})
})
})