diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-04-12 12:08:27 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-04-12 12:08:27 +0000 |
commit | e0d7577e29dcab90623e1f38cf11b351c665ee23 (patch) | |
tree | 5a34f26be66301f1af9e36b10a67dfca01fed8ec /spec/frontend | |
parent | 60e7627c998b74d48df10b9a7759d6038a1f139c (diff) | |
download | gitlab-ce-e0d7577e29dcab90623e1f38cf11b351c665ee23.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend')
19 files changed, 200 insertions, 132 deletions
diff --git a/spec/frontend/__helpers__/assert_props.js b/spec/frontend/__helpers__/assert_props.js new file mode 100644 index 00000000000..3e372454bf5 --- /dev/null +++ b/spec/frontend/__helpers__/assert_props.js @@ -0,0 +1,24 @@ +import { mount } from '@vue/test-utils'; +import { ErrorWithStack } from 'jest-util'; + +export function assertProps(Component, props, extraMountArgs = {}) { + const originalConsoleError = global.console.error; + global.console.error = function error(...args) { + throw new ErrorWithStack( + `Unexpected call of console.error() with:\n\n${args.join(', ')}`, + this.error, + ); + }; + const ComponentWithoutRenderFn = { + ...Component, + render() { + return ''; + }, + }; + + try { + mount(ComponentWithoutRenderFn, { propsData: props, ...extraMountArgs }); + } finally { + global.console.error = originalConsoleError; + } +} diff --git a/spec/frontend/blob/sketch/index_spec.js b/spec/frontend/blob/sketch/index_spec.js index 4b6cb79791c..64b6152a07d 100644 --- a/spec/frontend/blob/sketch/index_spec.js +++ b/spec/frontend/blob/sketch/index_spec.js @@ -1,10 +1,11 @@ import SketchLoader from '~/blob/sketch'; -import { loadHTMLFixture, resetHTMLFixture } from 'helpers/fixtures'; +import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures'; import waitForPromises from 'helpers/wait_for_promises'; +import htmlSketchViewer from 'test_fixtures_static/sketch_viewer.html'; describe('Sketch viewer', () => { beforeEach(() => { - loadHTMLFixture('static/sketch_viewer.html'); + setHTMLFixture(htmlSketchViewer); }); afterEach(() => { diff --git a/spec/frontend/ci/ci_variable_list/components/ci_variable_shared_spec.js b/spec/frontend/ci/ci_variable_list/components/ci_variable_shared_spec.js index 4107b08e9a4..c7bcace3883 100644 --- a/spec/frontend/ci/ci_variable_list/components/ci_variable_shared_spec.js +++ b/spec/frontend/ci/ci_variable_list/components/ci_variable_shared_spec.js @@ -2,6 +2,7 @@ import Vue from 'vue'; import VueApollo from 'vue-apollo'; import { GlLoadingIcon, GlTable } from '@gitlab/ui'; import { shallowMount } from '@vue/test-utils'; +import { assertProps } from 'helpers/assert_props'; import createMockApollo from 'helpers/mock_apollo_helper'; import waitForPromises from 'helpers/wait_for_promises'; import { createAlert } from '~/alert'; @@ -593,19 +594,14 @@ describe('Ci Variable Shared Component', () => { } }); - it('will not mount component with wrong data', async () => { - try { - await createComponentWithApollo({ - customHandlers: [[getGroupVariables, mockVariables]], - props: { ...createGroupProps(), queryData: { wrongKey: {} } }, - provide: pagesFeatureFlagProvide, - }); - } catch (e) { - error = e; - } finally { - expect(wrapper.exists()).toBe(false); - expect(error.toString()).toContain('custom validator check failed for prop'); - } + it('report custom validator error on wrong data', () => { + expect(() => + assertProps( + ciVariableShared, + { ...defaultProps, ...createGroupProps(), queryData: { wrongKey: {} } }, + { provide: mockProvide }, + ), + ).toThrow('custom validator check failed for prop'); }); }); @@ -630,18 +626,14 @@ describe('Ci Variable Shared Component', () => { } }); - it('will not mount component with wrong data', async () => { - try { - await createComponentWithApollo({ - props: { ...createGroupProps(), mutationData: { wrongKey: {} } }, - provide: pagesFeatureFlagProvide, - }); - } catch (e) { - error = e; - } finally { - expect(wrapper.exists()).toBe(false); - expect(error.toString()).toContain('custom validator check failed for prop'); - } + it('report custom validator error on wrong data', async () => { + expect(() => + assertProps( + ciVariableShared, + { ...defaultProps, ...createGroupProps(), mutationData: { wrongKey: {} } }, + { provide: { ...mockProvide, ...pagesFeatureFlagProvide } }, + ), + ).toThrow('custom validator check failed for prop'); }); }); }); diff --git a/spec/frontend/ci/runner/components/runner_filtered_search_bar_spec.js b/spec/frontend/ci/runner/components/runner_filtered_search_bar_spec.js index ac84c7898bf..7572122a5f3 100644 --- a/spec/frontend/ci/runner/components/runner_filtered_search_bar_spec.js +++ b/spec/frontend/ci/runner/components/runner_filtered_search_bar_spec.js @@ -1,5 +1,6 @@ import { GlFilteredSearch, GlDropdown, GlDropdownItem } from '@gitlab/ui'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; +import { assertProps } from 'helpers/assert_props'; import RunnerFilteredSearchBar from '~/ci/runner/components/runner_filtered_search_bar.vue'; import { statusTokenConfig } from '~/ci/runner/components/search_tokens/status_token_config'; import TagToken from '~/ci/runner/components/search_tokens/tag_token.vue'; @@ -43,12 +44,12 @@ describe('RunnerList', () => { expect(inputs[inputs.length - 1][0]).toEqual(value); }; + const defaultProps = { namespace: 'runners', tokens: [], value: mockSearch }; + const createComponent = ({ props = {}, options = {} } = {}) => { wrapper = shallowMountExtended(RunnerFilteredSearchBar, { propsData: { - namespace: 'runners', - tokens: [], - value: mockSearch, + ...defaultProps, ...props, }, stubs: { @@ -109,11 +110,14 @@ describe('RunnerList', () => { it('fails validation for v-model with the wrong shape', () => { expect(() => { - createComponent({ props: { value: { filters: 'wrong_filters', sort: 'sort' } } }); + assertProps(RunnerFilteredSearchBar, { + ...defaultProps, + value: { filters: 'wrong_filters', sort: 'sort' }, + }); }).toThrow('Invalid prop: custom validator check failed'); expect(() => { - createComponent({ props: { value: { sort: 'sort' } } }); + assertProps(RunnerFilteredSearchBar, { ...defaultProps, value: { sort: 'sort' } }); }).toThrow('Invalid prop: custom validator check failed'); }); diff --git a/spec/frontend/ci/runner/components/runner_type_badge_spec.js b/spec/frontend/ci/runner/components/runner_type_badge_spec.js index 7a0fb6f69ea..f7ecd108967 100644 --- a/spec/frontend/ci/runner/components/runner_type_badge_spec.js +++ b/spec/frontend/ci/runner/components/runner_type_badge_spec.js @@ -2,6 +2,7 @@ import { GlBadge } from '@gitlab/ui'; import { shallowMount } from '@vue/test-utils'; import RunnerTypeBadge from '~/ci/runner/components/runner_type_badge.vue'; import { createMockDirective, getBinding } from 'helpers/vue_mock_directive'; +import { assertProps } from 'helpers/assert_props'; import { INSTANCE_TYPE, GROUP_TYPE, @@ -50,7 +51,7 @@ describe('RunnerTypeBadge', () => { it('validation fails for an incorrect type', () => { expect(() => { - createComponent({ props: { type: 'AN_UNKNOWN_VALUE' } }); + assertProps(RunnerTypeBadge, { type: 'AN_UNKNOWN_VALUE' }); }).toThrow(); }); diff --git a/spec/frontend/diffs/components/app_spec.js b/spec/frontend/diffs/components/app_spec.js index 545ba4a0e04..ab01c3e528e 100644 --- a/spec/frontend/diffs/components/app_spec.js +++ b/spec/frontend/diffs/components/app_spec.js @@ -715,19 +715,27 @@ describe('diffs/components/app', () => { }); it.each` - currentDiffFileId | targetFile - ${'123'} | ${2} - ${'312'} | ${1} + currentDiffFileId | targetFile | newFileByFile + ${'123'} | ${2} | ${false} + ${'312'} | ${1} | ${true} `( 'calls navigateToDiffFileIndex with $index when $link is clicked', - async ({ currentDiffFileId, targetFile }) => { - createComponent({ fileByFileUserPreference: true }, ({ state }) => { - state.diffs.treeEntries = { - 123: { type: 'blob', fileHash: '123' }, - 312: { type: 'blob', fileHash: '312' }, - }; - state.diffs.currentDiffFileId = currentDiffFileId; - }); + async ({ currentDiffFileId, targetFile, newFileByFile }) => { + createComponent( + { fileByFileUserPreference: true }, + ({ state }) => { + state.diffs.treeEntries = { + 123: { type: 'blob', fileHash: '123', filePaths: { old: '1234', new: '123' } }, + 312: { type: 'blob', fileHash: '312', filePaths: { old: '3124', new: '312' } }, + }; + state.diffs.currentDiffFileId = currentDiffFileId; + }, + { + glFeatures: { + singleFileFileByFile: newFileByFile, + }, + }, + ); await nextTick(); @@ -737,7 +745,10 @@ describe('diffs/components/app', () => { await nextTick(); - expect(wrapper.vm.navigateToDiffFileIndex).toHaveBeenCalledWith(targetFile - 1); + expect(wrapper.vm.navigateToDiffFileIndex).toHaveBeenCalledWith({ + index: targetFile - 1, + singleFile: newFileByFile, + }); }, ); }); diff --git a/spec/frontend/diffs/store/actions_spec.js b/spec/frontend/diffs/store/actions_spec.js index b988472f947..f3581c3dd74 100644 --- a/spec/frontend/diffs/store/actions_spec.js +++ b/spec/frontend/diffs/store/actions_spec.js @@ -1026,50 +1026,67 @@ describe('DiffsStoreActions', () => { }); describe('when the app is in fileByFile mode', () => { - it('commits SET_CURRENT_DIFF_FILE', () => { - diffActions.goToFile({ state, commit, dispatch, getters }, file); + describe('when the singleFileFileByFile feature flag is enabled', () => { + it('commits SET_CURRENT_DIFF_FILE', () => { + diffActions.goToFile( + { state, commit, dispatch, getters }, + { path: file.path, singleFile: true }, + ); - expect(commit).toHaveBeenCalledWith(types.SET_CURRENT_DIFF_FILE, fileHash); - }); + expect(commit).toHaveBeenCalledWith(types.SET_CURRENT_DIFF_FILE, fileHash); + }); - it('does nothing more if the path has already been loaded', () => { - getters.isTreePathLoaded = () => true; + it('does nothing more if the path has already been loaded', () => { + getters.isTreePathLoaded = () => true; - diffActions.goToFile({ state, dispatch, getters, commit }, file); + diffActions.goToFile( + { state, dispatch, getters, commit }, + { path: file.path, singleFile: true }, + ); - expect(commit).toHaveBeenCalledWith(types.SET_CURRENT_DIFF_FILE, fileHash); - expect(dispatch).toHaveBeenCalledTimes(0); - }); + expect(commit).toHaveBeenCalledWith(types.SET_CURRENT_DIFF_FILE, fileHash); + expect(dispatch).toHaveBeenCalledTimes(0); + }); - describe('when the tree entry has not been loaded', () => { - it('updates location hash', () => { - diffActions.goToFile({ state, commit, getters, dispatch }, file); + describe('when the tree entry has not been loaded', () => { + it('updates location hash', () => { + diffActions.goToFile( + { state, commit, getters, dispatch }, + { path: file.path, singleFile: true }, + ); - expect(document.location.hash).toBe('#test'); - }); + expect(document.location.hash).toBe('#test'); + }); - it('loads the file and then scrolls to it', async () => { - diffActions.goToFile({ state, commit, getters, dispatch }, file); + it('loads the file and then scrolls to it', async () => { + diffActions.goToFile( + { state, commit, getters, dispatch }, + { path: file.path, singleFile: true }, + ); - // Wait for the fetchFileByFile dispatch to return, to trigger scrollToFile - await waitForPromises(); + // Wait for the fetchFileByFile dispatch to return, to trigger scrollToFile + await waitForPromises(); - expect(dispatch).toHaveBeenCalledWith('fetchFileByFile'); - expect(dispatch).toHaveBeenCalledWith('scrollToFile', file); - expect(dispatch).toHaveBeenCalledTimes(2); - }); + expect(dispatch).toHaveBeenCalledWith('fetchFileByFile'); + expect(dispatch).toHaveBeenCalledWith('scrollToFile', file); + expect(dispatch).toHaveBeenCalledTimes(2); + }); - it('shows an alert when there was an error fetching the file', async () => { - dispatch = jest.fn().mockRejectedValue(); + it('shows an alert when there was an error fetching the file', async () => { + dispatch = jest.fn().mockRejectedValue(); - diffActions.goToFile({ state, commit, getters, dispatch }, file); + diffActions.goToFile( + { state, commit, getters, dispatch }, + { path: file.path, singleFile: true }, + ); - // Wait for the fetchFileByFile dispatch to return, to trigger the catch - await waitForPromises(); + // Wait for the fetchFileByFile dispatch to return, to trigger the catch + await waitForPromises(); - expect(createAlert).toHaveBeenCalledTimes(1); - expect(createAlert).toHaveBeenCalledWith({ - message: expect.stringMatching(LOAD_SINGLE_DIFF_FAILED), + expect(createAlert).toHaveBeenCalledTimes(1); + expect(createAlert).toHaveBeenCalledWith({ + message: expect.stringMatching(LOAD_SINGLE_DIFF_FAILED), + }); }); }); }); @@ -1690,12 +1707,22 @@ describe('DiffsStoreActions', () => { it('commits SET_CURRENT_DIFF_FILE', () => { return testAction( diffActions.navigateToDiffFileIndex, - 0, + { index: 0, singleFile: false }, { flatBlobsList: [{ fileHash: '123' }] }, [{ type: types.SET_CURRENT_DIFF_FILE, payload: '123' }], [], ); }); + + it('dispatches the fetchFileByFile action when the state value viewDiffsFileByFile is true and the single-file file-by-file feature flag is enabled', () => { + return testAction( + diffActions.navigateToDiffFileIndex, + { index: 0, singleFile: true }, + { viewDiffsFileByFile: true, flatBlobsList: [{ fileHash: '123' }] }, + [{ type: types.SET_CURRENT_DIFF_FILE, payload: '123' }], + [{ type: 'fetchFileByFile' }], + ); + }); }); describe('setFileByFile', () => { diff --git a/spec/frontend/environment.js b/spec/frontend/environment.js index 7b160c48501..4e341b2bb2f 100644 --- a/spec/frontend/environment.js +++ b/spec/frontend/environment.js @@ -21,8 +21,17 @@ class CustomEnvironment extends TestEnvironment { // https://gitlab.com/gitlab-org/gitlab/-/merge_requests/39496#note_503084332 setGlobalDateToFakeDate(); + const { error: originalErrorFn } = context.console; Object.assign(context.console, { error(...args) { + if ( + args?.[0]?.includes('[Vue warn]: Missing required prop') || + args?.[0]?.includes('[Vue warn]: Invalid prop') + ) { + originalErrorFn.apply(context.console, args); + return; + } + throw new ErrorWithStack( `Unexpected call of console.error() with:\n\n${args.join(', ')}`, this.error, @@ -30,7 +39,7 @@ class CustomEnvironment extends TestEnvironment { }, warn(...args) { - if (args[0].includes('The updateQuery callback for fetchMore is deprecated')) { + if (args?.[0]?.includes('The updateQuery callback for fetchMore is deprecated')) { return; } throw new ErrorWithStack( diff --git a/spec/frontend/monitoring/pages/dashboard_page_spec.js b/spec/frontend/monitoring/pages/dashboard_page_spec.js index c5a8b50ee60..3de99673e71 100644 --- a/spec/frontend/monitoring/pages/dashboard_page_spec.js +++ b/spec/frontend/monitoring/pages/dashboard_page_spec.js @@ -2,6 +2,7 @@ import { shallowMount } from '@vue/test-utils'; import Dashboard from '~/monitoring/components/dashboard.vue'; import DashboardPage from '~/monitoring/pages/dashboard_page.vue'; import { createStore } from '~/monitoring/stores'; +import { assertProps } from 'helpers/assert_props'; import { dashboardProps } from '../fixture_data'; describe('monitoring/pages/dashboard_page', () => { @@ -45,7 +46,7 @@ describe('monitoring/pages/dashboard_page', () => { }); it('throws errors if dashboard props are not passed', () => { - expect(() => buildWrapper()).toThrow('Missing required prop: "dashboardProps"'); + expect(() => assertProps(DashboardPage, {})).toThrow('Missing required prop: "dashboardProps"'); }); it('renders the dashboard page with dashboard component', () => { diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/details_header_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/details_header_spec.js index 2fea0a9199b..01089422376 100644 --- a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/details_header_spec.js +++ b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/details_header_spec.js @@ -1,10 +1,10 @@ import { GlDropdownItem, GlIcon, GlDropdown } from '@gitlab/ui'; -import { shallowMount } from '@vue/test-utils'; import VueApollo from 'vue-apollo'; import Vue, { nextTick } from 'vue'; import { numberToHumanSize } from '~/lib/utils/number_utils'; import { useFakeDate } from 'helpers/fake_date'; import createMockApollo from 'helpers/mock_apollo_helper'; +import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import { createMockDirective, getBinding } from 'helpers/vue_mock_directive'; import waitForPromises from 'helpers/wait_for_promises'; import component from '~/packages_and_registries/container_registry/explorer/components/details_page/details_header.vue'; @@ -22,37 +22,27 @@ import { } from '~/packages_and_registries/container_registry/explorer/constants'; import getContainerRepositoryMetadata from '~/packages_and_registries/container_registry/explorer/graphql/queries/get_container_repository_metadata.query.graphql'; import TitleArea from '~/vue_shared/components/registry/title_area.vue'; -import { imageTagsCountMock } from '../../mock_data'; +import { containerRepositoryMock, imageTagsCountMock } from '../../mock_data'; describe('Details Header', () => { let wrapper; let apolloProvider; const defaultImage = { - name: 'foo', - updatedAt: '2020-11-03T13:29:21Z', - canDelete: true, - project: { - visibility: 'public', - path: 'path', - containerExpirationPolicy: { - enabled: false, - }, - }, + ...containerRepositoryMock, }; // set the date to Dec 4, 2020 useFakeDate(2020, 11, 4); - const findByTestId = (testId) => wrapper.find(`[data-testid="${testId}"]`); - const findLastUpdatedAndVisibility = () => findByTestId('updated-and-visibility'); - const findTitle = () => findByTestId('title'); - const findTagsCount = () => findByTestId('tags-count'); - const findCleanup = () => findByTestId('cleanup'); + const findCreatedAndVisibility = () => wrapper.findByTestId('created-and-visibility'); + const findTitle = () => wrapper.findByTestId('title'); + const findTagsCount = () => wrapper.findByTestId('tags-count'); + const findCleanup = () => wrapper.findByTestId('cleanup'); const findDeleteButton = () => wrapper.findComponent(GlDropdownItem); const findInfoIcon = () => wrapper.findComponent(GlIcon); const findMenu = () => wrapper.findComponent(GlDropdown); - const findSize = () => findByTestId('image-size'); + const findSize = () => wrapper.findByTestId('image-size'); const waitForMetadataItems = async () => { // Metadata items are printed by a loop in the title-area and it takes two ticks for them to be available @@ -69,7 +59,7 @@ describe('Details Header', () => { const requestHandlers = [[getContainerRepositoryMetadata, resolver]]; apolloProvider = createMockApollo(requestHandlers); - wrapper = shallowMount(component, { + wrapper = shallowMountExtended(component, { apolloProvider, propsData, directives: { @@ -97,7 +87,7 @@ describe('Details Header', () => { }); it('root image shows project path name', () => { - expect(findTitle().text()).toBe('path'); + expect(findTitle().text()).toBe('gitlab-test'); }); it('has an icon', () => { @@ -119,7 +109,7 @@ describe('Details Header', () => { }); it('shows image.name', () => { - expect(findTitle().text()).toContain('foo'); + expect(findTitle().text()).toContain('rails-12009'); }); it('has no icon', () => { @@ -287,12 +277,12 @@ describe('Details Header', () => { ); }); - describe('visibility and updated at', () => { - it('has last updated text', async () => { + describe('visibility and created at', () => { + it('has created text', async () => { mountComponent(); await waitForMetadataItems(); - expect(findLastUpdatedAndVisibility().props('text')).toBe('Last updated 1 month ago'); + expect(findCreatedAndVisibility().props('text')).toBe('Created Nov 3, 2020 13:29'); }); describe('visibility icon', () => { @@ -300,7 +290,7 @@ describe('Details Header', () => { mountComponent(); await waitForMetadataItems(); - expect(findLastUpdatedAndVisibility().props('icon')).toBe('eye'); + expect(findCreatedAndVisibility().props('icon')).toBe('eye'); }); it('shows an eye slashed when the project is not public', async () => { mountComponent({ @@ -308,7 +298,7 @@ describe('Details Header', () => { }); await waitForMetadataItems(); - expect(findLastUpdatedAndVisibility().props('icon')).toBe('eye-slash'); + expect(findCreatedAndVisibility().props('icon')).toBe('eye-slash'); }); }); }); diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/mock_data.js b/spec/frontend/packages_and_registries/container_registry/explorer/mock_data.js index cd54b856c97..8ca74f5077e 100644 --- a/spec/frontend/packages_and_registries/container_registry/explorer/mock_data.js +++ b/spec/frontend/packages_and_registries/container_registry/explorer/mock_data.js @@ -127,7 +127,6 @@ export const containerRepositoryMock = { location: 'host.docker.internal:5000/gitlab-org/gitlab-test/rails-12009', canDelete: true, createdAt: '2020-11-03T13:29:21Z', - updatedAt: '2020-11-03T13:29:21Z', expirationPolicyStartedAt: null, expirationPolicyCleanupStatus: 'UNSCHEDULED', project: { diff --git a/spec/frontend/releases/components/releases_sort_spec.js b/spec/frontend/releases/components/releases_sort_spec.js index 92199896ab4..76907b4b8bb 100644 --- a/spec/frontend/releases/components/releases_sort_spec.js +++ b/spec/frontend/releases/components/releases_sort_spec.js @@ -1,5 +1,6 @@ import { GlSorting, GlSortingItem } from '@gitlab/ui'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; +import { assertProps } from 'helpers/assert_props'; import ReleasesSort from '~/releases/components/releases_sort.vue'; import { RELEASED_AT_ASC, RELEASED_AT_DESC, CREATED_ASC, CREATED_DESC } from '~/releases/constants'; @@ -92,7 +93,7 @@ describe('releases_sort.vue', () => { describe('prop validation', () => { it('validates that the `value` prop is one of the expected sort strings', () => { expect(() => { - createComponent('not a valid value'); + assertProps(ReleasesSort, { value: 'not a valid value' }); }).toThrow('Invalid prop: custom validator check failed'); }); }); diff --git a/spec/frontend/super_sidebar/components/groups_list_spec.js b/spec/frontend/super_sidebar/components/groups_list_spec.js index 66397153d71..4b61991a5db 100644 --- a/spec/frontend/super_sidebar/components/groups_list_spec.js +++ b/spec/frontend/super_sidebar/components/groups_list_spec.js @@ -75,7 +75,7 @@ describe('GroupsList component', () => { it('passes the correct props to the frequent items list', () => { expect(findFrequentItemsList().props()).toEqual({ - title: s__('Navigation|Frequent groups'), + title: s__('Navigation|Frequently visited groups'), storageKey, maxItems: MAX_FREQUENT_GROUPS_COUNT, pristineText: s__('Navigation|Groups you visit often will appear here.'), diff --git a/spec/frontend/super_sidebar/components/projects_list_spec.js b/spec/frontend/super_sidebar/components/projects_list_spec.js index 3500e0acd6c..284b88ef27e 100644 --- a/spec/frontend/super_sidebar/components/projects_list_spec.js +++ b/spec/frontend/super_sidebar/components/projects_list_spec.js @@ -70,7 +70,7 @@ describe('ProjectsList component', () => { it('passes the correct props to the frequent items list', () => { expect(findFrequentItemsList().props()).toEqual({ - title: s__('Navigation|Frequent projects'), + title: s__('Navigation|Frequently visited projects'), storageKey, maxItems: MAX_FREQUENT_PROJECTS_COUNT, pristineText: s__('Navigation|Projects you visit often will appear here.'), diff --git a/spec/frontend/vue_merge_request_widget/components/widget/widget_spec.js b/spec/frontend/vue_merge_request_widget/components/widget/widget_spec.js index ea7dabf34c9..5be0f1a64a9 100644 --- a/spec/frontend/vue_merge_request_widget/components/widget/widget_spec.js +++ b/spec/frontend/vue_merge_request_widget/components/widget/widget_spec.js @@ -3,6 +3,7 @@ import * as Sentry from '@sentry/browser'; import { shallowMountExtended, mountExtended } from 'helpers/vue_test_utils_helper'; import HelpPopover from '~/vue_shared/components/help_popover.vue'; import waitForPromises from 'helpers/wait_for_promises'; +import { assertProps } from 'helpers/assert_props'; import StatusIcon from '~/vue_merge_request_widget/components/extensions/status_icon.vue'; import ActionButtons from '~/vue_merge_request_widget/components/widget/action_buttons.vue'; import Widget from '~/vue_merge_request_widget/components/widget/widget.vue'; @@ -111,9 +112,7 @@ describe('~/vue_merge_request_widget/components/widget/widget.vue', () => { it('validates widget name', () => { expect(() => { - createComponent({ - propsData: { widgetName: 'InvalidWidgetName' }, - }); + assertProps(Widget, { widgetName: 'InvalidWidgetName' }); }).toThrow(); }); }); diff --git a/spec/frontend/vue_shared/components/markdown/markdown_editor_spec.js b/spec/frontend/vue_shared/components/markdown/markdown_editor_spec.js index 3964d895b4b..ff4c66e534b 100644 --- a/spec/frontend/vue_shared/components/markdown/markdown_editor_spec.js +++ b/spec/frontend/vue_shared/components/markdown/markdown_editor_spec.js @@ -9,6 +9,7 @@ import ContentEditor from '~/content_editor/components/content_editor.vue'; import BubbleMenu from '~/content_editor/components/bubble_menus/bubble_menu.vue'; import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue'; import MarkdownField from '~/vue_shared/components/markdown/field.vue'; +import { assertProps } from 'helpers/assert_props'; import { stubComponent } from 'helpers/stub_component'; import { useLocalStorageSpy } from 'helpers/local_storage_helper'; import waitForPromises from 'helpers/wait_for_promises'; @@ -33,23 +34,26 @@ describe('vue_shared/component/markdown/markdown_editor', () => { const autocompleteDataSources = { commands: '/foobar/-/autcomplete_sources' }; let mock; + const defaultProps = { + value, + renderMarkdownPath, + markdownDocsPath, + quickActionsDocsPath, + enableAutocomplete, + autocompleteDataSources, + enablePreview, + formFieldProps: { + id: formFieldId, + name: formFieldName, + placeholder: formFieldPlaceholder, + 'aria-label': formFieldAriaLabel, + }, + }; const buildWrapper = ({ propsData = {}, attachTo, stubs = {} } = {}) => { wrapper = mountExtended(MarkdownEditor, { attachTo, propsData: { - value, - renderMarkdownPath, - markdownDocsPath, - quickActionsDocsPath, - enableAutocomplete, - autocompleteDataSources, - enablePreview, - formFieldProps: { - id: formFieldId, - name: formFieldName, - placeholder: formFieldPlaceholder, - 'aria-label': formFieldAriaLabel, - }, + ...defaultProps, ...propsData, }, stubs: { @@ -244,9 +248,9 @@ describe('vue_shared/component/markdown/markdown_editor', () => { }); it('fails to render if textarea id and name is not passed', () => { - expect(() => { - buildWrapper({ propsData: { formFieldProps: {} } }); - }).toThrow('Invalid prop: custom validator check failed for prop "formFieldProps"'); + expect(() => assertProps(MarkdownEditor, { ...defaultProps, formFieldProps: {} })).toThrow( + 'Invalid prop: custom validator check failed for prop "formFieldProps"', + ); }); it(`emits ${EDITING_MODE_CONTENT_EDITOR} event when enableContentEditor emitted from markdown editor`, async () => { diff --git a/spec/frontend/vue_shared/components/slot_switch_spec.js b/spec/frontend/vue_shared/components/slot_switch_spec.js index f25b9877aba..daca4977817 100644 --- a/spec/frontend/vue_shared/components/slot_switch_spec.js +++ b/spec/frontend/vue_shared/components/slot_switch_spec.js @@ -1,4 +1,5 @@ import { shallowMount } from '@vue/test-utils'; +import { assertProps } from 'helpers/assert_props'; import SlotSwitch from '~/vue_shared/components/slot_switch.vue'; @@ -26,7 +27,9 @@ describe('SlotSwitch', () => { }); it('throws an error if activeSlotNames is missing', () => { - expect(createComponent).toThrow('[Vue warn]: Missing required prop: "activeSlotNames"'); + expect(() => assertProps(SlotSwitch, {})).toThrow( + '[Vue warn]: Missing required prop: "activeSlotNames"', + ); }); it('renders no slots if activeSlotNames is empty', () => { diff --git a/spec/frontend/vue_shared/components/split_button_spec.js b/spec/frontend/vue_shared/components/split_button_spec.js index 6b869db4058..ffa25ae8448 100644 --- a/spec/frontend/vue_shared/components/split_button_spec.js +++ b/spec/frontend/vue_shared/components/split_button_spec.js @@ -2,6 +2,7 @@ import { GlDropdown, GlDropdownItem } from '@gitlab/ui'; import { shallowMount } from '@vue/test-utils'; import { nextTick } from 'vue'; +import { assertProps } from 'helpers/assert_props'; import SplitButton from '~/vue_shared/components/split_button.vue'; const mockActionItems = [ @@ -42,12 +43,12 @@ describe('SplitButton', () => { it('fails for empty actionItems', () => { const actionItems = []; - expect(() => createComponent({ actionItems })).toThrow(); + expect(() => assertProps(SplitButton, { actionItems })).toThrow(); }); it('fails for single actionItems', () => { const actionItems = [mockActionItems[0]]; - expect(() => createComponent({ actionItems })).toThrow(); + expect(() => assertProps(SplitButton, { actionItems })).toThrow(); }); it('renders actionItems', () => { diff --git a/spec/frontend/work_items/components/work_item_detail_spec.js b/spec/frontend/work_items/components/work_item_detail_spec.js index a4bf2386ed4..dee781209ac 100644 --- a/spec/frontend/work_items/components/work_item_detail_spec.js +++ b/spec/frontend/work_items/components/work_item_detail_spec.js @@ -388,11 +388,12 @@ describe('WorkItemDetail component', () => { expect(findParent().exists()).toBe(false); }); - it('shows work item type if there is not a parent', async () => { + it('shows work item type with reference when there is no a parent', async () => { createComponent({ handler: jest.fn().mockResolvedValue(workItemQueryResponseWithoutParent) }); await waitForPromises(); expect(findWorkItemType().exists()).toBe(true); + expect(findWorkItemType().text()).toBe('Task #1'); }); describe('with parent', () => { |