2022-08-13 15:12:31 +05:30
import { GlSearchBoxByType , GlToken , GlIcon } from '@gitlab/ui' ;
2022-04-04 11:22:00 +05:30
import Vue , { nextTick } from 'vue' ;
2021-11-11 11:23:49 +05:30
import Vuex from 'vuex' ;
import { shallowMountExtended } from 'helpers/vue_test_utils_helper' ;
2022-11-25 23:54:43 +05:30
import { mockTracking } from 'helpers/tracking_helper' ;
2022-08-13 15:12:31 +05:30
import { s _ _ , sprintf } from '~/locale' ;
2021-11-11 11:23:49 +05:30
import HeaderSearchApp from '~/header_search/components/app.vue' ;
2021-11-18 22:05:49 +05:30
import HeaderSearchAutocompleteItems from '~/header_search/components/header_search_autocomplete_items.vue' ;
2021-11-11 11:23:49 +05:30
import HeaderSearchDefaultItems from '~/header_search/components/header_search_default_items.vue' ;
import HeaderSearchScopedItems from '~/header_search/components/header_search_scoped_items.vue' ;
2022-08-13 15:12:31 +05:30
import {
SEARCH _INPUT _DESCRIPTION ,
SEARCH _RESULTS _DESCRIPTION ,
SEARCH _BOX _INDEX ,
ICON _PROJECT ,
ICON _GROUP ,
ICON _SUBGROUP ,
SCOPE _TOKEN _MAX _LENGTH ,
2022-08-27 11:52:29 +05:30
IS _SEARCHING ,
IS _NOT _FOCUSED ,
IS _FOCUSED ,
SEARCH _SHORTCUTS _MIN _CHARACTERS ,
2023-06-20 00:43:36 +05:30
DROPDOWN _CLOSE _TIMEOUT ,
2022-08-13 15:12:31 +05:30
} from '~/header_search/constants' ;
2022-01-26 12:08:38 +05:30
import DropdownKeyboardNavigation from '~/vue_shared/components/dropdown_keyboard_navigation.vue' ;
import { ENTER _KEY } from '~/lib/utils/keys' ;
2021-11-11 11:23:49 +05:30
import { visitUrl } from '~/lib/utils/url_utility' ;
2022-08-13 15:12:31 +05:30
import { truncate } from '~/lib/utils/text_utility' ;
2022-01-26 12:08:38 +05:30
import {
MOCK _SEARCH ,
MOCK _SEARCH _QUERY ,
MOCK _USERNAME ,
MOCK _DEFAULT _SEARCH _OPTIONS ,
MOCK _SCOPED _SEARCH _OPTIONS ,
2022-08-13 15:12:31 +05:30
MOCK _SEARCH _CONTEXT _FULL ,
2022-01-26 12:08:38 +05:30
} from '../mock_data' ;
2021-11-11 11:23:49 +05:30
Vue . use ( Vuex ) ;
jest . mock ( '~/lib/utils/url_utility' , ( ) => ( {
visitUrl : jest . fn ( ) ,
} ) ) ;
describe ( 'HeaderSearchApp' , ( ) => {
let wrapper ;
2023-06-20 00:43:36 +05:30
jest . useFakeTimers ( ) ;
jest . spyOn ( global , 'setTimeout' ) ;
2021-11-11 11:23:49 +05:30
const actionSpies = {
setSearch : jest . fn ( ) ,
2021-11-18 22:05:49 +05:30
fetchAutocompleteOptions : jest . fn ( ) ,
2022-01-26 12:08:38 +05:30
clearAutocomplete : jest . fn ( ) ,
2021-11-11 11:23:49 +05:30
} ;
2022-01-26 12:08:38 +05:30
const createComponent = ( initialState , mockGetters ) => {
2021-11-11 11:23:49 +05:30
const store = new Vuex . Store ( {
state : {
... initialState ,
} ,
actions : actionSpies ,
getters : {
searchQuery : ( ) => MOCK _SEARCH _QUERY ,
2022-01-26 12:08:38 +05:30
searchOptions : ( ) => MOCK _DEFAULT _SEARCH _OPTIONS ,
... mockGetters ,
2021-11-11 11:23:49 +05:30
} ,
} ) ;
wrapper = shallowMountExtended ( HeaderSearchApp , {
store ,
} ) ;
} ;
2022-08-13 15:12:31 +05:30
const formatScopeName = ( scopeName ) => {
if ( ! scopeName ) {
return false ;
}
const searchResultsScope = s _ _ ( 'GlobalSearch|in %{scope}' ) ;
return truncate (
sprintf ( searchResultsScope , {
scope : scopeName ,
} ) ,
SCOPE _TOKEN _MAX _LENGTH ,
) ;
} ;
const findHeaderSearchForm = ( ) => wrapper . findByTestId ( 'header-search-form' ) ;
2021-11-11 11:23:49 +05:30
const findHeaderSearchInput = ( ) => wrapper . findComponent ( GlSearchBoxByType ) ;
2022-08-13 15:12:31 +05:30
const findScopeToken = ( ) => wrapper . findComponent ( GlToken ) ;
const findHeaderSearchInputKBD = ( ) => wrapper . find ( '.keyboard-shortcut-helper' ) ;
2021-11-11 11:23:49 +05:30
const findHeaderSearchDropdown = ( ) => wrapper . findByTestId ( 'header-search-dropdown-menu' ) ;
const findHeaderSearchDefaultItems = ( ) => wrapper . findComponent ( HeaderSearchDefaultItems ) ;
const findHeaderSearchScopedItems = ( ) => wrapper . findComponent ( HeaderSearchScopedItems ) ;
2021-11-18 22:05:49 +05:30
const findHeaderSearchAutocompleteItems = ( ) =>
wrapper . findComponent ( HeaderSearchAutocompleteItems ) ;
2022-01-26 12:08:38 +05:30
const findDropdownKeyboardNavigation = ( ) => wrapper . findComponent ( DropdownKeyboardNavigation ) ;
const findSearchInputDescription = ( ) => wrapper . find ( ` # ${ SEARCH _INPUT _DESCRIPTION } ` ) ;
const findSearchResultsDescription = ( ) => wrapper . findByTestId ( SEARCH _RESULTS _DESCRIPTION ) ;
2021-11-11 11:23:49 +05:30
describe ( 'template' , ( ) => {
2022-01-26 12:08:38 +05:30
describe ( 'always renders' , ( ) => {
beforeEach ( ( ) => {
createComponent ( ) ;
} ) ;
it ( 'Header Search Input' , ( ) => {
expect ( findHeaderSearchInput ( ) . exists ( ) ) . toBe ( true ) ;
} ) ;
2022-08-13 15:12:31 +05:30
it ( 'Header Search Input KBD hint' , ( ) => {
expect ( findHeaderSearchInputKBD ( ) . exists ( ) ) . toBe ( true ) ;
expect ( findHeaderSearchInputKBD ( ) . text ( ) ) . toContain ( '/' ) ;
expect ( findHeaderSearchInputKBD ( ) . attributes ( 'title' ) ) . toContain (
'Use the shortcut key <kbd>/</kbd> to start a search' ,
) ;
} ) ;
2022-01-26 12:08:38 +05:30
it ( 'Search Input Description' , ( ) => {
expect ( findSearchInputDescription ( ) . exists ( ) ) . toBe ( true ) ;
} ) ;
it ( 'Search Results Description' , ( ) => {
expect ( findSearchResultsDescription ( ) . exists ( ) ) . toBe ( true ) ;
} ) ;
2021-11-11 11:23:49 +05:30
} ) ;
describe . each `
showDropdown | username | showSearchDropdown
$ { false } | $ { null } | $ { false }
$ { false } | $ { MOCK _USERNAME } | $ { false }
$ { true } | $ { null } | $ { false }
$ { true } | $ { MOCK _USERNAME } | $ { true }
` ('Header Search Dropdown', ({ showDropdown, username, showSearchDropdown }) => {
describe ( ` when showDropdown is ${ showDropdown } and current_username is ${ username } ` , ( ) => {
beforeEach ( ( ) => {
window . gon . current _username = username ;
2022-01-26 12:08:38 +05:30
createComponent ( ) ;
2023-06-20 00:43:36 +05:30
findHeaderSearchInput ( ) . vm . $emit ( showDropdown ? 'focusin' : '' ) ;
2021-11-11 11:23:49 +05:30
} ) ;
it ( ` should ${ showSearchDropdown ? '' : ' not' } render ` , ( ) => {
expect ( findHeaderSearchDropdown ( ) . exists ( ) ) . toBe ( showSearchDropdown ) ;
} ) ;
} ) ;
} ) ;
describe . each `
2022-08-13 15:12:31 +05:30
search | showDefault | showScoped | showAutocomplete
$ { null } | $ { true } | $ { false } | $ { false }
$ { '' } | $ { true } | $ { false } | $ { false }
$ { 't' } | $ { false } | $ { false } | $ { true }
$ { 'te' } | $ { false } | $ { false } | $ { true }
$ { 'tes' } | $ { false } | $ { true } | $ { true }
$ { MOCK _SEARCH } | $ { false } | $ { true } | $ { true }
` ('Header Search Dropdown Items', ({ search, showDefault, showScoped, showAutocomplete }) => {
describe ( ` when search is ${ search } ` , ( ) => {
beforeEach ( ( ) => {
window . gon . current _username = MOCK _USERNAME ;
createComponent ( { search } , { } ) ;
2023-06-20 00:43:36 +05:30
findHeaderSearchInput ( ) . vm . $emit ( 'focusin' ) ;
2022-08-13 15:12:31 +05:30
} ) ;
2022-01-26 12:08:38 +05:30
2022-08-13 15:12:31 +05:30
it ( ` should ${ showDefault ? '' : ' not' } render the Default Dropdown Items ` , ( ) => {
expect ( findHeaderSearchDefaultItems ( ) . exists ( ) ) . toBe ( showDefault ) ;
} ) ;
2022-01-26 12:08:38 +05:30
2022-08-13 15:12:31 +05:30
it ( ` should ${ showScoped ? '' : ' not' } render the Scoped Dropdown Items ` , ( ) => {
expect ( findHeaderSearchScopedItems ( ) . exists ( ) ) . toBe ( showScoped ) ;
} ) ;
2022-01-26 12:08:38 +05:30
2022-08-13 15:12:31 +05:30
it ( ` should ${ showAutocomplete ? '' : ' not' } render the Autocomplete Dropdown Items ` , ( ) => {
expect ( findHeaderSearchAutocompleteItems ( ) . exists ( ) ) . toBe ( showAutocomplete ) ;
} ) ;
2022-01-26 12:08:38 +05:30
2022-08-13 15:12:31 +05:30
it ( ` should render the Dropdown Navigation Component ` , ( ) => {
expect ( findDropdownKeyboardNavigation ( ) . exists ( ) ) . toBe ( true ) ;
2021-11-11 11:23:49 +05:30
} ) ;
2022-08-27 11:52:29 +05:30
it ( ` should close the dropdown when press escape key ` , async ( ) => {
findHeaderSearchInput ( ) . vm . $emit ( 'keydown' , new KeyboardEvent ( { key : 27 } ) ) ;
2023-06-20 00:43:36 +05:30
jest . runAllTimers ( ) ;
2022-08-27 11:52:29 +05:30
await nextTick ( ) ;
expect ( findHeaderSearchDropdown ( ) . exists ( ) ) . toBe ( false ) ;
expect ( wrapper . emitted ( ) . expandSearchBar . length ) . toBe ( 1 ) ;
} ) ;
2022-08-13 15:12:31 +05:30
} ) ;
} ) ;
2021-11-11 11:23:49 +05:30
2022-01-26 12:08:38 +05:30
describe . each `
username | showDropdown | expectedDesc
2023-05-27 22:25:52 +05:30
$ { null } | $ { false } | $ { HeaderSearchApp . i18n . SEARCH _INPUT _DESCRIBE _BY _NO _DROPDOWN }
$ { null } | $ { true } | $ { HeaderSearchApp . i18n . SEARCH _INPUT _DESCRIBE _BY _NO _DROPDOWN }
$ { MOCK _USERNAME } | $ { false } | $ { HeaderSearchApp . i18n . SEARCH _INPUT _DESCRIBE _BY _WITH _DROPDOWN }
$ { MOCK _USERNAME } | $ { true } | $ { HeaderSearchApp . i18n . SEARCH _INPUT _DESCRIBE _BY _WITH _DROPDOWN }
2022-01-26 12:08:38 +05:30
` ('Search Input Description', ({ username, showDropdown, expectedDesc }) => {
describe ( ` current_username is ${ username } and showDropdown is ${ showDropdown } ` , ( ) => {
beforeEach ( ( ) => {
window . gon . current _username = username ;
createComponent ( ) ;
2023-06-20 00:43:36 +05:30
findHeaderSearchInput ( ) . vm . $emit ( showDropdown ? 'focusin' : '' ) ;
2021-11-11 11:23:49 +05:30
} ) ;
2021-11-18 22:05:49 +05:30
2022-01-26 12:08:38 +05:30
it ( ` sets description to ${ expectedDesc } ` , ( ) => {
expect ( findSearchInputDescription ( ) . text ( ) ) . toBe ( expectedDesc ) ;
2021-11-18 22:05:49 +05:30
} ) ;
2021-11-11 11:23:49 +05:30
} ) ;
} ) ;
2022-01-26 12:08:38 +05:30
describe . each `
username | showDropdown | search | loading | searchOptions | expectedDesc
$ { null } | $ { true } | $ { '' } | $ { false } | $ { [ ] } | $ { '' }
$ { MOCK _USERNAME } | $ { false } | $ { '' } | $ { false } | $ { [ ] } | $ { '' }
$ { MOCK _USERNAME } | $ { true } | $ { '' } | $ { false } | $ { MOCK _DEFAULT _SEARCH _OPTIONS } | $ { ` ${ MOCK _DEFAULT _SEARCH _OPTIONS . length } default results provided. Use the up and down arrow keys to navigate search results list. ` }
$ { MOCK _USERNAME } | $ { true } | $ { '' } | $ { true } | $ { MOCK _DEFAULT _SEARCH _OPTIONS } | $ { ` ${ MOCK _DEFAULT _SEARCH _OPTIONS . length } default results provided. Use the up and down arrow keys to navigate search results list. ` }
$ { MOCK _USERNAME } | $ { true } | $ { MOCK _SEARCH } | $ { false } | $ { MOCK _SCOPED _SEARCH _OPTIONS } | $ { ` Results updated. ${ MOCK _SCOPED _SEARCH _OPTIONS . length } results available. Use the up and down arrow keys to navigate search results list, or ENTER to submit. ` }
2023-05-27 22:25:52 +05:30
$ { MOCK _USERNAME } | $ { true } | $ { MOCK _SEARCH } | $ { true } | $ { MOCK _SCOPED _SEARCH _OPTIONS } | $ { HeaderSearchApp . i18n . SEARCH _RESULTS _LOADING }
2022-01-26 12:08:38 +05:30
` (
'Search Results Description' ,
( { username , showDropdown , search , loading , searchOptions , expectedDesc } ) => {
2022-08-13 15:12:31 +05:30
describe ( ` search is " ${ search } ", loading is ${ loading } , and showSearchDropdown is ${ showDropdown } ` , ( ) => {
2022-01-26 12:08:38 +05:30
beforeEach ( ( ) => {
window . gon . current _username = username ;
2022-08-13 15:12:31 +05:30
createComponent (
{
search ,
loading ,
} ,
{
searchOptions : ( ) => searchOptions ,
} ,
) ;
2023-06-20 00:43:36 +05:30
findHeaderSearchInput ( ) . vm . $emit ( showDropdown ? 'focusin' : '' ) ;
2022-01-26 12:08:38 +05:30
} ) ;
it ( ` sets description to ${ expectedDesc } ` , ( ) => {
expect ( findSearchResultsDescription ( ) . text ( ) ) . toBe ( expectedDesc ) ;
} ) ;
} ) ;
} ,
) ;
2022-08-13 15:12:31 +05:30
describe ( 'input box' , ( ) => {
describe . each `
search | searchOptions | hasToken
$ { MOCK _SEARCH } | $ { [ MOCK _SCOPED _SEARCH _OPTIONS [ 0 ] ] } | $ { true }
$ { MOCK _SEARCH } | $ { [ MOCK _SCOPED _SEARCH _OPTIONS [ 1 ] ] } | $ { true }
$ { MOCK _SEARCH } | $ { [ MOCK _SCOPED _SEARCH _OPTIONS [ 2 ] ] } | $ { true }
$ { MOCK _SEARCH } | $ { [ MOCK _SCOPED _SEARCH _OPTIONS [ 3 ] ] } | $ { true }
$ { MOCK _SEARCH } | $ { [ MOCK _SCOPED _SEARCH _OPTIONS [ 4 ] ] } | $ { true }
$ { 'te' } | $ { [ MOCK _SCOPED _SEARCH _OPTIONS [ 5 ] ] } | $ { false }
$ { 'x' } | $ { [ ] } | $ { false }
` ('token', ({ search, searchOptions, hasToken }) => {
beforeEach ( ( ) => {
window . gon . current _username = MOCK _USERNAME ;
createComponent (
{ search } ,
{
searchOptions : ( ) => searchOptions ,
} ,
) ;
2023-06-20 00:43:36 +05:30
findHeaderSearchInput ( ) . vm . $emit ( 'focusin' ) ;
2022-08-13 15:12:31 +05:30
} ) ;
it ( ` ${ hasToken ? 'is' : 'is NOT' } rendered when data set has type " ${
searchOptions [ 0 ] ? . html _id
} " ` , () => {
expect ( findScopeToken ( ) . exists ( ) ) . toBe ( hasToken ) ;
} ) ;
it ( ` text ${ hasToken ? 'is correctly' : 'is NOT' } rendered when text is " ${
searchOptions [ 0 ] ? . scope || searchOptions [ 0 ] ? . description
} " ` , () => {
expect ( findScopeToken ( ) . exists ( ) && findScopeToken ( ) . text ( ) ) . toBe (
formatScopeName ( searchOptions [ 0 ] ? . scope || searchOptions [ 0 ] ? . description ) ,
) ;
} ) ;
} ) ;
} ) ;
2022-08-27 11:52:29 +05:30
describe ( 'form' , ( ) => {
2022-08-13 15:12:31 +05:30
describe . each `
2022-08-27 11:52:29 +05:30
searchContext | search | searchOptions | isFocused
$ { MOCK _SEARCH _CONTEXT _FULL } | $ { null } | $ { [ ] } | $ { true }
$ { MOCK _SEARCH _CONTEXT _FULL } | $ { MOCK _SEARCH } | $ { [ ] } | $ { true }
$ { MOCK _SEARCH _CONTEXT _FULL } | $ { MOCK _SEARCH } | $ { MOCK _SCOPED _SEARCH _OPTIONS } | $ { true }
$ { MOCK _SEARCH _CONTEXT _FULL } | $ { MOCK _SEARCH } | $ { MOCK _SCOPED _SEARCH _OPTIONS } | $ { false }
$ { null } | $ { MOCK _SEARCH } | $ { MOCK _SCOPED _SEARCH _OPTIONS } | $ { true }
$ { null } | $ { null } | $ { MOCK _SCOPED _SEARCH _OPTIONS } | $ { true }
$ { null } | $ { null } | $ { [ ] } | $ { true }
` ('wrapper', ({ searchContext, search, searchOptions, isFocused }) => {
2022-08-13 15:12:31 +05:30
beforeEach ( ( ) => {
window . gon . current _username = MOCK _USERNAME ;
createComponent ( { search , searchContext } , { searchOptions : ( ) => searchOptions } ) ;
2022-08-27 11:52:29 +05:30
if ( isFocused ) {
2023-06-20 00:43:36 +05:30
findHeaderSearchInput ( ) . vm . $emit ( 'focusin' ) ;
2022-08-27 11:52:29 +05:30
}
2022-08-13 15:12:31 +05:30
} ) ;
2022-08-27 11:52:29 +05:30
const isSearching = search ? . length > SEARCH _SHORTCUTS _MIN _CHARACTERS ;
2022-08-13 15:12:31 +05:30
2022-08-27 11:52:29 +05:30
it ( ` classes ${ isSearching ? 'contain' : 'do not contain' } " ${ IS _SEARCHING } " ` , ( ) => {
if ( isSearching ) {
expect ( findHeaderSearchForm ( ) . classes ( ) ) . toContain ( IS _SEARCHING ) ;
return ;
}
if ( ! isSearching ) {
expect ( findHeaderSearchForm ( ) . classes ( ) ) . not . toContain ( IS _SEARCHING ) ;
}
2022-08-13 15:12:31 +05:30
} ) ;
2022-08-27 11:52:29 +05:30
it ( ` classes ${ isSearching ? 'contain' : 'do not contain' } " ${
isFocused ? IS _FOCUSED : IS _NOT _FOCUSED
2022-08-13 15:12:31 +05:30
} " ` , () => {
2022-08-27 11:52:29 +05:30
expect ( findHeaderSearchForm ( ) . classes ( ) ) . toContain (
isFocused ? IS _FOCUSED : IS _NOT _FOCUSED ,
) ;
2022-08-13 15:12:31 +05:30
} ) ;
} ) ;
} ) ;
describe . each `
search | searchOptions | hasIcon | iconName
$ { MOCK _SEARCH } | $ { [ MOCK _SCOPED _SEARCH _OPTIONS [ 0 ] ] } | $ { true } | $ { ICON _PROJECT }
$ { MOCK _SEARCH } | $ { [ MOCK _SCOPED _SEARCH _OPTIONS [ 2 ] ] } | $ { true } | $ { ICON _GROUP }
$ { MOCK _SEARCH } | $ { [ MOCK _SCOPED _SEARCH _OPTIONS [ 3 ] ] } | $ { true } | $ { ICON _SUBGROUP }
$ { MOCK _SEARCH } | $ { [ MOCK _SCOPED _SEARCH _OPTIONS [ 4 ] ] } | $ { false } | $ { false }
` ('token', ({ search, searchOptions, hasIcon, iconName }) => {
beforeEach ( ( ) => {
window . gon . current _username = MOCK _USERNAME ;
createComponent (
{ search } ,
{
searchOptions : ( ) => searchOptions ,
} ,
) ;
2023-06-20 00:43:36 +05:30
findHeaderSearchInput ( ) . vm . $emit ( 'focusin' ) ;
2022-08-13 15:12:31 +05:30
} ) ;
it ( ` icon for data set type " ${ searchOptions [ 0 ] ? . html _id } " ${
hasIcon ? 'is' : 'is NOT'
} rendered ` , () => {
expect ( findScopeToken ( ) . findComponent ( GlIcon ) . exists ( ) ) . toBe ( hasIcon ) ;
} ) ;
it ( ` render ${ iconName ? ` " ${ iconName } " ` : 'NO' } icon for data set type " ${
searchOptions [ 0 ] ? . html _id
} " ` , () => {
expect (
findScopeToken ( ) . findComponent ( GlIcon ) . exists ( ) &&
findScopeToken ( ) . findComponent ( GlIcon ) . attributes ( 'name' ) ,
) . toBe ( iconName ) ;
} ) ;
} ) ;
2021-11-11 11:23:49 +05:30
} ) ;
describe ( 'events' , ( ) => {
describe ( 'Header Search Input' , ( ) => {
2023-06-20 00:43:36 +05:30
beforeEach ( ( ) => {
window . gon . current _username = MOCK _USERNAME ;
createComponent ( ) ;
} ) ;
2021-11-11 11:23:49 +05:30
describe ( 'when dropdown is closed' , ( ) => {
2022-11-25 23:54:43 +05:30
let trackingSpy ;
beforeEach ( ( ) => {
trackingSpy = mockTracking ( undefined , wrapper . element , jest . spyOn ) ;
} ) ;
2023-06-20 00:43:36 +05:30
it ( 'onFocusin opens dropdown and triggers snowplow event' , async ( ) => {
2021-11-11 11:23:49 +05:30
expect ( findHeaderSearchDropdown ( ) . exists ( ) ) . toBe ( false ) ;
2023-06-20 00:43:36 +05:30
findHeaderSearchInput ( ) . vm . $emit ( 'focusin' ) ;
2021-11-11 11:23:49 +05:30
2022-04-04 11:22:00 +05:30
await nextTick ( ) ;
2021-11-11 11:23:49 +05:30
expect ( findHeaderSearchDropdown ( ) . exists ( ) ) . toBe ( true ) ;
2022-11-25 23:54:43 +05:30
expect ( trackingSpy ) . toHaveBeenCalledWith ( undefined , 'focus_input' , {
label : 'global_search' ,
2023-04-23 21:23:45 +05:30
property : 'navigation_top' ,
2022-11-25 23:54:43 +05:30
} ) ;
2021-11-11 11:23:49 +05:30
} ) ;
2023-06-20 00:43:36 +05:30
it ( 'onFocusout closes dropdown and triggers snowplow event' , async ( ) => {
2021-11-11 11:23:49 +05:30
expect ( findHeaderSearchDropdown ( ) . exists ( ) ) . toBe ( false ) ;
2023-06-20 00:43:36 +05:30
findHeaderSearchInput ( ) . vm . $emit ( 'focusout' ) ;
jest . runAllTimers ( ) ;
2022-04-04 11:22:00 +05:30
await nextTick ( ) ;
2021-11-11 11:23:49 +05:30
2023-06-20 00:43:36 +05:30
expect ( findHeaderSearchDropdown ( ) . exists ( ) ) . toBe ( false ) ;
expect ( trackingSpy ) . toHaveBeenCalledWith ( undefined , 'blur_input' , {
2022-11-25 23:54:43 +05:30
label : 'global_search' ,
2023-04-23 21:23:45 +05:30
property : 'navigation_top' ,
2022-11-25 23:54:43 +05:30
} ) ;
} ) ;
2021-11-11 11:23:49 +05:30
} ) ;
2022-01-26 12:08:38 +05:30
describe ( 'onInput' , ( ) => {
describe ( 'when search has text' , ( ) => {
beforeEach ( ( ) => {
findHeaderSearchInput ( ) . vm . $emit ( 'input' , MOCK _SEARCH ) ;
} ) ;
it ( 'calls setSearch with search term' , ( ) => {
expect ( actionSpies . setSearch ) . toHaveBeenCalledWith ( expect . any ( Object ) , MOCK _SEARCH ) ;
} ) ;
it ( 'calls fetchAutocompleteOptions' , ( ) => {
expect ( actionSpies . fetchAutocompleteOptions ) . toHaveBeenCalled ( ) ;
} ) ;
it ( 'does not call clearAutocomplete' , ( ) => {
expect ( actionSpies . clearAutocomplete ) . not . toHaveBeenCalled ( ) ;
} ) ;
2021-11-11 11:23:49 +05:30
} ) ;
2022-01-26 12:08:38 +05:30
describe ( 'when search is emptied' , ( ) => {
beforeEach ( ( ) => {
findHeaderSearchInput ( ) . vm . $emit ( 'input' , '' ) ;
} ) ;
2021-11-11 11:23:49 +05:30
2022-01-26 12:08:38 +05:30
it ( 'calls setSearch with empty term' , ( ) => {
expect ( actionSpies . setSearch ) . toHaveBeenCalledWith ( expect . any ( Object ) , '' ) ;
} ) ;
2021-11-11 11:23:49 +05:30
2022-01-26 12:08:38 +05:30
it ( 'does not call fetchAutocompleteOptions' , ( ) => {
expect ( actionSpies . fetchAutocompleteOptions ) . not . toHaveBeenCalled ( ) ;
} ) ;
it ( 'calls clearAutocomplete' , ( ) => {
expect ( actionSpies . clearAutocomplete ) . toHaveBeenCalled ( ) ;
} ) ;
2021-11-11 11:23:49 +05:30
} ) ;
} ) ;
2022-01-26 12:08:38 +05:30
} ) ;
2021-11-11 11:23:49 +05:30
2023-06-20 00:43:36 +05:30
describe ( 'onFocusout dropdown' , ( ) => {
2022-01-26 12:08:38 +05:30
beforeEach ( ( ) => {
2023-06-20 00:43:36 +05:30
window . gon . current _username = MOCK _USERNAME ;
createComponent ( { search : 'tes' } , { } ) ;
findHeaderSearchInput ( ) . vm . $emit ( 'focusin' ) ;
2022-01-26 12:08:38 +05:30
} ) ;
2021-11-11 11:23:49 +05:30
2023-06-20 00:43:36 +05:30
it ( 'closes with timeout so click event gets emited' , ( ) => {
findHeaderSearchInput ( ) . vm . $emit ( 'focusout' ) ;
2022-01-26 12:08:38 +05:30
2023-06-20 00:43:36 +05:30
expect ( setTimeout ) . toHaveBeenCalledTimes ( 1 ) ;
expect ( setTimeout ) . toHaveBeenLastCalledWith ( expect . any ( Function ) , DROPDOWN _CLOSE _TIMEOUT ) ;
2022-01-26 12:08:38 +05:30
} ) ;
} ) ;
} ) ;
describe ( 'computed' , ( ) => {
2022-08-13 15:12:31 +05:30
describe . each `
MOCK _INDEX | search
$ { 1 } | $ { null }
$ { SEARCH _BOX _INDEX } | $ { 'test' }
$ { 2 } | $ { 'test1' }
` ('currentFocusedOption', ({ MOCK_INDEX, search }) => {
2022-01-26 12:08:38 +05:30
beforeEach ( ( ) => {
window . gon . current _username = MOCK _USERNAME ;
2023-05-27 22:25:52 +05:30
createComponent ( { search } ) ;
2023-06-20 00:43:36 +05:30
findHeaderSearchInput ( ) . vm . $emit ( 'focusin' ) ;
2022-01-26 12:08:38 +05:30
} ) ;
2022-08-13 15:12:31 +05:30
it ( ` when currentFocusIndex changes to ${ MOCK _INDEX } updates the data to searchOptions[ ${ MOCK _INDEX } ] ` , ( ) => {
2022-01-26 12:08:38 +05:30
findDropdownKeyboardNavigation ( ) . vm . $emit ( 'change' , MOCK _INDEX ) ;
expect ( wrapper . vm . currentFocusedOption ) . toBe ( MOCK _DEFAULT _SEARCH _OPTIONS [ MOCK _INDEX ] ) ;
2021-11-11 11:23:49 +05:30
} ) ;
2022-01-26 12:08:38 +05:30
} ) ;
} ) ;
2021-11-11 11:23:49 +05:30
2022-01-26 12:08:38 +05:30
describe ( 'Submitting a search' , ( ) => {
describe ( 'with no currentFocusedOption' , ( ) => {
beforeEach ( ( ) => {
createComponent ( ) ;
} ) ;
2022-08-13 15:12:31 +05:30
it ( 'onKey-enter submits a search' , ( ) => {
2021-11-11 11:23:49 +05:30
findHeaderSearchInput ( ) . vm . $emit ( 'keydown' , new KeyboardEvent ( { key : ENTER _KEY } ) ) ;
expect ( visitUrl ) . toHaveBeenCalledWith ( MOCK _SEARCH _QUERY ) ;
} ) ;
} ) ;
2022-01-26 12:08:38 +05:30
2022-08-13 15:12:31 +05:30
describe ( 'with less than min characters and no dropdown results' , ( ) => {
beforeEach ( ( ) => {
createComponent ( { search : 'x' } ) ;
} ) ;
it ( 'onKey-enter will NOT submit a search' , ( ) => {
findHeaderSearchInput ( ) . vm . $emit ( 'keydown' , new KeyboardEvent ( { key : ENTER _KEY } ) ) ;
expect ( visitUrl ) . not . toHaveBeenCalledWith ( MOCK _SEARCH _QUERY ) ;
} ) ;
} ) ;
2022-01-26 12:08:38 +05:30
describe ( 'with currentFocusedOption' , ( ) => {
const MOCK _INDEX = 1 ;
beforeEach ( ( ) => {
window . gon . current _username = MOCK _USERNAME ;
2023-05-27 22:25:52 +05:30
createComponent ( ) ;
2023-06-20 00:43:36 +05:30
findHeaderSearchInput ( ) . vm . $emit ( 'focusin' ) ;
2022-01-26 12:08:38 +05:30
} ) ;
2023-06-20 00:43:36 +05:30
it ( 'onKey-enter clicks the selected dropdown item rather than submitting a search' , async ( ) => {
await nextTick ( ) ;
2022-01-26 12:08:38 +05:30
findDropdownKeyboardNavigation ( ) . vm . $emit ( 'change' , MOCK _INDEX ) ;
2022-08-13 15:12:31 +05:30
2022-01-26 12:08:38 +05:30
findHeaderSearchInput ( ) . vm . $emit ( 'keydown' , new KeyboardEvent ( { key : ENTER _KEY } ) ) ;
expect ( visitUrl ) . toHaveBeenCalledWith ( MOCK _DEFAULT _SEARCH _OPTIONS [ MOCK _INDEX ] . url ) ;
} ) ;
} ) ;
2021-11-11 11:23:49 +05:30
} ) ;
} ) ;