spec/frontend/search/elastic_search_spec.js (115 lines of code) (raw):
/**
* @jest-environment jsdom
*/
import { mount } from '@vue/test-utils';
import flushPromises from 'flush-promises';
import { mockResults, mockNoResults, mockHistoryCookie } from '../__mocks__/search_results_mock';
import SearchForm from '../../../content/frontend/search/components/elastic_search_form.vue';
import {
trackPageHistory,
RECENT_HISTORY_ITEMS,
} from '../../../content/frontend/search/recently_viewed';
import { getCookie, setCookie } from '../../../content/frontend/shared/cookies';
import { fetchResults } from '../../../content/frontend/services/elastic_search_api';
jest.mock('../../../content/frontend/services/elastic_search_api', () => ({
fetchResults: jest.fn(),
MAX_RESULTS_PER_PAGE: 10,
}));
describe('content/frontend/search/components/elastic_search_form.vue', () => {
let wrapper;
// Use fake timers to mock debounce behavior.
beforeAll(() => {
jest.useFakeTimers();
});
afterAll(() => {
jest.runAllTimers();
});
beforeEach(() => {
jest.clearAllMocks();
// Add a container around the mounted component.
// We need this to avoid tooltip errors from BootstrapVue.
const createContainer = (tag = 'div') => {
const container = document.createElement(tag);
document.body.appendChild(container);
return container;
};
const componentData = {
attachTo: createContainer(),
propsData: {
numResults: 10,
},
};
wrapper = mount(SearchForm, componentData);
});
afterEach(() => {
wrapper.destroy();
});
it('runs a search when the user types in a query', async () => {
fetchResults.mockResolvedValueOnce(mockResults);
const input = wrapper.find('input');
input.setValue('how does jest work');
await input.trigger('keyup');
jest.advanceTimersByTime(500); // debounce
expect(fetchResults).toHaveBeenCalledTimes(1);
});
it('displays "No results found" message when there are no search results', async () => {
fetchResults.mockResolvedValueOnce(mockNoResults);
const input = wrapper.find('input');
input.setValue('non-existent query');
await input.trigger('keyup');
jest.advanceTimersByTime(500);
await flushPromises();
expect(fetchResults).toHaveBeenCalledTimes(1);
expect(wrapper.find('[data-testid="no-results"]').exists()).toBe(true);
});
it('displays "See all results" link when there are more results than shown', async () => {
fetchResults.mockResolvedValueOnce(mockResults);
const input = wrapper.find('input');
input.setValue('test');
await input.trigger('keyup');
jest.advanceTimersByTime(500);
await flushPromises();
expect(wrapper.vm.hasMoreResults).toBe(true);
const moreResultsLink = wrapper.find('[data-testid="more-results"]');
expect(moreResultsLink.exists()).toBe(true);
expect(moreResultsLink.attributes('href')).toBe('/search/?q=test');
});
});
describe('content/frontend/search/recently_viewed.js', () => {
afterEach(() => {
// Delete the cookie after each test
document.cookie = 'pageHistory=; expires=Mon, 12 June 2023 00:00:00 UTC; path=/;';
});
it('should set a cookie with the current page URL and title', () => {
// Set up the DOM
document.title = 'Test Page | GitLab';
const location = {
...window.location,
pathname: '/test-page',
};
Object.defineProperty(window, 'location', {
writable: true,
value: location,
});
trackPageHistory();
// Check that the cookie was set correctly
const cookieValue = getCookie('pageHistory');
expect(cookieValue).not.toBeNull();
const pageHistory = JSON.parse(cookieValue);
expect(pageHistory).toHaveLength(1);
expect(pageHistory[0].path).toBe('/test-page');
expect(pageHistory[0].title).toBe('Test Page');
});
it('should limit the number of items in the history to RECENT_HISTORY_ITEMS', () => {
document.title = 'Test Page | GitLab';
// Set a cookie with RECENT_HISTORY_ITEMS pages in it, then track this page
setCookie('pageHistory', JSON.stringify(mockHistoryCookie), 365);
trackPageHistory();
// Check that the cookie still contains RECENT_HISTORY_ITEMS
const cookieValue = getCookie('pageHistory');
expect(cookieValue).not.toBeNull();
const pageHistory = JSON.parse(cookieValue);
expect(pageHistory).toHaveLength(RECENT_HISTORY_ITEMS);
});
it('should not add duplicate history items', () => {
document.title = 'Test Page | GitLab';
// Set a cookie with the current page URL
const initialPageHistory = [{ path: '/test-page', title: 'Test Page' }];
setCookie('pageHistory', JSON.stringify(initialPageHistory), 365);
trackPageHistory();
// Check that the cookie was updated correctly, with one instance of Test Page
const cookieValue = getCookie('pageHistory');
expect(cookieValue).not.toBeNull();
const pageHistory = JSON.parse(cookieValue);
expect(pageHistory).toHaveLength(1);
expect(pageHistory[0].path).toBe('/test-page');
expect(pageHistory[0].title).toBe('Test Page');
});
});