Commit c930f24b authored by Andrew Fontaine's avatar Andrew Fontaine

Merge branch 'xanf/introduce-stub-component' into 'master'

Introduce stubComponent helper

See merge request gitlab-org/gitlab!50103
parents 819526d1 6b9a0c5e
...@@ -2,6 +2,7 @@ import { shallowMount } from '@vue/test-utils'; ...@@ -2,6 +2,7 @@ import { shallowMount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter'; import MockAdapter from 'axios-mock-adapter';
import JiraIssuesListRoot from 'ee/integrations/jira/issues_list/components/jira_issues_list_root.vue'; import JiraIssuesListRoot from 'ee/integrations/jira/issues_list/components/jira_issues_list_root.vue';
import { stubComponent } from 'helpers/stub_component';
import createFlash from '~/flash'; import createFlash from '~/flash';
import IssuableList from '~/issuable_list/components/issuable_list_root.vue'; import IssuableList from '~/issuable_list/components/issuable_list_root.vue';
...@@ -25,6 +26,9 @@ const createComponent = ({ provide = mockProvide, initialFilterParams = {} } = { ...@@ -25,6 +26,9 @@ const createComponent = ({ provide = mockProvide, initialFilterParams = {} } = {
initialFilterParams, initialFilterParams,
}, },
provide, provide,
stubs: {
IssuableList: stubComponent(IssuableList),
},
}); });
describe('JiraIssuesListRoot', () => { describe('JiraIssuesListRoot', () => {
......
export function stubComponent(Component, options = {}) {
return {
props: Component.props,
model: Component.model,
// Do not render any slots/scoped slots except default
// This differs from VTU behavior which renders all slots
template: '<div><slot></slot></div>',
// allows wrapper.find(Component) to work for stub
$_vueTestUtils_original: Component,
...options,
};
}
...@@ -2,6 +2,7 @@ import { shallowMount } from '@vue/test-utils'; ...@@ -2,6 +2,7 @@ import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue'; import { nextTick } from 'vue';
import { GlTokenSelector } from '@gitlab/ui'; import { GlTokenSelector } from '@gitlab/ui';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
import { stubComponent } from 'helpers/stub_component';
import Api from '~/api'; import Api from '~/api';
import MembersTokenSelect from '~/invite_members/components/members_token_select.vue'; import MembersTokenSelect from '~/invite_members/components/members_token_select.vue';
...@@ -17,6 +18,9 @@ const createComponent = () => { ...@@ -17,6 +18,9 @@ const createComponent = () => {
ariaLabelledby: label, ariaLabelledby: label,
placeholder, placeholder,
}, },
stubs: {
GlTokenSelector: stubComponent(GlTokenSelector),
},
}); });
}; };
......
import { GlEmptyState } from '@gitlab/ui'; import { GlEmptyState } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { stubComponent } from 'helpers/stub_component';
import GroupEmptyState from '~/monitoring/components/group_empty_state.vue'; import GroupEmptyState from '~/monitoring/components/group_empty_state.vue';
import { metricStates } from '~/monitoring/constants'; import { metricStates } from '~/monitoring/constants';
const MockGlEmptyState = {
props: GlEmptyState.props,
template: '<div><slot name="description"></slot></div>',
};
function createComponent(props) { function createComponent(props) {
return shallowMount(GroupEmptyState, { return shallowMount(GroupEmptyState, {
propsData: { propsData: {
...@@ -17,7 +13,9 @@ function createComponent(props) { ...@@ -17,7 +13,9 @@ function createComponent(props) {
svgPath: '/path/to/empty-group-illustration.svg', svgPath: '/path/to/empty-group-illustration.svg',
}, },
stubs: { stubs: {
GlEmptyState: MockGlEmptyState, GlEmptyState: stubComponent(GlEmptyState, {
template: '<div><slot name="description"></slot></div>',
}),
}, },
}); });
} }
...@@ -47,7 +45,7 @@ describe('GroupEmptyState', () => { ...@@ -47,7 +45,7 @@ describe('GroupEmptyState', () => {
}); });
it('passes the expected props to GlEmptyState', () => { it('passes the expected props to GlEmptyState', () => {
expect(wrapper.find(MockGlEmptyState).props()).toMatchSnapshot(); expect(wrapper.find(GlEmptyState).props()).toMatchSnapshot();
}); });
}); });
}); });
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { GlLink, GlSprintf } from '@gitlab/ui'; import { GlLink, GlSprintf } from '@gitlab/ui';
import { stubComponent } from 'helpers/stub_component';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import HistoryItem from '~/vue_shared/components/registry/history_item.vue'; import HistoryItem from '~/vue_shared/components/registry/history_item.vue';
import { HISTORY_PIPELINES_LIMIT } from '~/packages/details/constants'; import { HISTORY_PIPELINES_LIMIT } from '~/packages/details/constants';
...@@ -21,10 +22,9 @@ describe('Package History', () => { ...@@ -21,10 +22,9 @@ describe('Package History', () => {
wrapper = shallowMount(component, { wrapper = shallowMount(component, {
propsData: { ...defaultProps, ...props }, propsData: { ...defaultProps, ...props },
stubs: { stubs: {
HistoryItem: { HistoryItem: stubComponent(HistoryItem, {
props: HistoryItem.props,
template: '<div data-testid="history-element"><slot></slot></div>', template: '<div data-testid="history-element"><slot></slot></div>',
}, }),
GlSprintf, GlSprintf,
}, },
}); });
......
import { GlFilteredSearchToken, GlFilteredSearchSuggestion, GlIcon } from '@gitlab/ui'; import { GlFilteredSearchToken, GlFilteredSearchSuggestion, GlIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { stubComponent } from 'helpers/stub_component';
import PipelineStatusToken from '~/pipelines/components/pipelines_list/tokens/pipeline_status_token.vue'; import PipelineStatusToken from '~/pipelines/components/pipelines_list/tokens/pipeline_status_token.vue';
describe('Pipeline Status Token', () => { describe('Pipeline Status Token', () => {
let wrapper; let wrapper;
const stubs = { const findFilteredSearchToken = () => wrapper.find(GlFilteredSearchToken);
GlFilteredSearchToken: {
props: GlFilteredSearchToken.props,
template: `<div><slot name="suggestions"></slot></div>`,
},
};
const findFilteredSearchToken = () => wrapper.find(stubs.GlFilteredSearchToken);
const findAllFilteredSearchSuggestions = () => wrapper.findAll(GlFilteredSearchSuggestion); const findAllFilteredSearchSuggestions = () => wrapper.findAll(GlFilteredSearchSuggestion);
const findAllGlIcons = () => wrapper.findAll(GlIcon); const findAllGlIcons = () => wrapper.findAll(GlIcon);
...@@ -33,7 +27,11 @@ describe('Pipeline Status Token', () => { ...@@ -33,7 +27,11 @@ describe('Pipeline Status Token', () => {
propsData: { propsData: {
...defaultProps, ...defaultProps,
}, },
stubs, stubs: {
GlFilteredSearchToken: stubComponent(GlFilteredSearchToken, {
template: `<div><slot name="suggestions"></slot></div>`,
}),
},
}); });
}; };
......
import { GlFilteredSearchToken, GlFilteredSearchSuggestion, GlLoadingIcon } from '@gitlab/ui'; import { GlFilteredSearchToken, GlFilteredSearchSuggestion, GlLoadingIcon } from '@gitlab/ui';
import { stubComponent } from 'helpers/stub_component';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import Api from '~/api'; import Api from '~/api';
import PipelineTriggerAuthorToken from '~/pipelines/components/pipelines_list/tokens/pipeline_trigger_author_token.vue'; import PipelineTriggerAuthorToken from '~/pipelines/components/pipelines_list/tokens/pipeline_trigger_author_token.vue';
...@@ -7,14 +8,7 @@ import { users } from '../mock_data'; ...@@ -7,14 +8,7 @@ import { users } from '../mock_data';
describe('Pipeline Trigger Author Token', () => { describe('Pipeline Trigger Author Token', () => {
let wrapper; let wrapper;
const stubs = { const findFilteredSearchToken = () => wrapper.find(GlFilteredSearchToken);
GlFilteredSearchToken: {
props: GlFilteredSearchToken.props,
template: `<div><slot name="suggestions"></slot></div>`,
},
};
const findFilteredSearchToken = () => wrapper.find(stubs.GlFilteredSearchToken);
const findAllFilteredSearchSuggestions = () => wrapper.findAll(GlFilteredSearchSuggestion); const findAllFilteredSearchSuggestions = () => wrapper.findAll(GlFilteredSearchSuggestion);
const findLoadingIcon = () => wrapper.find(GlLoadingIcon); const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
...@@ -42,7 +36,11 @@ describe('Pipeline Trigger Author Token', () => { ...@@ -42,7 +36,11 @@ describe('Pipeline Trigger Author Token', () => {
...data, ...data,
}; };
}, },
stubs, stubs: {
GlFilteredSearchToken: stubComponent(GlFilteredSearchToken, {
template: `<div><slot name="suggestions"></slot></div>`,
}),
},
}); });
}; };
......
...@@ -2,9 +2,7 @@ ...@@ -2,9 +2,7 @@
exports[`TagsLoader component has the correct markup 1`] = ` exports[`TagsLoader component has the correct markup 1`] = `
<div> <div>
<div <div>
preserve-aspect-ratio="xMinYMax meet"
>
<rect <rect
height="15" height="15"
rx="4" rx="4"
......
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Registry Group Empty state to match the default snapshot 1`] = ` exports[`Registry Group Empty state to match the default snapshot 1`] = `
<div <div>
svg-path="foo"
title="There are no container images available in this group"
>
<p> <p>
With the Container Registry, every project can have its own space to store its Docker images. Push at least one Docker image in one of this group's projects in order to show up here. With the Container Registry, every project can have its own space to store its Docker images. Push at least one Docker image in one of this group's projects in order to show up here.
<gl-link-stub <gl-link-stub
......
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Registry Project Empty state to match the default snapshot 1`] = ` exports[`Registry Project Empty state to match the default snapshot 1`] = `
<div <div>
svg-path="bazFoo"
title="There are no container images stored for this project"
>
<p> <p>
With the Container Registry, every project can have its own space to store its Docker images. With the Container Registry, every project can have its own space to store its Docker images.
<gl-link-stub <gl-link-stub
......
...@@ -135,13 +135,13 @@ describe('List Page', () => { ...@@ -135,13 +135,13 @@ describe('List Page', () => {
it('empty state should have an svg-path', () => { it('empty state should have an svg-path', () => {
mountComponent({ config }); mountComponent({ config });
expect(findEmptyState().attributes('svg-path')).toBe(config.containersErrorImage); expect(findEmptyState().props('svgPath')).toBe(config.containersErrorImage);
}); });
it('empty state should have a description', () => { it('empty state should have a description', () => {
mountComponent({ config }); mountComponent({ config });
expect(findEmptyState().html()).toContain('connection error'); expect(findEmptyState().props('title')).toContain('connection error');
}); });
it('should not show the loading or default state', () => { it('should not show the loading or default state', () => {
......
import {
GlModal as RealGlModal,
GlEmptyState as RealGlEmptyState,
GlSkeletonLoader as RealGlSkeletonLoader,
} from '@gitlab/ui';
import { RouterLinkStub } from '@vue/test-utils';
import { stubComponent } from 'helpers/stub_component';
import RealDeleteModal from '~/registry/explorer/components/details_page/delete_modal.vue'; import RealDeleteModal from '~/registry/explorer/components/details_page/delete_modal.vue';
import RealListItem from '~/vue_shared/components/registry/list_item.vue'; import RealListItem from '~/vue_shared/components/registry/list_item.vue';
export const GlModal = { export const GlModal = stubComponent(RealGlModal, {
template: '<div><slot name="modal-title"></slot><slot></slot><slot name="modal-ok"></slot></div>', template: '<div><slot name="modal-title"></slot><slot></slot><slot name="modal-ok"></slot></div>',
methods: { methods: {
show: jest.fn(), show: jest.fn(),
}, },
}; });
export const GlEmptyState = { export const GlEmptyState = stubComponent(RealGlEmptyState, {
template: '<div><slot name="description"></slot></div>', template: '<div><slot name="description"></slot></div>',
name: 'GlEmptyStateSTub', });
};
export const RouterLink = { export const RouterLink = RouterLinkStub;
template: `<div><slot></slot></div>`,
props: ['to'],
};
export const DeleteModal = { export const DeleteModal = stubComponent(RealDeleteModal, {
template: '<div></div>',
methods: { methods: {
show: jest.fn(), show: jest.fn(),
}, },
props: RealDeleteModal.props, });
};
export const GlSkeletonLoader = { export const GlSkeletonLoader = stubComponent(RealGlSkeletonLoader);
template: `<div><slot></slot></div>`,
props: ['width', 'height'],
};
export const ListItem = { export const ListItem = {
...RealListItem, ...RealListItem,
......
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