import { mount } from '@vue/test-utils' import Vuex from 'vuex' import SearchResults from './SearchResults' import helpers from '~/storybook/helpers' helpers.init() const localVue = global.localVue localVue.directive('scrollTo', jest.fn()) const stubs = { 'client-only': true, 'nuxt-link': true, } describe('SearchResults', () => { let mocks, getters, propsData, wrapper const Wrapper = () => { const store = new Vuex.Store({ getters, }) return mount(SearchResults, { mocks, localVue, propsData, store, stubs }) } beforeEach(() => { mocks = { $t: jest.fn(), $env: { CATEGORIES_ACTIVE: false, }, } getters = { 'auth/user': () => { return { id: 'u343', name: 'Matt' } }, 'auth/isModerator': () => false, } propsData = { pageSize: 12, search: '', } wrapper = Wrapper() }) describe('mount', () => { it('renders tab-navigation component', () => { expect(wrapper.find('.tab-navigation').exists()).toBe(true) }) describe('searchResults', () => { describe('contains no results', () => { it('renders hc-empty component', () => { expect(wrapper.find('.hc-empty').exists()).toBe(true) }) }) describe('result contains 25 posts, 8 users and 0 hashtags', () => { // we couldn't get it running with "jest.runAllTimers()" and so we used "setTimeout" // time is a bit more then 3000 milisec see "webapp/components/CountTo.vue" const counterTimeout = 3000 + 10 beforeEach(async () => { wrapper.setData({ posts: helpers.fakePost(12), postCount: 25, users: helpers.fakeUser(8), userCount: 8, activeTab: 'Post', }) }) it('shows a total of 33 results', () => { setTimeout(() => { expect(wrapper.find('.total-search-results').text()).toContain('33') }, counterTimeout) }) it('shows tab with 25 posts found', () => { setTimeout(() => { expect(wrapper.find('[data-test="Post-tab"]').text()).toContain('25') }, counterTimeout) }) it('shows tab with 8 users found', () => { setTimeout(() => { expect(wrapper.find('[data-test="User-tab"]').text()).toContain('8') }, counterTimeout) }) it('shows tab with 0 hashtags found', () => { setTimeout(() => { expect(wrapper.find('[data-test="Hashtag-tab"]').text()).toContain('0') }, counterTimeout) }) it('has post tab as active tab', () => { expect(wrapper.find('[data-test="Post-tab"]').classes('--active')).toBe(true) }) it('has user tab inactive', () => { expect(wrapper.find('[data-test="User-tab"]').classes('--active')).toBe(false) }) it('has hashtag tab disabled', () => { expect(wrapper.find('[data-test="Hashtag-tab"]').classes('--disabled')).toBe(true) }) it('displays 12 (pageSize) posts', () => { expect(wrapper.findAll('.post-teaser')).toHaveLength(12) }) it('has post tab inactive after emitting switch-tab', async () => { wrapper.find('.tab-navigation').vm.$emit('switch-tab', 'User') // emits direct from tab component to search results await wrapper.vm.$nextTick() await expect(wrapper.find('[data-test="Post-tab"]').classes('--active')).toBe(false) }) it('has post tab inactive after clicking on user tab', async () => { wrapper.find('[data-test="User-tab-click"]').trigger('click') await wrapper.vm.$nextTick() await expect(wrapper.find('[data-test="Post-tab"]').classes('--active')).toBe(false) }) it('has user tab active after clicking on user tab', async () => { wrapper.find('[data-test="User-tab-click"]').trigger('click') await wrapper.vm.$nextTick() await expect(wrapper.find('[data-test="User-tab"]').classes('--active')).toBe(true) }) it('displays 8 users after clicking on user tab', async () => { wrapper.find('[data-test="User-tab-click"]').trigger('click') await wrapper.vm.$nextTick() await expect(wrapper.findAll('.user-teaser')).toHaveLength(8) }) it('shows the pagination buttons for posts', () => { expect(wrapper.find('.pagination-buttons').exists()).toBe(true) }) it('shows no pagination buttons for users', async () => { wrapper.find('[data-test="User-tab-click"]').trigger('click') await wrapper.vm.$nextTick() await expect(wrapper.find('.pagination-buttons').exists()).toBe(false) }) it('displays page 1 of 3 for the 25 posts', () => { expect(wrapper.find('.pagination-pageCount').text().replace(/\s+/g, ' ')).toContain( '1 / 3', ) }) it('displays the next page button for the 25 posts', () => { expect(wrapper.find('.next-button').exists()).toBe(true) }) it('deactivates previous page button for the 25 posts', () => { const previousButton = wrapper.find('[data-test="previous-button"]') expect(previousButton.attributes().disabled).toEqual('disabled') }) it('displays page 2 / 3 when next-button is clicked', async () => { wrapper.find('.next-button').trigger('click') await wrapper.vm.$nextTick() await expect(wrapper.find('.pagination-pageCount').text().replace(/\s+/g, ' ')).toContain( '2 / 3', ) }) it('sets apollo searchPosts offset to 12 when next-button is clicked', async () => { wrapper.find('.next-button').trigger('click') await wrapper.vm.$nextTick() await expect( wrapper.vm.$options.apollo.searchPosts.variables.bind(wrapper.vm)(), ).toMatchObject({ query: '', firstPosts: 12, postsOffset: 12 }) }) it('displays the next page button when next-button is clicked', async () => { wrapper.find('.next-button').trigger('click') await wrapper.vm.$nextTick() await expect(wrapper.find('.next-button').exists()).toBe(true) }) it('displays the previous page button when next-button is clicked', async () => { wrapper.find('.next-button').trigger('click') await wrapper.vm.$nextTick() await expect(wrapper.find('.previous-button').exists()).toBe(true) }) it('displays page 3 / 3 when next-button is clicked twice', async () => { wrapper.find('.next-button').trigger('click') wrapper.find('.next-button').trigger('click') await wrapper.vm.$nextTick() await expect(wrapper.find('.pagination-pageCount').text().replace(/\s+/g, ' ')).toContain( '3 / 3', ) }) it('sets apollo searchPosts offset to 24 when next-button is clicked twice', async () => { wrapper.find('.next-button').trigger('click') wrapper.find('.next-button').trigger('click') await wrapper.vm.$nextTick() await expect( wrapper.vm.$options.apollo.searchPosts.variables.bind(wrapper.vm)(), ).toMatchObject({ query: '', firstPosts: 12, postsOffset: 24 }) }) it('deactivates next page button when next-button is clicked twice', async () => { const nextButton = wrapper.find('[data-test="next-button"]') nextButton.trigger('click') nextButton.trigger('click') await wrapper.vm.$nextTick() expect(nextButton.attributes().disabled).toEqual('disabled') }) it('displays the previous page button when next-button is clicked twice', async () => { wrapper.find('.next-button').trigger('click') wrapper.find('.next-button').trigger('click') await wrapper.vm.$nextTick() await expect(wrapper.find('.previous-button').exists()).toBe(true) }) it('displays page 1 / 3 when previous-button is clicked after next-button', async () => { wrapper.find('.next-button').trigger('click') await wrapper.vm.$nextTick() wrapper.find('.previous-button').trigger('click') await wrapper.vm.$nextTick() await expect(wrapper.find('.pagination-pageCount').text().replace(/\s+/g, ' ')).toContain( '1 / 3', ) }) it('sets apollo searchPosts offset to 0 when previous-button is clicked after next-button', async () => { wrapper.find('.next-button').trigger('click') await wrapper.vm.$nextTick() wrapper.find('.previous-button').trigger('click') await wrapper.vm.$nextTick() await expect( wrapper.vm.$options.apollo.searchPosts.variables.bind(wrapper.vm)(), ).toMatchObject({ query: '', firstPosts: 12, postsOffset: 0 }) }) }) }) }) })