import React from 'react'; import {mount} from 'enzyme'; import SearchBar from 'app/views/organizationEvents/searchBar'; import TagStore from 'app/stores/tagStore'; const focusInput = el => el.find('input[name="query"]').simulate('focus'); const selectFirstAutocompleteItem = el => { focusInput(el); el .find('.search-autocomplete-item') .first() .simulate('click'); const input = el.find('input'); input .getDOMNode() .setSelectionRange(input.prop('value').length, input.prop('value').length); return el; }; const setQuery = (el, query) => { el .find('input') .simulate('change', {target: {value: query}}) .getDOMNode() .setSelectionRange(query.length, query.length); }; describe('SearchBar', function() { let options; let tagValuesMock; let tagKeysMock; let organization = TestStubs.Organization(); let props = { organization, }; beforeEach(function() { TagStore.reset(); TagStore.onLoadTagsSuccess(TestStubs.Tags()); options = TestStubs.routerContext(); tagValuesMock = MockApiClient.addMockResponse({ url: '/organizations/org-slug/tags/gpu/values/', body: [{count: 2, name: 'Nvidia 1080ti'}], }); tagKeysMock = MockApiClient.addMockResponse({ url: '/organizations/org-slug/tags/', body: [{count: 3, key: 'gpu'}, {count: 3, key: 'mytag'}], }); }); afterEach(function() { MockApiClient.clearMockResponses(); }); it('fetches organization tags on mount', async function() { let wrapper = await mount(, options); expect(tagKeysMock).toHaveBeenCalledTimes(1); wrapper.update(); expect(wrapper.find('SmartSearchBar').prop('supportedTags')).toEqual( expect.objectContaining({ gpu: {key: 'gpu', name: 'gpu'}, mytag: {key: 'mytag', name: 'mytag'}, }) ); }); it('searches and selects an event field value', async function() { let wrapper = await mount(, options); setQuery(wrapper, 'gpu:'); expect(tagValuesMock).toHaveBeenCalledWith( '/organizations/org-slug/tags/gpu/values/', expect.objectContaining({data: {query: ''}}) ); await tick(); wrapper.update(); expect(wrapper.find('SearchDropdown').prop('searchSubstring')).toEqual(''); expect(wrapper.find('SearchDropdown').prop('items')).toEqual([ expect.objectContaining({ value: '"Nvidia 1080ti"', }), ]); selectFirstAutocompleteItem(wrapper); wrapper.update(); expect(wrapper.find('input').prop('value')).toBe('gpu:"Nvidia 1080ti" '); }); it('does not requery for event field values if query does not change', async function() { let wrapper = await mount(, options); setQuery(wrapper, 'gpu:'); expect(tagValuesMock).toHaveBeenCalledTimes(1); // Click will fire "updateAutocompleteItems" wrapper.find('input').simulate('click'); await tick(); wrapper.update(); expect(tagValuesMock).toHaveBeenCalledTimes(1); }); it('removes highlight when query is empty', async function() { let wrapper = await mount(, options); setQuery(wrapper, 'gpu'); await tick(); wrapper.update(); expect(wrapper.find('.search-description strong').text()).toBe('gpu'); // Should have nothing highlighted setQuery(wrapper, ''); expect(wrapper.find('.search-description strong')).toHaveLength(0); }); it('ignores negation ("!") at the beginning of search term', async function() { let wrapper = await mount(, options); setQuery(wrapper, '!gp'); await tick(); wrapper.update(); expect(wrapper.find('.search-autocomplete-item')).toHaveLength(1); expect(wrapper.find('.search-autocomplete-item').text()).toBe('gpu:'); }); it('ignores wildcard ("*") at the beginning of tag value query', async function() { let wrapper = await mount(, options); setQuery(wrapper, '!gpu:*'); await tick(); wrapper.update(); expect(tagValuesMock).toHaveBeenCalledWith( '/organizations/org-slug/tags/gpu/values/', expect.objectContaining({data: {query: ''}}) ); selectFirstAutocompleteItem(wrapper); expect(wrapper.find('input').prop('value')).toBe('!gpu:*"Nvidia 1080ti" '); }); });