Commit d194f3dc authored by Phil Hughes's avatar Phil Hughes

Merge branch 'himkp-jest-filtered-search' into 'master'

Migrate some filtered_search specs to Jest

See merge request gitlab-org/gitlab!32455
parents 2f8ee6f8 91db0aef
...@@ -9,8 +9,14 @@ import FilteredSearchDropdownManager from '~/filtered_search/filtered_search_dro ...@@ -9,8 +9,14 @@ import FilteredSearchDropdownManager from '~/filtered_search/filtered_search_dro
import FilteredSearchManager from '~/filtered_search/filtered_search_manager'; import FilteredSearchManager from '~/filtered_search/filtered_search_manager';
import FilteredSearchSpecHelper from '../helpers/filtered_search_spec_helper'; import FilteredSearchSpecHelper from '../helpers/filtered_search_spec_helper';
import { BACKSPACE_KEY_CODE, DELETE_KEY_CODE } from '~/lib/utils/keycodes'; import { BACKSPACE_KEY_CODE, DELETE_KEY_CODE } from '~/lib/utils/keycodes';
import { visitUrl } from '~/lib/utils/url_utility';
describe('Filtered Search Manager', function() { jest.mock('~/lib/utils/url_utility', () => ({
...jest.requireActual('~/lib/utils/url_utility'),
visitUrl: jest.fn(),
}));
describe('Filtered Search Manager', () => {
let input; let input;
let manager; let manager;
let tokensContainer; let tokensContainer;
...@@ -68,17 +74,17 @@ describe('Filtered Search Manager', function() { ...@@ -68,17 +74,17 @@ describe('Filtered Search Manager', function() {
</div> </div>
`); `);
spyOn(FilteredSearchDropdownManager.prototype, 'setDropdown').and.callFake(() => {}); jest.spyOn(FilteredSearchDropdownManager.prototype, 'setDropdown').mockImplementation();
}); });
const initializeManager = () => { const initializeManager = () => {
/* eslint-disable jasmine/no-unsafe-spy */ jest.spyOn(FilteredSearchManager.prototype, 'loadSearchParamsFromURL').mockImplementation();
spyOn(FilteredSearchManager.prototype, 'loadSearchParamsFromURL').and.callFake(() => {}); jest.spyOn(FilteredSearchManager.prototype, 'tokenChange').mockImplementation();
spyOn(FilteredSearchManager.prototype, 'tokenChange').and.callFake(() => {}); jest
spyOn(FilteredSearchDropdownManager.prototype, 'updateDropdownOffset').and.callFake(() => {}); .spyOn(FilteredSearchDropdownManager.prototype, 'updateDropdownOffset')
spyOn(gl.utils, 'getParameterByName').and.returnValue(null); .mockImplementation();
spyOn(FilteredSearchVisualTokens, 'unselectTokens').and.callThrough(); jest.spyOn(gl.utils, 'getParameterByName').mockReturnValue(null);
/* eslint-enable jasmine/no-unsafe-spy */ jest.spyOn(FilteredSearchVisualTokens, 'unselectTokens');
input = document.querySelector('.filtered-search'); input = document.querySelector('.filtered-search');
tokensContainer = document.querySelector('.tokens-container'); tokensContainer = document.querySelector('.tokens-container');
...@@ -92,22 +98,22 @@ describe('Filtered Search Manager', function() { ...@@ -92,22 +98,22 @@ describe('Filtered Search Manager', function() {
describe('class constructor', () => { describe('class constructor', () => {
const isLocalStorageAvailable = 'isLocalStorageAvailable'; const isLocalStorageAvailable = 'isLocalStorageAvailable';
let RecentSearchesStoreSpy;
beforeEach(() => { beforeEach(() => {
spyOn(RecentSearchesService, 'isAvailable').and.returnValue(isLocalStorageAvailable); jest.spyOn(RecentSearchesService, 'isAvailable').mockReturnValue(isLocalStorageAvailable);
spyOn(RecentSearchesRoot.prototype, 'render'); jest.spyOn(RecentSearchesRoot.prototype, 'render').mockImplementation();
RecentSearchesStoreSpy = spyOnDependency(FilteredSearchManager, 'RecentSearchesStore');
}); });
it('should instantiate RecentSearchesStore with isLocalStorageAvailable', () => { it('should instantiate RecentSearchesStore with isLocalStorageAvailable', () => {
manager = new FilteredSearchManager({ page }); manager = new FilteredSearchManager({ page });
expect(RecentSearchesService.isAvailable).toHaveBeenCalled(); expect(RecentSearchesService.isAvailable).toHaveBeenCalled();
expect(RecentSearchesStoreSpy).toHaveBeenCalledWith({ expect(manager.recentSearchesStore.state).toEqual(
isLocalStorageAvailable, expect.objectContaining({
allowedKeys: IssuableFilteredSearchTokenKeys.getKeys(), isLocalStorageAvailable,
}); allowedKeys: IssuableFilteredSearchTokenKeys.getKeys(),
}),
);
}); });
}); });
...@@ -117,10 +123,10 @@ describe('Filtered Search Manager', function() { ...@@ -117,10 +123,10 @@ describe('Filtered Search Manager', function() {
}); });
it('should not instantiate Flash if an RecentSearchesServiceError is caught', () => { it('should not instantiate Flash if an RecentSearchesServiceError is caught', () => {
spyOn(RecentSearchesService.prototype, 'fetch').and.callFake(() => jest
Promise.reject(new RecentSearchesServiceError()), .spyOn(RecentSearchesService.prototype, 'fetch')
); .mockImplementation(() => Promise.reject(new RecentSearchesServiceError()));
spyOn(window, 'Flash'); jest.spyOn(window, 'Flash').mockImplementation();
manager.setup(); manager.setup();
...@@ -130,7 +136,7 @@ describe('Filtered Search Manager', function() { ...@@ -130,7 +136,7 @@ describe('Filtered Search Manager', function() {
describe('searchState', () => { describe('searchState', () => {
beforeEach(() => { beforeEach(() => {
spyOn(FilteredSearchManager.prototype, 'search').and.callFake(() => {}); jest.spyOn(FilteredSearchManager.prototype, 'search').mockImplementation();
initializeManager(); initializeManager();
}); });
...@@ -141,7 +147,7 @@ describe('Filtered Search Manager', function() { ...@@ -141,7 +147,7 @@ describe('Filtered Search Manager', function() {
blur: () => {}, blur: () => {},
}, },
}; };
spyOn(e.currentTarget, 'blur').and.callThrough(); jest.spyOn(e.currentTarget, 'blur');
manager.searchState(e); manager.searchState(e);
expect(e.currentTarget.blur).toHaveBeenCalled(); expect(e.currentTarget.blur).toHaveBeenCalled();
...@@ -187,7 +193,7 @@ describe('Filtered Search Manager', function() { ...@@ -187,7 +193,7 @@ describe('Filtered Search Manager', function() {
it('should search with a single word', done => { it('should search with a single word', done => {
input.value = 'searchTerm'; input.value = 'searchTerm';
spyOnDependency(FilteredSearchManager, 'visitUrl').and.callFake(url => { visitUrl.mockImplementation(url => {
expect(url).toEqual(`${defaultParams}&search=searchTerm`); expect(url).toEqual(`${defaultParams}&search=searchTerm`);
done(); done();
}); });
...@@ -198,7 +204,7 @@ describe('Filtered Search Manager', function() { ...@@ -198,7 +204,7 @@ describe('Filtered Search Manager', function() {
it('should search with multiple words', done => { it('should search with multiple words', done => {
input.value = 'awesome search terms'; input.value = 'awesome search terms';
spyOnDependency(FilteredSearchManager, 'visitUrl').and.callFake(url => { visitUrl.mockImplementation(url => {
expect(url).toEqual(`${defaultParams}&search=awesome+search+terms`); expect(url).toEqual(`${defaultParams}&search=awesome+search+terms`);
done(); done();
}); });
...@@ -209,7 +215,7 @@ describe('Filtered Search Manager', function() { ...@@ -209,7 +215,7 @@ describe('Filtered Search Manager', function() {
it('should search with special characters', done => { it('should search with special characters', done => {
input.value = '~!@#$%^&*()_+{}:<>,.?/'; input.value = '~!@#$%^&*()_+{}:<>,.?/';
spyOnDependency(FilteredSearchManager, 'visitUrl').and.callFake(url => { visitUrl.mockImplementation(url => {
expect(url).toEqual( expect(url).toEqual(
`${defaultParams}&search=~!%40%23%24%25%5E%26*()_%2B%7B%7D%3A%3C%3E%2C.%3F%2F`, `${defaultParams}&search=~!%40%23%24%25%5E%26*()_%2B%7B%7D%3A%3C%3E%2C.%3F%2F`,
); );
...@@ -225,7 +231,7 @@ describe('Filtered Search Manager', function() { ...@@ -225,7 +231,7 @@ describe('Filtered Search Manager', function() {
${FilteredSearchSpecHelper.createFilterVisualTokenHTML('label', '=', '~bug')} ${FilteredSearchSpecHelper.createFilterVisualTokenHTML('label', '=', '~bug')}
`); `);
spyOnDependency(FilteredSearchManager, 'visitUrl').and.callFake(url => { visitUrl.mockImplementation(url => {
expect(url).toEqual(`${defaultParams}&label_name[]=bug`); expect(url).toEqual(`${defaultParams}&label_name[]=bug`);
done(); done();
}); });
...@@ -277,7 +283,7 @@ describe('Filtered Search Manager', function() { ...@@ -277,7 +283,7 @@ describe('Filtered Search Manager', function() {
}); });
it('removes last token', () => { it('removes last token', () => {
spyOn(FilteredSearchVisualTokens, 'removeLastTokenPartial').and.callThrough(); jest.spyOn(FilteredSearchVisualTokens, 'removeLastTokenPartial');
dispatchBackspaceEvent(input, 'keyup'); dispatchBackspaceEvent(input, 'keyup');
dispatchBackspaceEvent(input, 'keyup'); dispatchBackspaceEvent(input, 'keyup');
...@@ -285,7 +291,7 @@ describe('Filtered Search Manager', function() { ...@@ -285,7 +291,7 @@ describe('Filtered Search Manager', function() {
}); });
it('sets the input', () => { it('sets the input', () => {
spyOn(FilteredSearchVisualTokens, 'getLastTokenPartial').and.callThrough(); jest.spyOn(FilteredSearchVisualTokens, 'getLastTokenPartial');
dispatchDeleteEvent(input, 'keyup'); dispatchDeleteEvent(input, 'keyup');
dispatchDeleteEvent(input, 'keyup'); dispatchDeleteEvent(input, 'keyup');
...@@ -295,8 +301,8 @@ describe('Filtered Search Manager', function() { ...@@ -295,8 +301,8 @@ describe('Filtered Search Manager', function() {
}); });
it('does not remove token or change input when there is existing input', () => { it('does not remove token or change input when there is existing input', () => {
spyOn(FilteredSearchVisualTokens, 'removeLastTokenPartial').and.callThrough(); jest.spyOn(FilteredSearchVisualTokens, 'removeLastTokenPartial');
spyOn(FilteredSearchVisualTokens, 'getLastTokenPartial').and.callThrough(); jest.spyOn(FilteredSearchVisualTokens, 'getLastTokenPartial');
input.value = 'text'; input.value = 'text';
dispatchDeleteEvent(input, 'keyup'); dispatchDeleteEvent(input, 'keyup');
...@@ -307,8 +313,8 @@ describe('Filtered Search Manager', function() { ...@@ -307,8 +313,8 @@ describe('Filtered Search Manager', function() {
}); });
it('does not remove previous token on single backspace press', () => { it('does not remove previous token on single backspace press', () => {
spyOn(FilteredSearchVisualTokens, 'removeLastTokenPartial').and.callThrough(); jest.spyOn(FilteredSearchVisualTokens, 'removeLastTokenPartial');
spyOn(FilteredSearchVisualTokens, 'getLastTokenPartial').and.callThrough(); jest.spyOn(FilteredSearchVisualTokens, 'getLastTokenPartial');
input.value = 't'; input.value = 't';
dispatchDeleteEvent(input, 'keyup'); dispatchDeleteEvent(input, 'keyup');
...@@ -322,7 +328,7 @@ describe('Filtered Search Manager', function() { ...@@ -322,7 +328,7 @@ describe('Filtered Search Manager', function() {
describe('checkForAltOrCtrlBackspace', () => { describe('checkForAltOrCtrlBackspace', () => {
beforeEach(() => { beforeEach(() => {
initializeManager(); initializeManager();
spyOn(FilteredSearchVisualTokens, 'removeLastTokenPartial').and.callThrough(); jest.spyOn(FilteredSearchVisualTokens, 'removeLastTokenPartial');
}); });
describe('tokens and no input', () => { describe('tokens and no input', () => {
...@@ -384,7 +390,7 @@ describe('Filtered Search Manager', function() { ...@@ -384,7 +390,7 @@ describe('Filtered Search Manager', function() {
}); });
it('removes all tokens and input', () => { it('removes all tokens and input', () => {
spyOn(FilteredSearchManager.prototype, 'clearSearch').and.callThrough(); jest.spyOn(FilteredSearchManager.prototype, 'clearSearch');
dispatchMetaBackspaceEvent(input, 'keydown'); dispatchMetaBackspaceEvent(input, 'keydown');
expect(manager.clearSearch).toHaveBeenCalled(); expect(manager.clearSearch).toHaveBeenCalled();
...@@ -410,7 +416,7 @@ describe('Filtered Search Manager', function() { ...@@ -410,7 +416,7 @@ describe('Filtered Search Manager', function() {
describe('unselected token', () => { describe('unselected token', () => {
beforeEach(() => { beforeEach(() => {
spyOn(FilteredSearchManager.prototype, 'removeSelectedToken').and.callThrough(); jest.spyOn(FilteredSearchManager.prototype, 'removeSelectedToken');
tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML( tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(
FilteredSearchSpecHelper.createFilterVisualTokenHTML('milestone', '=', 'none'), FilteredSearchSpecHelper.createFilterVisualTokenHTML('milestone', '=', 'none'),
...@@ -481,9 +487,9 @@ describe('Filtered Search Manager', function() { ...@@ -481,9 +487,9 @@ describe('Filtered Search Manager', function() {
describe('removeSelectedToken', () => { describe('removeSelectedToken', () => {
beforeEach(() => { beforeEach(() => {
spyOn(FilteredSearchVisualTokens, 'removeSelectedToken').and.callThrough(); jest.spyOn(FilteredSearchVisualTokens, 'removeSelectedToken');
spyOn(FilteredSearchManager.prototype, 'handleInputPlaceholder').and.callThrough(); jest.spyOn(FilteredSearchManager.prototype, 'handleInputPlaceholder');
spyOn(FilteredSearchManager.prototype, 'toggleClearSearchButton').and.callThrough(); jest.spyOn(FilteredSearchManager.prototype, 'toggleClearSearchButton');
initializeManager(); initializeManager();
}); });
...@@ -554,8 +560,9 @@ describe('Filtered Search Manager', function() { ...@@ -554,8 +560,9 @@ describe('Filtered Search Manager', function() {
}); });
describe('getAllParams', () => { describe('getAllParams', () => {
let paramsArr;
beforeEach(() => { beforeEach(() => {
this.paramsArr = ['key=value', 'otherkey=othervalue']; paramsArr = ['key=value', 'otherkey=othervalue'];
initializeManager(); initializeManager();
}); });
...@@ -563,18 +570,18 @@ describe('Filtered Search Manager', function() { ...@@ -563,18 +570,18 @@ describe('Filtered Search Manager', function() {
it('correctly modifies params when custom modifier is passed', () => { it('correctly modifies params when custom modifier is passed', () => {
const modifedParams = manager.getAllParams.call( const modifedParams = manager.getAllParams.call(
{ {
modifyUrlParams: paramsArr => paramsArr.reverse(), modifyUrlParams: params => params.reverse(),
}, },
[].concat(this.paramsArr), [].concat(paramsArr),
); );
expect(modifedParams[0]).toBe(this.paramsArr[1]); expect(modifedParams[0]).toBe(paramsArr[1]);
}); });
it('does not modify params when no custom modifier is passed', () => { it('does not modify params when no custom modifier is passed', () => {
const modifedParams = manager.getAllParams.call({}, this.paramsArr); const modifedParams = manager.getAllParams.call({}, paramsArr);
expect(modifedParams[1]).toBe(this.paramsArr[1]); expect(modifedParams[1]).toBe(paramsArr[1]);
}); });
}); });
}); });
import Vue from 'vue';
import RecentSearchesRoot from '~/filtered_search/recent_searches_root'; import RecentSearchesRoot from '~/filtered_search/recent_searches_root';
jest.mock('vue');
describe('RecentSearchesRoot', () => { describe('RecentSearchesRoot', () => {
describe('render', () => { describe('render', () => {
let recentSearchesRoot; let recentSearchesRoot;
let data; let data;
let template; let template;
let VueSpy;
beforeEach(() => { beforeEach(() => {
recentSearchesRoot = { recentSearchesRoot = {
...@@ -14,7 +16,7 @@ describe('RecentSearchesRoot', () => { ...@@ -14,7 +16,7 @@ describe('RecentSearchesRoot', () => {
}, },
}; };
VueSpy = spyOnDependency(RecentSearchesRoot, 'Vue').and.callFake(options => { Vue.mockImplementation(options => {
({ data, template } = options); ({ data, template } = options);
}); });
...@@ -22,7 +24,7 @@ describe('RecentSearchesRoot', () => { ...@@ -22,7 +24,7 @@ describe('RecentSearchesRoot', () => {
}); });
it('should instantiate Vue', () => { it('should instantiate Vue', () => {
expect(VueSpy).toHaveBeenCalled(); expect(Vue).toHaveBeenCalled();
expect(data()).toBe(recentSearchesRoot.store.state); expect(data()).toBe(recentSearchesRoot.store.state);
expect(template).toContain(':is-local-storage-available="isLocalStorageAvailable"'); expect(template).toContain(':is-local-storage-available="isLocalStorageAvailable"');
}); });
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment