diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-04-13 15:09:20 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-04-13 15:09:20 +0000 |
commit | b77fb04678a4e76d025048e9846adc2ac709414a (patch) | |
tree | c65f719e326e1d33d313b5e9d8b3f72366ad7bd2 /spec/frontend | |
parent | 75ee59f7a108cf0c57e1e66e3ef5e439bae24fcd (diff) | |
download | gitlab-ce-b77fb04678a4e76d025048e9846adc2ac709414a.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend')
4 files changed, 190 insertions, 64 deletions
diff --git a/spec/frontend/logs/components/environment_logs_spec.js b/spec/frontend/logs/components/environment_logs_spec.js index d097610cb0a..9046253bdc6 100644 --- a/spec/frontend/logs/components/environment_logs_spec.js +++ b/spec/frontend/logs/components/environment_logs_spec.js @@ -10,7 +10,6 @@ import { mockPods, mockLogsResult, mockTrace, - mockPodName, mockEnvironmentsEndpoint, mockDocumentationPath, } from '../mock_data'; @@ -302,11 +301,11 @@ describe('EnvironmentLogs', () => { }); it('refresh button, trace is refreshed', () => { - expect(dispatch).not.toHaveBeenCalledWith(`${module}/showPodLogs`, expect.anything()); + expect(dispatch).not.toHaveBeenCalledWith(`${module}/fetchLogs`, undefined); findLogControlButtons().vm.$emit('refresh'); - expect(dispatch).toHaveBeenCalledWith(`${module}/showPodLogs`, mockPodName); + expect(dispatch).toHaveBeenCalledWith(`${module}/fetchLogs`, undefined); }); }); }); diff --git a/spec/frontend/logs/components/log_advanced_filters_spec.js b/spec/frontend/logs/components/log_advanced_filters_spec.js index a6fbc40c2c6..adcd6b4fb07 100644 --- a/spec/frontend/logs/components/log_advanced_filters_spec.js +++ b/spec/frontend/logs/components/log_advanced_filters_spec.js @@ -1,8 +1,9 @@ -import { GlIcon, GlDropdownItem } from '@gitlab/ui'; import { shallowMount } from '@vue/test-utils'; import { defaultTimeRange } from '~/vue_shared/constants'; +import { GlFilteredSearch } from '@gitlab/ui'; import { convertToFixedRange } from '~/lib/utils/datetime_range'; import { createStore } from '~/logs/stores'; +import { TOKEN_TYPE_POD_NAME } from '~/logs/constants'; import { mockPods, mockSearch } from '../mock_data'; import LogAdvancedFilters from '~/logs/components/log_advanced_filters.vue'; @@ -15,26 +16,19 @@ describe('LogAdvancedFilters', () => { let wrapper; let state; - const findPodsDropdown = () => wrapper.find({ ref: 'podsDropdown' }); - const findPodsNoPodsText = () => wrapper.find({ ref: 'noPodsMsg' }); - const findPodsDropdownItems = () => - findPodsDropdown() - .findAll(GlDropdownItem) - .filter(item => !item.is('[disabled]')); - const findPodsDropdownItemsSelected = () => - findPodsDropdownItems() - .filter(item => { - return !item.find(GlIcon).classes('invisible'); - }) - .at(0); - const findSearchBox = () => wrapper.find({ ref: 'searchBox' }); + const findFilteredSearch = () => wrapper.find(GlFilteredSearch); const findTimeRangePicker = () => wrapper.find({ ref: 'dateTimePicker' }); + const getSearchToken = type => + findFilteredSearch() + .props('availableTokens') + .filter(token => token.type === type)[0]; const mockStateLoading = () => { state.timeRange.selected = defaultTimeRange; state.timeRange.current = convertToFixedRange(defaultTimeRange); state.pods.options = []; state.pods.current = null; + state.logs.isLoading = true; }; const mockStateWithData = () => { @@ -42,6 +36,7 @@ describe('LogAdvancedFilters', () => { state.timeRange.current = convertToFixedRange(defaultTimeRange); state.pods.options = mockPods; state.pods.current = null; + state.logs.isLoading = false; }; const initWrapper = (propsData = {}) => { @@ -76,11 +71,18 @@ describe('LogAdvancedFilters', () => { expect(wrapper.isVueInstance()).toBe(true); expect(wrapper.isEmpty()).toBe(false); - expect(findPodsDropdown().exists()).toBe(true); - expect(findSearchBox().exists()).toBe(true); + expect(findFilteredSearch().exists()).toBe(true); expect(findTimeRangePicker().exists()).toBe(true); }); + it('displays search tokens', () => { + expect(getSearchToken(TOKEN_TYPE_POD_NAME)).toMatchObject({ + title: 'Pod name', + unique: true, + operators: [expect.objectContaining({ value: '=' })], + }); + }); + describe('disabled state', () => { beforeEach(() => { mockStateLoading(); @@ -90,9 +92,7 @@ describe('LogAdvancedFilters', () => { }); it('displays disabled filters', () => { - expect(findPodsDropdown().props('text')).toBe('All pods'); - expect(findPodsDropdown().attributes('disabled')).toBeTruthy(); - expect(findSearchBox().attributes('disabled')).toBeTruthy(); + expect(findFilteredSearch().attributes('disabled')).toBeTruthy(); expect(findTimeRangePicker().attributes('disabled')).toBeTruthy(); }); }); @@ -103,16 +103,17 @@ describe('LogAdvancedFilters', () => { initWrapper(); }); - it('displays a enabled filters', () => { - expect(findPodsDropdown().props('text')).toBe('All pods'); - expect(findPodsDropdown().attributes('disabled')).toBeFalsy(); - expect(findSearchBox().attributes('disabled')).toBeFalsy(); + it('displays a disabled search', () => { + expect(findFilteredSearch().attributes('disabled')).toBeTruthy(); + }); + + it('displays an enable date filter', () => { expect(findTimeRangePicker().attributes('disabled')).toBeFalsy(); }); - it('displays an empty pods dropdown', () => { - expect(findPodsNoPodsText().exists()).toBe(true); - expect(findPodsDropdownItems()).toHaveLength(0); + it('displays no pod options when no pods are available, so suggestions can be displayed', () => { + expect(getSearchToken(TOKEN_TYPE_POD_NAME).options).toBe(null); + expect(getSearchToken(TOKEN_TYPE_POD_NAME).loading).toBe(true); }); }); @@ -122,20 +123,24 @@ describe('LogAdvancedFilters', () => { initWrapper(); }); - it('displays an enabled pods dropdown', () => { - expect(findPodsDropdown().attributes('disabled')).toBeFalsy(); - expect(findPodsDropdown().props('text')).toBe('All pods'); + it('displays a single token for pods', () => { + initWrapper(); + + const tokens = findFilteredSearch().props('availableTokens'); + + expect(tokens).toHaveLength(1); + expect(tokens[0].type).toBe(TOKEN_TYPE_POD_NAME); }); - it('displays options in a pods dropdown', () => { - const items = findPodsDropdownItems(); - expect(items).toHaveLength(mockPods.length + 1); + it('displays a enabled filters', () => { + expect(findFilteredSearch().attributes('disabled')).toBeFalsy(); + expect(findTimeRangePicker().attributes('disabled')).toBeFalsy(); }); - it('displays "all pods" selected in a pods dropdown', () => { - const selected = findPodsDropdownItemsSelected(); + it('displays options in the pods token', () => { + const { options } = getSearchToken(TOKEN_TYPE_POD_NAME); - expect(selected.text()).toBe('All pods'); + expect(options).toHaveLength(mockPods.length); }); it('displays options in date time picker', () => { @@ -146,30 +151,16 @@ describe('LogAdvancedFilters', () => { }); describe('when the user interacts', () => { - it('clicks on a all options, showPodLogs is dispatched with null', () => { - const items = findPodsDropdownItems(); - items.at(0).vm.$emit('click'); - - expect(dispatch).toHaveBeenCalledWith(`${module}/showPodLogs`, null); - }); - - it('clicks on a pod name, showPodLogs is dispatched with pod name', () => { - const items = findPodsDropdownItems(); - const index = 2; // any pod + it('clicks on the search button, showFilteredLogs is dispatched', () => { + findFilteredSearch().vm.$emit('submit', null); - items.at(index + 1).vm.$emit('click'); // skip "All pods" option - - expect(dispatch).toHaveBeenCalledWith(`${module}/showPodLogs`, mockPods[index]); + expect(dispatch).toHaveBeenCalledWith(`${module}/showFilteredLogs`, null); }); - it('clicks on search, a serches is done', () => { - expect(findSearchBox().attributes('disabled')).toBeFalsy(); - - // input a query and click `search` - findSearchBox().vm.$emit('input', mockSearch); - findSearchBox().vm.$emit('submit'); + it('clicks on the search button, showFilteredLogs is dispatched with null', () => { + findFilteredSearch().vm.$emit('submit', [mockSearch]); - expect(dispatch).toHaveBeenCalledWith(`${module}/setSearch`, mockSearch); + expect(dispatch).toHaveBeenCalledWith(`${module}/showFilteredLogs`, [mockSearch]); }); it('selects a new time range', () => { diff --git a/spec/frontend/logs/components/tokens/token_with_loading_state_spec.js b/spec/frontend/logs/components/tokens/token_with_loading_state_spec.js new file mode 100644 index 00000000000..d98d7d05c92 --- /dev/null +++ b/spec/frontend/logs/components/tokens/token_with_loading_state_spec.js @@ -0,0 +1,68 @@ +import { GlFilteredSearchToken, GlLoadingIcon } from '@gitlab/ui'; +import { shallowMount } from '@vue/test-utils'; + +import TokenWithLoadingState from '~/logs/components/tokens/token_with_loading_state.vue'; + +describe('TokenWithLoadingState', () => { + let wrapper; + + const findFilteredSearchToken = () => wrapper.find(GlFilteredSearchToken); + const findLoadingIcon = () => wrapper.find(GlLoadingIcon); + + const initWrapper = (props = {}, options) => { + wrapper = shallowMount(TokenWithLoadingState, { + propsData: props, + ...options, + }); + }; + + beforeEach(() => {}); + + it('passes entire config correctly', () => { + const config = { + icon: 'pod', + type: 'pod', + title: 'Pod name', + unique: true, + }; + + initWrapper({ config }); + + expect(findFilteredSearchToken().props('config')).toEqual(config); + }); + + describe('suggestions are replaced', () => { + let mockNoOptsText; + let config; + let stubs; + + beforeEach(() => { + mockNoOptsText = 'No suggestions available'; + config = { + loading: false, + noOptionsText: mockNoOptsText, + }; + stubs = { + GlFilteredSearchToken: { + template: `<div><slot name="suggestions"></slot></div>`, + }, + }; + }); + + it('renders a loading icon', () => { + config.loading = true; + + initWrapper({ config }, { stubs }); + + expect(findLoadingIcon().exists()).toBe(true); + expect(wrapper.text()).toBe(''); + }); + + it('renders an empty results message', () => { + initWrapper({ config }, { stubs }); + + expect(findLoadingIcon().exists()).toBe(false); + expect(wrapper.text()).toBe(mockNoOptsText); + }); + }); +}); diff --git a/spec/frontend/logs/stores/actions_spec.js b/spec/frontend/logs/stores/actions_spec.js index 882673af984..6199c400e16 100644 --- a/spec/frontend/logs/stores/actions_spec.js +++ b/spec/frontend/logs/stores/actions_spec.js @@ -6,7 +6,7 @@ import { convertToFixedRange } from '~/lib/utils/datetime_range'; import logsPageState from '~/logs/stores/state'; import { setInitData, - setSearch, + showFilteredLogs, showPodLogs, fetchEnvironments, fetchLogs, @@ -31,6 +31,7 @@ import { mockCursor, mockNextCursor, } from '../mock_data'; +import { TOKEN_TYPE_POD_NAME } from '~/logs/constants'; jest.mock('~/flash'); jest.mock('~/lib/utils/datetime_range'); @@ -93,13 +94,80 @@ describe('Logs Store actions', () => { )); }); - describe('setSearch', () => { - it('should commit search mutation', () => + describe('showFilteredLogs', () => { + it('empty search should filter with defaults', () => testAction( - setSearch, - mockSearch, + showFilteredLogs, + undefined, state, - [{ type: types.SET_SEARCH, payload: mockSearch }], + [ + { type: types.SET_CURRENT_POD_NAME, payload: null }, + { type: types.SET_SEARCH, payload: '' }, + ], + [{ type: 'fetchLogs' }], + )); + + it('text search should filter with a search term', () => + testAction( + showFilteredLogs, + [mockSearch], + state, + [ + { type: types.SET_CURRENT_POD_NAME, payload: null }, + { type: types.SET_SEARCH, payload: mockSearch }, + ], + [{ type: 'fetchLogs' }], + )); + + it('pod search should filter with a search term', () => + testAction( + showFilteredLogs, + [{ type: TOKEN_TYPE_POD_NAME, value: { data: mockPodName, operator: '=' } }], + state, + [ + { type: types.SET_CURRENT_POD_NAME, payload: mockPodName }, + { type: types.SET_SEARCH, payload: '' }, + ], + [{ type: 'fetchLogs' }], + )); + + it('pod search should filter with a pod selection and a search term', () => + testAction( + showFilteredLogs, + [{ type: TOKEN_TYPE_POD_NAME, value: { data: mockPodName, operator: '=' } }, mockSearch], + state, + [ + { type: types.SET_CURRENT_POD_NAME, payload: mockPodName }, + { type: types.SET_SEARCH, payload: mockSearch }, + ], + [{ type: 'fetchLogs' }], + )); + + it('pod search should filter with a pod selection and two search terms', () => + testAction( + showFilteredLogs, + ['term1', 'term2'], + state, + [ + { type: types.SET_CURRENT_POD_NAME, payload: null }, + { type: types.SET_SEARCH, payload: `term1 term2` }, + ], + [{ type: 'fetchLogs' }], + )); + + it('pod search should filter with a pod selection and a search terms before and after', () => + testAction( + showFilteredLogs, + [ + 'term1', + { type: TOKEN_TYPE_POD_NAME, value: { data: mockPodName, operator: '=' } }, + 'term2', + ], + state, + [ + { type: types.SET_CURRENT_POD_NAME, payload: mockPodName }, + { type: types.SET_SEARCH, payload: `term1 term2` }, + ], [{ type: 'fetchLogs' }], )); }); |