Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-08-18 11:17:02 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-08-18 11:17:02 +0300
commitb39512ed755239198a9c294b6a45e65c05900235 (patch)
treed234a3efade1de67c46b9e5a38ce813627726aa7 /spec/frontend/vue_shared/components
parentd31474cf3b17ece37939d20082b07f6657cc79a9 (diff)
Add latest changes from gitlab-org/gitlab@15-3-stable-eev15.3.0-rc42
Diffstat (limited to 'spec/frontend/vue_shared/components')
-rw-r--r--spec/frontend/vue_shared/components/actions_button_spec.js4
-rw-r--r--spec/frontend/vue_shared/components/alert_details_table_spec.js4
-rw-r--r--spec/frontend/vue_shared/components/blob_viewers/rich_viewer_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/changed_file_icon_spec.js6
-rw-r--r--spec/frontend/vue_shared/components/ci_icon_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/clipboard_button_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/clone_dropdown_spec.js12
-rw-r--r--spec/frontend/vue_shared/components/color_picker/color_picker_spec.js10
-rw-r--r--spec/frontend/vue_shared/components/commit_spec.js6
-rw-r--r--spec/frontend/vue_shared/components/confirm_modal_spec.js6
-rw-r--r--spec/frontend/vue_shared/components/dismissible_alert_spec.js4
-rw-r--r--spec/frontend/vue_shared/components/dismissible_container_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/dropdown/dropdown_button_spec.js77
-rw-r--r--spec/frontend/vue_shared/components/dropdown/dropdown_widget_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/expand_button_spec.js22
-rw-r--r--spec/frontend/vue_shared/components/file_icon_spec.js4
-rw-r--r--spec/frontend/vue_shared/components/file_row_spec.js4
-rw-r--r--spec/frontend/vue_shared/components/file_tree_spec.js4
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js44
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/mock_data.js8
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js12
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/tokens/branch_token_spec.js14
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/tokens/crm_contact_token_spec.js18
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/tokens/crm_organization_token_spec.js18
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/tokens/emoji_token_spec.js22
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/tokens/label_token_spec.js18
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/tokens/milestone_token_spec.js18
-rw-r--r--spec/frontend/vue_shared/components/gitlab_version_check_spec.js31
-rw-r--r--spec/frontend/vue_shared/components/gl_modal_vuex_spec.js10
-rw-r--r--spec/frontend/vue_shared/components/help_popover_spec.js4
-rw-r--r--spec/frontend/vue_shared/components/integration_help_text_spec.js12
-rw-r--r--spec/frontend/vue_shared/components/markdown/field_spec.js7
-rw-r--r--spec/frontend/vue_shared/components/markdown/header_spec.js17
-rw-r--r--spec/frontend/vue_shared/components/markdown/suggestion_diff_header_spec.js4
-rw-r--r--spec/frontend/vue_shared/components/markdown/suggestion_diff_spec.js6
-rw-r--r--spec/frontend/vue_shared/components/markdown/toolbar_button_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/memory_graph_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/metric_images/metric_images_tab_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/namespace_select/namespace_select_spec.js81
-rw-r--r--spec/frontend/vue_shared/components/navigation_tabs_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/notes/noteable_warning_spec.js13
-rw-r--r--spec/frontend/vue_shared/components/notes/placeholder_note_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/paginated_table_with_search_and_tabs/paginated_table_with_search_and_tabs_spec.js18
-rw-r--r--spec/frontend/vue_shared/components/pagination_bar/pagination_bar_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/pagination_links_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/project_avatar_spec.js36
-rw-r--r--spec/frontend/vue_shared/components/project_selector/project_list_item_spec.js1
-rw-r--r--spec/frontend/vue_shared/components/project_selector/project_selector_spec.js6
-rw-r--r--spec/frontend/vue_shared/components/registry/code_instruction_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/registry/details_row_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/registry/history_item_spec.js4
-rw-r--r--spec/frontend/vue_shared/components/registry/list_item_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/registry/metadata_item_spec.js6
-rw-r--r--spec/frontend/vue_shared/components/registry/registry_search_spec.js6
-rw-r--r--spec/frontend/vue_shared/components/registry/title_area_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/rich_timestamp_tooltip_spec.js41
-rw-r--r--spec/frontend/vue_shared/components/runner_instructions/runner_instructions_modal_spec.js6
-rw-r--r--spec/frontend/vue_shared/components/security_reports/artifact_downloads/merge_request_artifact_download_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/security_reports/help_icon_spec.js6
-rw-r--r--spec/frontend/vue_shared/components/sidebar/issuable_move_dropdown_spec.js32
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_button_spec.js6
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_create_view_spec.js16
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view_spec.js16
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_title_spec.js4
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_vue/label_item_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_vue/labels_select_root_spec.js14
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js1
-rw-r--r--spec/frontend/vue_shared/components/sidebar/todo_button_spec.js12
-rw-r--r--spec/frontend/vue_shared/components/source_editor_spec.js26
-rw-r--r--spec/frontend/vue_shared/components/source_viewer/components/chunk_line_spec.js29
-rw-r--r--spec/frontend/vue_shared/components/source_viewer/components/chunk_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/source_viewer/plugins/link_dependencies_spec.js9
-rw-r--r--spec/frontend/vue_shared/components/source_viewer/plugins/mock_data.js2
-rw-r--r--spec/frontend/vue_shared/components/source_viewer/plugins/utils/dependency_linker_util_spec.js5
-rw-r--r--spec/frontend/vue_shared/components/source_viewer/plugins/utils/gemspec_linker_spec.js14
-rw-r--r--spec/frontend/vue_shared/components/source_viewer/source_viewer_spec.js3
-rw-r--r--spec/frontend/vue_shared/components/split_button_spec.js5
-rw-r--r--spec/frontend/vue_shared/components/table_pagination_spec.js6
-rw-r--r--spec/frontend/vue_shared/components/tooltip_on_truncate_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/upload_dropzone/upload_dropzone_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/user_access_role_badge_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/user_avatar/user_avatar_image_new_spec.js45
-rw-r--r--spec/frontend/vue_shared/components/user_avatar/user_avatar_image_spec.js64
-rw-r--r--spec/frontend/vue_shared/components/user_avatar/user_avatar_link_new_spec.js1
-rw-r--r--spec/frontend/vue_shared/components/user_avatar/user_avatar_link_old_spec.js1
-rw-r--r--spec/frontend/vue_shared/components/user_avatar/user_avatar_link_spec.js64
-rw-r--r--spec/frontend/vue_shared/components/user_avatar/user_avatar_list_spec.js14
-rw-r--r--spec/frontend/vue_shared/components/user_popover/user_popover_spec.js39
-rw-r--r--spec/frontend/vue_shared/components/user_select_spec.js95
-rw-r--r--spec/frontend/vue_shared/components/web_ide_link_spec.js10
90 files changed, 773 insertions, 454 deletions
diff --git a/spec/frontend/vue_shared/components/actions_button_spec.js b/spec/frontend/vue_shared/components/actions_button_spec.js
index e5b7b693cb5..07c53c04723 100644
--- a/spec/frontend/vue_shared/components/actions_button_spec.js
+++ b/spec/frontend/vue_shared/components/actions_button_spec.js
@@ -45,9 +45,9 @@ describe('Actions button component', () => {
return directiveBinding.value;
};
- const findButton = () => wrapper.find(GlButton);
+ const findButton = () => wrapper.findComponent(GlButton);
const findButtonTooltip = () => getTooltip(findButton());
- const findDropdown = () => wrapper.find(GlDropdown);
+ const findDropdown = () => wrapper.findComponent(GlDropdown);
const findDropdownTooltip = () => getTooltip(findDropdown());
const parseDropdownItems = () =>
findDropdown()
diff --git a/spec/frontend/vue_shared/components/alert_details_table_spec.js b/spec/frontend/vue_shared/components/alert_details_table_spec.js
index b9a8a5bee97..8a9ee4699bd 100644
--- a/spec/frontend/vue_shared/components/alert_details_table_spec.js
+++ b/spec/frontend/vue_shared/components/alert_details_table_spec.js
@@ -74,7 +74,7 @@ describe('AlertDetails', () => {
});
it('displays a loading state when loading', () => {
- expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
+ expect(wrapper.findComponent(GlLoadingIcon).exists()).toBe(true);
});
});
@@ -130,7 +130,7 @@ describe('AlertDetails', () => {
environmentData = { name: null, path: null };
mountComponent();
- expect(findTableFieldValueByKey('Environment').text()).toBeFalsy();
+ expect(findTableFieldValueByKey('Environment').text()).toBe('');
});
});
diff --git a/spec/frontend/vue_shared/components/blob_viewers/rich_viewer_spec.js b/spec/frontend/vue_shared/components/blob_viewers/rich_viewer_spec.js
index d14f3e5559f..ce7fd40937f 100644
--- a/spec/frontend/vue_shared/components/blob_viewers/rich_viewer_spec.js
+++ b/spec/frontend/vue_shared/components/blob_viewers/rich_viewer_spec.js
@@ -43,6 +43,6 @@ describe('Blob Rich Viewer component', () => {
});
it('is using Markdown View Field', () => {
- expect(wrapper.find(MarkdownFieldView).exists()).toBe(true);
+ expect(wrapper.findComponent(MarkdownFieldView).exists()).toBe(true);
});
});
diff --git a/spec/frontend/vue_shared/components/changed_file_icon_spec.js b/spec/frontend/vue_shared/components/changed_file_icon_spec.js
index 6b9658a6d18..ea708b6f3fe 100644
--- a/spec/frontend/vue_shared/components/changed_file_icon_spec.js
+++ b/spec/frontend/vue_shared/components/changed_file_icon_spec.js
@@ -25,7 +25,7 @@ describe('Changed file icon', () => {
wrapper.destroy();
});
- const findIcon = () => wrapper.find(GlIcon);
+ const findIcon = () => wrapper.findComponent(GlIcon);
const findIconName = () => findIcon().props('name');
const findIconClasses = () => findIcon().classes();
const findTooltipText = () => wrapper.attributes('title');
@@ -51,7 +51,7 @@ describe('Changed file icon', () => {
showTooltip: false,
});
- expect(findTooltipText()).toBeFalsy();
+ expect(findTooltipText()).toBeUndefined();
});
describe.each`
@@ -87,7 +87,7 @@ describe('Changed file icon', () => {
});
it('does not have tooltip text', () => {
- expect(findTooltipText()).toBeFalsy();
+ expect(findTooltipText()).toBeUndefined();
});
});
diff --git a/spec/frontend/vue_shared/components/ci_icon_spec.js b/spec/frontend/vue_shared/components/ci_icon_spec.js
index 1b502f9587c..2064bee9673 100644
--- a/spec/frontend/vue_shared/components/ci_icon_spec.js
+++ b/spec/frontend/vue_shared/components/ci_icon_spec.js
@@ -22,7 +22,7 @@ describe('CI Icon component', () => {
});
expect(wrapper.find('span').exists()).toBe(true);
- expect(wrapper.find(GlIcon).exists()).toBe(true);
+ expect(wrapper.findComponent(GlIcon).exists()).toBe(true);
});
describe('active icons', () => {
diff --git a/spec/frontend/vue_shared/components/clipboard_button_spec.js b/spec/frontend/vue_shared/components/clipboard_button_spec.js
index fca5e664a96..b18b00e70bb 100644
--- a/spec/frontend/vue_shared/components/clipboard_button_spec.js
+++ b/spec/frontend/vue_shared/components/clipboard_button_spec.js
@@ -21,7 +21,7 @@ describe('clipboard button', () => {
});
};
- const findButton = () => wrapper.find(GlButton);
+ const findButton = () => wrapper.findComponent(GlButton);
const expectConfirmationTooltip = async ({ event, message }) => {
const title = 'Copy this value';
diff --git a/spec/frontend/vue_shared/components/clone_dropdown_spec.js b/spec/frontend/vue_shared/components/clone_dropdown_spec.js
index eefd1838988..31c08260dd0 100644
--- a/spec/frontend/vue_shared/components/clone_dropdown_spec.js
+++ b/spec/frontend/vue_shared/components/clone_dropdown_spec.js
@@ -38,9 +38,9 @@ describe('Clone Dropdown Button', () => {
${'HTTP'} | ${1} | ${httpLink}
`('renders correct link and a copy-button for $name', ({ index, value }) => {
createComponent();
- const group = wrapper.findAll(GlFormInputGroup).at(index);
+ const group = wrapper.findAllComponents(GlFormInputGroup).at(index);
expect(group.props('value')).toBe(value);
- expect(group.find(GlFormInputGroup).exists()).toBe(true);
+ expect(group.findComponent(GlFormInputGroup).exists()).toBe(true);
});
it.each`
@@ -50,8 +50,8 @@ describe('Clone Dropdown Button', () => {
`('does not fail if only $name is set', ({ name, value }) => {
createComponent({ [name]: value });
- expect(wrapper.find(GlFormInputGroup).props('value')).toBe(value);
- expect(wrapper.findAll(GlDropdownSectionHeader).length).toBe(1);
+ expect(wrapper.findComponent(GlFormInputGroup).props('value')).toBe(value);
+ expect(wrapper.findAllComponents(GlDropdownSectionHeader).length).toBe(1);
});
});
@@ -63,12 +63,12 @@ describe('Clone Dropdown Button', () => {
`('allows null values for the props', ({ name, value }) => {
createComponent({ ...defaultPropsData, [name]: value });
- expect(wrapper.findAll(GlDropdownSectionHeader).length).toBe(1);
+ expect(wrapper.findAllComponents(GlDropdownSectionHeader).length).toBe(1);
});
it('correctly calculates httpLabel for HTTPS protocol', () => {
createComponent({ httpLink: httpsLink });
- expect(wrapper.find(GlDropdownSectionHeader).text()).toContain('HTTPS');
+ expect(wrapper.findComponent(GlDropdownSectionHeader).text()).toContain('HTTPS');
});
});
});
diff --git a/spec/frontend/vue_shared/components/color_picker/color_picker_spec.js b/spec/frontend/vue_shared/components/color_picker/color_picker_spec.js
index 8cbe0630426..060048c4bbd 100644
--- a/spec/frontend/vue_shared/components/color_picker/color_picker_spec.js
+++ b/spec/frontend/vue_shared/components/color_picker/color_picker_spec.js
@@ -16,14 +16,14 @@ describe('ColorPicker', () => {
const setColor = '#000000';
const invalidText = 'Please enter a valid hex (#RRGGBB or #RGB) color value';
- const findGlFormGroup = () => wrapper.find(GlFormGroup);
+ const findGlFormGroup = () => wrapper.findComponent(GlFormGroup);
const colorPreview = () => wrapper.find('[data-testid="color-preview"]');
- const colorPicker = () => wrapper.find(GlFormInput);
+ const colorPicker = () => wrapper.findComponent(GlFormInput);
const colorInput = () => wrapper.find('input[type="color"]');
- const colorTextInput = () => wrapper.find(GlFormInputGroup).find('input[type="text"]');
+ const colorTextInput = () => wrapper.findComponent(GlFormInputGroup).find('input[type="text"]');
const invalidFeedback = () => wrapper.find('.invalid-feedback');
- const description = () => wrapper.find(GlFormGroup).attributes('description');
- const presetColors = () => wrapper.findAll(GlLink);
+ const description = () => wrapper.findComponent(GlFormGroup).attributes('description');
+ const presetColors = () => wrapper.findAllComponents(GlLink);
beforeEach(() => {
gon.suggested_label_colors = {
diff --git a/spec/frontend/vue_shared/components/commit_spec.js b/spec/frontend/vue_shared/components/commit_spec.js
index d91853e7b79..1893e127f6f 100644
--- a/spec/frontend/vue_shared/components/commit_spec.js
+++ b/spec/frontend/vue_shared/components/commit_spec.js
@@ -9,11 +9,11 @@ describe('Commit component', () => {
let wrapper;
const findIcon = (name) => {
- const icons = wrapper.findAll(GlIcon).filter((c) => c.attributes('name') === name);
+ const icons = wrapper.findAllComponents(GlIcon).filter((c) => c.attributes('name') === name);
return icons.length ? icons.at(0) : icons;
};
- const findUserAvatar = () => wrapper.find(UserAvatarLink);
+ const findUserAvatar = () => wrapper.findComponent(UserAvatarLink);
const findRefName = () => wrapper.findByTestId('ref-name');
const createComponent = (propsData) => {
@@ -47,7 +47,7 @@ describe('Commit component', () => {
},
});
- expect(wrapper.find('.icon-container').find(GlIcon).exists()).toBe(true);
+ expect(wrapper.find('.icon-container').findComponent(GlIcon).exists()).toBe(true);
});
describe('Given all the props', () => {
diff --git a/spec/frontend/vue_shared/components/confirm_modal_spec.js b/spec/frontend/vue_shared/components/confirm_modal_spec.js
index 3ca1c943398..c1e682a1aae 100644
--- a/spec/frontend/vue_shared/components/confirm_modal_spec.js
+++ b/spec/frontend/vue_shared/components/confirm_modal_spec.js
@@ -51,13 +51,13 @@ describe('vue_shared/components/confirm_modal', () => {
wrapper.destroy();
});
- const findModal = () => wrapper.find(GlModalStub);
+ const findModal = () => wrapper.findComponent(GlModalStub);
const findForm = () => wrapper.find('form');
const findFormData = () =>
findForm()
.findAll('input')
.wrappers.map((x) => ({ name: x.attributes('name'), value: x.attributes('value') }));
- const findDomElementListener = () => wrapper.find(DomElementListener);
+ const findDomElementListener = () => wrapper.findComponent(DomElementListener);
const triggerOpenWithEventHub = (modalData) => {
eventHub.$emit(EVENT_OPEN_CONFIRM_MODAL, modalData);
};
@@ -104,7 +104,7 @@ describe('vue_shared/components/confirm_modal', () => {
});
it('renders GlModal with data', () => {
- expect(findModal().exists()).toBeTruthy();
+ expect(findModal().exists()).toBe(true);
expect(findModal().attributes()).toEqual(
expect.objectContaining({
oktitle: MOCK_MODAL_DATA.modalAttributes.okTitle,
diff --git a/spec/frontend/vue_shared/components/dismissible_alert_spec.js b/spec/frontend/vue_shared/components/dismissible_alert_spec.js
index 879d4aba441..8b1189f25d5 100644
--- a/spec/frontend/vue_shared/components/dismissible_alert_spec.js
+++ b/spec/frontend/vue_shared/components/dismissible_alert_spec.js
@@ -20,7 +20,7 @@ describe('vue_shared/components/dismissible_alert', () => {
wrapper.destroy();
});
- const findAlert = () => wrapper.find(GlAlert);
+ const findAlert = () => wrapper.findComponent(GlAlert);
describe('default', () => {
beforeEach(() => {
@@ -45,7 +45,7 @@ describe('vue_shared/components/dismissible_alert', () => {
});
it('emmits alertDismissed', () => {
- expect(wrapper.emitted('alertDismissed')).toBeTruthy();
+ expect(wrapper.emitted()).toHaveProperty('alertDismissed');
});
});
});
diff --git a/spec/frontend/vue_shared/components/dismissible_container_spec.js b/spec/frontend/vue_shared/components/dismissible_container_spec.js
index b8aeea38e77..f7030f38709 100644
--- a/spec/frontend/vue_shared/components/dismissible_container_spec.js
+++ b/spec/frontend/vue_shared/components/dismissible_container_spec.js
@@ -33,7 +33,7 @@ describe('DismissibleContainer', () => {
button.trigger('click');
- expect(wrapper.emitted().dismiss).toBeTruthy();
+ expect(wrapper.emitted().dismiss).toEqual(expect.any(Array));
});
});
diff --git a/spec/frontend/vue_shared/components/dropdown/dropdown_button_spec.js b/spec/frontend/vue_shared/components/dropdown/dropdown_button_spec.js
index 08e5d828b8f..e34ed31b4bf 100644
--- a/spec/frontend/vue_shared/components/dropdown/dropdown_button_spec.js
+++ b/spec/frontend/vue_shared/components/dropdown/dropdown_button_spec.js
@@ -1,80 +1,71 @@
-import Vue from 'vue';
+import { mount } from '@vue/test-utils';
+import DropdownButton from '~/vue_shared/components/dropdown/dropdown_button.vue';
-import { mountComponentWithSlots } from 'helpers/vue_mount_component_helper';
-import dropdownButtonComponent from '~/vue_shared/components/dropdown/dropdown_button.vue';
+describe('DropdownButton component', () => {
+ let wrapper;
-const defaultLabel = 'Select';
-const customLabel = 'Select project';
+ const defaultLabel = 'Select';
+ const customLabel = 'Select project';
-const createComponent = (props, slots = {}) => {
- const Component = Vue.extend(dropdownButtonComponent);
-
- return mountComponentWithSlots(Component, { props, slots });
-};
-
-describe('DropdownButtonComponent', () => {
- let vm;
-
- beforeEach(() => {
- vm = createComponent();
- });
+ const createComponent = (props, slots = {}) => {
+ wrapper = mount(DropdownButton, { propsData: props, slots });
+ };
afterEach(() => {
- vm.$destroy();
+ wrapper.destroy();
});
describe('computed', () => {
describe('dropdownToggleText', () => {
it('returns default toggle text', () => {
- expect(vm.toggleText).toBe(defaultLabel);
+ createComponent();
+
+ expect(wrapper.vm.toggleText).toBe(defaultLabel);
});
it('returns custom toggle text when provided via props', () => {
- const vmEmptyLabels = createComponent({ toggleText: customLabel });
+ createComponent({ toggleText: customLabel });
- expect(vmEmptyLabels.toggleText).toBe(customLabel);
- vmEmptyLabels.$destroy();
+ expect(wrapper.vm.toggleText).toBe(customLabel);
});
});
});
describe('template', () => {
it('renders component container element of type `button`', () => {
- expect(vm.$el.nodeName).toBe('BUTTON');
+ createComponent();
+
+ expect(wrapper.element.nodeName).toBe('BUTTON');
});
it('renders component container element with required data attributes', () => {
- expect(vm.$el.dataset.abilityName).toBe(vm.abilityName);
- expect(vm.$el.dataset.fieldName).toBe(vm.fieldName);
- expect(vm.$el.dataset.issueUpdate).toBe(vm.updatePath);
- expect(vm.$el.dataset.labels).toBe(vm.labelsPath);
- expect(vm.$el.dataset.namespacePath).toBe(vm.namespace);
- expect(vm.$el.dataset.showAny).not.toBeDefined();
+ createComponent();
+
+ expect(wrapper.element.dataset.abilityName).toBe(wrapper.vm.abilityName);
+ expect(wrapper.element.dataset.fieldName).toBe(wrapper.vm.fieldName);
+ expect(wrapper.element.dataset.issueUpdate).toBe(wrapper.vm.updatePath);
+ expect(wrapper.element.dataset.labels).toBe(wrapper.vm.labelsPath);
+ expect(wrapper.element.dataset.namespacePath).toBe(wrapper.vm.namespace);
+ expect(wrapper.element.dataset.showAny).toBeUndefined();
});
it('renders dropdown toggle text element', () => {
- const dropdownToggleTextEl = vm.$el.querySelector('.dropdown-toggle-text');
+ createComponent();
- expect(dropdownToggleTextEl).not.toBeNull();
- expect(dropdownToggleTextEl.innerText.trim()).toBe(defaultLabel);
+ expect(wrapper.find('.dropdown-toggle-text').text()).toBe(defaultLabel);
});
it('renders dropdown button icon', () => {
- const dropdownIconEl = vm.$el.querySelector('[data-testid="chevron-down-icon"]');
+ createComponent();
- expect(dropdownIconEl).not.toBeNull();
+ expect(wrapper.find('[data-testid="chevron-down-icon"]').exists()).toBe(true);
});
it('renders slot, if default slot exists', () => {
- vm = createComponent(
- {},
- {
- default: ['Lorem Ipsum Dolar'],
- },
- );
-
- expect(vm.$el.querySelector('.dropdown-toggle-text')).toBeNull();
- expect(vm.$el).toHaveText('Lorem Ipsum Dolar');
+ createComponent({}, { default: ['Lorem Ipsum Dolar'] });
+
+ expect(wrapper.find('.dropdown-toggle-text').exists()).toBe(false);
+ expect(wrapper.text()).toBe('Lorem Ipsum Dolar');
});
});
});
diff --git a/spec/frontend/vue_shared/components/dropdown/dropdown_widget_spec.js b/spec/frontend/vue_shared/components/dropdown/dropdown_widget_spec.js
index 084d0559665..dd3e55c82bb 100644
--- a/spec/frontend/vue_shared/components/dropdown/dropdown_widget_spec.js
+++ b/spec/frontend/vue_shared/components/dropdown/dropdown_widget_spec.js
@@ -8,7 +8,7 @@ describe('DropdownWidget component', () => {
let wrapper;
const findDropdown = () => wrapper.findComponent(GlDropdown);
- const findDropdownItems = () => wrapper.findAll(GlDropdownItem);
+ const findDropdownItems = () => wrapper.findAllComponents(GlDropdownItem);
const findSearch = () => wrapper.findComponent(GlSearchBoxByType);
const createComponent = ({ props = {} } = {}) => {
diff --git a/spec/frontend/vue_shared/components/expand_button_spec.js b/spec/frontend/vue_shared/components/expand_button_spec.js
index 87d6ed6b21f..170c947e520 100644
--- a/spec/frontend/vue_shared/components/expand_button_spec.js
+++ b/spec/frontend/vue_shared/components/expand_button_spec.js
@@ -37,11 +37,11 @@ describe('Expand button', () => {
});
it('renders no text when short text is not provided', () => {
- expect(wrapper.find(ExpandButton).text()).toBe('');
+ expect(wrapper.findComponent(ExpandButton).text()).toBe('');
});
it('does not render expanded text', () => {
- expect(wrapper.find(ExpandButton).text().trim()).not.toBe(text.short);
+ expect(wrapper.findComponent(ExpandButton).text().trim()).not.toBe(text.short);
});
describe('when short text is provided', () => {
@@ -55,13 +55,13 @@ describe('Expand button', () => {
});
it('renders short text', () => {
- expect(wrapper.find(ExpandButton).text().trim()).toBe(text.short);
+ expect(wrapper.findComponent(ExpandButton).text().trim()).toBe(text.short);
});
it('renders button before text', () => {
expect(expanderPrependEl().isVisible()).toBe(true);
expect(expanderAppendEl().isVisible()).toBe(false);
- expect(wrapper.find(ExpandButton).element).toMatchSnapshot();
+ expect(wrapper.findComponent(ExpandButton).element).toMatchSnapshot();
});
});
@@ -81,7 +81,7 @@ describe('Expand button', () => {
});
it('renders the expanded text', () => {
- expect(wrapper.find(ExpandButton).text()).toContain(text.expanded);
+ expect(wrapper.findComponent(ExpandButton).text()).toContain(text.expanded);
});
describe('when short text is provided', () => {
@@ -98,13 +98,13 @@ describe('Expand button', () => {
});
it('only renders expanded text', () => {
- expect(wrapper.find(ExpandButton).text().trim()).toBe(text.expanded);
+ expect(wrapper.findComponent(ExpandButton).text().trim()).toBe(text.expanded);
});
it('renders button after text', () => {
expect(expanderPrependEl().isVisible()).toBe(false);
expect(expanderAppendEl().isVisible()).toBe(true);
- expect(wrapper.find(ExpandButton).element).toMatchSnapshot();
+ expect(wrapper.findComponent(ExpandButton).element).toMatchSnapshot();
});
});
});
@@ -124,11 +124,11 @@ describe('Expand button', () => {
});
it('clicking hides expanded text', async () => {
- expect(wrapper.find(ExpandButton).text().trim()).toBe(text.expanded);
+ expect(wrapper.findComponent(ExpandButton).text().trim()).toBe(text.expanded);
expanderAppendEl().trigger('click');
await nextTick();
- expect(wrapper.find(ExpandButton).text().trim()).not.toBe(text.expanded);
+ expect(wrapper.findComponent(ExpandButton).text().trim()).not.toBe(text.expanded);
});
describe('when short text is provided', () => {
@@ -145,11 +145,11 @@ describe('Expand button', () => {
});
it('clicking reveals short text', async () => {
- expect(wrapper.find(ExpandButton).text().trim()).toBe(text.expanded);
+ expect(wrapper.findComponent(ExpandButton).text().trim()).toBe(text.expanded);
expanderAppendEl().trigger('click');
await nextTick();
- expect(wrapper.find(ExpandButton).text().trim()).toBe(text.short);
+ expect(wrapper.findComponent(ExpandButton).text().trim()).toBe(text.short);
});
});
});
diff --git a/spec/frontend/vue_shared/components/file_icon_spec.js b/spec/frontend/vue_shared/components/file_icon_spec.js
index b0e623520a8..3f4bfc86b67 100644
--- a/spec/frontend/vue_shared/components/file_icon_spec.js
+++ b/spec/frontend/vue_shared/components/file_icon_spec.js
@@ -6,7 +6,7 @@ import { FILE_SYMLINK_MODE } from '~/vue_shared/constants';
describe('File Icon component', () => {
let wrapper;
const findSvgIcon = () => wrapper.find('svg');
- const findGlIcon = () => wrapper.find(GlIcon);
+ const findGlIcon = () => wrapper.findComponent(GlIcon);
const getIconName = () =>
findSvgIcon()
.find('use')
@@ -61,7 +61,7 @@ describe('File Icon component', () => {
loading: true,
});
- expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
+ expect(wrapper.findComponent(GlLoadingIcon).exists()).toBe(true);
});
it('should add a special class and a size class', () => {
diff --git a/spec/frontend/vue_shared/components/file_row_spec.js b/spec/frontend/vue_shared/components/file_row_spec.js
index 62fb29c455c..f5a545891d5 100644
--- a/spec/frontend/vue_shared/components/file_row_spec.js
+++ b/spec/frontend/vue_shared/components/file_row_spec.js
@@ -119,7 +119,7 @@ describe('File row component', () => {
level: 0,
});
- expect(wrapper.find(FileHeader).exists()).toBe(true);
+ expect(wrapper.findComponent(FileHeader).exists()).toBe(true);
});
it('matches the current route against encoded file URL', () => {
@@ -164,6 +164,6 @@ describe('File row component', () => {
level: 0,
});
- expect(wrapper.find(FileIcon).props('submodule')).toBe(submodule);
+ expect(wrapper.findComponent(FileIcon).props('submodule')).toBe(submodule);
});
});
diff --git a/spec/frontend/vue_shared/components/file_tree_spec.js b/spec/frontend/vue_shared/components/file_tree_spec.js
index 39a7c7a2b3a..e8818e09dc0 100644
--- a/spec/frontend/vue_shared/components/file_tree_spec.js
+++ b/spec/frontend/vue_shared/components/file_tree_spec.js
@@ -25,8 +25,8 @@ describe('File Tree component', () => {
});
};
- const findFileRow = () => wrapper.find(MockFileRow);
- const findChildrenTrees = () => wrapper.findAll(FileTree).wrappers.slice(1);
+ const findFileRow = () => wrapper.findComponent(MockFileRow);
+ const findChildrenTrees = () => wrapper.findAllComponents(FileTree).wrappers.slice(1);
const findChildrenTreeProps = () =>
findChildrenTrees().map((x) => ({
...x.props(),
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js
index e44bc8771f5..1b9ca8e6092 100644
--- a/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js
@@ -88,10 +88,10 @@ describe('FilteredSearchBarRoot', () => {
expect(wrapper.vm.filterValue).toEqual([]);
expect(wrapper.vm.selectedSortOption).toBe(mockSortOptions[0]);
expect(wrapper.vm.selectedSortDirection).toBe(SortDirection.descending);
- expect(wrapper.find(GlButtonGroup).exists()).toBe(true);
- expect(wrapper.find(GlButton).exists()).toBe(true);
- expect(wrapper.find(GlDropdown).exists()).toBe(true);
- expect(wrapper.find(GlDropdownItem).exists()).toBe(true);
+ expect(wrapper.findComponent(GlButtonGroup).exists()).toBe(true);
+ expect(wrapper.findComponent(GlButton).exists()).toBe(true);
+ expect(wrapper.findComponent(GlDropdown).exists()).toBe(true);
+ expect(wrapper.findComponent(GlDropdownItem).exists()).toBe(true);
});
it('does not initialize `selectedSortOption` and `selectedSortDirection` when `sortOptions` is not applied and hides the sort dropdown', () => {
@@ -99,10 +99,10 @@ describe('FilteredSearchBarRoot', () => {
expect(wrapperNoSort.vm.filterValue).toEqual([]);
expect(wrapperNoSort.vm.selectedSortOption).toBe(undefined);
- expect(wrapperNoSort.find(GlButtonGroup).exists()).toBe(false);
- expect(wrapperNoSort.find(GlButton).exists()).toBe(false);
- expect(wrapperNoSort.find(GlDropdown).exists()).toBe(false);
- expect(wrapperNoSort.find(GlDropdownItem).exists()).toBe(false);
+ expect(wrapperNoSort.findComponent(GlButtonGroup).exists()).toBe(false);
+ expect(wrapperNoSort.findComponent(GlButton).exists()).toBe(false);
+ expect(wrapperNoSort.findComponent(GlDropdown).exists()).toBe(false);
+ expect(wrapperNoSort.findComponent(GlDropdownItem).exists()).toBe(false);
});
});
@@ -217,7 +217,7 @@ describe('FilteredSearchBarRoot', () => {
it('emits component event `onFilter` with empty array and true when initially selected filter value was cleared', async () => {
wrapper = createComponent({ initialFilterValue: [tokenValueLabel] });
- wrapper.find(GlFilteredSearch).vm.$emit('clear');
+ wrapper.findComponent(GlFilteredSearch).vm.$emit('clear');
await nextTick();
expect(wrapper.emitted('onFilter')[0]).toEqual([[], true]);
@@ -362,7 +362,7 @@ describe('FilteredSearchBarRoot', () => {
it('calls `blurSearchInput` method to remove focus from filter input field', () => {
jest.spyOn(wrapper.vm, 'blurSearchInput');
- wrapper.find(GlFilteredSearch).vm.$emit('submit', mockFilters);
+ wrapper.findComponent(GlFilteredSearch).vm.$emit('submit', mockFilters);
expect(wrapper.vm.blurSearchInput).toHaveBeenCalled();
});
@@ -392,7 +392,7 @@ describe('FilteredSearchBarRoot', () => {
});
it('renders gl-filtered-search component', () => {
- const glFilteredSearchEl = wrapper.find(GlFilteredSearch);
+ const glFilteredSearchEl = wrapper.findComponent(GlFilteredSearch);
expect(glFilteredSearchEl.props('placeholder')).toBe('Filter requirements');
expect(glFilteredSearchEl.props('availableTokens')).toEqual(mockAvailableTokens);
@@ -404,8 +404,10 @@ describe('FilteredSearchBarRoot', () => {
showCheckbox: true,
});
- expect(wrapperWithCheckbox.find(GlFormCheckbox).exists()).toBe(true);
- expect(wrapperWithCheckbox.find(GlFormCheckbox).attributes('checked')).not.toBeDefined();
+ expect(wrapperWithCheckbox.findComponent(GlFormCheckbox).exists()).toBe(true);
+ expect(
+ wrapperWithCheckbox.findComponent(GlFormCheckbox).attributes('checked'),
+ ).not.toBeDefined();
wrapperWithCheckbox.destroy();
@@ -414,7 +416,7 @@ describe('FilteredSearchBarRoot', () => {
checkboxChecked: true,
});
- expect(wrapperWithCheckbox.find(GlFormCheckbox).attributes('checked')).toBe('true');
+ expect(wrapperWithCheckbox.findComponent(GlFormCheckbox).attributes('checked')).toBe('true');
wrapperWithCheckbox.destroy();
});
@@ -448,7 +450,7 @@ describe('FilteredSearchBarRoot', () => {
await nextTick();
- expect(wrapperFullMount.find(GlDropdownItem).text()).toBe('Membership := Direct');
+ expect(wrapperFullMount.findComponent(GlDropdownItem).text()).toBe('Membership := Direct');
wrapperFullMount.destroy();
});
@@ -466,20 +468,20 @@ describe('FilteredSearchBarRoot', () => {
await nextTick();
- expect(wrapperFullMount.find(GlDropdownItem).text()).toBe('Membership := exclude');
+ expect(wrapperFullMount.findComponent(GlDropdownItem).text()).toBe('Membership := exclude');
wrapperFullMount.destroy();
});
});
it('renders sort dropdown component', () => {
- expect(wrapper.find(GlButtonGroup).exists()).toBe(true);
- expect(wrapper.find(GlDropdown).exists()).toBe(true);
- expect(wrapper.find(GlDropdown).props('text')).toBe(mockSortOptions[0].title);
+ expect(wrapper.findComponent(GlButtonGroup).exists()).toBe(true);
+ expect(wrapper.findComponent(GlDropdown).exists()).toBe(true);
+ expect(wrapper.findComponent(GlDropdown).props('text')).toBe(mockSortOptions[0].title);
});
it('renders sort dropdown items', () => {
- const dropdownItemsEl = wrapper.findAll(GlDropdownItem);
+ const dropdownItemsEl = wrapper.findAllComponents(GlDropdownItem);
expect(dropdownItemsEl).toHaveLength(mockSortOptions.length);
expect(dropdownItemsEl.at(0).text()).toBe(mockSortOptions[0].title);
@@ -488,7 +490,7 @@ describe('FilteredSearchBarRoot', () => {
});
it('renders sort direction button', () => {
- const sortButtonEl = wrapper.find(GlButton);
+ const sortButtonEl = wrapper.findComponent(GlButton);
expect(sortButtonEl.attributes('title')).toBe('Sort direction: Descending');
expect(sortButtonEl.props('icon')).toBe('sort-highest');
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/mock_data.js b/spec/frontend/vue_shared/components/filtered_search_bar/mock_data.js
index 86d1f21fd04..a6713b7e7e4 100644
--- a/spec/frontend/vue_shared/components/filtered_search_bar/mock_data.js
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/mock_data.js
@@ -66,12 +66,14 @@ export const mockMilestones = [
export const mockCrmContacts = [
{
+ __typename: 'CustomerRelationsContact',
id: 'gid://gitlab/CustomerRelations::Contact/1',
firstName: 'John',
lastName: 'Smith',
email: 'john@smith.com',
},
{
+ __typename: 'CustomerRelationsContact',
id: 'gid://gitlab/CustomerRelations::Contact/2',
firstName: 'Andy',
lastName: 'Green',
@@ -81,10 +83,12 @@ export const mockCrmContacts = [
export const mockCrmOrganizations = [
{
+ __typename: 'CustomerRelationsOrganization',
id: 'gid://gitlab/CustomerRelations::Organization/1',
name: 'First Org Ltd.',
},
{
+ __typename: 'CustomerRelationsOrganization',
id: 'gid://gitlab/CustomerRelations::Organization/2',
name: 'Organizer S.p.a.',
},
@@ -102,11 +106,9 @@ export const mockProjectCrmContactsQueryResponse = {
__typename: 'CustomerRelationsContactConnection',
nodes: [
{
- __typename: 'CustomerRelationsContact',
...mockCrmContacts[0],
},
{
- __typename: 'CustomerRelationsContact',
...mockCrmContacts[1],
},
],
@@ -128,11 +130,9 @@ export const mockProjectCrmOrganizationsQueryResponse = {
__typename: 'CustomerRelationsOrganizationConnection',
nodes: [
{
- __typename: 'CustomerRelationsOrganization',
...mockCrmOrganizations[0],
},
{
- __typename: 'CustomerRelationsOrganization',
...mockCrmOrganizations[1],
},
],
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js
index 3f24d5df858..302dfabffb2 100644
--- a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js
@@ -195,7 +195,7 @@ describe('AuthorToken', () => {
});
await nextTick();
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
expect(tokenSegments).toHaveLength(3); // Author, =, "Administrator"
@@ -207,7 +207,7 @@ describe('AuthorToken', () => {
it('renders token value with correct avatarUrl from author object', async () => {
const getAvatarEl = () =>
- wrapper.findAll(GlFilteredSearchTokenSegment).at(2).findComponent(GlAvatar);
+ wrapper.findAllComponents(GlFilteredSearchTokenSegment).at(2).findComponent(GlAvatar);
wrapper = createComponent({
value: { data: mockAuthors[0].username },
@@ -252,7 +252,7 @@ describe('AuthorToken', () => {
await activateSuggestionsList();
- const suggestions = wrapper.findAll(GlFilteredSearchSuggestion);
+ const suggestions = wrapper.findAllComponents(GlFilteredSearchSuggestion);
expect(suggestions).toHaveLength(defaultAuthors.length + currentUserLength);
defaultAuthors.forEach((label, index) => {
@@ -266,12 +266,12 @@ describe('AuthorToken', () => {
config: { ...mockAuthorToken, defaultAuthors: [] },
stubs: { Portal: true },
});
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
const suggestionsSegment = tokenSegments.at(2);
suggestionsSegment.vm.$emit('activate');
await nextTick();
- expect(wrapper.find(GlDropdownDivider).exists()).toBe(false);
+ expect(wrapper.findComponent(GlDropdownDivider).exists()).toBe(false);
});
it('renders `DEFAULT_NONE_ANY` as default suggestions', async () => {
@@ -283,7 +283,7 @@ describe('AuthorToken', () => {
await activateSuggestionsList();
- const suggestions = wrapper.findAll(GlFilteredSearchSuggestion);
+ const suggestions = wrapper.findAllComponents(GlFilteredSearchSuggestion);
expect(suggestions).toHaveLength(2 + currentUserLength);
expect(suggestions.at(0).text()).toBe(DEFAULT_NONE_ANY[0].text);
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/branch_token_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/branch_token_spec.js
index 7b495ec9bee..1de35daa3a5 100644
--- a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/branch_token_spec.js
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/branch_token_spec.js
@@ -114,7 +114,7 @@ describe('BranchToken', () => {
describe('template', () => {
const defaultBranches = DEFAULT_NONE_ANY;
async function showSuggestions() {
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
const suggestionsSegment = tokenSegments.at(2);
suggestionsSegment.vm.$emit('activate');
await nextTick();
@@ -133,11 +133,11 @@ describe('BranchToken', () => {
});
it('renders gl-filtered-search-token component', () => {
- expect(wrapper.find(GlFilteredSearchToken).exists()).toBe(true);
+ expect(wrapper.findComponent(GlFilteredSearchToken).exists()).toBe(true);
});
it('renders token item when value is selected', () => {
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
expect(tokenSegments).toHaveLength(3);
expect(tokenSegments.at(2).text()).toBe(mockBranches[0].name);
@@ -150,7 +150,7 @@ describe('BranchToken', () => {
stubs: { Portal: true },
});
await showSuggestions();
- const suggestions = wrapper.findAll(GlFilteredSearchSuggestion);
+ const suggestions = wrapper.findAllComponents(GlFilteredSearchSuggestion);
expect(suggestions).toHaveLength(defaultBranches.length);
defaultBranches.forEach((branch, index) => {
@@ -166,8 +166,8 @@ describe('BranchToken', () => {
});
await showSuggestions();
- expect(wrapper.find(GlFilteredSearchSuggestion).exists()).toBe(false);
- expect(wrapper.find(GlDropdownDivider).exists()).toBe(false);
+ expect(wrapper.findComponent(GlFilteredSearchSuggestion).exists()).toBe(false);
+ expect(wrapper.findComponent(GlDropdownDivider).exists()).toBe(false);
});
it('renders no suggestions as default', async () => {
@@ -177,7 +177,7 @@ describe('BranchToken', () => {
stubs: { Portal: true },
});
await showSuggestions();
- const suggestions = wrapper.findAll(GlFilteredSearchSuggestion);
+ const suggestions = wrapper.findAllComponents(GlFilteredSearchSuggestion);
expect(suggestions).toHaveLength(0);
});
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/crm_contact_token_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/crm_contact_token_spec.js
index 157e021fc60..c9879987931 100644
--- a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/crm_contact_token_spec.js
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/crm_contact_token_spec.js
@@ -195,7 +195,7 @@ describe('CrmContactToken', () => {
value: { data: '1' },
});
- const baseTokenEl = wrapper.find(BaseToken);
+ const baseTokenEl = wrapper.findComponent(BaseToken);
expect(baseTokenEl.exists()).toBe(true);
expect(baseTokenEl.props()).toMatchObject({
@@ -210,7 +210,7 @@ describe('CrmContactToken', () => {
value: { data: `${getIdFromGraphQLId(contact.id)}` },
});
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
expect(tokenSegments).toHaveLength(3); // Contact, =, Contact name
expect(tokenSegments.at(2).text()).toBe(`${contact.firstName} ${contact.lastName}`); // Contact name
@@ -222,12 +222,12 @@ describe('CrmContactToken', () => {
config: { ...mockCrmContactToken, defaultContacts },
stubs: { Portal: true },
});
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
const suggestionsSegment = tokenSegments.at(2);
suggestionsSegment.vm.$emit('activate');
await nextTick();
- const suggestions = wrapper.findAll(GlFilteredSearchSuggestion);
+ const suggestions = wrapper.findAllComponents(GlFilteredSearchSuggestion);
expect(suggestions).toHaveLength(defaultContacts.length);
defaultContacts.forEach((contact, index) => {
@@ -241,13 +241,13 @@ describe('CrmContactToken', () => {
config: { ...mockCrmContactToken, defaultContacts: [] },
stubs: { Portal: true },
});
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
const suggestionsSegment = tokenSegments.at(2);
suggestionsSegment.vm.$emit('activate');
await nextTick();
- expect(wrapper.find(GlFilteredSearchSuggestion).exists()).toBe(false);
- expect(wrapper.find(GlDropdownDivider).exists()).toBe(false);
+ expect(wrapper.findComponent(GlFilteredSearchSuggestion).exists()).toBe(false);
+ expect(wrapper.findComponent(GlDropdownDivider).exists()).toBe(false);
});
it('renders `DEFAULT_NONE_ANY` as default suggestions', () => {
@@ -256,11 +256,11 @@ describe('CrmContactToken', () => {
config: { ...mockCrmContactToken },
stubs: { Portal: true },
});
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
const suggestionsSegment = tokenSegments.at(2);
suggestionsSegment.vm.$emit('activate');
- const suggestions = wrapper.findAll(GlFilteredSearchSuggestion);
+ const suggestions = wrapper.findAllComponents(GlFilteredSearchSuggestion);
expect(suggestions).toHaveLength(DEFAULT_NONE_ANY.length);
DEFAULT_NONE_ANY.forEach((contact, index) => {
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/crm_organization_token_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/crm_organization_token_spec.js
index 977f8bbef61..16333b052e6 100644
--- a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/crm_organization_token_spec.js
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/crm_organization_token_spec.js
@@ -194,7 +194,7 @@ describe('CrmOrganizationToken', () => {
value: { data: '1' },
});
- const baseTokenEl = wrapper.find(BaseToken);
+ const baseTokenEl = wrapper.findComponent(BaseToken);
expect(baseTokenEl.exists()).toBe(true);
expect(baseTokenEl.props()).toMatchObject({
@@ -209,7 +209,7 @@ describe('CrmOrganizationToken', () => {
value: { data: `${getIdFromGraphQLId(organization.id)}` },
});
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
expect(tokenSegments).toHaveLength(3); // Organization, =, Organization name
expect(tokenSegments.at(2).text()).toBe(organization.name); // Organization name
@@ -221,12 +221,12 @@ describe('CrmOrganizationToken', () => {
config: { ...mockCrmOrganizationToken, defaultOrganizations },
stubs: { Portal: true },
});
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
const suggestionsSegment = tokenSegments.at(2);
suggestionsSegment.vm.$emit('activate');
await nextTick();
- const suggestions = wrapper.findAll(GlFilteredSearchSuggestion);
+ const suggestions = wrapper.findAllComponents(GlFilteredSearchSuggestion);
expect(suggestions).toHaveLength(defaultOrganizations.length);
defaultOrganizations.forEach((organization, index) => {
@@ -240,13 +240,13 @@ describe('CrmOrganizationToken', () => {
config: { ...mockCrmOrganizationToken, defaultOrganizations: [] },
stubs: { Portal: true },
});
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
const suggestionsSegment = tokenSegments.at(2);
suggestionsSegment.vm.$emit('activate');
await nextTick();
- expect(wrapper.find(GlFilteredSearchSuggestion).exists()).toBe(false);
- expect(wrapper.find(GlDropdownDivider).exists()).toBe(false);
+ expect(wrapper.findComponent(GlFilteredSearchSuggestion).exists()).toBe(false);
+ expect(wrapper.findComponent(GlDropdownDivider).exists()).toBe(false);
});
it('renders `DEFAULT_NONE_ANY` as default suggestions', () => {
@@ -255,11 +255,11 @@ describe('CrmOrganizationToken', () => {
config: { ...mockCrmOrganizationToken },
stubs: { Portal: true },
});
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
const suggestionsSegment = tokenSegments.at(2);
suggestionsSegment.vm.$emit('activate');
- const suggestions = wrapper.findAll(GlFilteredSearchSuggestion);
+ const suggestions = wrapper.findAllComponents(GlFilteredSearchSuggestion);
expect(suggestions).toHaveLength(DEFAULT_NONE_ANY.length);
DEFAULT_NONE_ANY.forEach((organization, index) => {
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/emoji_token_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/emoji_token_spec.js
index dcb0d095b1b..bf4a6eb7635 100644
--- a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/emoji_token_spec.js
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/emoji_token_spec.js
@@ -135,14 +135,16 @@ describe('EmojiToken', () => {
});
it('renders gl-filtered-search-token component', () => {
- expect(wrapper.find(GlFilteredSearchToken).exists()).toBe(true);
+ expect(wrapper.findComponent(GlFilteredSearchToken).exists()).toBe(true);
});
it('renders token item when value is selected', () => {
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
expect(tokenSegments).toHaveLength(3); // My Reaction, =, "thumbsup"
- expect(tokenSegments.at(2).find(GlEmoji).attributes('data-name')).toEqual('thumbsup');
+ expect(tokenSegments.at(2).findComponent(GlEmoji).attributes('data-name')).toEqual(
+ 'thumbsup',
+ );
});
it('renders provided defaultEmojis as suggestions', async () => {
@@ -151,12 +153,12 @@ describe('EmojiToken', () => {
config: { ...mockReactionEmojiToken, defaultEmojis },
stubs: { Portal: true, GlEmoji },
});
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
const suggestionsSegment = tokenSegments.at(2);
suggestionsSegment.vm.$emit('activate');
await nextTick();
- const suggestions = wrapper.findAll(GlFilteredSearchSuggestion);
+ const suggestions = wrapper.findAllComponents(GlFilteredSearchSuggestion);
expect(suggestions).toHaveLength(defaultEmojis.length);
defaultEmojis.forEach((emoji, index) => {
@@ -170,13 +172,13 @@ describe('EmojiToken', () => {
config: { ...mockReactionEmojiToken, defaultEmojis: [] },
stubs: { Portal: true, GlEmoji },
});
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
const suggestionsSegment = tokenSegments.at(2);
suggestionsSegment.vm.$emit('activate');
await nextTick();
- expect(wrapper.find(GlFilteredSearchSuggestion).exists()).toBe(false);
- expect(wrapper.find(GlDropdownDivider).exists()).toBe(false);
+ expect(wrapper.findComponent(GlFilteredSearchSuggestion).exists()).toBe(false);
+ expect(wrapper.findComponent(GlDropdownDivider).exists()).toBe(false);
});
it('renders `DEFAULT_LABEL_NONE` and `DEFAULT_LABEL_ANY` as default suggestions', async () => {
@@ -185,12 +187,12 @@ describe('EmojiToken', () => {
config: { ...mockReactionEmojiToken },
stubs: { Portal: true, GlEmoji },
});
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
const suggestionsSegment = tokenSegments.at(2);
suggestionsSegment.vm.$emit('activate');
await nextTick();
- const suggestions = wrapper.findAll(GlFilteredSearchSuggestion);
+ const suggestions = wrapper.findAllComponents(GlFilteredSearchSuggestion);
expect(suggestions).toHaveLength(2);
expect(suggestions.at(0).text()).toBe(DEFAULT_LABEL_NONE.text);
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/label_token_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/label_token_spec.js
index 51161a1a0ef..01e281884ed 100644
--- a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/label_token_spec.js
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/label_token_spec.js
@@ -156,7 +156,7 @@ describe('LabelToken', () => {
});
it('renders base-token component', () => {
- const baseTokenEl = wrapper.find(BaseToken);
+ const baseTokenEl = wrapper.findComponent(BaseToken);
expect(baseTokenEl.exists()).toBe(true);
expect(baseTokenEl.props()).toMatchObject({
@@ -166,7 +166,7 @@ describe('LabelToken', () => {
});
it('renders token item when value is selected', () => {
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
expect(tokenSegments).toHaveLength(3); // Label, =, "Foo Label"
expect(tokenSegments.at(2).text()).toBe(`~${mockRegularLabel.title}`); // "Foo Label"
@@ -181,12 +181,12 @@ describe('LabelToken', () => {
config: { ...mockLabelToken, defaultLabels },
stubs: { Portal: true },
});
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
const suggestionsSegment = tokenSegments.at(2);
suggestionsSegment.vm.$emit('activate');
await nextTick();
- const suggestions = wrapper.findAll(GlFilteredSearchSuggestion);
+ const suggestions = wrapper.findAllComponents(GlFilteredSearchSuggestion);
expect(suggestions).toHaveLength(defaultLabels.length);
defaultLabels.forEach((label, index) => {
@@ -200,13 +200,13 @@ describe('LabelToken', () => {
config: { ...mockLabelToken, defaultLabels: [] },
stubs: { Portal: true },
});
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
const suggestionsSegment = tokenSegments.at(2);
suggestionsSegment.vm.$emit('activate');
await nextTick();
- expect(wrapper.find(GlFilteredSearchSuggestion).exists()).toBe(false);
- expect(wrapper.find(GlDropdownDivider).exists()).toBe(false);
+ expect(wrapper.findComponent(GlFilteredSearchSuggestion).exists()).toBe(false);
+ expect(wrapper.findComponent(GlDropdownDivider).exists()).toBe(false);
});
it('renders `DEFAULT_NONE_ANY` as default suggestions', () => {
@@ -215,11 +215,11 @@ describe('LabelToken', () => {
config: { ...mockLabelToken },
stubs: { Portal: true },
});
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
const suggestionsSegment = tokenSegments.at(2);
suggestionsSegment.vm.$emit('activate');
- const suggestions = wrapper.findAll(GlFilteredSearchSuggestion);
+ const suggestions = wrapper.findAllComponents(GlFilteredSearchSuggestion);
expect(suggestions).toHaveLength(DEFAULT_NONE_ANY.length);
DEFAULT_NONE_ANY.forEach((label, index) => {
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/milestone_token_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/milestone_token_spec.js
index 7c545f76c0b..f71ba51fc5b 100644
--- a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/milestone_token_spec.js
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/milestone_token_spec.js
@@ -155,11 +155,11 @@ describe('MilestoneToken', () => {
});
it('renders gl-filtered-search-token component', () => {
- expect(wrapper.find(GlFilteredSearchToken).exists()).toBe(true);
+ expect(wrapper.findComponent(GlFilteredSearchToken).exists()).toBe(true);
});
it('renders token item when value is selected', () => {
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
expect(tokenSegments).toHaveLength(3); // Milestone, =, '%"4.0"'
expect(tokenSegments.at(2).text()).toBe(`%${mockRegularMilestone.title}`); // "4.0 RC1"
@@ -171,12 +171,12 @@ describe('MilestoneToken', () => {
config: { ...mockMilestoneToken, defaultMilestones },
stubs: { Portal: true },
});
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
const suggestionsSegment = tokenSegments.at(2);
suggestionsSegment.vm.$emit('activate');
await nextTick();
- const suggestions = wrapper.findAll(GlFilteredSearchSuggestion);
+ const suggestions = wrapper.findAllComponents(GlFilteredSearchSuggestion);
expect(suggestions).toHaveLength(defaultMilestones.length);
defaultMilestones.forEach((milestone, index) => {
@@ -190,13 +190,13 @@ describe('MilestoneToken', () => {
config: { ...mockMilestoneToken, defaultMilestones: [] },
stubs: { Portal: true },
});
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
const suggestionsSegment = tokenSegments.at(2);
suggestionsSegment.vm.$emit('activate');
await nextTick();
- expect(wrapper.find(GlFilteredSearchSuggestion).exists()).toBe(false);
- expect(wrapper.find(GlDropdownDivider).exists()).toBe(false);
+ expect(wrapper.findComponent(GlFilteredSearchSuggestion).exists()).toBe(false);
+ expect(wrapper.findComponent(GlDropdownDivider).exists()).toBe(false);
});
it('renders `DEFAULT_MILESTONES` as default suggestions', async () => {
@@ -205,12 +205,12 @@ describe('MilestoneToken', () => {
config: { ...mockMilestoneToken },
stubs: { Portal: true },
});
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
const suggestionsSegment = tokenSegments.at(2);
suggestionsSegment.vm.$emit('activate');
await nextTick();
- const suggestions = wrapper.findAll(GlFilteredSearchSuggestion);
+ const suggestions = wrapper.findAllComponents(GlFilteredSearchSuggestion);
expect(suggestions).toHaveLength(DEFAULT_MILESTONES.length);
DEFAULT_MILESTONES.forEach((milestone, index) => {
diff --git a/spec/frontend/vue_shared/components/gitlab_version_check_spec.js b/spec/frontend/vue_shared/components/gitlab_version_check_spec.js
index b180e8c12dd..6699ae5fb69 100644
--- a/spec/frontend/vue_shared/components/gitlab_version_check_spec.js
+++ b/spec/frontend/vue_shared/components/gitlab_version_check_spec.js
@@ -26,13 +26,44 @@ describe('GitlabVersionCheck', () => {
wrapper = shallowMount(GitlabVersionCheck);
};
+ const dummyGon = {
+ relative_url_root: '/',
+ };
+
+ let originalGon;
+
afterEach(() => {
wrapper.destroy();
mock.restore();
+ window.gon = originalGon;
});
const findGlBadge = () => wrapper.findComponent(GlBadge);
+ describe.each`
+ root | description
+ ${'/'} | ${'not used (uses its own (sub)domain)'}
+ ${'/gitlab'} | ${'custom path'}
+ ${'/service/gitlab'} | ${'custom path with 2 depth'}
+ `('path for version_check.json', ({ root, description }) => {
+ describe(`when relative url is ${description}: ${root}`, () => {
+ beforeEach(async () => {
+ originalGon = window.gon;
+ window.gon = { ...dummyGon };
+ window.gon.relative_url_root = root;
+ createComponent(defaultResponse);
+ await waitForPromises(); // Ensure we wrap up the axios call
+ });
+
+ it('reflects the relative url setting', () => {
+ expect(mock.history.get.length).toBe(1);
+
+ const pathRegex = new RegExp(`^${root}`);
+ expect(mock.history.get[0].url).toMatch(pathRegex);
+ });
+ });
+ });
+
describe('template', () => {
describe.each`
description | mockResponse | renders
diff --git a/spec/frontend/vue_shared/components/gl_modal_vuex_spec.js b/spec/frontend/vue_shared/components/gl_modal_vuex_spec.js
index c0a6588833e..2dcd91f737f 100644
--- a/spec/frontend/vue_shared/components/gl_modal_vuex_spec.js
+++ b/spec/frontend/vue_shared/components/gl_modal_vuex_spec.js
@@ -59,7 +59,7 @@ describe('GlModalVuex', () => {
default: `<div>${TEST_SLOT}</div>`,
},
});
- const glModal = wrapper.find(GlModal);
+ const glModal = wrapper.findComponent(GlModal);
expect(glModal.props('modalId')).toBe(TEST_MODAL_ID);
expect(glModal.text()).toContain(TEST_SLOT);
@@ -76,7 +76,7 @@ describe('GlModalVuex', () => {
okVariant,
},
});
- const glModal = wrapper.find(GlModal);
+ const glModal = wrapper.findComponent(GlModal);
expect(glModal.attributes('title')).toEqual(title);
expect(glModal.attributes('oktitle')).toEqual(title);
@@ -90,7 +90,7 @@ describe('GlModalVuex', () => {
listeners: { ok },
});
- const glModal = wrapper.find(GlModal);
+ const glModal = wrapper.findComponent(GlModal);
glModal.vm.$emit('ok');
expect(ok).toHaveBeenCalledTimes(1);
@@ -101,7 +101,7 @@ describe('GlModalVuex', () => {
factory();
- const glModal = wrapper.find(GlModal);
+ const glModal = wrapper.findComponent(GlModal);
glModal.vm.$emit('shown');
expect(actions.show).toHaveBeenCalledTimes(1);
@@ -112,7 +112,7 @@ describe('GlModalVuex', () => {
factory();
- const glModal = wrapper.find(GlModal);
+ const glModal = wrapper.findComponent(GlModal);
glModal.vm.$emit('hidden');
expect(actions.hide).toHaveBeenCalledTimes(1);
diff --git a/spec/frontend/vue_shared/components/help_popover_spec.js b/spec/frontend/vue_shared/components/help_popover_spec.js
index 64dce194327..6fd5ae0e946 100644
--- a/spec/frontend/vue_shared/components/help_popover_spec.js
+++ b/spec/frontend/vue_shared/components/help_popover_spec.js
@@ -7,8 +7,8 @@ describe('HelpPopover', () => {
const title = 'popover <strong>title</strong>';
const content = 'popover <b>content</b>';
- const findQuestionButton = () => wrapper.find(GlButton);
- const findPopover = () => wrapper.find(GlPopover);
+ const findQuestionButton = () => wrapper.findComponent(GlButton);
+ const findPopover = () => wrapper.findComponent(GlPopover);
const createComponent = ({ props, ...opts } = {}) => {
wrapper = mount(HelpPopover, {
diff --git a/spec/frontend/vue_shared/components/integration_help_text_spec.js b/spec/frontend/vue_shared/components/integration_help_text_spec.js
index c0e8b719007..c63e46313b3 100644
--- a/spec/frontend/vue_shared/components/integration_help_text_spec.js
+++ b/spec/frontend/vue_shared/components/integration_help_text_spec.js
@@ -30,9 +30,9 @@ describe('IntegrationHelpText component', () => {
it('should use the gl components', () => {
wrapper = createComponent();
- expect(wrapper.find(GlSprintf).exists()).toBe(true);
- expect(wrapper.find(GlIcon).exists()).toBe(true);
- expect(wrapper.find(GlLink).exists()).toBe(true);
+ expect(wrapper.findComponent(GlSprintf).exists()).toBe(true);
+ expect(wrapper.findComponent(GlIcon).exists()).toBe(true);
+ expect(wrapper.findComponent(GlLink).exists()).toBe(true);
});
it('should render the help text', () => {
@@ -44,9 +44,9 @@ describe('IntegrationHelpText component', () => {
it('should not use the gl-link and gl-icon components', () => {
wrapper = createComponent({ message: 'Click nowhere!' });
- expect(wrapper.find(GlSprintf).exists()).toBe(true);
- expect(wrapper.find(GlIcon).exists()).toBe(false);
- expect(wrapper.find(GlLink).exists()).toBe(false);
+ expect(wrapper.findComponent(GlSprintf).exists()).toBe(true);
+ expect(wrapper.findComponent(GlIcon).exists()).toBe(false);
+ expect(wrapper.findComponent(GlLink).exists()).toBe(false);
});
it('should not render the link when start and end is not provided', () => {
diff --git a/spec/frontend/vue_shared/components/markdown/field_spec.js b/spec/frontend/vue_shared/components/markdown/field_spec.js
index 85a135d2b89..50864a4bf25 100644
--- a/spec/frontend/vue_shared/components/markdown/field_spec.js
+++ b/spec/frontend/vue_shared/components/markdown/field_spec.js
@@ -76,7 +76,7 @@ describe('Markdown field component', () => {
const getMarkdownButton = () => subject.find('.js-md');
const getListBulletedButton = () => subject.findAll('.js-md[title="Add a bullet list"]');
const getVideo = () => subject.find('video');
- const getAttachButton = () => subject.find('.button-attach-file');
+ const getAttachButton = () => subject.findByTestId('button-attach-file');
const clickAttachButton = () => getAttachButton().trigger('click');
const findDropzone = () => subject.find('.div-dropzone');
const findMarkdownHeader = () => subject.findComponent(MarkdownFieldHeader);
@@ -232,13 +232,10 @@ describe('Markdown field component', () => {
});
});
- it('should render attach a file button', () => {
- expect(getAttachButton().text()).toBe('Attach a file');
- });
-
it('should trigger dropzone when attach button is clicked', () => {
expect(dropzoneSpy).not.toHaveBeenCalled();
+ getAttachButton().trigger('click');
clickAttachButton();
expect(dropzoneSpy).toHaveBeenCalled();
diff --git a/spec/frontend/vue_shared/components/markdown/header_spec.js b/spec/frontend/vue_shared/components/markdown/header_spec.js
index 67222cab247..9831908f806 100644
--- a/spec/frontend/vue_shared/components/markdown/header_spec.js
+++ b/spec/frontend/vue_shared/components/markdown/header_spec.js
@@ -21,7 +21,7 @@ describe('Markdown field header component', () => {
const findWriteTab = () => wrapper.findByTestId('write-tab');
const findPreviewTab = () => wrapper.findByTestId('preview-tab');
const findToolbar = () => wrapper.findByTestId('md-header-toolbar');
- const findToolbarButtons = () => wrapper.findAll(ToolbarButton);
+ const findToolbarButtons = () => wrapper.findAllComponents(ToolbarButton);
const findToolbarButtonByProp = (prop, value) =>
findToolbarButtons()
.filter((button) => button.props(prop) === value)
@@ -44,16 +44,16 @@ describe('Markdown field header component', () => {
describe('markdown header buttons', () => {
it('renders the buttons with the correct title', () => {
const buttons = [
+ 'Insert suggestion',
'Add bold text (⌘B)',
'Add italic text (⌘I)',
'Add strikethrough text (⌘⇧X)',
'Insert a quote',
- 'Insert suggestion',
'Insert code',
'Add a link (⌘K)',
'Add a bullet list',
'Add a numbered list',
- 'Add a task list',
+ 'Add a checklist',
'Add a collapsible section',
'Add a table',
'Go full screen',
@@ -65,6 +65,13 @@ describe('Markdown field header component', () => {
});
});
+ it('renders "Attach a file or image" button using gl-button', () => {
+ const button = wrapper.findByTestId('button-attach-file');
+
+ expect(button.element.tagName).toBe('GL-BUTTON-STUB');
+ expect(button.attributes('title')).toBe('Attach a file or image');
+ });
+
describe('when the user is on a non-Mac', () => {
beforeEach(() => {
delete window.gl.client.isMac;
@@ -118,8 +125,8 @@ describe('Markdown field header component', () => {
),
]);
- expect(wrapper.emitted('preview-markdown')).toBeFalsy();
- expect(wrapper.emitted('write-markdown')).toBeFalsy();
+ expect(wrapper.emitted('preview-markdown')).toBeUndefined();
+ expect(wrapper.emitted('write-markdown')).toBeUndefined();
});
it('blurs preview link after click', () => {
diff --git a/spec/frontend/vue_shared/components/markdown/suggestion_diff_header_spec.js b/spec/frontend/vue_shared/components/markdown/suggestion_diff_header_spec.js
index 9944267cf24..9db1b779a04 100644
--- a/spec/frontend/vue_shared/components/markdown/suggestion_diff_header_spec.js
+++ b/spec/frontend/vue_shared/components/markdown/suggestion_diff_header_spec.js
@@ -38,13 +38,13 @@ describe('Suggestion Diff component', () => {
wrapper.destroy();
});
- const findApplyButton = () => wrapper.find(ApplySuggestion);
+ const findApplyButton = () => wrapper.findComponent(ApplySuggestion);
const findApplyBatchButton = () => wrapper.find('.js-apply-batch-btn');
const findAddToBatchButton = () => wrapper.find('.js-add-to-batch-btn');
const findRemoveFromBatchButton = () => wrapper.find('.js-remove-from-batch-btn');
const findHeader = () => wrapper.find('.js-suggestion-diff-header');
const findHelpButton = () => wrapper.find('.js-help-btn');
- const findLoading = () => wrapper.find(GlLoadingIcon);
+ const findLoading = () => wrapper.findComponent(GlLoadingIcon);
it('renders a suggestion header', () => {
createComponent();
diff --git a/spec/frontend/vue_shared/components/markdown/suggestion_diff_spec.js b/spec/frontend/vue_shared/components/markdown/suggestion_diff_spec.js
index af27e953776..d84483c1663 100644
--- a/spec/frontend/vue_shared/components/markdown/suggestion_diff_spec.js
+++ b/spec/frontend/vue_shared/components/markdown/suggestion_diff_spec.js
@@ -71,7 +71,7 @@ describe('Suggestion Diff component', () => {
});
it('renders a correct amount of suggestion diff rows', () => {
- expect(wrapper.findAll(SuggestionDiffRow)).toHaveLength(3);
+ expect(wrapper.findAllComponents(SuggestionDiffRow)).toHaveLength(3);
});
it.each`
@@ -81,14 +81,14 @@ describe('Suggestion Diff component', () => {
${'addToBatch'} | ${[]} | ${[suggestionId]}
${'removeFromBatch'} | ${[]} | ${[suggestionId]}
`('emits $event event on sugestion diff header $event', ({ event, childArgs, args }) => {
- wrapper.find(SuggestionDiffHeader).vm.$emit(event, ...childArgs);
+ wrapper.findComponent(SuggestionDiffHeader).vm.$emit(event, ...childArgs);
expect(wrapper.emitted(event)).toBeDefined();
expect(wrapper.emitted(event)).toEqual([args]);
});
it('passes suggestion batch props to suggestion diff header', () => {
- expect(wrapper.find(SuggestionDiffHeader).props()).toMatchObject({
+ expect(wrapper.findComponent(SuggestionDiffHeader).props()).toMatchObject({
batchSuggestionsCount: 1,
isBatched: true,
isApplyingBatch: MOCK_DATA.suggestion.is_applying_batch,
diff --git a/spec/frontend/vue_shared/components/markdown/toolbar_button_spec.js b/spec/frontend/vue_shared/components/markdown/toolbar_button_spec.js
index 19e4f2d8c92..82210e79799 100644
--- a/spec/frontend/vue_shared/components/markdown/toolbar_button_spec.js
+++ b/spec/frontend/vue_shared/components/markdown/toolbar_button_spec.js
@@ -26,7 +26,7 @@ describe('toolbar_button', () => {
});
const getButtonShortcutsAttr = () => {
- return wrapper.find(GlButton).attributes('data-md-shortcuts');
+ return wrapper.findComponent(GlButton).attributes('data-md-shortcuts');
};
describe('keyboard shortcuts', () => {
diff --git a/spec/frontend/vue_shared/components/memory_graph_spec.js b/spec/frontend/vue_shared/components/memory_graph_spec.js
index 53b96bd1b98..ae8d5ff78ba 100644
--- a/spec/frontend/vue_shared/components/memory_graph_spec.js
+++ b/spec/frontend/vue_shared/components/memory_graph_spec.js
@@ -47,7 +47,7 @@ describe('MemoryGraph', () => {
it('should draw container with chart', () => {
expect(wrapper.element).toMatchSnapshot();
expect(wrapper.find('.memory-graph-container').exists()).toBe(true);
- expect(wrapper.find(GlSparklineChart).exists()).toBe(true);
+ expect(wrapper.findComponent(GlSparklineChart).exists()).toBe(true);
});
});
});
diff --git a/spec/frontend/vue_shared/components/metric_images/metric_images_tab_spec.js b/spec/frontend/vue_shared/components/metric_images/metric_images_tab_spec.js
index 2cefa77b72d..1789610dba9 100644
--- a/spec/frontend/vue_shared/components/metric_images/metric_images_tab_spec.js
+++ b/spec/frontend/vue_shared/components/metric_images/metric_images_tab_spec.js
@@ -114,7 +114,7 @@ describe('Metric images tab', () => {
await waitForPromises();
- expect(findModal().attributes('visible')).toBeFalsy();
+ expect(findModal().attributes('visible')).toBeUndefined();
});
it('should add files and url when selected', async () => {
diff --git a/spec/frontend/vue_shared/components/namespace_select/namespace_select_spec.js b/spec/frontend/vue_shared/components/namespace_select/namespace_select_spec.js
index c11b20a692e..2c14d65186b 100644
--- a/spec/frontend/vue_shared/components/namespace_select/namespace_select_spec.js
+++ b/spec/frontend/vue_shared/components/namespace_select/namespace_select_spec.js
@@ -1,5 +1,12 @@
import { nextTick } from 'vue';
-import { GlDropdown, GlDropdownItem, GlDropdownSectionHeader, GlSearchBoxByType } from '@gitlab/ui';
+import {
+ GlDropdown,
+ GlDropdownItem,
+ GlDropdownSectionHeader,
+ GlSearchBoxByType,
+ GlIntersectionObserver,
+ GlLoadingIcon,
+} from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import NamespaceSelect, {
i18n,
@@ -7,7 +14,7 @@ import NamespaceSelect, {
} from '~/vue_shared/components/namespace_select/namespace_select.vue';
import { userNamespaces, groupNamespaces } from './mock_data';
-const FLAT_NAMESPACES = [...groupNamespaces, ...userNamespaces];
+const FLAT_NAMESPACES = [...userNamespaces, ...groupNamespaces];
const EMPTY_NAMESPACE_TITLE = 'Empty namespace TEST';
const EMPTY_NAMESPACE_ITEM = { id: EMPTY_NAMESPACE_ID, humanName: EMPTY_NAMESPACE_TITLE };
@@ -31,6 +38,8 @@ describe('Namespace Select', () => {
const findDropdown = () => wrapper.findComponent(GlDropdown);
const findDropdownText = () => findDropdown().props('text');
const findDropdownItems = () => wrapper.findAllComponents(GlDropdownItem);
+ const findGroupDropdownItems = () =>
+ wrapper.findByTestId('namespace-list-groups').findAllComponents(GlDropdownItem);
const findDropdownItemsTexts = () => findDropdownItems().wrappers.map((x) => x.text());
const findSectionHeaders = () => wrapper.findAllComponents(GlDropdownSectionHeader);
const findSearchBox = () => wrapper.findComponent(GlSearchBoxByType);
@@ -59,7 +68,7 @@ describe('Namespace Select', () => {
it('splits group and user namespaces', () => {
const headers = findSectionHeaders();
- expect(wrappersText(headers)).toEqual([i18n.GROUPS, i18n.USERS]);
+ expect(wrappersText(headers)).toEqual([i18n.USERS, i18n.GROUPS]);
});
it('does not render wrapper as full width', () => {
@@ -89,18 +98,20 @@ describe('Namespace Select', () => {
describe('with search', () => {
it.each`
- term | includeEmptyNamespace | expectedItems
- ${''} | ${false} | ${[...groupNamespaces, ...userNamespaces]}
- ${'sub'} | ${false} | ${[groupNamespaces[1]]}
- ${'User'} | ${false} | ${[...userNamespaces]}
- ${'User'} | ${true} | ${[...userNamespaces]}
- ${'namespace'} | ${true} | ${[EMPTY_NAMESPACE_ITEM, ...userNamespaces]}
+ term | includeEmptyNamespace | shouldFilterNamespaces | expectedItems
+ ${''} | ${false} | ${true} | ${[...userNamespaces, ...groupNamespaces]}
+ ${'sub'} | ${false} | ${true} | ${[groupNamespaces[1]]}
+ ${'User'} | ${false} | ${true} | ${[...userNamespaces]}
+ ${'User'} | ${true} | ${true} | ${[...userNamespaces]}
+ ${'namespace'} | ${true} | ${true} | ${[EMPTY_NAMESPACE_ITEM, ...userNamespaces]}
+ ${'sub'} | ${false} | ${false} | ${[...userNamespaces, ...groupNamespaces]}
`(
- 'with term=$term and includeEmptyNamespace=$includeEmptyNamespace, should show $expectedItems.length',
- async ({ term, includeEmptyNamespace, expectedItems }) => {
+ 'with term=$term, includeEmptyNamespace=$includeEmptyNamespace, and shouldFilterNamespaces=$shouldFilterNamespaces should show $expectedItems.length',
+ async ({ term, includeEmptyNamespace, shouldFilterNamespaces, expectedItems }) => {
wrapper = createComponent({
includeEmptyNamespace,
emptyNamespaceTitle: EMPTY_NAMESPACE_TITLE,
+ shouldFilterNamespaces,
});
search(term);
@@ -114,6 +125,18 @@ describe('Namespace Select', () => {
);
});
+ describe('when search is typed in', () => {
+ it('emits `search` event', async () => {
+ wrapper = createComponent();
+
+ wrapper.findComponent(GlSearchBoxByType).vm.$emit('input', 'foo');
+
+ await nextTick();
+
+ expect(wrapper.emitted('search')).toEqual([['foo']]);
+ });
+ });
+
describe('with a selected namespace', () => {
const selectedGroupIndex = 1;
const selectedItem = groupNamespaces[selectedGroupIndex];
@@ -121,7 +144,8 @@ describe('Namespace Select', () => {
beforeEach(() => {
wrapper = createComponent();
- findDropdownItems().at(selectedGroupIndex).vm.$emit('click');
+ wrapper.findComponent(GlSearchBoxByType).vm.$emit('input', 'foo');
+ findGroupDropdownItems().at(selectedGroupIndex).vm.$emit('click');
});
it('sets the dropdown text', () => {
@@ -132,6 +156,10 @@ describe('Namespace Select', () => {
const args = [selectedItem];
expect(wrapper.emitted('select')).toEqual([args]);
});
+
+ it('clears search', () => {
+ expect(wrapper.findComponent(GlSearchBoxByType).props('value')).toBe('');
+ });
});
describe('with an empty namespace option', () => {
@@ -166,4 +194,33 @@ describe('Namespace Select', () => {
expect(findDropdownItemsTexts().includes(EMPTY_NAMESPACE_TITLE)).toBe(shouldShow);
});
});
+
+ describe('when `hasNextPageOfGroups` prop is `true`', () => {
+ it('renders `GlIntersectionObserver` and emits `load-more-groups` event when bottom is reached', () => {
+ wrapper = createComponent({ hasNextPageOfGroups: true });
+
+ const intersectionObserver = wrapper.findComponent(GlIntersectionObserver);
+
+ intersectionObserver.vm.$emit('appear');
+
+ expect(intersectionObserver.exists()).toBe(true);
+ expect(wrapper.emitted('load-more-groups')).toEqual([[]]);
+ });
+
+ describe('when `isLoadingMoreGroups` prop is `true`', () => {
+ it('renders a loading icon', () => {
+ wrapper = createComponent({ hasNextPageOfGroups: true, isLoadingMoreGroups: true });
+
+ expect(wrapper.findComponent(GlLoadingIcon).exists()).toBe(true);
+ });
+ });
+ });
+
+ describe('when `isSearchLoading` prop is `true`', () => {
+ it('sets `isLoading` prop to `true`', () => {
+ wrapper = createComponent({ isSearchLoading: true });
+
+ expect(wrapper.findComponent(GlSearchBoxByType).props('isLoading')).toBe(true);
+ });
+ });
});
diff --git a/spec/frontend/vue_shared/components/navigation_tabs_spec.js b/spec/frontend/vue_shared/components/navigation_tabs_spec.js
index 30a89fed12f..b1bec28bffb 100644
--- a/spec/frontend/vue_shared/components/navigation_tabs_spec.js
+++ b/spec/frontend/vue_shared/components/navigation_tabs_spec.js
@@ -44,7 +44,7 @@ describe('navigation tabs component', () => {
});
it('should render tabs', () => {
- expect(wrapper.findAll(GlTab)).toHaveLength(data.length);
+ expect(wrapper.findAllComponents(GlTab)).toHaveLength(data.length);
});
it('should render active tab', () => {
diff --git a/spec/frontend/vue_shared/components/notes/noteable_warning_spec.js b/spec/frontend/vue_shared/components/notes/noteable_warning_spec.js
index 99b65ca6937..17a62ae8a33 100644
--- a/spec/frontend/vue_shared/components/notes/noteable_warning_spec.js
+++ b/spec/frontend/vue_shared/components/notes/noteable_warning_spec.js
@@ -6,10 +6,11 @@ import NoteableWarning from '~/vue_shared/components/notes/noteable_warning.vue'
describe('Issue Warning Component', () => {
let wrapper;
- const findIcon = (w = wrapper) => w.find(GlIcon);
- const findLockedBlock = (w = wrapper) => w.find({ ref: 'locked' });
- const findConfidentialBlock = (w = wrapper) => w.find({ ref: 'confidential' });
- const findLockedAndConfidentialBlock = (w = wrapper) => w.find({ ref: 'lockedAndConfidential' });
+ const findIcon = (w = wrapper) => w.findComponent(GlIcon);
+ const findLockedBlock = (w = wrapper) => w.findComponent({ ref: 'locked' });
+ const findConfidentialBlock = (w = wrapper) => w.findComponent({ ref: 'confidential' });
+ const findLockedAndConfidentialBlock = (w = wrapper) =>
+ w.findComponent({ ref: 'lockedAndConfidential' });
const createComponent = (props) =>
shallowMount(NoteableWarning, {
@@ -73,7 +74,7 @@ describe('Issue Warning Component', () => {
});
it('renders warning icon', () => {
- expect(wrapper.find(GlIcon).exists()).toBe(true);
+ expect(wrapper.findComponent(GlIcon).exists()).toBe(true);
});
it('does not render information about locked noteable', () => {
@@ -99,7 +100,7 @@ describe('Issue Warning Component', () => {
});
it('does not render warning icon', () => {
- expect(wrapper.find(GlIcon).exists()).toBe(false);
+ expect(wrapper.findComponent(GlIcon).exists()).toBe(false);
});
it('does not render information about locked noteable', () => {
diff --git a/spec/frontend/vue_shared/components/notes/placeholder_note_spec.js b/spec/frontend/vue_shared/components/notes/placeholder_note_spec.js
index f951cfd5cd9..b86c8946e96 100644
--- a/spec/frontend/vue_shared/components/notes/placeholder_note_spec.js
+++ b/spec/frontend/vue_shared/components/notes/placeholder_note_spec.js
@@ -14,7 +14,7 @@ const getters = {
describe('Issue placeholder note component', () => {
let wrapper;
- const findNote = () => wrapper.find({ ref: 'note' });
+ const findNote = () => wrapper.findComponent({ ref: 'note' });
const createComponent = (isIndividual = false, propsData = {}) => {
wrapper = shallowMount(IssuePlaceholderNote, {
diff --git a/spec/frontend/vue_shared/components/paginated_table_with_search_and_tabs/paginated_table_with_search_and_tabs_spec.js b/spec/frontend/vue_shared/components/paginated_table_with_search_and_tabs/paginated_table_with_search_and_tabs_spec.js
index 51a936c0509..c0c3c4a9729 100644
--- a/spec/frontend/vue_shared/components/paginated_table_with_search_and_tabs/paginated_table_with_search_and_tabs_spec.js
+++ b/spec/frontend/vue_shared/components/paginated_table_with_search_and_tabs/paginated_table_with_search_and_tabs_spec.js
@@ -92,15 +92,15 @@ describe('AlertManagementEmptyState', () => {
const EmptyState = () => wrapper.find('.empty-state');
const ItemsTable = () => wrapper.find('.gl-table');
- const ErrorAlert = () => wrapper.find(GlAlert);
- const Pagination = () => wrapper.find(GlPagination);
- const Tabs = () => wrapper.find(GlTabs);
+ const ErrorAlert = () => wrapper.findComponent(GlAlert);
+ const Pagination = () => wrapper.findComponent(GlPagination);
+ const Tabs = () => wrapper.findComponent(GlTabs);
const ActionButton = () => wrapper.find('.header-actions > button');
- const Filters = () => wrapper.find(FilteredSearchBar);
- const findPagination = () => wrapper.find(GlPagination);
- const findStatusFilterTabs = () => wrapper.findAll(GlTab);
- const findStatusTabs = () => wrapper.find(GlTabs);
- const findStatusFilterBadge = () => wrapper.findAll(GlBadge);
+ const Filters = () => wrapper.findComponent(FilteredSearchBar);
+ const findPagination = () => wrapper.findComponent(GlPagination);
+ const findStatusFilterTabs = () => wrapper.findAllComponents(GlTab);
+ const findStatusTabs = () => wrapper.findComponent(GlTabs);
+ const findStatusFilterBadge = () => wrapper.findAllComponents(GlBadge);
describe('Snowplow tracking', () => {
beforeEach(() => {
@@ -213,7 +213,7 @@ describe('AlertManagementEmptyState', () => {
});
it('should render pagination', () => {
- expect(wrapper.find(GlPagination).exists()).toBe(true);
+ expect(wrapper.findComponent(GlPagination).exists()).toBe(true);
});
describe('prevPage', () => {
diff --git a/spec/frontend/vue_shared/components/pagination_bar/pagination_bar_spec.js b/spec/frontend/vue_shared/components/pagination_bar/pagination_bar_spec.js
index 08119dee8af..b3be2f8a775 100644
--- a/spec/frontend/vue_shared/components/pagination_bar/pagination_bar_spec.js
+++ b/spec/frontend/vue_shared/components/pagination_bar/pagination_bar_spec.js
@@ -64,7 +64,7 @@ describe('Pagination bar', () => {
},
});
- expect(wrapper.find(GlDropdown).find('button').text()).toMatchInterpolatedText(
+ expect(wrapper.findComponent(GlDropdown).find('button').text()).toMatchInterpolatedText(
`${CURRENT_PAGE_SIZE} items per page`,
);
});
diff --git a/spec/frontend/vue_shared/components/pagination_links_spec.js b/spec/frontend/vue_shared/components/pagination_links_spec.js
index 83f1e2844f9..d444ad7a733 100644
--- a/spec/frontend/vue_shared/components/pagination_links_spec.js
+++ b/spec/frontend/vue_shared/components/pagination_links_spec.js
@@ -41,7 +41,7 @@ describe('Pagination links component', () => {
beforeEach(() => {
createComponent();
- glPagination = wrapper.find(GlPagination);
+ glPagination = wrapper.findComponent(GlPagination);
});
afterEach(() => {
diff --git a/spec/frontend/vue_shared/components/project_avatar_spec.js b/spec/frontend/vue_shared/components/project_avatar_spec.js
index d55f3127a74..af828fbca51 100644
--- a/spec/frontend/vue_shared/components/project_avatar_spec.js
+++ b/spec/frontend/vue_shared/components/project_avatar_spec.js
@@ -42,6 +42,42 @@ describe('ProjectAvatar', () => {
});
});
+ describe('with `projectId` prop', () => {
+ const validatorFunc = ProjectAvatar.props.projectId.validator;
+
+ it('prop validators return true for valid types', () => {
+ expect(validatorFunc(1)).toBe(true);
+ expect(validatorFunc('gid://gitlab/Project/1')).toBe(true);
+ });
+
+ it('prop validators return false for invalid types', () => {
+ expect(validatorFunc('1')).toBe(false);
+ });
+
+ it('renders GlAvatar with `entityId` 0 when `projectId` is not informed', () => {
+ createComponent({ props: { projectId: undefined } });
+
+ const avatar = findGlAvatar();
+ expect(avatar.props('entityId')).toBe(0);
+ });
+
+ it('renders GlAvatar with specified `entityId` when `projectId` is a Number', () => {
+ const mockProjectId = 1;
+ createComponent({ props: { projectId: mockProjectId } });
+
+ const avatar = findGlAvatar();
+ expect(avatar.props('entityId')).toBe(mockProjectId);
+ });
+
+ it('renders GlAvatar with specified `entityId` when `projectId` is a gid String', () => {
+ const mockProjectId = 'gid://gitlab/Project/1';
+ createComponent({ props: { projectId: mockProjectId } });
+
+ const avatar = findGlAvatar();
+ expect(avatar.props('entityId')).toBe(1);
+ });
+ });
+
describe('with `projectAvatarUrl` prop', () => {
it('renders GlAvatar with specified `src` prop', () => {
const mockProjectAvatarUrl = 'https://gitlab.com';
diff --git a/spec/frontend/vue_shared/components/project_selector/project_list_item_spec.js b/spec/frontend/vue_shared/components/project_selector/project_list_item_spec.js
index 397ab2254b9..4e0c318c84e 100644
--- a/spec/frontend/vue_shared/components/project_selector/project_list_item_spec.js
+++ b/spec/frontend/vue_shared/components/project_selector/project_list_item_spec.js
@@ -56,6 +56,7 @@ describe('ProjectListItem component', () => {
expect(avatar.exists()).toBe(true);
expect(avatar.props()).toMatchObject({
+ projectId: project.id,
projectAvatarUrl: '',
projectName: project.name_with_namespace,
});
diff --git a/spec/frontend/vue_shared/components/project_selector/project_selector_spec.js b/spec/frontend/vue_shared/components/project_selector/project_selector_spec.js
index 379e60c1b2d..a0832dd7030 100644
--- a/spec/frontend/vue_shared/components/project_selector/project_selector_spec.js
+++ b/spec/frontend/vue_shared/components/project_selector/project_selector_spec.js
@@ -15,7 +15,7 @@ describe('ProjectSelector component', () => {
let selected = [];
selected = selected.concat(allProjects.slice(0, 3)).concat(allProjects.slice(5, 8));
- const findSearchInput = () => wrapper.find(GlSearchBoxByType).find('input');
+ const findSearchInput = () => wrapper.findComponent(GlSearchBoxByType).find('input');
const findLegendText = () => wrapper.find('[data-testid="legend-text"]').text();
const search = (query) => {
const searchInput = findSearchInput();
@@ -65,14 +65,14 @@ describe('ProjectSelector component', () => {
it(`triggers a "bottomReached" event when user has scrolled to the bottom of the list`, () => {
jest.spyOn(vm, '$emit').mockImplementation(() => {});
- wrapper.find(GlInfiniteScroll).vm.$emit('bottomReached');
+ wrapper.findComponent(GlInfiniteScroll).vm.$emit('bottomReached');
expect(vm.$emit).toHaveBeenCalledWith('bottomReached');
});
it(`triggers a "projectClicked" event when a project is clicked`, () => {
jest.spyOn(vm, '$emit').mockImplementation(() => {});
- wrapper.find(ProjectListItem).vm.$emit('click', head(searchResults));
+ wrapper.findComponent(ProjectListItem).vm.$emit('click', head(searchResults));
expect(vm.$emit).toHaveBeenCalledWith('projectClicked', head(searchResults));
});
diff --git a/spec/frontend/vue_shared/components/registry/code_instruction_spec.js b/spec/frontend/vue_shared/components/registry/code_instruction_spec.js
index 3a2ea263a05..8f19f0ea14d 100644
--- a/spec/frontend/vue_shared/components/registry/code_instruction_spec.js
+++ b/spec/frontend/vue_shared/components/registry/code_instruction_spec.js
@@ -22,7 +22,7 @@ describe('Package code instruction', () => {
});
}
- const findCopyButton = () => wrapper.find(ClipboardButton);
+ const findCopyButton = () => wrapper.findComponent(ClipboardButton);
const findInputElement = () => wrapper.find('[data-testid="instruction-input"]');
const findMultilineInstruction = () => wrapper.find('[data-testid="multiline-instruction"]');
diff --git a/spec/frontend/vue_shared/components/registry/details_row_spec.js b/spec/frontend/vue_shared/components/registry/details_row_spec.js
index 3134e0d3e21..ebc9816f983 100644
--- a/spec/frontend/vue_shared/components/registry/details_row_spec.js
+++ b/spec/frontend/vue_shared/components/registry/details_row_spec.js
@@ -5,7 +5,7 @@ import component from '~/vue_shared/components/registry/details_row.vue';
describe('DetailsRow', () => {
let wrapper;
- const findIcon = () => wrapper.find(GlIcon);
+ const findIcon = () => wrapper.findComponent(GlIcon);
const findDefaultSlot = () => wrapper.find('[data-testid="default-slot"]');
const mountComponent = (props) => {
diff --git a/spec/frontend/vue_shared/components/registry/history_item_spec.js b/spec/frontend/vue_shared/components/registry/history_item_spec.js
index f146f87342f..947520567e6 100644
--- a/spec/frontend/vue_shared/components/registry/history_item_spec.js
+++ b/spec/frontend/vue_shared/components/registry/history_item_spec.js
@@ -27,8 +27,8 @@ describe('History Item', () => {
wrapper = null;
});
- const findTimelineEntry = () => wrapper.find(TimelineEntryItem);
- const findGlIcon = () => wrapper.find(GlIcon);
+ const findTimelineEntry = () => wrapper.findComponent(TimelineEntryItem);
+ const findGlIcon = () => wrapper.findComponent(GlIcon);
const findDefaultSlot = () => wrapper.find('[data-testid="default-slot"]');
const findBodySlot = () => wrapper.find('[data-testid="body-slot"]');
diff --git a/spec/frontend/vue_shared/components/registry/list_item_spec.js b/spec/frontend/vue_shared/components/registry/list_item_spec.js
index 6e9abb2bfb3..b941eb77c32 100644
--- a/spec/frontend/vue_shared/components/registry/list_item_spec.js
+++ b/spec/frontend/vue_shared/components/registry/list_item_spec.js
@@ -13,7 +13,7 @@ describe('list item', () => {
const findRightSecondarySlot = () => wrapper.find('[data-testid="right-secondary"]');
const findRightActionSlot = () => wrapper.find('[data-testid="right-action"]');
const findDetailsSlot = (name) => wrapper.find(`[data-testid="${name}"]`);
- const findToggleDetailsButton = () => wrapper.find(GlButton);
+ const findToggleDetailsButton = () => wrapper.findComponent(GlButton);
const mountComponent = (propsData, slots) => {
wrapper = shallowMount(component, {
diff --git a/spec/frontend/vue_shared/components/registry/metadata_item_spec.js b/spec/frontend/vue_shared/components/registry/metadata_item_spec.js
index e4abdc15fd5..a04e1e237d4 100644
--- a/spec/frontend/vue_shared/components/registry/metadata_item_spec.js
+++ b/spec/frontend/vue_shared/components/registry/metadata_item_spec.js
@@ -24,10 +24,10 @@ describe('Metadata Item', () => {
wrapper = null;
});
- const findIcon = () => wrapper.find(GlIcon);
- const findLink = (w = wrapper) => w.find(GlLink);
+ const findIcon = () => wrapper.findComponent(GlIcon);
+ const findLink = (w = wrapper) => w.findComponent(GlLink);
const findText = () => wrapper.find('[data-testid="metadata-item-text"]');
- const findTooltipOnTruncate = (w = wrapper) => w.find(TooltipOnTruncate);
+ const findTooltipOnTruncate = (w = wrapper) => w.findComponent(TooltipOnTruncate);
const findTextTooltip = () => wrapper.find('[data-testid="text-tooltip-container"]');
describe.each(['xs', 's', 'm', 'l', 'xl'])('size class', (size) => {
diff --git a/spec/frontend/vue_shared/components/registry/registry_search_spec.js b/spec/frontend/vue_shared/components/registry/registry_search_spec.js
index 20716e79a04..70f4693ae81 100644
--- a/spec/frontend/vue_shared/components/registry/registry_search_spec.js
+++ b/spec/frontend/vue_shared/components/registry/registry_search_spec.js
@@ -6,9 +6,9 @@ import component from '~/vue_shared/components/registry/registry_search.vue';
describe('Registry Search', () => {
let wrapper;
- const findPackageListSorting = () => wrapper.find(GlSorting);
- const findSortingItems = () => wrapper.findAll(GlSortingItem);
- const findFilteredSearch = () => wrapper.find(GlFilteredSearch);
+ const findPackageListSorting = () => wrapper.findComponent(GlSorting);
+ const findSortingItems = () => wrapper.findAllComponents(GlSortingItem);
+ const findFilteredSearch = () => wrapper.findComponent(GlFilteredSearch);
const defaultProps = {
filters: [],
diff --git a/spec/frontend/vue_shared/components/registry/title_area_spec.js b/spec/frontend/vue_shared/components/registry/title_area_spec.js
index b62676b35be..efb57ddd310 100644
--- a/spec/frontend/vue_shared/components/registry/title_area_spec.js
+++ b/spec/frontend/vue_shared/components/registry/title_area_spec.js
@@ -199,7 +199,7 @@ describe('title area', () => {
const message = findInfoMessages().at(0);
- expect(message.find(GlLink).attributes('href')).toBe('bar');
+ expect(message.findComponent(GlLink).attributes('href')).toBe('bar');
expect(message.text()).toBe('foo link');
});
diff --git a/spec/frontend/vue_shared/components/rich_timestamp_tooltip_spec.js b/spec/frontend/vue_shared/components/rich_timestamp_tooltip_spec.js
new file mode 100644
index 00000000000..5d96fe27676
--- /dev/null
+++ b/spec/frontend/vue_shared/components/rich_timestamp_tooltip_spec.js
@@ -0,0 +1,41 @@
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+
+import { formatDate } from '~/lib/utils/datetime_utility';
+import RichTimestampTooltip from '~/vue_shared/components/rich_timestamp_tooltip.vue';
+
+describe('RichTimestampTooltip', () => {
+ const currentDate = new Date();
+ const mockRawTimestamp = currentDate.toISOString();
+ const mockTimestamp = formatDate(currentDate);
+ let wrapper;
+
+ const createComponent = ({
+ target = 'some-element',
+ rawTimestamp = mockRawTimestamp,
+ timestampTypeText = 'Created',
+ } = {}) => {
+ wrapper = shallowMountExtended(RichTimestampTooltip, {
+ propsData: {
+ target,
+ rawTimestamp,
+ timestampTypeText,
+ },
+ });
+ };
+
+ beforeEach(() => {
+ createComponent();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('renders the tooltip text header', () => {
+ expect(wrapper.findByTestId('header-text').text()).toBe('Created just now');
+ });
+
+ it('renders the tooltip text body', () => {
+ expect(wrapper.findByTestId('body-text').text()).toBe(mockTimestamp);
+ });
+});
diff --git a/spec/frontend/vue_shared/components/runner_instructions/runner_instructions_modal_spec.js b/spec/frontend/vue_shared/components/runner_instructions/runner_instructions_modal_spec.js
index a38dcd626f4..7c5fc63856a 100644
--- a/spec/frontend/vue_shared/components/runner_instructions/runner_instructions_modal_spec.js
+++ b/spec/frontend/vue_shared/components/runner_instructions/runner_instructions_modal_spec.js
@@ -166,7 +166,7 @@ describe('RunnerInstructionsModal component', () => {
});
it('sets the focus on the default selected platform', () => {
- const findOsxPlatformButton = () => wrapper.find({ ref: 'osx' });
+ const findOsxPlatformButton = () => wrapper.findComponent({ ref: 'osx' });
findOsxPlatformButton().element.focus = jest.fn();
@@ -234,14 +234,14 @@ describe('RunnerInstructionsModal component', () => {
MockResizeObserver.mockResize('xs');
await nextTick();
- expect(findPlatformButtonGroup().attributes('vertical')).toBeTruthy();
+ expect(findPlatformButtonGroup().attributes('vertical')).toEqual('true');
});
it('to a non-xs viewport', async () => {
MockResizeObserver.mockResize('sm');
await nextTick();
- expect(findPlatformButtonGroup().props('vertical')).toBeFalsy();
+ expect(findPlatformButtonGroup().props('vertical')).toBeUndefined();
});
});
});
diff --git a/spec/frontend/vue_shared/components/security_reports/artifact_downloads/merge_request_artifact_download_spec.js b/spec/frontend/vue_shared/components/security_reports/artifact_downloads/merge_request_artifact_download_spec.js
index 71ebe561def..c5672bc28cc 100644
--- a/spec/frontend/vue_shared/components/security_reports/artifact_downloads/merge_request_artifact_download_spec.js
+++ b/spec/frontend/vue_shared/components/security_reports/artifact_downloads/merge_request_artifact_download_spec.js
@@ -50,7 +50,7 @@ describe('Merge request artifact Download', () => {
return createMockApollo(requestHandlers);
};
- const findDownloadDropdown = () => wrapper.find(SecurityReportDownloadDropdown);
+ const findDownloadDropdown = () => wrapper.findComponent(SecurityReportDownloadDropdown);
afterEach(() => {
wrapper.destroy();
diff --git a/spec/frontend/vue_shared/components/security_reports/help_icon_spec.js b/spec/frontend/vue_shared/components/security_reports/help_icon_spec.js
index ae86106d86e..08d3d5b19d4 100644
--- a/spec/frontend/vue_shared/components/security_reports/help_icon_spec.js
+++ b/spec/frontend/vue_shared/components/security_reports/help_icon_spec.js
@@ -17,9 +17,9 @@ describe('HelpIcon component', () => {
});
};
- const findLink = () => wrapper.find(GlLink);
- const findPopover = () => wrapper.find(GlPopover);
- const findPopoverTarget = () => wrapper.find({ ref: 'discoverProjectSecurity' });
+ const findLink = () => wrapper.findComponent(GlLink);
+ const findPopover = () => wrapper.findComponent(GlPopover);
+ const findPopoverTarget = () => wrapper.findComponent({ ref: 'discoverProjectSecurity' });
afterEach(() => {
wrapper.destroy();
diff --git a/spec/frontend/vue_shared/components/sidebar/issuable_move_dropdown_spec.js b/spec/frontend/vue_shared/components/sidebar/issuable_move_dropdown_spec.js
index f213e37cbc1..9b1316677d7 100644
--- a/spec/frontend/vue_shared/components/sidebar/issuable_move_dropdown_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/issuable_move_dropdown_spec.js
@@ -173,15 +173,15 @@ describe('IssuableMoveDropdown', () => {
});
describe('template', () => {
- const findDropdownEl = () => wrapper.find(GlDropdown);
+ const findDropdownEl = () => wrapper.findComponent(GlDropdown);
it('renders collapsed state element with icon', () => {
const collapsedEl = wrapper.find('[data-testid="move-collapsed"]');
expect(collapsedEl.exists()).toBe(true);
expect(collapsedEl.attributes('title')).toBe(mockProps.dropdownButtonTitle);
- expect(collapsedEl.find(GlIcon).exists()).toBe(true);
- expect(collapsedEl.find(GlIcon).props('name')).toBe('arrow-right');
+ expect(collapsedEl.findComponent(GlIcon).exists()).toBe(true);
+ expect(collapsedEl.findComponent(GlIcon).props('name')).toBe('arrow-right');
});
describe('gl-dropdown component', () => {
@@ -191,7 +191,7 @@ describe('IssuableMoveDropdown', () => {
});
it('renders gl-dropdown-form component', () => {
- expect(findDropdownEl().find(GlDropdownForm).exists()).toBe(true);
+ expect(findDropdownEl().findComponent(GlDropdownForm).exists()).toBe(true);
});
it('renders header element', () => {
@@ -199,11 +199,11 @@ describe('IssuableMoveDropdown', () => {
expect(headerEl.exists()).toBe(true);
expect(headerEl.find('span').text()).toBe(mockProps.dropdownHeaderTitle);
- expect(headerEl.find(GlButton).props('icon')).toBe('close');
+ expect(headerEl.findComponent(GlButton).props('icon')).toBe('close');
});
it('renders gl-search-box-by-type component', () => {
- const searchEl = findDropdownEl().find(GlSearchBoxByType);
+ const searchEl = findDropdownEl().findComponent(GlSearchBoxByType);
expect(searchEl.exists()).toBe(true);
expect(searchEl.attributes()).toMatchObject({
@@ -221,7 +221,7 @@ describe('IssuableMoveDropdown', () => {
await nextTick();
- expect(findDropdownEl().find(GlLoadingIcon).exists()).toBe(true);
+ expect(findDropdownEl().findComponent(GlLoadingIcon).exists()).toBe(true);
});
it('renders gl-dropdown-item components for available projects', async () => {
@@ -234,7 +234,7 @@ describe('IssuableMoveDropdown', () => {
await nextTick();
- const dropdownItems = wrapper.findAll(GlDropdownItem);
+ const dropdownItems = wrapper.findAllComponents(GlDropdownItem);
expect(dropdownItems).toHaveLength(mockProjects.length);
expect(dropdownItems.at(0).props()).toMatchObject({
@@ -285,7 +285,7 @@ describe('IssuableMoveDropdown', () => {
});
it('renders gl-button within footer', async () => {
- const moveButtonEl = wrapper.find('[data-testid="footer"]').find(GlButton);
+ const moveButtonEl = wrapper.find('[data-testid="footer"]').findComponent(GlButton);
expect(moveButtonEl.text()).toBe('Move');
expect(moveButtonEl.attributes('disabled')).toBe('true');
@@ -299,7 +299,7 @@ describe('IssuableMoveDropdown', () => {
await nextTick();
expect(
- wrapper.find('[data-testid="footer"]').find(GlButton).attributes('disabled'),
+ wrapper.find('[data-testid="footer"]').findComponent(GlButton).attributes('disabled'),
).not.toBeDefined();
});
});
@@ -308,7 +308,7 @@ describe('IssuableMoveDropdown', () => {
it('collapsed state element emits `toggle-collapse` event on component when clicked', () => {
wrapper.find('[data-testid="move-collapsed"]').trigger('click');
- expect(wrapper.emitted('toggle-collapse')).toBeTruthy();
+ expect(wrapper.emitted('toggle-collapse')).toHaveLength(1);
});
it('gl-dropdown component calls `fetchProjects` on `shown` event', () => {
@@ -337,11 +337,11 @@ describe('IssuableMoveDropdown', () => {
it('gl-dropdown component emits `dropdown-close` event on component from `hide` event', async () => {
findDropdownEl().vm.$emit('hide');
- expect(wrapper.emitted('dropdown-close')).toBeTruthy();
+ expect(wrapper.emitted('dropdown-close')).toHaveLength(1);
});
it('close icon in dropdown header closes the dropdown when clicked', () => {
- wrapper.find('[data-testid="header"]').find(GlButton).vm.$emit('click', mockEvent);
+ wrapper.find('[data-testid="header"]').findComponent(GlButton).vm.$emit('click', mockEvent);
expect(wrapper.vm.$refs.dropdown.hide).toHaveBeenCalled();
});
@@ -355,7 +355,7 @@ describe('IssuableMoveDropdown', () => {
await nextTick();
- wrapper.findAll(GlDropdownItem).at(0).vm.$emit('click', mockEvent);
+ wrapper.findAllComponents(GlDropdownItem).at(0).vm.$emit('click', mockEvent);
expect(wrapper.vm.selectedProject).toBe(mockProjects[0]);
});
@@ -369,10 +369,10 @@ describe('IssuableMoveDropdown', () => {
await nextTick();
- wrapper.find('[data-testid="footer"]').find(GlButton).vm.$emit('click');
+ wrapper.find('[data-testid="footer"]').findComponent(GlButton).vm.$emit('click');
expect(wrapper.vm.$refs.dropdown.hide).toHaveBeenCalled();
- expect(wrapper.emitted('move-issuable')).toBeTruthy();
+ expect(wrapper.emitted('move-issuable')).toHaveLength(1);
expect(wrapper.emitted('move-issuable')[0]).toEqual([mockProjects[0]]);
});
});
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_button_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_button_spec.js
index c05513a6d5f..c0e5408e1bd 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_button_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_button_spec.js
@@ -33,9 +33,9 @@ describe('DropdownButton', () => {
wrapper.destroy();
});
- const findDropdownButton = () => wrapper.find(GlButton);
+ const findDropdownButton = () => wrapper.findComponent(GlButton);
const findDropdownText = () => wrapper.find('.dropdown-toggle-text');
- const findDropdownIcon = () => wrapper.find(GlIcon);
+ const findDropdownIcon = () => wrapper.findComponent(GlIcon);
describe('methods', () => {
describe('handleButtonClick', () => {
@@ -61,7 +61,7 @@ describe('DropdownButton', () => {
describe('template', () => {
it('renders component container element', () => {
- expect(wrapper.find(GlButton).element).toBe(wrapper.element);
+ expect(wrapper.findComponent(GlButton).element).toBe(wrapper.element);
});
it('renders default button text element', () => {
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_create_view_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_create_view_spec.js
index 0673ffee22b..799e2c1d08e 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_create_view_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_create_view_spec.js
@@ -127,7 +127,7 @@ describe('DropdownContentsCreateView', () => {
});
it('renders dropdown back button element', () => {
- const backBtnEl = wrapper.find('.dropdown-title').findAll(GlButton).at(0);
+ const backBtnEl = wrapper.find('.dropdown-title').findAllComponents(GlButton).at(0);
expect(backBtnEl.exists()).toBe(true);
expect(backBtnEl.attributes('aria-label')).toBe('Go back');
@@ -142,7 +142,7 @@ describe('DropdownContentsCreateView', () => {
});
it('renders dropdown close button element', () => {
- const closeBtnEl = wrapper.find('.dropdown-title').findAll(GlButton).at(1);
+ const closeBtnEl = wrapper.find('.dropdown-title').findAllComponents(GlButton).at(1);
expect(closeBtnEl.exists()).toBe(true);
expect(closeBtnEl.attributes('aria-label')).toBe('Close');
@@ -150,7 +150,7 @@ describe('DropdownContentsCreateView', () => {
});
it('renders label title input element', () => {
- const titleInputEl = wrapper.find('.dropdown-input').find(GlFormInput);
+ const titleInputEl = wrapper.find('.dropdown-input').findComponent(GlFormInput);
expect(titleInputEl.exists()).toBe(true);
expect(titleInputEl.attributes('placeholder')).toBe('Name new label');
@@ -158,7 +158,7 @@ describe('DropdownContentsCreateView', () => {
});
it('renders color block element for all suggested colors', () => {
- const colorBlocksEl = wrapper.find('.dropdown-content').findAll(GlLink);
+ const colorBlocksEl = wrapper.find('.dropdown-content').findAllComponents(GlLink);
colorBlocksEl.wrappers.forEach((colorBlock, index) => {
expect(colorBlock.attributes('style')).toContain('background-color');
@@ -175,7 +175,7 @@ describe('DropdownContentsCreateView', () => {
await nextTick();
const colorPreviewEl = wrapper.find('.color-input-container > .dropdown-label-color-preview');
- const colorInputEl = wrapper.find('.color-input-container').find(GlFormInput);
+ const colorInputEl = wrapper.find('.color-input-container').findComponent(GlFormInput);
expect(colorPreviewEl.exists()).toBe(true);
expect(colorPreviewEl.attributes('style')).toContain('background-color');
@@ -185,7 +185,7 @@ describe('DropdownContentsCreateView', () => {
});
it('renders create button element', () => {
- const createBtnEl = wrapper.find('.dropdown-actions').findAll(GlButton).at(0);
+ const createBtnEl = wrapper.find('.dropdown-actions').findAllComponents(GlButton).at(0);
expect(createBtnEl.exists()).toBe(true);
expect(createBtnEl.text()).toContain('Create');
@@ -195,14 +195,14 @@ describe('DropdownContentsCreateView', () => {
wrapper.vm.$store.dispatch('requestCreateLabel');
await nextTick();
- const loadingIconEl = wrapper.find('.dropdown-actions').find(GlLoadingIcon);
+ const loadingIconEl = wrapper.find('.dropdown-actions').findComponent(GlLoadingIcon);
expect(loadingIconEl.exists()).toBe(true);
expect(loadingIconEl.isVisible()).toBe(true);
});
it('renders cancel button element', () => {
- const cancelBtnEl = wrapper.find('.dropdown-actions').findAll(GlButton).at(1);
+ const cancelBtnEl = wrapper.find('.dropdown-actions').findAllComponents(GlButton).at(1);
expect(cancelBtnEl.exists()).toBe(true);
expect(cancelBtnEl.text()).toContain('Cancel');
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view_spec.js
index 00c8e3a814a..cc9b9f393ce 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view_spec.js
@@ -58,7 +58,7 @@ describe('DropdownContentsLabelsView', () => {
const findDropdownContent = () => wrapper.find('[data-testid="dropdown-content"]');
const findDropdownTitle = () => wrapper.find('[data-testid="dropdown-title"]');
const findDropdownFooter = () => wrapper.find('[data-testid="dropdown-footer"]');
- const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
+ const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
describe('computed', () => {
describe('visibleLabels', () => {
@@ -285,7 +285,7 @@ describe('DropdownContentsLabelsView', () => {
describe('template', () => {
it('renders gl-intersection-observer as component root', () => {
- expect(wrapper.find(GlIntersectionObserver).exists()).toBe(true);
+ expect(wrapper.findComponent(GlIntersectionObserver).exists()).toBe(true);
});
it('renders gl-loading-icon component when `labelsFetchInProgress` prop is true', async () => {
@@ -316,20 +316,20 @@ describe('DropdownContentsLabelsView', () => {
});
it('renders dropdown close button element', () => {
- const closeButtonEl = findDropdownTitle().find(GlButton);
+ const closeButtonEl = findDropdownTitle().findComponent(GlButton);
expect(closeButtonEl.exists()).toBe(true);
expect(closeButtonEl.props('icon')).toBe('close');
});
it('renders label search input element', () => {
- const searchInputEl = wrapper.find(GlSearchBoxByType);
+ const searchInputEl = wrapper.findComponent(GlSearchBoxByType);
expect(searchInputEl.exists()).toBe(true);
});
it('renders label elements for all labels', () => {
- expect(wrapper.findAll(LabelItem)).toHaveLength(mockLabels.length);
+ expect(wrapper.findAllComponents(LabelItem)).toHaveLength(mockLabels.length);
});
it('renders label element with `highlight` set to true when value of `currentHighlightItem` is more than -1', async () => {
@@ -340,7 +340,7 @@ describe('DropdownContentsLabelsView', () => {
});
await nextTick();
- const labelItemEl = findDropdownContent().find(LabelItem);
+ const labelItemEl = findDropdownContent().findComponent(LabelItem);
expect(labelItemEl.attributes('highlight')).toBe('true');
});
@@ -373,7 +373,7 @@ describe('DropdownContentsLabelsView', () => {
});
it('renders footer list items', () => {
- const footerLinks = findDropdownFooter().findAll(GlLink);
+ const footerLinks = findDropdownFooter().findAllComponents(GlLink);
const createLabelLink = footerLinks.at(0);
const manageLabelsLink = footerLinks.at(1);
@@ -387,7 +387,7 @@ describe('DropdownContentsLabelsView', () => {
wrapper.vm.$store.state.allowLabelCreate = false;
await nextTick();
- const createLabelLink = findDropdownFooter().findAll(GlLink).at(0);
+ const createLabelLink = findDropdownFooter().findAllComponents(GlLink).at(0);
expect(createLabelLink.text()).not.toBe('Create label');
});
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_title_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_title_spec.js
index 84e9f3f41c3..54804f85f81 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_title_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_title_spec.js
@@ -41,7 +41,7 @@ describe('DropdownTitle', () => {
});
it('renders edit link', () => {
- const editBtnEl = wrapper.find(GlButton);
+ const editBtnEl = wrapper.findComponent(GlButton);
expect(editBtnEl.exists()).toBe(true);
expect(editBtnEl.text()).toBe('Edit');
@@ -53,7 +53,7 @@ describe('DropdownTitle', () => {
});
await nextTick();
- expect(wrapper.find(GlLoadingIcon).isVisible()).toBe(true);
+ expect(wrapper.findComponent(GlLoadingIcon).isVisible()).toBe(true);
});
});
});
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/label_item_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/label_item_spec.js
index bedb6204088..bb0f1777de6 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/label_item_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/label_item_spec.js
@@ -32,7 +32,7 @@ describe('LabelItem', () => {
describe('template', () => {
it('renders gl-link component', () => {
- expect(wrapper.find(GlLink).exists()).toBe(true);
+ expect(wrapper.findComponent(GlLink).exists()).toBe(true);
});
it('renders component root with class `is-focused` when `highlight` prop is true', () => {
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/labels_select_root_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/labels_select_root_spec.js
index c150410ff8e..4c7ac6e9a6f 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/labels_select_root_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/labels_select_root_spec.js
@@ -138,13 +138,13 @@ describe('LabelsSelectRoot', () => {
it('renders `dropdown-value-collapsed` component when `allowLabelCreate` prop is `true`', async () => {
createComponent();
await nextTick();
- expect(wrapper.find(DropdownValueCollapsed).exists()).toBe(true);
+ expect(wrapper.findComponent(DropdownValueCollapsed).exists()).toBe(true);
});
it('renders `dropdown-title` component', async () => {
createComponent();
await nextTick();
- expect(wrapper.find(DropdownTitle).exists()).toBe(true);
+ expect(wrapper.findComponent(DropdownTitle).exists()).toBe(true);
});
it('renders `dropdown-value` component', async () => {
@@ -153,7 +153,7 @@ describe('LabelsSelectRoot', () => {
});
await nextTick();
- const valueComp = wrapper.find(DropdownValue);
+ const valueComp = wrapper.findComponent(DropdownValue);
expect(valueComp.exists()).toBe(true);
expect(valueComp.text()).toBe('None');
@@ -163,14 +163,14 @@ describe('LabelsSelectRoot', () => {
createComponent();
wrapper.vm.$store.dispatch('toggleDropdownButton');
await nextTick();
- expect(wrapper.find(DropdownButton).exists()).toBe(true);
+ expect(wrapper.findComponent(DropdownButton).exists()).toBe(true);
});
it('renders `dropdown-contents` component when `showDropdownButton` & `showDropdownContents` prop is `true`', async () => {
createComponent();
wrapper.vm.$store.dispatch('toggleDropdownContents');
await nextTick();
- expect(wrapper.find(DropdownContents).exists()).toBe(true);
+ expect(wrapper.findComponent(DropdownContents).exists()).toBe(true);
});
describe('sets content direction based on viewport', () => {
@@ -187,7 +187,7 @@ describe('LabelsSelectRoot', () => {
wrapper.vm.setContentIsOnViewport(wrapper.vm.$store.state);
await nextTick();
- expect(wrapper.find(DropdownContents).props('renderOnTop')).toBe(true);
+ expect(wrapper.findComponent(DropdownContents).props('renderOnTop')).toBe(true);
});
it('does not set direction when inside of viewport', async () => {
@@ -195,7 +195,7 @@ describe('LabelsSelectRoot', () => {
wrapper.vm.setContentIsOnViewport(wrapper.vm.$store.state);
await nextTick();
- expect(wrapper.find(DropdownContents).props('renderOnTop')).toBe(false);
+ expect(wrapper.findComponent(DropdownContents).props('renderOnTop')).toBe(false);
});
},
);
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js
index 1b27a294b90..cad401e0013 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js
@@ -131,6 +131,7 @@ describe('LabelsSelectRoot', () => {
expect(findDropdownValue().exists()).toBe(true);
expect(findDropdownValue().props('selectedLabels')).toEqual([
{
+ __typename: 'Label',
color: '#330066',
description: null,
id: 'gid://gitlab/ProjectLabel/1',
diff --git a/spec/frontend/vue_shared/components/sidebar/todo_button_spec.js b/spec/frontend/vue_shared/components/sidebar/todo_button_spec.js
index de3e1ccfb03..01958a144ed 100644
--- a/spec/frontend/vue_shared/components/sidebar/todo_button_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/todo_button_spec.js
@@ -30,19 +30,19 @@ describe('Todo Button', () => {
it('renders GlButton', () => {
createComponent();
- expect(wrapper.find(GlButton).exists()).toBe(true);
+ expect(wrapper.findComponent(GlButton).exists()).toBe(true);
});
it('emits click event when clicked', () => {
createComponent({}, mount);
- wrapper.find(GlButton).trigger('click');
+ wrapper.findComponent(GlButton).trigger('click');
- expect(wrapper.emitted().click).toBeTruthy();
+ expect(wrapper.emitted().click).toHaveLength(1);
});
it('calls dispatchDocumentEvent to update global To-Do counter correctly', () => {
createComponent({}, mount);
- wrapper.find(GlButton).trigger('click');
+ wrapper.findComponent(GlButton).trigger('click');
const dispatchedEvent = dispatchEventSpy.mock.calls[0][0];
expect(dispatchEventSpy).toHaveBeenCalledTimes(1);
@@ -57,12 +57,12 @@ describe('Todo Button', () => {
`('sets correct label when isTodo is $isTodo', ({ label, isTodo }) => {
createComponent({ isTodo });
- expect(wrapper.find(GlButton).text()).toBe(label);
+ expect(wrapper.findComponent(GlButton).text()).toBe(label);
});
it('binds additional props to GlButton', () => {
createComponent({ loading: true });
- expect(wrapper.find(GlButton).props('loading')).toBe(true);
+ expect(wrapper.findComponent(GlButton).props('loading')).toBe(true);
});
});
diff --git a/spec/frontend/vue_shared/components/source_editor_spec.js b/spec/frontend/vue_shared/components/source_editor_spec.js
index dca4d60e23c..ca5b990bc29 100644
--- a/spec/frontend/vue_shared/components/source_editor_spec.js
+++ b/spec/frontend/vue_shared/components/source_editor_spec.js
@@ -3,6 +3,7 @@ import { nextTick } from 'vue';
import { EDITOR_READY_EVENT } from '~/editor/constants';
import Editor from '~/editor/source_editor';
import SourceEditor from '~/vue_shared/components/source_editor.vue';
+import * as helpers from 'jest/editor/helpers';
jest.mock('~/editor/source_editor');
@@ -13,6 +14,7 @@ describe('Source Editor component', () => {
const value = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.';
const fileName = 'lorem.txt';
const fileGlobalId = 'snippet_777';
+ const useSpy = jest.fn();
const createInstanceMock = jest.fn().mockImplementation(() => {
mockInstance = {
onDidChangeModelContent: jest.fn(),
@@ -20,6 +22,7 @@ describe('Source Editor component', () => {
getValue: jest.fn(),
setValue: jest.fn(),
dispose: jest.fn(),
+ use: useSpy,
};
return mockInstance;
});
@@ -77,16 +80,33 @@ describe('Source Editor component', () => {
});
it('initialises Source Editor instance', () => {
- const el = wrapper.find({ ref: 'editor' }).element;
+ const el = wrapper.findComponent({ ref: 'editor' }).element;
expect(createInstanceMock).toHaveBeenCalledWith({
el,
blobPath: fileName,
blobGlobalId: fileGlobalId,
blobContent: value,
- extensions: null,
});
});
+ it.each`
+ description | extensions | toBeCalled
+ ${'no extension when `undefined` is'} | ${undefined} | ${false}
+ ${'no extension when {} is'} | ${{}} | ${false}
+ ${'no extension when [] is'} | ${[]} | ${false}
+ ${'single extension'} | ${{ definition: helpers.SEClassExtension }} | ${true}
+ ${'single extension with options'} | ${{ definition: helpers.SEWithSetupExt, setupOptions: { foo: 'bar' } }} | ${true}
+ ${'multiple extensions'} | ${[{ definition: helpers.SEClassExtension }, { definition: helpers.SEWithSetupExt }]} | ${true}
+ ${'multiple extensions with options'} | ${[{ definition: helpers.SEClassExtension }, { definition: helpers.SEWithSetupExt, setupOptions: { foo: 'bar' } }]} | ${true}
+ `('installs $description passed as a prop', ({ extensions, toBeCalled }) => {
+ createComponent({ extensions });
+ if (toBeCalled) {
+ expect(useSpy).toHaveBeenCalledWith(extensions);
+ } else {
+ expect(useSpy).not.toHaveBeenCalled();
+ }
+ });
+
it('reacts to the changes in fileName', () => {
const newFileName = 'ipsum.txt';
@@ -112,7 +132,7 @@ describe('Source Editor component', () => {
});
it('emits EDITOR_READY_EVENT event when the Source Editor is ready', async () => {
- const el = wrapper.find({ ref: 'editor' }).element;
+ const el = wrapper.findComponent({ ref: 'editor' }).element;
expect(wrapper.emitted()[EDITOR_READY_EVENT]).toBeUndefined();
await el.dispatchEvent(new Event(EDITOR_READY_EVENT));
diff --git a/spec/frontend/vue_shared/components/source_viewer/components/chunk_line_spec.js b/spec/frontend/vue_shared/components/source_viewer/components/chunk_line_spec.js
index eb2eec92534..fd3ff9ce892 100644
--- a/spec/frontend/vue_shared/components/source_viewer/components/chunk_line_spec.js
+++ b/spec/frontend/vue_shared/components/source_viewer/components/chunk_line_spec.js
@@ -1,4 +1,3 @@
-import { GlLink } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import ChunkLine from '~/vue_shared/components/source_viewer/components/chunk_line.vue';
import {
@@ -11,16 +10,26 @@ const DEFAULT_PROPS = {
number: 2,
content: '// Line content',
language: 'javascript',
+ blamePath: 'blame/file.js',
};
describe('Chunk Line component', () => {
let wrapper;
+ const fileLineBlame = true;
const createComponent = (props = {}) => {
- wrapper = shallowMountExtended(ChunkLine, { propsData: { ...DEFAULT_PROPS, ...props } });
+ wrapper = shallowMountExtended(ChunkLine, {
+ propsData: { ...DEFAULT_PROPS, ...props },
+ provide: {
+ glFeatures: {
+ fileLineBlame,
+ },
+ },
+ });
};
- const findLink = () => wrapper.findComponent(GlLink);
+ const findLineLink = () => wrapper.find('.file-line-num');
+ const findBlameLink = () => wrapper.find('.file-line-blame');
const findContent = () => wrapper.findByTestId('content');
const findWrappedBidiChars = () => wrapper.findAllByTestId('bidi-wrapper');
@@ -47,14 +56,22 @@ describe('Chunk Line component', () => {
});
});
+ it('renders a blame link', () => {
+ expect(findBlameLink().attributes()).toMatchObject({
+ href: `${DEFAULT_PROPS.blamePath}#L${DEFAULT_PROPS.number}`,
+ });
+
+ expect(findBlameLink().text()).toBe('');
+ });
+
it('renders a line number', () => {
- expect(findLink().attributes()).toMatchObject({
+ expect(findLineLink().attributes()).toMatchObject({
'data-line-number': `${DEFAULT_PROPS.number}`,
- to: `#L${DEFAULT_PROPS.number}`,
+ href: `#L${DEFAULT_PROPS.number}`,
id: `L${DEFAULT_PROPS.number}`,
});
- expect(findLink().text()).toBe(DEFAULT_PROPS.number.toString());
+ expect(findLineLink().text()).toBe(DEFAULT_PROPS.number.toString());
});
it('renders content', () => {
diff --git a/spec/frontend/vue_shared/components/source_viewer/components/chunk_spec.js b/spec/frontend/vue_shared/components/source_viewer/components/chunk_spec.js
index 42c4f2eacb8..8dc3348acfa 100644
--- a/spec/frontend/vue_shared/components/source_viewer/components/chunk_spec.js
+++ b/spec/frontend/vue_shared/components/source_viewer/components/chunk_spec.js
@@ -10,6 +10,7 @@ const DEFAULT_PROPS = {
startingFrom: 140,
totalLines: 50,
language: 'javascript',
+ blamePath: 'blame/file.js',
};
describe('Chunk component', () => {
@@ -76,6 +77,7 @@ describe('Chunk component', () => {
number: DEFAULT_PROPS.startingFrom + 1,
content: splitContent[0],
language: DEFAULT_PROPS.language,
+ blamePath: DEFAULT_PROPS.blamePath,
});
});
});
diff --git a/spec/frontend/vue_shared/components/source_viewer/plugins/link_dependencies_spec.js b/spec/frontend/vue_shared/components/source_viewer/plugins/link_dependencies_spec.js
index 3036ce43888..375b1307616 100644
--- a/spec/frontend/vue_shared/components/source_viewer/plugins/link_dependencies_spec.js
+++ b/spec/frontend/vue_shared/components/source_viewer/plugins/link_dependencies_spec.js
@@ -1,8 +1,10 @@
import packageJsonLinker from '~/vue_shared/components/source_viewer/plugins/utils/package_json_linker';
+import gemspecLinker from '~/vue_shared/components/source_viewer/plugins/utils/gemspec_linker';
import linkDependencies from '~/vue_shared/components/source_viewer/plugins/link_dependencies';
-import { PACKAGE_JSON_FILE_TYPE, PACKAGE_JSON_CONTENT } from './mock_data';
+import { PACKAGE_JSON_FILE_TYPE, PACKAGE_JSON_CONTENT, GEMSPEC_FILE_TYPE } from './mock_data';
jest.mock('~/vue_shared/components/source_viewer/plugins/utils/package_json_linker');
+jest.mock('~/vue_shared/components/source_viewer/plugins/utils/gemspec_linker');
describe('Highlight.js plugin for linking dependencies', () => {
const hljsResultMock = { value: 'test' };
@@ -11,4 +13,9 @@ describe('Highlight.js plugin for linking dependencies', () => {
linkDependencies(hljsResultMock, PACKAGE_JSON_FILE_TYPE, PACKAGE_JSON_CONTENT);
expect(packageJsonLinker).toHaveBeenCalled();
});
+
+ it('calls gemspecLinker for gemspec file types', () => {
+ linkDependencies(hljsResultMock, GEMSPEC_FILE_TYPE);
+ expect(gemspecLinker).toHaveBeenCalled();
+ });
});
diff --git a/spec/frontend/vue_shared/components/source_viewer/plugins/mock_data.js b/spec/frontend/vue_shared/components/source_viewer/plugins/mock_data.js
index 75659770e2c..aa874c9c081 100644
--- a/spec/frontend/vue_shared/components/source_viewer/plugins/mock_data.js
+++ b/spec/frontend/vue_shared/components/source_viewer/plugins/mock_data.js
@@ -1,2 +1,4 @@
export const PACKAGE_JSON_FILE_TYPE = 'package_json';
export const PACKAGE_JSON_CONTENT = '{ "dependencies": { "@babel/core": "^7.18.5" } }';
+
+export const GEMSPEC_FILE_TYPE = 'gemspec';
diff --git a/spec/frontend/vue_shared/components/source_viewer/plugins/utils/dependency_linker_util_spec.js b/spec/frontend/vue_shared/components/source_viewer/plugins/utils/dependency_linker_util_spec.js
index ee200747af9..8079d5ad99a 100644
--- a/spec/frontend/vue_shared/components/source_viewer/plugins/utils/dependency_linker_util_spec.js
+++ b/spec/frontend/vue_shared/components/source_viewer/plugins/utils/dependency_linker_util_spec.js
@@ -14,10 +14,11 @@ describe('createLink', () => {
it('escapes the user-controlled content', () => {
const unescapedXSS = '<script>XSS</script>';
- const escapedXSS = '&amp;lt;script&amp;gt;XSS&amp;lt;/script&amp;gt;';
+ const escapedPackageName = '&lt;script&gt;XSS&lt;/script&gt;';
+ const escapedHref = '&amp;lt;script&amp;gt;XSS&amp;lt;/script&amp;gt;';
const href = `http://test.com/${unescapedXSS}`;
const innerText = `testing${unescapedXSS}`;
- const result = `<a href="http://test.com/${escapedXSS}" rel="nofollow noreferrer noopener">testing${escapedXSS}</a>`;
+ const result = `<a href="http://test.com/${escapedHref}" rel="nofollow noreferrer noopener">testing${escapedPackageName}</a>`;
expect(createLink(href, innerText)).toBe(result);
});
diff --git a/spec/frontend/vue_shared/components/source_viewer/plugins/utils/gemspec_linker_spec.js b/spec/frontend/vue_shared/components/source_viewer/plugins/utils/gemspec_linker_spec.js
new file mode 100644
index 00000000000..3f74bfa117f
--- /dev/null
+++ b/spec/frontend/vue_shared/components/source_viewer/plugins/utils/gemspec_linker_spec.js
@@ -0,0 +1,14 @@
+import gemspecLinker from '~/vue_shared/components/source_viewer/plugins/utils/gemspec_linker';
+
+describe('Highlight.js plugin for linking gemspec dependencies', () => {
+ it('mutates the input value by wrapping dependency names in anchors', () => {
+ const inputValue =
+ 's.add_dependency(<span class="hljs-string">&#x27;rugged&#x27;</span>, <span class="hljs-string">&#x27;~&gt; 0.24.0&#x27;</span>)';
+ const outputValue =
+ 's.add_dependency(<span class="hljs-string linked">&#x27;<a href="https://rubygems.org/gems/rugged" rel="nofollow noreferrer noopener">rugged</a>&#x27;</span>, <span class="hljs-string">&#x27;~&gt; 0.24.0&#x27;</span>)';
+ const hljsResultMock = { value: inputValue };
+
+ const output = gemspecLinker(hljsResultMock);
+ expect(output).toBe(outputValue);
+ });
+});
diff --git a/spec/frontend/vue_shared/components/source_viewer/source_viewer_spec.js b/spec/frontend/vue_shared/components/source_viewer/source_viewer_spec.js
index 2c03b7aa7d3..4fbc907a813 100644
--- a/spec/frontend/vue_shared/components/source_viewer/source_viewer_spec.js
+++ b/spec/frontend/vue_shared/components/source_viewer/source_viewer_spec.js
@@ -40,8 +40,9 @@ describe('Source Viewer component', () => {
const chunk2 = generateContent('// Some source code 2', 70);
const content = chunk1 + chunk2;
const path = 'some/path.js';
+ const blamePath = 'some/blame/path.js';
const fileType = 'javascript';
- const DEFAULT_BLOB_DATA = { language, rawTextBlob: content, path, fileType };
+ const DEFAULT_BLOB_DATA = { language, rawTextBlob: content, path, blamePath, fileType };
const highlightedContent = `<span data-testid='test-highlighted' id='LC1'>${content}</span><span id='LC2'></span>`;
const createComponent = async (blob = {}) => {
diff --git a/spec/frontend/vue_shared/components/split_button_spec.js b/spec/frontend/vue_shared/components/split_button_spec.js
index 4965969bc3e..6b869db4058 100644
--- a/spec/frontend/vue_shared/components/split_button_spec.js
+++ b/spec/frontend/vue_shared/components/split_button_spec.js
@@ -26,8 +26,9 @@ describe('SplitButton', () => {
});
};
- const findDropdown = () => wrapper.find(GlDropdown);
- const findDropdownItem = (index = 0) => findDropdown().findAll(GlDropdownItem).at(index);
+ const findDropdown = () => wrapper.findComponent(GlDropdown);
+ const findDropdownItem = (index = 0) =>
+ findDropdown().findAllComponents(GlDropdownItem).at(index);
const selectItem = async (index) => {
findDropdownItem(index).vm.$emit('click');
diff --git a/spec/frontend/vue_shared/components/table_pagination_spec.js b/spec/frontend/vue_shared/components/table_pagination_spec.js
index ed23a47c328..99de26ce2ae 100644
--- a/spec/frontend/vue_shared/components/table_pagination_spec.js
+++ b/spec/frontend/vue_shared/components/table_pagination_spec.js
@@ -50,7 +50,7 @@ describe('Pagination component', () => {
change: spy,
});
- expect(wrapper.find(GlPagination).exists()).toBe(true);
+ expect(wrapper.findComponent(GlPagination).exists()).toBe(true);
});
it('renders if there is a prev page', () => {
@@ -66,7 +66,7 @@ describe('Pagination component', () => {
change: spy,
});
- expect(wrapper.find(GlPagination).exists()).toBe(true);
+ expect(wrapper.findComponent(GlPagination).exists()).toBe(true);
});
});
@@ -83,7 +83,7 @@ describe('Pagination component', () => {
},
change: spy,
});
- wrapper.find(GlPagination).vm.$emit('input', 3);
+ wrapper.findComponent(GlPagination).vm.$emit('input', 3);
expect(spy).toHaveBeenCalledWith(3);
});
});
diff --git a/spec/frontend/vue_shared/components/tooltip_on_truncate_spec.js b/spec/frontend/vue_shared/components/tooltip_on_truncate_spec.js
index 9e7e5c1263f..ca1f7996ad6 100644
--- a/spec/frontend/vue_shared/components/tooltip_on_truncate_spec.js
+++ b/spec/frontend/vue_shared/components/tooltip_on_truncate_spec.js
@@ -68,7 +68,7 @@ describe('TooltipOnTruncate component', () => {
},
);
- wrapper = parent.find(WrappedTooltipOnTruncate);
+ wrapper = parent.findComponent(WrappedTooltipOnTruncate);
};
const getTooltipValue = () => getBinding(wrapper.element, 'gl-tooltip')?.value;
diff --git a/spec/frontend/vue_shared/components/upload_dropzone/upload_dropzone_spec.js b/spec/frontend/vue_shared/components/upload_dropzone/upload_dropzone_spec.js
index 21e9b401215..a063a5591e3 100644
--- a/spec/frontend/vue_shared/components/upload_dropzone/upload_dropzone_spec.js
+++ b/spec/frontend/vue_shared/components/upload_dropzone/upload_dropzone_spec.js
@@ -14,7 +14,7 @@ describe('Upload dropzone component', () => {
const findDropzoneCard = () => wrapper.find('.upload-dropzone-card');
const findDropzoneArea = () => wrapper.find('[data-testid="dropzone-area"]');
- const findIcon = () => wrapper.find(GlIcon);
+ const findIcon = () => wrapper.findComponent(GlIcon);
const findUploadText = () => wrapper.find('[data-testid="upload-text"]').text();
const findFileInput = () => wrapper.find('input[type="file"]');
diff --git a/spec/frontend/vue_shared/components/user_access_role_badge_spec.js b/spec/frontend/vue_shared/components/user_access_role_badge_spec.js
index 7f25f7c08e7..cea6fcac8c8 100644
--- a/spec/frontend/vue_shared/components/user_access_role_badge_spec.js
+++ b/spec/frontend/vue_shared/components/user_access_role_badge_spec.js
@@ -18,7 +18,7 @@ describe('UserAccessRoleBadge', () => {
},
});
- const badge = wrapper.find(GlBadge);
+ const badge = wrapper.findComponent(GlBadge);
expect(badge.exists()).toBe(true);
expect(badge.html()).toContain('test slot content');
diff --git a/spec/frontend/vue_shared/components/user_avatar/user_avatar_image_new_spec.js b/spec/frontend/vue_shared/components/user_avatar/user_avatar_image_new_spec.js
index 5e05b54cb8c..f87737ca86a 100644
--- a/spec/frontend/vue_shared/components/user_avatar/user_avatar_image_new_spec.js
+++ b/spec/frontend/vue_shared/components/user_avatar/user_avatar_image_new_spec.js
@@ -18,6 +18,8 @@ const PROVIDED_PROPS = {
describe('User Avatar Image Component', () => {
let wrapper;
+ const findAvatar = () => wrapper.findComponent(GlAvatar);
+
afterEach(() => {
wrapper.destroy();
});
@@ -28,21 +30,14 @@ describe('User Avatar Image Component', () => {
propsData: {
...PROVIDED_PROPS,
},
- provide: {
- glFeatures: {
- glAvatarForAllUserAvatars: true,
- },
- },
});
});
it('should render `GlAvatar` and provide correct properties to it', () => {
- const avatar = wrapper.findComponent(GlAvatar);
-
- expect(avatar.attributes('data-src')).toBe(
+ expect(findAvatar().attributes('data-src')).toBe(
`${PROVIDED_PROPS.imgSrc}?width=${PROVIDED_PROPS.size}`,
);
- expect(avatar.props()).toMatchObject({
+ expect(findAvatar().props()).toMatchObject({
src: `${PROVIDED_PROPS.imgSrc}?width=${PROVIDED_PROPS.size}`,
alt: PROVIDED_PROPS.imgAlt,
size: PROVIDED_PROPS.size,
@@ -63,23 +58,28 @@ describe('User Avatar Image Component', () => {
...PROVIDED_PROPS,
lazy: true,
},
- provide: {
- glFeatures: {
- glAvatarForAllUserAvatars: true,
- },
- },
});
});
it('should add lazy attributes', () => {
- const avatar = wrapper.findComponent(GlAvatar);
-
- expect(avatar.classes()).toContain('lazy');
- expect(avatar.attributes()).toMatchObject({
+ expect(findAvatar().classes()).toContain('lazy');
+ expect(findAvatar().attributes()).toMatchObject({
src: placeholderImage,
'data-src': `${PROVIDED_PROPS.imgSrc}?width=${PROVIDED_PROPS.size}`,
});
});
+
+ it('should use maximum number when size is provided as an object', () => {
+ wrapper = shallowMount(UserAvatarImage, {
+ propsData: {
+ ...PROVIDED_PROPS,
+ size: { default: 16, md: 64, lg: 24 },
+ lazy: true,
+ },
+ });
+
+ expect(findAvatar().attributes('data-src')).toBe(`${PROVIDED_PROPS.imgSrc}?width=${64}`);
+ });
});
describe('Initialization without src', () => {
@@ -89,18 +89,11 @@ describe('User Avatar Image Component', () => {
...PROVIDED_PROPS,
imgSrc: null,
},
- provide: {
- glFeatures: {
- glAvatarForAllUserAvatars: true,
- },
- },
});
});
it('should have default avatar image', () => {
- const avatar = wrapper.findComponent(GlAvatar);
-
- expect(avatar.props('src')).toBe(`${defaultAvatarUrl}?width=${PROVIDED_PROPS.size}`);
+ expect(findAvatar().props('src')).toBe(`${defaultAvatarUrl}?width=${PROVIDED_PROPS.size}`);
});
});
diff --git a/spec/frontend/vue_shared/components/user_avatar/user_avatar_image_spec.js b/spec/frontend/vue_shared/components/user_avatar/user_avatar_image_spec.js
index 75d2a936b34..6ad2ef226c2 100644
--- a/spec/frontend/vue_shared/components/user_avatar/user_avatar_image_spec.js
+++ b/spec/frontend/vue_shared/components/user_avatar/user_avatar_image_spec.js
@@ -15,47 +15,37 @@ const PROVIDED_PROPS = {
describe('User Avatar Image Component', () => {
let wrapper;
- afterEach(() => {
- wrapper.destroy();
- });
-
- describe('when `glAvatarForAllUserAvatars` feature flag enabled', () => {
- beforeEach(() => {
- wrapper = shallowMount(UserAvatarImage, {
- propsData: {
- ...PROVIDED_PROPS,
+ const createWrapper = (props = {}, { glAvatarForAllUserAvatars } = {}) => {
+ wrapper = shallowMount(UserAvatarImage, {
+ propsData: {
+ ...PROVIDED_PROPS,
+ ...props,
+ },
+ provide: {
+ glFeatures: {
+ glAvatarForAllUserAvatars,
},
- provide: {
- glFeatures: {
- glAvatarForAllUserAvatars: true,
- },
- },
- });
+ },
});
+ };
- it('should render `UserAvatarImageNew` component', () => {
- expect(wrapper.findComponent(UserAvatarImageNew).exists()).toBe(true);
- expect(wrapper.findComponent(UserAvatarImageOld).exists()).toBe(false);
- });
+ afterEach(() => {
+ wrapper.destroy();
});
- describe('when `glAvatarForAllUserAvatars` feature flag disabled', () => {
- beforeEach(() => {
- wrapper = shallowMount(UserAvatarImage, {
- propsData: {
- ...PROVIDED_PROPS,
- },
- provide: {
- glFeatures: {
- glAvatarForAllUserAvatars: false,
- },
- },
+ describe.each([
+ [false, true, true],
+ [true, false, true],
+ [true, true, true],
+ [false, false, false],
+ ])(
+ 'when glAvatarForAllUserAvatars=%s and enforceGlAvatar=%s',
+ (glAvatarForAllUserAvatars, enforceGlAvatar, isUsingNewVersion) => {
+ it(`will render ${isUsingNewVersion ? 'new' : 'old'} version`, () => {
+ createWrapper({ enforceGlAvatar }, { glAvatarForAllUserAvatars });
+ expect(wrapper.findComponent(UserAvatarImageNew).exists()).toBe(isUsingNewVersion);
+ expect(wrapper.findComponent(UserAvatarImageOld).exists()).toBe(!isUsingNewVersion);
});
- });
-
- it('should render `UserAvatarImageOld` component', () => {
- expect(wrapper.findComponent(UserAvatarImageNew).exists()).toBe(false);
- expect(wrapper.findComponent(UserAvatarImageOld).exists()).toBe(true);
- });
- });
+ },
+ );
});
diff --git a/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_new_spec.js b/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_new_spec.js
index 5ba80b31b99..f485a14cfea 100644
--- a/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_new_spec.js
+++ b/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_new_spec.js
@@ -54,6 +54,7 @@ describe('User Avatar Link Component', () => {
size: defaultProps.imgSize,
tooltipPlacement: defaultProps.tooltipPlacement,
tooltipText: '',
+ enforceGlAvatar: false,
});
});
diff --git a/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_old_spec.js b/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_old_spec.js
index 2d513c46e77..cf7a1025dba 100644
--- a/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_old_spec.js
+++ b/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_old_spec.js
@@ -54,6 +54,7 @@ describe('User Avatar Link Component', () => {
size: defaultProps.imgSize,
tooltipPlacement: defaultProps.tooltipPlacement,
tooltipText: '',
+ enforceGlAvatar: false,
});
});
diff --git a/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_spec.js b/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_spec.js
index b36b83d1fea..fd3f59008ec 100644
--- a/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_spec.js
+++ b/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_spec.js
@@ -15,47 +15,37 @@ const PROVIDED_PROPS = {
describe('User Avatar Link Component', () => {
let wrapper;
- afterEach(() => {
- wrapper.destroy();
- });
-
- describe('when `glAvatarForAllUserAvatars` feature flag enabled', () => {
- beforeEach(() => {
- wrapper = shallowMount(UserAvatarLink, {
- propsData: {
- ...PROVIDED_PROPS,
+ const createWrapper = (props = {}, { glAvatarForAllUserAvatars } = {}) => {
+ wrapper = shallowMount(UserAvatarLink, {
+ propsData: {
+ ...PROVIDED_PROPS,
+ ...props,
+ },
+ provide: {
+ glFeatures: {
+ glAvatarForAllUserAvatars,
},
- provide: {
- glFeatures: {
- glAvatarForAllUserAvatars: true,
- },
- },
- });
+ },
});
+ };
- it('should render `UserAvatarLinkNew` component', () => {
- expect(wrapper.findComponent(UserAvatarLinkNew).exists()).toBe(true);
- expect(wrapper.findComponent(UserAvatarLinkOld).exists()).toBe(false);
- });
+ afterEach(() => {
+ wrapper.destroy();
});
- describe('when `glAvatarForAllUserAvatars` feature flag disabled', () => {
- beforeEach(() => {
- wrapper = shallowMount(UserAvatarLink, {
- propsData: {
- ...PROVIDED_PROPS,
- },
- provide: {
- glFeatures: {
- glAvatarForAllUserAvatars: false,
- },
- },
+ describe.each([
+ [false, true, true],
+ [true, false, true],
+ [true, true, true],
+ [false, false, false],
+ ])(
+ 'when glAvatarForAllUserAvatars=%s and enforceGlAvatar=%s',
+ (glAvatarForAllUserAvatars, enforceGlAvatar, isUsingNewVersion) => {
+ it(`will render ${isUsingNewVersion ? 'new' : 'old'} version`, () => {
+ createWrapper({ enforceGlAvatar }, { glAvatarForAllUserAvatars });
+ expect(wrapper.findComponent(UserAvatarLinkNew).exists()).toBe(isUsingNewVersion);
+ expect(wrapper.findComponent(UserAvatarLinkOld).exists()).toBe(!isUsingNewVersion);
});
- });
-
- it('should render `UserAvatarLinkOld` component', () => {
- expect(wrapper.findComponent(UserAvatarLinkNew).exists()).toBe(false);
- expect(wrapper.findComponent(UserAvatarLinkOld).exists()).toBe(true);
- });
- });
+ },
+ );
});
diff --git a/spec/frontend/vue_shared/components/user_avatar/user_avatar_list_spec.js b/spec/frontend/vue_shared/components/user_avatar/user_avatar_list_spec.js
index 20ff0848cff..b9accbf0373 100644
--- a/spec/frontend/vue_shared/components/user_avatar/user_avatar_list_spec.js
+++ b/spec/frontend/vue_shared/components/user_avatar/user_avatar_list_spec.js
@@ -38,7 +38,7 @@ describe('UserAvatarList', () => {
};
const clickButton = () => {
- const button = wrapper.find(GlButton);
+ const button = wrapper.findComponent(GlButton);
button.vm.$emit('click');
};
@@ -79,7 +79,7 @@ describe('UserAvatarList', () => {
const items = createList(20);
factory({ propsData: { items } });
- const links = wrapper.findAll(UserAvatarLink);
+ const links = wrapper.findAllComponents(UserAvatarLink);
const linkProps = links.wrappers.map((x) => x.props());
expect(linkProps).toEqual(
@@ -105,7 +105,7 @@ describe('UserAvatarList', () => {
it('renders all avatars if length is <= breakpoint', () => {
factory();
- const links = wrapper.findAll(UserAvatarLink);
+ const links = wrapper.findAllComponents(UserAvatarLink);
expect(links.length).toEqual(props.items.length);
});
@@ -113,7 +113,7 @@ describe('UserAvatarList', () => {
it('does not show button', () => {
factory();
- expect(wrapper.find(GlButton).exists()).toBe(false);
+ expect(wrapper.findComponent(GlButton).exists()).toBe(false);
});
});
@@ -126,7 +126,7 @@ describe('UserAvatarList', () => {
it('renders avatars up to breakpoint', () => {
factory();
- const links = wrapper.findAll(UserAvatarLink);
+ const links = wrapper.findAllComponents(UserAvatarLink);
expect(links.length).toEqual(TEST_BREAKPOINT);
});
@@ -138,7 +138,7 @@ describe('UserAvatarList', () => {
});
it('renders all avatars', () => {
- const links = wrapper.findAll(UserAvatarLink);
+ const links = wrapper.findAllComponents(UserAvatarLink);
expect(links.length).toEqual(props.items.length);
});
@@ -147,7 +147,7 @@ describe('UserAvatarList', () => {
clickButton();
await nextTick();
- const links = wrapper.findAll(UserAvatarLink);
+ const links = wrapper.findAllComponents(UserAvatarLink);
expect(links.length).toEqual(TEST_BREAKPOINT);
});
diff --git a/spec/frontend/vue_shared/components/user_popover/user_popover_spec.js b/spec/frontend/vue_shared/components/user_popover/user_popover_spec.js
index 9550368eefc..b7ce3e47cef 100644
--- a/spec/frontend/vue_shared/components/user_popover/user_popover_spec.js
+++ b/spec/frontend/vue_shared/components/user_popover/user_popover_spec.js
@@ -6,6 +6,7 @@ import UserPopover from '~/vue_shared/components/user_popover/user_popover.vue';
import axios from '~/lib/utils/axios_utils';
import createFlash from '~/flash';
import { followUser, unfollowUser } from '~/api/user_api';
+import { mockTracking } from 'helpers/tracking_helper';
jest.mock('~/flash');
jest.mock('~/api/user_api', () => ({
@@ -51,6 +52,18 @@ describe('User Popover Component', () => {
const findUserLocalTime = () => wrapper.findByTestId('user-popover-local-time');
const findToggleFollowButton = () => wrapper.findByTestId('toggle-follow-button');
+ const itTracksToggleFollowButtonClick = (expectedLabel) => {
+ it('tracks click', async () => {
+ const trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn);
+
+ await findToggleFollowButton().trigger('click');
+
+ expect(trackingSpy).toHaveBeenCalledWith(undefined, 'click_button', {
+ label: expectedLabel,
+ });
+ });
+ };
+
const createWrapper = (props = {}) => {
wrapper = mountExtended(UserPopover, {
propsData: {
@@ -75,7 +88,7 @@ describe('User Popover Component', () => {
},
});
- expect(wrapper.find(GlSkeletonLoader).exists()).toBe(true);
+ expect(wrapper.findComponent(GlSkeletonLoader).exists()).toBe(true);
});
});
@@ -89,7 +102,7 @@ describe('User Popover Component', () => {
it('shows icon for location', () => {
createWrapper();
- const iconEl = wrapper.find(GlIcon);
+ const iconEl = wrapper.findComponent(GlIcon);
expect(iconEl.props('name')).toEqual('location');
});
@@ -102,8 +115,8 @@ describe('User Popover Component', () => {
});
describe('job data', () => {
- const findWorkInformation = () => wrapper.find({ ref: 'workInformation' });
- const findBio = () => wrapper.find({ ref: 'bio' });
+ const findWorkInformation = () => wrapper.findComponent({ ref: 'workInformation' });
+ const findBio = () => wrapper.findComponent({ ref: 'bio' });
const bio = 'My super interesting bio';
it('should show only bio if work information is not available', () => {
@@ -159,7 +172,7 @@ describe('User Popover Component', () => {
createWrapper({ user });
expect(
- wrapper.findAll(GlIcon).filter((icon) => icon.props('name') === 'profile').length,
+ wrapper.findAllComponents(GlIcon).filter((icon) => icon.props('name') === 'profile').length,
).toEqual(1);
});
@@ -172,7 +185,7 @@ describe('User Popover Component', () => {
createWrapper({ user });
expect(
- wrapper.findAll(GlIcon).filter((icon) => icon.props('name') === 'work').length,
+ wrapper.findAllComponents(GlIcon).filter((icon) => icon.props('name') === 'work').length,
).toEqual(1);
});
});
@@ -338,9 +351,11 @@ describe('User Popover Component', () => {
await axios.waitForAll();
expect(wrapper.emitted().follow.length).toBe(1);
- expect(wrapper.emitted().unfollow).toBeFalsy();
+ expect(wrapper.emitted().unfollow).toBeUndefined();
});
+ itTracksToggleFollowButtonClick('follow_from_user_popover');
+
describe('when an error occurs', () => {
beforeEach(() => {
followUser.mockRejectedValue({});
@@ -361,8 +376,8 @@ describe('User Popover Component', () => {
it('emits no events', async () => {
await axios.waitForAll();
- expect(wrapper.emitted().follow).toBe(undefined);
- expect(wrapper.emitted().unfollow).toBe(undefined);
+ expect(wrapper.emitted().follow).toBeUndefined();
+ expect(wrapper.emitted().unfollow).toBeUndefined();
});
});
});
@@ -388,6 +403,8 @@ describe('User Popover Component', () => {
expect(wrapper.emitted().unfollow.length).toBe(1);
});
+ itTracksToggleFollowButtonClick('unfollow_from_user_popover');
+
describe('when an error occurs', () => {
beforeEach(async () => {
unfollowUser.mockRejectedValue({});
@@ -406,8 +423,8 @@ describe('User Popover Component', () => {
});
it('emits no events', () => {
- expect(wrapper.emitted().follow).toBe(undefined);
- expect(wrapper.emitted().unfollow).toBe(undefined);
+ expect(wrapper.emitted().follow).toBeUndefined();
+ expect(wrapper.emitted().unfollow).toBeUndefined();
});
});
});
diff --git a/spec/frontend/vue_shared/components/user_select_spec.js b/spec/frontend/vue_shared/components/user_select_spec.js
index ec9128d5e38..4188adc72a1 100644
--- a/spec/frontend/vue_shared/components/user_select_spec.js
+++ b/spec/frontend/vue_shared/components/user_select_spec.js
@@ -9,6 +9,7 @@ import searchUsersQuery from '~/graphql_shared/queries/users_search.query.graphq
import searchUsersQueryOnMR from '~/graphql_shared/queries/users_search_with_mr_permissions.graphql';
import { IssuableType } from '~/issues/constants';
import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants';
+import SidebarParticipant from '~/sidebar/components/assignees/sidebar_participant.vue';
import getIssueParticipantsQuery from '~/vue_shared/components/sidebar/queries/get_issue_participants.query.graphql';
import UserSelect from '~/vue_shared/components/user_select/user_select.vue';
import {
@@ -16,6 +17,8 @@ import {
searchResponseOnMR,
projectMembersResponse,
participantsQueryResponse,
+ mockUser1,
+ mockUser2,
} from 'jest/sidebar/mock_data';
const assignee = {
@@ -45,9 +48,14 @@ describe('User select dropdown', () => {
const findSearchField = () => wrapper.findComponent(GlSearchBoxByType);
const findParticipantsLoading = () => wrapper.find('[data-testid="loading-participants"]');
const findSelectedParticipants = () => wrapper.findAll('[data-testid="selected-participant"]');
+ const findSelectedParticipantByIndex = (index) =>
+ findSelectedParticipants().at(index).findComponent(SidebarParticipant);
const findUnselectedParticipants = () =>
wrapper.findAll('[data-testid="unselected-participant"]');
+ const findUnselectedParticipantByIndex = (index) =>
+ findUnselectedParticipants().at(index).findComponent(SidebarParticipant);
const findCurrentUser = () => wrapper.findAll('[data-testid="current-user"]');
+ const findIssuableAuthor = () => wrapper.findAll('[data-testid="issuable-author"]');
const findUnassignLink = () => wrapper.find('[data-testid="unassign"]');
const findEmptySearchResults = () => wrapper.find('[data-testid="empty-results"]');
@@ -136,6 +144,93 @@ describe('User select dropdown', () => {
expect(findCurrentUser().exists()).toBe(true);
});
+ it('does not render current user if user is not logged in', async () => {
+ createComponent({
+ props: {
+ currentUser: {},
+ },
+ });
+ await waitForPromises();
+
+ expect(findCurrentUser().exists()).toBe(false);
+ });
+
+ it('does not render issuable author if author is not passed as a prop', async () => {
+ createComponent();
+ await waitForPromises();
+
+ expect(findIssuableAuthor().exists()).toBe(false);
+ });
+
+ describe('when issuable author is passed as a prop', () => {
+ it('moves issuable author on top of assigned list, if author is assigned', async () => {
+ createComponent({
+ props: {
+ value: [assignee, mockUser2],
+ issuableAuthor: mockUser2,
+ },
+ });
+ await waitForPromises();
+
+ expect(findSelectedParticipantByIndex(0).props('user')).toEqual(mockUser2);
+ });
+
+ it('moves issuable author on top of assigned list after current user, if author and current user are assigned', async () => {
+ const currentUser = mockUser1;
+ const issuableAuthor = mockUser2;
+
+ createComponent({
+ props: {
+ value: [assignee, issuableAuthor, currentUser],
+ issuableAuthor,
+ currentUser,
+ },
+ });
+ await waitForPromises();
+
+ expect(findSelectedParticipantByIndex(0).props('user')).toEqual(currentUser);
+ expect(findSelectedParticipantByIndex(1).props('user')).toEqual(issuableAuthor);
+ });
+
+ it('moves issuable author on top of unassigned list, if author is unassigned project member', async () => {
+ createComponent({
+ props: {
+ issuableAuthor: mockUser2,
+ },
+ });
+ await waitForPromises();
+
+ expect(findUnselectedParticipantByIndex(0).props('user')).toEqual(mockUser2);
+ });
+
+ it('moves issuable author on top of unassigned list after current user, if author and current user are unassigned project members', async () => {
+ const currentUser = mockUser2;
+ const issuableAuthor = mockUser1;
+
+ createComponent({
+ props: {
+ issuableAuthor,
+ currentUser,
+ },
+ });
+ await waitForPromises();
+
+ expect(findUnselectedParticipantByIndex(0).props('user')).toEqual(currentUser);
+ expect(findUnselectedParticipantByIndex(1).props('user')).toMatchObject(issuableAuthor);
+ });
+
+ it('displays author in a designated position if author is not assigned and not a project member', async () => {
+ createComponent({
+ props: {
+ issuableAuthor: assignee,
+ },
+ });
+ await waitForPromises();
+
+ expect(findIssuableAuthor().exists()).toBe(true);
+ });
+ });
+
it('displays correct amount of selected users', async () => {
createComponent({
props: {
diff --git a/spec/frontend/vue_shared/components/web_ide_link_spec.js b/spec/frontend/vue_shared/components/web_ide_link_spec.js
index 040461f6be4..a0b868d1d52 100644
--- a/spec/frontend/vue_shared/components/web_ide_link_spec.js
+++ b/spec/frontend/vue_shared/components/web_ide_link_spec.js
@@ -3,7 +3,7 @@ import { nextTick } from 'vue';
import ActionsButton from '~/vue_shared/components/actions_button.vue';
import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue';
-import WebIdeLink from '~/vue_shared/components/web_ide_link.vue';
+import WebIdeLink, { i18n } from '~/vue_shared/components/web_ide_link.vue';
import ConfirmForkModal from '~/vue_shared/components/confirm_fork_modal.vue';
import { stubComponent } from 'helpers/stub_component';
@@ -37,8 +37,8 @@ const ACTION_EDIT_CONFIRM_FORK = {
const ACTION_WEB_IDE = {
href: TEST_WEB_IDE_URL,
key: 'webide',
- secondaryText: 'Quickly and easily edit multiple files in your project.',
- tooltip: '',
+ secondaryText: i18n.webIdeText,
+ tooltip: i18n.webIdeTooltip,
text: 'Web IDE',
attrs: {
'data-qa-selector': 'web_ide_button',
@@ -108,8 +108,8 @@ describe('Web IDE link component', () => {
wrapper.destroy();
});
- const findActionsButton = () => wrapper.find(ActionsButton);
- const findLocalStorageSync = () => wrapper.find(LocalStorageSync);
+ const findActionsButton = () => wrapper.findComponent(ActionsButton);
+ const findLocalStorageSync = () => wrapper.findComponent(LocalStorageSync);
const findModal = () => wrapper.findComponent(GlModal);
const findForkConfirmModal = () => wrapper.findComponent(ConfirmForkModal);