summaryrefslogtreecommitdiff
path: root/spec/frontend/vue_shared/components
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/vue_shared/components')
-rw-r--r--spec/frontend/vue_shared/components/dropdown/dropdown_widget_spec.js97
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js3
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js4
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/tokens/base_token_spec.js28
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/tokens/branch_token_spec.js34
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/tokens/emoji_token_spec.js34
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/tokens/iteration_token_spec.js4
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/tokens/label_token_spec.js23
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/tokens/milestone_token_spec.js42
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/tokens/weight_token_spec.js1
-rw-r--r--spec/frontend/vue_shared/components/issue/related_issuable_item_spec.js17
-rw-r--r--spec/frontend/vue_shared/components/markdown/toolbar_button_spec.js3
-rw-r--r--spec/frontend/vue_shared/components/papa_parse_alert_spec.js44
-rw-r--r--spec/frontend/vue_shared/components/remove_member_modal_spec.js110
-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/sidebar/labels_select_vue/dropdown_contents_labels_view_spec.js5
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_vue/labels_select_root_spec.js10
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_vue/store/actions_spec.js15
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_vue/store/mutations_spec.js22
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view_spec.js4
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view_spec.js434
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_spec.js7
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js52
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_widget/mock_data.js25
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/actions_spec.js88
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/mutations_spec.js52
-rw-r--r--spec/frontend/vue_shared/components/url_sync_spec.js8
-rw-r--r--spec/frontend/vue_shared/components/user_avatar/user_avatar_link_spec.js11
-rw-r--r--spec/frontend/vue_shared/components/web_ide_link_spec.js8
29 files changed, 438 insertions, 749 deletions
diff --git a/spec/frontend/vue_shared/components/dropdown/dropdown_widget_spec.js b/spec/frontend/vue_shared/components/dropdown/dropdown_widget_spec.js
new file mode 100644
index 00000000000..016fe1f131e
--- /dev/null
+++ b/spec/frontend/vue_shared/components/dropdown/dropdown_widget_spec.js
@@ -0,0 +1,97 @@
+import { GlDropdown, GlSearchBoxByType, GlDropdownItem } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+
+import DropdownWidget from '~/vue_shared/components/dropdown/dropdown_widget/dropdown_widget.vue';
+
+describe('DropdownWidget component', () => {
+ let wrapper;
+
+ const findDropdown = () => wrapper.findComponent(GlDropdown);
+ const findDropdownItems = () => wrapper.findAll(GlDropdownItem);
+ const findSearch = () => wrapper.findComponent(GlSearchBoxByType);
+
+ const createComponent = ({ props = {} } = {}) => {
+ wrapper = shallowMount(DropdownWidget, {
+ propsData: {
+ options: [
+ {
+ id: '1',
+ title: 'Option 1',
+ },
+ {
+ id: '2',
+ title: 'Option 2',
+ },
+ ],
+ ...props,
+ },
+ stubs: {
+ GlDropdown,
+ },
+ });
+
+ // We need to mock out `showDropdown` which
+ // invokes `show` method of BDropdown used inside GlDropdown.
+ // Context: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54895#note_524281679
+ jest.spyOn(wrapper.vm, 'showDropdown').mockImplementation();
+ };
+
+ beforeEach(() => {
+ createComponent();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ it('passes default selectText prop to dropdown', () => {
+ expect(findDropdown().props('text')).toBe('Select');
+ });
+
+ describe('when dropdown is open', () => {
+ beforeEach(async () => {
+ findDropdown().vm.$emit('show');
+ await wrapper.vm.$nextTick();
+ });
+
+ it('emits search event when typing in search box', () => {
+ const searchTerm = 'searchTerm';
+ findSearch().vm.$emit('input', searchTerm);
+
+ expect(wrapper.emitted('set-search')).toEqual([[searchTerm]]);
+ });
+
+ it('renders one selectable item per passed option', async () => {
+ expect(findDropdownItems()).toHaveLength(2);
+ });
+
+ it('emits set-option event when clicking on an option', async () => {
+ wrapper
+ .findAll('[data-testid="unselected-option"]')
+ .at(1)
+ .vm.$emit('click', new Event('click'));
+ await wrapper.vm.$nextTick();
+
+ expect(wrapper.emitted('set-option')).toEqual([[wrapper.props().options[1]]]);
+ });
+ });
+
+ describe('when options are users', () => {
+ const mockUser = {
+ id: 1,
+ name: 'User name',
+ username: 'username',
+ avatarUrl: 'foo/bar',
+ };
+
+ beforeEach(() => {
+ createComponent({ props: { options: [mockUser] } });
+ });
+
+ it('passes user related props to dropdown item', () => {
+ expect(findDropdownItems().at(0).props('avatarUrl')).toBe(mockUser.avatarUrl);
+ expect(findDropdownItems().at(0).props('secondaryText')).toBe(mockUser.username);
+ });
+ });
+});
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 9fa9d35e3e2..8e931aebfe0 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
@@ -32,6 +32,9 @@ jest.mock('~/vue_shared/components/filtered_search_bar/filtered_search_utils', (
stripQuotes: jest.requireActual(
'~/vue_shared/components/filtered_search_bar/filtered_search_utils',
).stripQuotes,
+ filterEmptySearchTerm: jest.requireActual(
+ '~/vue_shared/components/filtered_search_bar/filtered_search_utils',
+ ).filterEmptySearchTerm,
}));
const createComponent = ({
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 74f579e77ed..d3e1bfef561 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
@@ -86,7 +86,7 @@ describe('AuthorToken', () => {
});
describe('methods', () => {
- describe('fetchAuthorBySearchTerm', () => {
+ describe('fetchAuthors', () => {
beforeEach(() => {
wrapper = createComponent();
});
@@ -155,7 +155,7 @@ describe('AuthorToken', () => {
expect(baseTokenEl.exists()).toBe(true);
expect(baseTokenEl.props()).toMatchObject({
suggestions: mockAuthors,
- fnActiveTokenValue: wrapper.vm.getActiveAuthor,
+ getActiveTokenValue: wrapper.vm.getActiveAuthor,
});
});
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/base_token_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/base_token_spec.js
index cd6ffd679d0..eb1dbed52cc 100644
--- a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/base_token_spec.js
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/base_token_spec.js
@@ -5,7 +5,7 @@ import {
mockLabels,
} from 'jest/vue_shared/components/sidebar/labels_select_vue/mock_data';
-import { DEFAULT_LABELS } from '~/vue_shared/components/filtered_search_bar/constants';
+import { DEFAULT_NONE_ANY } from '~/vue_shared/components/filtered_search_bar/constants';
import {
getRecentlyUsedSuggestions,
setTokenValueToRecentlyUsed,
@@ -51,9 +51,8 @@ const mockProps = {
active: false,
suggestions: [],
suggestionsLoading: false,
- defaultSuggestions: DEFAULT_LABELS,
+ defaultSuggestions: DEFAULT_NONE_ANY,
recentSuggestionsStorageKey: mockStorageKey,
- fnCurrentTokenValue: jest.fn(),
};
function createComponent({
@@ -99,31 +98,20 @@ describe('BaseToken', () => {
});
describe('computed', () => {
- describe('currentTokenValue', () => {
- it('calls `fnCurrentTokenValue` when it is provided', () => {
- // We're disabling lint to trigger computed prop execution for this test.
- // eslint-disable-next-line no-unused-vars
- const { currentTokenValue } = wrapper.vm;
-
- expect(wrapper.vm.fnCurrentTokenValue).toHaveBeenCalledWith(`"${mockRegularLabel.title}"`);
- });
- });
-
describe('activeTokenValue', () => {
- it('calls `fnActiveTokenValue` when it is provided', async () => {
- const mockFnActiveTokenValue = jest.fn();
+ it('calls `getActiveTokenValue` when it is provided', async () => {
+ const mockGetActiveTokenValue = jest.fn();
wrapper.setProps({
- fnActiveTokenValue: mockFnActiveTokenValue,
- fnCurrentTokenValue: undefined,
+ getActiveTokenValue: mockGetActiveTokenValue,
});
await wrapper.vm.$nextTick();
- expect(mockFnActiveTokenValue).toHaveBeenCalledTimes(1);
- expect(mockFnActiveTokenValue).toHaveBeenCalledWith(
+ expect(mockGetActiveTokenValue).toHaveBeenCalledTimes(1);
+ expect(mockGetActiveTokenValue).toHaveBeenCalledWith(
mockLabels,
- `"${mockRegularLabel.title.toLowerCase()}"`,
+ `"${mockRegularLabel.title}"`,
);
});
});
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 331c9c2c14d..09eac636cae 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
@@ -61,40 +61,16 @@ describe('BranchToken', () => {
wrapper.destroy();
});
- describe('computed', () => {
- beforeEach(async () => {
- wrapper = createComponent({ value: { data: mockBranches[0].name } });
-
- wrapper.setData({
- branches: mockBranches,
- });
-
- await wrapper.vm.$nextTick();
- });
-
- describe('currentValue', () => {
- it('returns lowercase string for `value.data`', () => {
- expect(wrapper.vm.currentValue).toBe('main');
- });
- });
-
- describe('activeBranch', () => {
- it('returns object for currently present `value.data`', () => {
- expect(wrapper.vm.activeBranch).toEqual(mockBranches[0]);
- });
- });
- });
-
describe('methods', () => {
beforeEach(() => {
wrapper = createComponent();
});
- describe('fetchBranchBySearchTerm', () => {
+ describe('fetchBranches', () => {
it('calls `config.fetchBranches` with provided searchTerm param', () => {
jest.spyOn(wrapper.vm.config, 'fetchBranches');
- wrapper.vm.fetchBranchBySearchTerm('foo');
+ wrapper.vm.fetchBranches('foo');
expect(wrapper.vm.config.fetchBranches).toHaveBeenCalledWith('foo');
});
@@ -102,7 +78,7 @@ describe('BranchToken', () => {
it('sets response to `branches` when request is succesful', () => {
jest.spyOn(wrapper.vm.config, 'fetchBranches').mockResolvedValue({ data: mockBranches });
- wrapper.vm.fetchBranchBySearchTerm('foo');
+ wrapper.vm.fetchBranches('foo');
return waitForPromises().then(() => {
expect(wrapper.vm.branches).toEqual(mockBranches);
@@ -112,7 +88,7 @@ describe('BranchToken', () => {
it('calls `createFlash` with flash error message when request fails', () => {
jest.spyOn(wrapper.vm.config, 'fetchBranches').mockRejectedValue({});
- wrapper.vm.fetchBranchBySearchTerm('foo');
+ wrapper.vm.fetchBranches('foo');
return waitForPromises().then(() => {
expect(createFlash).toHaveBeenCalledWith({
@@ -124,7 +100,7 @@ describe('BranchToken', () => {
it('sets `loading` to false when request completes', () => {
jest.spyOn(wrapper.vm.config, 'fetchBranches').mockRejectedValue({});
- wrapper.vm.fetchBranchBySearchTerm('foo');
+ wrapper.vm.fetchBranches('foo');
return waitForPromises().then(() => {
expect(wrapper.vm.loading).toBe(false);
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 778a214f97e..c2d61fd9f05 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
@@ -67,40 +67,16 @@ describe('EmojiToken', () => {
wrapper.destroy();
});
- describe('computed', () => {
- beforeEach(async () => {
- wrapper = createComponent({ value: { data: mockEmojis[0].name } });
-
- wrapper.setData({
- emojis: mockEmojis,
- });
-
- await wrapper.vm.$nextTick();
- });
-
- describe('currentValue', () => {
- it('returns lowercase string for `value.data`', () => {
- expect(wrapper.vm.currentValue).toBe(mockEmojis[0].name);
- });
- });
-
- describe('activeEmoji', () => {
- it('returns object for currently present `value.data`', () => {
- expect(wrapper.vm.activeEmoji).toEqual(mockEmojis[0]);
- });
- });
- });
-
describe('methods', () => {
beforeEach(() => {
wrapper = createComponent();
});
- describe('fetchEmojiBySearchTerm', () => {
+ describe('fetchEmojis', () => {
it('calls `config.fetchEmojis` with provided searchTerm param', () => {
jest.spyOn(wrapper.vm.config, 'fetchEmojis');
- wrapper.vm.fetchEmojiBySearchTerm('foo');
+ wrapper.vm.fetchEmojis('foo');
expect(wrapper.vm.config.fetchEmojis).toHaveBeenCalledWith('foo');
});
@@ -108,7 +84,7 @@ describe('EmojiToken', () => {
it('sets response to `emojis` when request is successful', () => {
jest.spyOn(wrapper.vm.config, 'fetchEmojis').mockResolvedValue(mockEmojis);
- wrapper.vm.fetchEmojiBySearchTerm('foo');
+ wrapper.vm.fetchEmojis('foo');
return waitForPromises().then(() => {
expect(wrapper.vm.emojis).toEqual(mockEmojis);
@@ -118,7 +94,7 @@ describe('EmojiToken', () => {
it('calls `createFlash` with flash error message when request fails', () => {
jest.spyOn(wrapper.vm.config, 'fetchEmojis').mockRejectedValue({});
- wrapper.vm.fetchEmojiBySearchTerm('foo');
+ wrapper.vm.fetchEmojis('foo');
return waitForPromises().then(() => {
expect(createFlash).toHaveBeenCalledWith({
@@ -130,7 +106,7 @@ describe('EmojiToken', () => {
it('sets `loading` to false when request completes', () => {
jest.spyOn(wrapper.vm.config, 'fetchEmojis').mockRejectedValue({});
- wrapper.vm.fetchEmojiBySearchTerm('foo');
+ wrapper.vm.fetchEmojis('foo');
return waitForPromises().then(() => {
expect(wrapper.vm.loading).toBe(false);
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/iteration_token_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/iteration_token_spec.js
index bd654c5a9cb..a609aaa1c4e 100644
--- a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/iteration_token_spec.js
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/iteration_token_spec.js
@@ -1,5 +1,6 @@
import { GlFilteredSearchToken, GlFilteredSearchTokenSegment } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
+import waitForPromises from 'helpers/wait_for_promises';
import createFlash from '~/flash';
import IterationToken from '~/vue_shared/components/filtered_search_bar/tokens/iteration_token.vue';
import { mockIterationToken } from '../mock_data';
@@ -13,6 +14,7 @@ describe('IterationToken', () => {
const createComponent = ({ config = mockIterationToken, value = { data: '' } } = {}) =>
mount(IterationToken, {
propsData: {
+ active: false,
config,
value,
},
@@ -69,7 +71,7 @@ describe('IterationToken', () => {
config: { ...mockIterationToken, fetchIterations: fetchIterationsSpy },
});
- await wrapper.vm.$nextTick();
+ await waitForPromises();
expect(createFlash).toHaveBeenCalledWith({
message: 'There was a problem fetching iterations.',
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 ec9458f64d2..a348344b9dd 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
@@ -13,10 +13,7 @@ import {
import createFlash from '~/flash';
import axios from '~/lib/utils/axios_utils';
-import {
- DEFAULT_LABELS,
- DEFAULT_NONE_ANY,
-} from '~/vue_shared/components/filtered_search_bar/constants';
+import { DEFAULT_NONE_ANY } from '~/vue_shared/components/filtered_search_bar/constants';
import BaseToken from '~/vue_shared/components/filtered_search_bar/tokens/base_token.vue';
import LabelToken from '~/vue_shared/components/filtered_search_bar/tokens/label_token.vue';
@@ -98,11 +95,11 @@ describe('LabelToken', () => {
});
});
- describe('fetchLabelBySearchTerm', () => {
+ describe('fetchLabels', () => {
it('calls `config.fetchLabels` with provided searchTerm param', () => {
jest.spyOn(wrapper.vm.config, 'fetchLabels');
- wrapper.vm.fetchLabelBySearchTerm('foo');
+ wrapper.vm.fetchLabels('foo');
expect(wrapper.vm.config.fetchLabels).toHaveBeenCalledWith('foo');
});
@@ -110,7 +107,7 @@ describe('LabelToken', () => {
it('sets response to `labels` when request is succesful', () => {
jest.spyOn(wrapper.vm.config, 'fetchLabels').mockResolvedValue(mockLabels);
- wrapper.vm.fetchLabelBySearchTerm('foo');
+ wrapper.vm.fetchLabels('foo');
return waitForPromises().then(() => {
expect(wrapper.vm.labels).toEqual(mockLabels);
@@ -120,7 +117,7 @@ describe('LabelToken', () => {
it('calls `createFlash` with flash error message when request fails', () => {
jest.spyOn(wrapper.vm.config, 'fetchLabels').mockRejectedValue({});
- wrapper.vm.fetchLabelBySearchTerm('foo');
+ wrapper.vm.fetchLabels('foo');
return waitForPromises().then(() => {
expect(createFlash).toHaveBeenCalledWith({
@@ -132,7 +129,7 @@ describe('LabelToken', () => {
it('sets `loading` to false when request completes', () => {
jest.spyOn(wrapper.vm.config, 'fetchLabels').mockRejectedValue({});
- wrapper.vm.fetchLabelBySearchTerm('foo');
+ wrapper.vm.fetchLabels('foo');
return waitForPromises().then(() => {
expect(wrapper.vm.loading).toBe(false);
@@ -160,7 +157,7 @@ describe('LabelToken', () => {
expect(baseTokenEl.exists()).toBe(true);
expect(baseTokenEl.props()).toMatchObject({
suggestions: mockLabels,
- fnActiveTokenValue: wrapper.vm.getActiveLabel,
+ getActiveTokenValue: wrapper.vm.getActiveLabel,
});
});
@@ -208,7 +205,7 @@ describe('LabelToken', () => {
expect(wrapper.find(GlDropdownDivider).exists()).toBe(false);
});
- it('renders `DEFAULT_LABELS` as default suggestions', () => {
+ it('renders `DEFAULT_NONE_ANY` as default suggestions', () => {
wrapper = createComponent({
active: true,
config: { ...mockLabelToken },
@@ -220,8 +217,8 @@ describe('LabelToken', () => {
const suggestions = wrapper.findAll(GlFilteredSearchSuggestion);
- expect(suggestions).toHaveLength(DEFAULT_LABELS.length);
- DEFAULT_LABELS.forEach((label, index) => {
+ expect(suggestions).toHaveLength(DEFAULT_NONE_ANY.length);
+ DEFAULT_NONE_ANY.forEach((label, index) => {
expect(suggestions.at(index).text()).toBe(label.text);
});
});
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 74ceb03bb96..529844817d3 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
@@ -14,12 +14,7 @@ import { sortMilestonesByDueDate } from '~/milestones/milestone_utils';
import { DEFAULT_MILESTONES } from '~/vue_shared/components/filtered_search_bar/constants';
import MilestoneToken from '~/vue_shared/components/filtered_search_bar/tokens/milestone_token.vue';
-import {
- mockMilestoneToken,
- mockMilestones,
- mockRegularMilestone,
- mockEscapedMilestone,
-} from '../mock_data';
+import { mockMilestoneToken, mockMilestones, mockRegularMilestone } from '../mock_data';
jest.mock('~/flash');
jest.mock('~/milestones/milestone_utils');
@@ -70,37 +65,12 @@ describe('MilestoneToken', () => {
wrapper.destroy();
});
- describe('computed', () => {
- beforeEach(async () => {
- // Milestone title with spaces is always enclosed in quotations by component.
- wrapper = createComponent({ value: { data: `"${mockEscapedMilestone.title}"` } });
-
- wrapper.setData({
- milestones: mockMilestones,
- });
-
- await wrapper.vm.$nextTick();
- });
-
- describe('currentValue', () => {
- it('returns lowercase string for `value.data`', () => {
- expect(wrapper.vm.currentValue).toBe('"5.0 rc1"');
- });
- });
-
- describe('activeMilestone', () => {
- it('returns object for currently present `value.data`', () => {
- expect(wrapper.vm.activeMilestone).toEqual(mockEscapedMilestone);
- });
- });
- });
-
describe('methods', () => {
- describe('fetchMilestoneBySearchTerm', () => {
+ describe('fetchMilestones', () => {
it('calls `config.fetchMilestones` with provided searchTerm param', () => {
jest.spyOn(wrapper.vm.config, 'fetchMilestones');
- wrapper.vm.fetchMilestoneBySearchTerm('foo');
+ wrapper.vm.fetchMilestones('foo');
expect(wrapper.vm.config.fetchMilestones).toHaveBeenCalledWith('foo');
});
@@ -110,7 +80,7 @@ describe('MilestoneToken', () => {
data: mockMilestones,
});
- wrapper.vm.fetchMilestoneBySearchTerm();
+ wrapper.vm.fetchMilestones();
return waitForPromises().then(() => {
expect(wrapper.vm.milestones).toEqual(mockMilestones);
@@ -121,7 +91,7 @@ describe('MilestoneToken', () => {
it('calls `createFlash` with flash error message when request fails', () => {
jest.spyOn(wrapper.vm.config, 'fetchMilestones').mockRejectedValue({});
- wrapper.vm.fetchMilestoneBySearchTerm('foo');
+ wrapper.vm.fetchMilestones('foo');
return waitForPromises().then(() => {
expect(createFlash).toHaveBeenCalledWith({
@@ -133,7 +103,7 @@ describe('MilestoneToken', () => {
it('sets `loading` to false when request completes', () => {
jest.spyOn(wrapper.vm.config, 'fetchMilestones').mockRejectedValue({});
- wrapper.vm.fetchMilestoneBySearchTerm('foo');
+ wrapper.vm.fetchMilestones('foo');
return waitForPromises().then(() => {
expect(wrapper.vm.loading).toBe(false);
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/weight_token_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/weight_token_spec.js
index 9a72be636cd..e788c742736 100644
--- a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/weight_token_spec.js
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/weight_token_spec.js
@@ -12,6 +12,7 @@ describe('WeightToken', () => {
const createComponent = ({ config = mockWeightToken, value = { data: '' } } = {}) =>
mount(WeightToken, {
propsData: {
+ active: false,
config,
value,
},
diff --git a/spec/frontend/vue_shared/components/issue/related_issuable_item_spec.js b/spec/frontend/vue_shared/components/issue/related_issuable_item_spec.js
index 8738924f717..6ab828efebe 100644
--- a/spec/frontend/vue_shared/components/issue/related_issuable_item_spec.js
+++ b/spec/frontend/vue_shared/components/issue/related_issuable_item_spec.js
@@ -144,23 +144,6 @@ describe('RelatedIssuableItem', () => {
expect(wrapper.find(IssueDueDate).props('closed')).toBe(true);
});
-
- it('should not contain the `.text-danger` css class for overdue issue that is closed', async () => {
- mountComponent({
- props: {
- ...props,
- closedAt: '2018-12-01T00:00:00.00Z',
- },
- });
- await wrapper.vm.$nextTick();
-
- expect(wrapper.find(IssueDueDate).find('.board-card-info-icon').classes('text-danger')).toBe(
- false,
- );
- expect(wrapper.find(IssueDueDate).find('.board-card-info-text').classes('text-danger')).toBe(
- false,
- );
- });
});
describe('token assignees', () => {
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 786dfabb990..19e4f2d8c92 100644
--- a/spec/frontend/vue_shared/components/markdown/toolbar_button_spec.js
+++ b/spec/frontend/vue_shared/components/markdown/toolbar_button_spec.js
@@ -1,3 +1,4 @@
+import { GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import ToolbarButton from '~/vue_shared/components/markdown/toolbar_button.vue';
@@ -25,7 +26,7 @@ describe('toolbar_button', () => {
});
const getButtonShortcutsAttr = () => {
- return wrapper.find('button').attributes('data-md-shortcuts');
+ return wrapper.find(GlButton).attributes('data-md-shortcuts');
};
describe('keyboard shortcuts', () => {
diff --git a/spec/frontend/vue_shared/components/papa_parse_alert_spec.js b/spec/frontend/vue_shared/components/papa_parse_alert_spec.js
new file mode 100644
index 00000000000..9be2de17d01
--- /dev/null
+++ b/spec/frontend/vue_shared/components/papa_parse_alert_spec.js
@@ -0,0 +1,44 @@
+import { GlAlert } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
+import PapaParseAlert from '~/vue_shared/components/papa_parse_alert.vue';
+
+describe('app/assets/javascripts/vue_shared/components/papa_parse_alert.vue', () => {
+ let wrapper;
+
+ const createComponent = ({ errorMessages } = {}) => {
+ wrapper = shallowMount(PapaParseAlert, {
+ propsData: {
+ papaParseErrors: errorMessages,
+ },
+ });
+ };
+
+ const findAlert = () => wrapper.findComponent(GlAlert);
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('should render alert with correct props', async () => {
+ createComponent({ errorMessages: [{ code: 'MissingQuotes' }] });
+ await nextTick;
+
+ expect(findAlert().props()).toMatchObject({
+ variant: 'danger',
+ });
+ expect(findAlert().text()).toContain(
+ 'Failed to render the CSV file for the following reasons:',
+ );
+ expect(findAlert().text()).toContain('Quoted field unterminated');
+ });
+
+ it('should render original message if no translation available', async () => {
+ createComponent({
+ errorMessages: [{ code: 'NotDefined', message: 'Error code is undefined' }],
+ });
+ await nextTick;
+
+ expect(findAlert().text()).toContain('Error code is undefined');
+ });
+});
diff --git a/spec/frontend/vue_shared/components/remove_member_modal_spec.js b/spec/frontend/vue_shared/components/remove_member_modal_spec.js
deleted file mode 100644
index ce9de28d53c..00000000000
--- a/spec/frontend/vue_shared/components/remove_member_modal_spec.js
+++ /dev/null
@@ -1,110 +0,0 @@
-import { GlModal } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
-import OncallSchedulesList from '~/vue_shared/components/oncall_schedules_list.vue';
-import RemoveMemberModal from '~/vue_shared/components/remove_member_modal.vue';
-
-const mockSchedules = JSON.stringify({
- schedules: [
- {
- id: 1,
- name: 'Schedule 1',
- },
- ],
- name: 'User1',
-});
-
-describe('RemoveMemberModal', () => {
- const memberPath = '/gitlab-org/gitlab-test/-/project_members/90';
- let wrapper;
-
- const findForm = () => wrapper.find({ ref: 'form' });
- const findGlModal = () => wrapper.findComponent(GlModal);
- const findOnCallSchedulesList = () => wrapper.findComponent(OncallSchedulesList);
-
- afterEach(() => {
- wrapper.destroy();
- wrapper = null;
- });
-
- describe.each`
- state | memberType | isAccessRequest | isInvite | actionText | removeSubMembershipsCheckboxExpected | unassignIssuablesCheckboxExpected | message | onCallSchedules
- ${'removing a group member'} | ${'GroupMember'} | ${false} | ${'false'} | ${'Remove member'} | ${true} | ${true} | ${'Are you sure you want to remove Jane Doe from the Gitlab Org / Gitlab Test project?'} | ${`{}`}
- ${'removing a project member'} | ${'ProjectMember'} | ${false} | ${'false'} | ${'Remove member'} | ${false} | ${true} | ${'Are you sure you want to remove Jane Doe from the Gitlab Org / Gitlab Test project?'} | ${mockSchedules}
- ${'denying an access request'} | ${'ProjectMember'} | ${true} | ${'false'} | ${'Deny access request'} | ${false} | ${false} | ${"Are you sure you want to deny Jane Doe's request to join the Gitlab Org / Gitlab Test project?"} | ${`{}`}
- ${'revoking invite'} | ${'ProjectMember'} | ${false} | ${'true'} | ${'Revoke invite'} | ${false} | ${false} | ${'Are you sure you want to revoke the invitation for foo@bar.com to join the Gitlab Org / Gitlab Test project?'} | ${mockSchedules}
- `(
- 'when $state',
- ({
- actionText,
- memberType,
- isAccessRequest,
- isInvite,
- message,
- removeSubMembershipsCheckboxExpected,
- unassignIssuablesCheckboxExpected,
- onCallSchedules,
- }) => {
- beforeEach(() => {
- wrapper = shallowMount(RemoveMemberModal, {
- data() {
- return {
- modalData: {
- isAccessRequest,
- isInvite,
- message,
- memberPath,
- memberType,
- onCallSchedules,
- },
- };
- },
- });
- });
-
- const parsedSchedules = JSON.parse(onCallSchedules);
- const isPartOfOncallSchedules = Boolean(isAccessRequest && parsedSchedules.schedules?.length);
-
- it(`has the title ${actionText}`, () => {
- expect(findGlModal().attributes('title')).toBe(actionText);
- });
-
- it('contains a form action', () => {
- expect(findForm().attributes('action')).toBe(memberPath);
- });
-
- it('displays a message to the user', () => {
- expect(wrapper.find('[data-testid=modal-message]').text()).toBe(message);
- });
-
- it(`shows ${
- removeSubMembershipsCheckboxExpected ? 'a' : 'no'
- } checkbox to remove direct memberships of subgroups/projects`, () => {
- expect(wrapper.find('[name=remove_sub_memberships]').exists()).toBe(
- removeSubMembershipsCheckboxExpected,
- );
- });
-
- it(`shows ${
- unassignIssuablesCheckboxExpected ? 'a' : 'no'
- } checkbox to allow removal from related issues and MRs`, () => {
- expect(wrapper.find('[name=unassign_issuables]').exists()).toBe(
- unassignIssuablesCheckboxExpected,
- );
- });
-
- it(`shows ${isPartOfOncallSchedules ? 'all' : 'no'} related on-call schedules`, () => {
- expect(findOnCallSchedulesList().exists()).toBe(isPartOfOncallSchedules);
- });
-
- it('submits the form when the modal is submitted', () => {
- const spy = jest.spyOn(findForm().element, 'submit');
-
- findGlModal().vm.$emit('primary');
-
- expect(spy).toHaveBeenCalled();
-
- spy.mockRestore();
- });
- },
- );
-});
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 395c74dcba6..71ebe561def 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
@@ -13,7 +13,7 @@ import {
REPORT_TYPE_SAST,
REPORT_TYPE_SECRET_DETECTION,
} from '~/vue_shared/security_reports/constants';
-import securityReportMergeRequestDownloadPathsQuery from '~/vue_shared/security_reports/queries/security_report_merge_request_download_paths.query.graphql';
+import securityReportMergeRequestDownloadPathsQuery from '~/vue_shared/security_reports/graphql/queries/security_report_merge_request_download_paths.query.graphql';
jest.mock('~/flash');
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 06ea88c09a0..a1942e59571 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
@@ -116,6 +116,8 @@ describe('DropdownContentsLabelsView', () => {
});
describe('methods', () => {
+ const fakePreventDefault = jest.fn();
+
describe('isLabelSelected', () => {
it('returns true when provided `label` param is one of the selected labels', () => {
expect(wrapper.vm.isLabelSelected(mockRegularLabel)).toBe(true);
@@ -191,9 +193,11 @@ describe('DropdownContentsLabelsView', () => {
wrapper.vm.handleKeyDown({
keyCode: ENTER_KEY_CODE,
+ preventDefault: fakePreventDefault,
});
expect(wrapper.vm.searchKey).toBe('');
+ expect(fakePreventDefault).toHaveBeenCalled();
});
it('calls action `updateSelectedLabels` with currently highlighted label when Enter key is pressed', () => {
@@ -204,6 +208,7 @@ describe('DropdownContentsLabelsView', () => {
wrapper.vm.handleKeyDown({
keyCode: ENTER_KEY_CODE,
+ preventDefault: fakePreventDefault,
});
expect(wrapper.vm.updateSelectedLabels).toHaveBeenCalledWith([
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 be849789667..bc1ec8b812b 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
@@ -238,4 +238,14 @@ describe('LabelsSelectRoot', () => {
expect(store.dispatch).not.toHaveBeenCalled();
});
+
+ it('calls updateLabelsSetState after selected labels were updated', async () => {
+ createComponent();
+
+ jest.spyOn(store, 'dispatch').mockResolvedValue();
+ await wrapper.setProps({ selectedLabels: [] });
+ jest.advanceTimersByTime(100);
+
+ expect(store.dispatch).toHaveBeenCalledWith('updateLabelsSetState');
+ });
});
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/store/actions_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/store/actions_spec.js
index 46ade5d5857..2e4c056df61 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/store/actions_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/store/actions_spec.js
@@ -214,7 +214,7 @@ describe('LabelsSelect Actions', () => {
});
describe('on success', () => {
- it('dispatches `requestCreateLabel`, `receiveCreateLabelSuccess` & `toggleDropdownContentsCreateView` actions', (done) => {
+ it('dispatches `requestCreateLabel`, `fetchLabels` & `receiveCreateLabelSuccess` & `toggleDropdownContentsCreateView` actions', (done) => {
const label = { id: 1 };
mock.onPost(/labels.json/).replyOnce(200, label);
@@ -225,6 +225,7 @@ describe('LabelsSelect Actions', () => {
[],
[
{ type: 'requestCreateLabel' },
+ { payload: { refetch: true }, type: 'fetchLabels' },
{ type: 'receiveCreateLabelSuccess' },
{ type: 'toggleDropdownContentsCreateView' },
],
@@ -263,4 +264,16 @@ describe('LabelsSelect Actions', () => {
);
});
});
+
+ describe('updateLabelsSetState', () => {
+ it('updates labels `set` state to match `selectedLabels`', () => {
+ testAction(
+ actions.updateLabelsSetState,
+ {},
+ state,
+ [{ type: types.UPDATE_LABELS_SET_STATE }],
+ [],
+ );
+ });
+ });
});
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/store/mutations_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/store/mutations_spec.js
index 1d2a9c34599..14e0c8a2278 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/store/mutations_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/store/mutations_spec.js
@@ -197,4 +197,26 @@ describe('LabelsSelect Mutations', () => {
});
});
});
+
+ describe(`${types.UPDATE_LABELS_SET_STATE}`, () => {
+ it('updates labels `set` state to match selected labels', () => {
+ const state = {
+ labels: [
+ { id: 1, title: 'scoped::test', set: false },
+ { id: 2, set: true, title: 'scoped::one', touched: true },
+ { id: 3, title: '' },
+ { id: 4, title: '' },
+ ],
+ selectedLabels: [{ id: 1 }, { id: 3 }],
+ };
+ mutations[types.UPDATE_LABELS_SET_STATE](state);
+
+ expect(state.labels).toEqual([
+ { id: 1, title: 'scoped::test', set: true },
+ { id: 2, set: false, title: 'scoped::one', touched: true },
+ { id: 3, title: '', set: true },
+ { id: 4, title: '', set: false },
+ ]);
+ });
+ });
});
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view_spec.js
index 46a11bc28d8..90bc1980ac3 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view_spec.js
@@ -1,6 +1,6 @@
import { GlLoadingIcon, GlLink } from '@gitlab/ui';
import { shallowMount, createLocalVue } from '@vue/test-utils';
-import Vue, { nextTick } from 'vue';
+import { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
@@ -14,7 +14,7 @@ jest.mock('~/flash');
const colors = Object.keys(mockSuggestedColors);
const localVue = createLocalVue();
-Vue.use(VueApollo);
+localVue.use(VueApollo);
const userRecoverableError = {
...createLabelSuccessfulResponse,
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view_spec.js
index 51301387c99..8bd944a3d54 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view_spec.js
@@ -1,357 +1,213 @@
-import { GlIntersectionObserver, GlLoadingIcon, GlSearchBoxByType, GlLink } from '@gitlab/ui';
+import { GlLoadingIcon, GlSearchBoxByType } from '@gitlab/ui';
import { shallowMount, createLocalVue } from '@vue/test-utils';
-import Vuex from 'vuex';
-import { UP_KEY_CODE, DOWN_KEY_CODE, ENTER_KEY_CODE, ESC_KEY_CODE } from '~/lib/utils/keycodes';
+import { nextTick } from 'vue';
+import VueApollo from 'vue-apollo';
+import createMockApollo from 'helpers/mock_apollo_helper';
+import waitForPromises from 'helpers/wait_for_promises';
+import createFlash from '~/flash';
+import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants';
+import { DropdownVariant } from '~/vue_shared/components/sidebar/labels_select_widget/constants';
import DropdownContentsLabelsView from '~/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view.vue';
+import projectLabelsQuery from '~/vue_shared/components/sidebar/labels_select_widget/graphql/project_labels.query.graphql';
import LabelItem from '~/vue_shared/components/sidebar/labels_select_widget/label_item.vue';
+import { mockConfig, labelsQueryResponse } from './mock_data';
-import * as actions from '~/vue_shared/components/sidebar/labels_select_widget/store/actions';
-import * as getters from '~/vue_shared/components/sidebar/labels_select_widget/store/getters';
-import mutations from '~/vue_shared/components/sidebar/labels_select_widget/store/mutations';
-import defaultState from '~/vue_shared/components/sidebar/labels_select_widget/store/state';
-
-import { mockConfig, mockLabels, mockRegularLabel } from './mock_data';
+jest.mock('~/flash');
const localVue = createLocalVue();
-localVue.use(Vuex);
+localVue.use(VueApollo);
+
+const selectedLabels = [
+ {
+ id: 28,
+ title: 'Bug',
+ description: 'Label for bugs',
+ color: '#FF0000',
+ textColor: '#FFFFFF',
+ },
+];
describe('DropdownContentsLabelsView', () => {
let wrapper;
- const createComponent = (initialState = mockConfig) => {
- const store = new Vuex.Store({
- getters,
- mutations,
- state: {
- ...defaultState(),
- footerCreateLabelTitle: 'Create label',
- footerManageLabelTitle: 'Manage labels',
- },
- actions: {
- ...actions,
- fetchLabels: jest.fn(),
- },
- });
+ const successfulQueryHandler = jest.fn().mockResolvedValue(labelsQueryResponse);
- store.dispatch('setInitialState', initialState);
- store.dispatch('receiveLabelsSuccess', mockLabels);
+ const createComponent = ({
+ initialState = mockConfig,
+ queryHandler = successfulQueryHandler,
+ injected = {},
+ } = {}) => {
+ const mockApollo = createMockApollo([[projectLabelsQuery, queryHandler]]);
wrapper = shallowMount(DropdownContentsLabelsView, {
localVue,
- store,
+ apolloProvider: mockApollo,
+ provide: {
+ projectPath: 'test',
+ iid: 1,
+ allowLabelCreate: true,
+ labelsManagePath: '/gitlab-org/my-project/-/labels',
+ variant: DropdownVariant.Sidebar,
+ ...injected,
+ },
+ propsData: {
+ ...initialState,
+ selectedLabels,
+ },
+ stubs: {
+ GlSearchBoxByType,
+ },
});
};
- beforeEach(() => {
- createComponent();
- });
-
afterEach(() => {
wrapper.destroy();
- wrapper = null;
});
- const findDropdownContent = () => wrapper.find('[data-testid="dropdown-content"]');
+ const findSearchInput = () => wrapper.findComponent(GlSearchBoxByType);
+ const findLabels = () => wrapper.findAllComponents(LabelItem);
+ const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
+
+ const findLabelsList = () => wrapper.find('[data-testid="labels-list"]');
+ const findDropdownWrapper = () => wrapper.find('[data-testid="dropdown-wrapper"]');
const findDropdownFooter = () => wrapper.find('[data-testid="dropdown-footer"]');
- const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
-
- describe('computed', () => {
- describe('visibleLabels', () => {
- it('returns matching labels filtered with `searchKey`', () => {
- wrapper.setData({
- searchKey: 'bug',
- });
-
- expect(wrapper.vm.visibleLabels.length).toBe(1);
- expect(wrapper.vm.visibleLabels[0].title).toBe('Bug');
- });
-
- it('returns matching labels with fuzzy filtering', () => {
- wrapper.setData({
- searchKey: 'bg',
- });
-
- expect(wrapper.vm.visibleLabels.length).toBe(2);
- expect(wrapper.vm.visibleLabels[0].title).toBe('Bug');
- expect(wrapper.vm.visibleLabels[1].title).toBe('Boog');
- });
-
- it('returns all labels when `searchKey` is empty', () => {
- wrapper.setData({
- searchKey: '',
- });
-
- expect(wrapper.vm.visibleLabels.length).toBe(mockLabels.length);
- });
- });
+ const findNoResultsMessage = () => wrapper.find('[data-testid="no-results"]');
+ const findCreateLabelButton = () => wrapper.find('[data-testid="create-label-button"]');
- describe('showNoMatchingResultsMessage', () => {
- it.each`
- searchKey | labels | labelsDescription | returnValue
- ${''} | ${[]} | ${'empty'} | ${false}
- ${'bug'} | ${[]} | ${'empty'} | ${true}
- ${''} | ${mockLabels} | ${'not empty'} | ${false}
- ${'bug'} | ${mockLabels} | ${'not empty'} | ${false}
- `(
- 'returns $returnValue when searchKey is "$searchKey" and visibleLabels is $labelsDescription',
- async ({ searchKey, labels, returnValue }) => {
- wrapper.setData({
- searchKey,
- });
-
- wrapper.vm.$store.dispatch('receiveLabelsSuccess', labels);
-
- await wrapper.vm.$nextTick();
-
- expect(wrapper.vm.showNoMatchingResultsMessage).toBe(returnValue);
- },
- );
+ describe('when loading labels', () => {
+ it('renders disabled search input field', async () => {
+ createComponent();
+ expect(findSearchInput().props('disabled')).toBe(true);
});
- });
-
- describe('methods', () => {
- describe('isLabelSelected', () => {
- it('returns true when provided `label` param is one of the selected labels', () => {
- expect(wrapper.vm.isLabelSelected(mockRegularLabel)).toBe(true);
- });
- it('returns false when provided `label` param is not one of the selected labels', () => {
- expect(wrapper.vm.isLabelSelected(mockLabels[2])).toBe(false);
- });
+ it('renders loading icon', async () => {
+ createComponent();
+ expect(findLoadingIcon().exists()).toBe(true);
});
- describe('handleComponentAppear', () => {
- it('calls `focusInput` on searchInput field', async () => {
- wrapper.vm.$refs.searchInput.focusInput = jest.fn();
-
- await wrapper.vm.handleComponentAppear();
-
- expect(wrapper.vm.$refs.searchInput.focusInput).toHaveBeenCalled();
- });
+ it('does not render labels list', async () => {
+ createComponent();
+ expect(findLabelsList().exists()).toBe(false);
});
+ });
- describe('handleComponentDisappear', () => {
- it('calls action `receiveLabelsSuccess` with empty array', () => {
- jest.spyOn(wrapper.vm, 'receiveLabelsSuccess');
-
- wrapper.vm.handleComponentDisappear();
-
- expect(wrapper.vm.receiveLabelsSuccess).toHaveBeenCalledWith([]);
- });
+ describe('when labels are loaded', () => {
+ beforeEach(async () => {
+ createComponent();
+ await waitForPromises();
});
- describe('handleCreateLabelClick', () => {
- it('calls actions `receiveLabelsSuccess` with empty array and `toggleDropdownContentsCreateView`', () => {
- jest.spyOn(wrapper.vm, 'receiveLabelsSuccess');
- jest.spyOn(wrapper.vm, 'toggleDropdownContentsCreateView');
-
- wrapper.vm.handleCreateLabelClick();
-
- expect(wrapper.vm.receiveLabelsSuccess).toHaveBeenCalledWith([]);
- expect(wrapper.vm.toggleDropdownContentsCreateView).toHaveBeenCalled();
- });
+ it('renders enabled search input field', async () => {
+ expect(findSearchInput().props('disabled')).toBe(false);
});
- describe('handleKeyDown', () => {
- it('decreases `currentHighlightItem` value by 1 when Up arrow key is pressed', () => {
- wrapper.setData({
- currentHighlightItem: 1,
- });
-
- wrapper.vm.handleKeyDown({
- keyCode: UP_KEY_CODE,
- });
-
- expect(wrapper.vm.currentHighlightItem).toBe(0);
- });
-
- it('increases `currentHighlightItem` value by 1 when Down arrow key is pressed', () => {
- wrapper.setData({
- currentHighlightItem: 1,
- });
-
- wrapper.vm.handleKeyDown({
- keyCode: DOWN_KEY_CODE,
- });
-
- expect(wrapper.vm.currentHighlightItem).toBe(2);
- });
-
- it('resets the search text when the Enter key is pressed', () => {
- wrapper.setData({
- currentHighlightItem: 1,
- searchKey: 'bug',
- });
-
- wrapper.vm.handleKeyDown({
- keyCode: ENTER_KEY_CODE,
- });
-
- expect(wrapper.vm.searchKey).toBe('');
- });
-
- it('calls action `updateSelectedLabels` with currently highlighted label when Enter key is pressed', () => {
- jest.spyOn(wrapper.vm, 'updateSelectedLabels').mockImplementation();
- wrapper.setData({
- currentHighlightItem: 1,
- });
-
- wrapper.vm.handleKeyDown({
- keyCode: ENTER_KEY_CODE,
- });
-
- expect(wrapper.vm.updateSelectedLabels).toHaveBeenCalledWith([
- {
- ...mockLabels[1],
- set: true,
- },
- ]);
- });
-
- it('calls action `toggleDropdownContents` when Esc key is pressed', () => {
- jest.spyOn(wrapper.vm, 'toggleDropdownContents').mockImplementation();
- wrapper.setData({
- currentHighlightItem: 1,
- });
-
- wrapper.vm.handleKeyDown({
- keyCode: ESC_KEY_CODE,
- });
-
- expect(wrapper.vm.toggleDropdownContents).toHaveBeenCalled();
- });
-
- it('calls action `scrollIntoViewIfNeeded` in next tick when any key is pressed', () => {
- jest.spyOn(wrapper.vm, 'scrollIntoViewIfNeeded').mockImplementation();
- wrapper.setData({
- currentHighlightItem: 1,
- });
-
- wrapper.vm.handleKeyDown({
- keyCode: DOWN_KEY_CODE,
- });
-
- return wrapper.vm.$nextTick(() => {
- expect(wrapper.vm.scrollIntoViewIfNeeded).toHaveBeenCalled();
- });
- });
+ it('does not render loading icon', async () => {
+ expect(findLoadingIcon().exists()).toBe(false);
});
- describe('handleLabelClick', () => {
- beforeEach(() => {
- jest.spyOn(wrapper.vm, 'updateSelectedLabels').mockImplementation();
- });
-
- it('calls action `updateSelectedLabels` with provided `label` param', () => {
- wrapper.vm.handleLabelClick(mockRegularLabel);
-
- expect(wrapper.vm.updateSelectedLabels).toHaveBeenCalledWith([mockRegularLabel]);
- });
+ it('renders labels list', async () => {
+ expect(findLabelsList().exists()).toBe(true);
+ expect(findLabels()).toHaveLength(2);
+ });
- it('calls action `toggleDropdownContents` when `state.allowMultiselect` is false', () => {
- jest.spyOn(wrapper.vm, 'toggleDropdownContents');
- wrapper.vm.$store.state.allowMultiselect = false;
+ it('changes highlighted label correctly on pressing down button', async () => {
+ expect(findLabels().at(0).attributes('highlight')).toBeUndefined();
- wrapper.vm.handleLabelClick(mockRegularLabel);
+ await findDropdownWrapper().trigger('keydown.down');
+ expect(findLabels().at(0).attributes('highlight')).toBe('true');
- expect(wrapper.vm.toggleDropdownContents).toHaveBeenCalled();
- });
+ await findDropdownWrapper().trigger('keydown.down');
+ expect(findLabels().at(1).attributes('highlight')).toBe('true');
+ expect(findLabels().at(0).attributes('highlight')).toBeUndefined();
});
- });
- describe('template', () => {
- it('renders gl-intersection-observer as component root', () => {
- expect(wrapper.find(GlIntersectionObserver).exists()).toBe(true);
- });
+ it('changes highlighted label correctly on pressing up button', async () => {
+ await findDropdownWrapper().trigger('keydown.down');
+ await findDropdownWrapper().trigger('keydown.down');
+ expect(findLabels().at(1).attributes('highlight')).toBe('true');
- it('renders gl-loading-icon component when `labelsFetchInProgress` prop is true', () => {
- wrapper.vm.$store.dispatch('requestLabels');
+ await findDropdownWrapper().trigger('keydown.up');
+ expect(findLabels().at(0).attributes('highlight')).toBe('true');
+ });
- return wrapper.vm.$nextTick(() => {
- const loadingIconEl = findLoadingIcon();
+ it('changes label selected state when Enter is pressed', async () => {
+ expect(findLabels().at(0).attributes('islabelset')).toBeUndefined();
+ await findDropdownWrapper().trigger('keydown.down');
+ await findDropdownWrapper().trigger('keydown.enter');
- expect(loadingIconEl.exists()).toBe(true);
- expect(loadingIconEl.attributes('class')).toContain('labels-fetch-loading');
- });
+ expect(findLabels().at(0).attributes('islabelset')).toBe('true');
});
- it('renders label search input element', () => {
- const searchInputEl = wrapper.find(GlSearchBoxByType);
+ it('emits `closeDropdown event` when Esc button is pressed', () => {
+ findDropdownWrapper().trigger('keydown.esc');
- expect(searchInputEl.exists()).toBe(true);
+ expect(wrapper.emitted('closeDropdown')).toEqual([[selectedLabels]]);
});
+ });
- it('renders label elements for all labels', () => {
- expect(wrapper.findAll(LabelItem)).toHaveLength(mockLabels.length);
+ it('when search returns 0 results', async () => {
+ createComponent({
+ queryHandler: jest.fn().mockResolvedValue({
+ data: {
+ workspace: {
+ labels: {
+ nodes: [],
+ },
+ },
+ },
+ }),
});
+ findSearchInput().vm.$emit('input', '123');
+ await waitForPromises();
+ await nextTick();
- it('renders label element with `highlight` set to true when value of `currentHighlightItem` is more than -1', () => {
- wrapper.setData({
- currentHighlightItem: 0,
- });
+ expect(findNoResultsMessage().isVisible()).toBe(true);
+ });
- return wrapper.vm.$nextTick(() => {
- const labelItemEl = findDropdownContent().find(LabelItem);
+ it('calls `createFlash` when fetching labels failed', async () => {
+ createComponent({ queryHandler: jest.fn().mockRejectedValue('Houston, we have a problem!') });
+ jest.advanceTimersByTime(DEFAULT_DEBOUNCE_AND_THROTTLE_MS);
+ await waitForPromises();
+ expect(createFlash).toHaveBeenCalled();
+ });
- expect(labelItemEl.attributes('highlight')).toBe('true');
- });
- });
+ it('does not render footer on standalone dropdown', () => {
+ createComponent({ injected: { variant: DropdownVariant.Standalone } });
- it('renders element containing "No matching results" when `searchKey` does not match with any label', () => {
- wrapper.setData({
- searchKey: 'abc',
- });
+ expect(findDropdownFooter().exists()).toBe(false);
+ });
- return wrapper.vm.$nextTick(() => {
- const noMatchEl = findDropdownContent().find('li');
+ it('renders footer on sidebar dropdown', () => {
+ createComponent();
- expect(noMatchEl.isVisible()).toBe(true);
- expect(noMatchEl.text()).toContain('No matching results');
- });
- });
+ expect(findDropdownFooter().exists()).toBe(true);
+ });
- it('renders empty content while loading', () => {
- wrapper.vm.$store.state.labelsFetchInProgress = true;
+ it('renders footer on embedded dropdown', () => {
+ createComponent({ injected: { variant: DropdownVariant.Embedded } });
- return wrapper.vm.$nextTick(() => {
- const dropdownContent = findDropdownContent();
- const loadingIcon = findLoadingIcon();
+ expect(findDropdownFooter().exists()).toBe(true);
+ });
- expect(dropdownContent.exists()).toBe(true);
- expect(dropdownContent.isVisible()).toBe(true);
- expect(loadingIcon.exists()).toBe(true);
- expect(loadingIcon.isVisible()).toBe(true);
- });
- });
+ it('does not render create label button if `allowLabelCreate` is false', () => {
+ createComponent({ injected: { allowLabelCreate: false } });
- it('renders footer list items', () => {
- const footerLinks = findDropdownFooter().findAll(GlLink);
- const createLabelLink = footerLinks.at(0);
- const manageLabelsLink = footerLinks.at(1);
+ expect(findCreateLabelButton().exists()).toBe(false);
+ });
- expect(createLabelLink.exists()).toBe(true);
- expect(createLabelLink.text()).toBe('Create label');
- expect(manageLabelsLink.exists()).toBe(true);
- expect(manageLabelsLink.text()).toBe('Manage labels');
+ describe('when `allowLabelCreate` is true', () => {
+ beforeEach(() => {
+ createComponent();
});
- it('does not render "Create label" footer link when `state.allowLabelCreate` is `false`', () => {
- wrapper.vm.$store.state.allowLabelCreate = false;
-
- return wrapper.vm.$nextTick(() => {
- const createLabelLink = findDropdownFooter().findAll(GlLink).at(0);
-
- expect(createLabelLink.text()).not.toBe('Create label');
- });
+ it('renders create label button', () => {
+ expect(findCreateLabelButton().exists()).toBe(true);
});
- it('does not render footer list items when `state.variant` is "standalone"', () => {
- createComponent({ ...mockConfig, variant: 'standalone' });
- expect(findDropdownFooter().exists()).toBe(false);
- });
+ it('emits `toggleDropdownContentsCreateView` event on create label button click', () => {
+ findCreateLabelButton().vm.$emit('click');
- it('renders footer list items when `state.variant` is "embedded"', () => {
- expect(findDropdownFooter().exists()).toBe(true);
+ expect(wrapper.emitted('toggleDropdownContentsCreateView')).toEqual([[]]);
});
});
});
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_spec.js
index 8273bbdf7a7..3c2fd0c5acc 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_spec.js
@@ -5,7 +5,7 @@ import { DropdownVariant } from '~/vue_shared/components/sidebar/labels_select_w
import DropdownContents from '~/vue_shared/components/sidebar/labels_select_widget/dropdown_contents.vue';
import labelsSelectModule from '~/vue_shared/components/sidebar/labels_select_widget/store';
-import { mockConfig } from './mock_data';
+import { mockConfig, mockLabels } from './mock_data';
const localVue = createLocalVue();
localVue.use(Vuex);
@@ -19,6 +19,11 @@ const createComponent = (initialState = mockConfig, defaultProps = {}) => {
propsData: {
...defaultProps,
labelsCreateTitle: 'test',
+ selectedLabels: mockLabels,
+ allowMultiselect: true,
+ labelsListTitle: 'Assign labels',
+ footerCreateLabelTitle: 'create',
+ footerManageLabelTitle: 'manage',
},
localVue,
store,
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 66971446f47..e17dfd93efc 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
@@ -50,58 +50,6 @@ describe('LabelsSelectRoot', () => {
});
describe('methods', () => {
- describe('handleVuexActionDispatch', () => {
- it('calls `handleDropdownClose` when params `action.type` is `toggleDropdownContents` and state has `showDropdownButton` & `showDropdownContents` props `false`', () => {
- createComponent();
- jest.spyOn(wrapper.vm, 'handleDropdownClose').mockImplementation();
-
- wrapper.vm.handleVuexActionDispatch(
- { type: 'toggleDropdownContents' },
- {
- showDropdownButton: false,
- showDropdownContents: false,
- labels: [{ id: 1 }, { id: 2, touched: true }],
- },
- );
-
- expect(wrapper.vm.handleDropdownClose).toHaveBeenCalledWith(
- expect.arrayContaining([
- {
- id: 2,
- touched: true,
- },
- ]),
- );
- });
-
- it('calls `handleDropdownClose` with state.labels filterd using `set` prop when dropdown variant is `embedded`', () => {
- createComponent({
- ...mockConfig,
- variant: 'embedded',
- });
-
- jest.spyOn(wrapper.vm, 'handleDropdownClose').mockImplementation();
-
- wrapper.vm.handleVuexActionDispatch(
- { type: 'toggleDropdownContents' },
- {
- showDropdownButton: false,
- showDropdownContents: false,
- labels: [{ id: 1 }, { id: 2, set: true }],
- },
- );
-
- expect(wrapper.vm.handleDropdownClose).toHaveBeenCalledWith(
- expect.arrayContaining([
- {
- id: 2,
- set: true,
- },
- ]),
- );
- });
- });
-
describe('handleDropdownClose', () => {
beforeEach(() => {
createComponent();
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/mock_data.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/mock_data.js
index 9e29030fb56..5dd8fc1b8b2 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/mock_data.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/mock_data.js
@@ -48,6 +48,8 @@ export const mockConfig = {
labelsManagePath: '/gitlab-org/my-project/-/labels',
labelsFilterBasePath: '/gitlab-org/my-project/issues',
labelsFilterParam: 'label_name',
+ footerCreateLabelTitle: 'create',
+ footerManageLabelTitle: 'manage',
};
export const mockSuggestedColors = {
@@ -91,3 +93,26 @@ export const createLabelSuccessfulResponse = {
},
},
};
+
+export const labelsQueryResponse = {
+ data: {
+ workspace: {
+ labels: {
+ nodes: [
+ {
+ color: '#330066',
+ description: null,
+ id: 'gid://gitlab/ProjectLabel/1',
+ title: 'Label1',
+ },
+ {
+ color: '#2f7b2e',
+ description: null,
+ id: 'gid://gitlab/ProjectLabel/2',
+ title: 'Label2',
+ },
+ ],
+ },
+ },
+ },
+};
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/actions_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/actions_spec.js
index 27de7de2411..ee905410ffa 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/actions_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/actions_spec.js
@@ -1,8 +1,4 @@
-import MockAdapter from 'axios-mock-adapter';
-
import testAction from 'helpers/vuex_action_helper';
-import createFlash from '~/flash';
-import axios from '~/lib/utils/axios_utils';
import * as actions from '~/vue_shared/components/sidebar/labels_select_widget/store/actions';
import * as types from '~/vue_shared/components/sidebar/labels_select_widget/store/mutation_types';
import defaultState from '~/vue_shared/components/sidebar/labels_select_widget/store/state';
@@ -72,90 +68,6 @@ describe('LabelsSelect Actions', () => {
});
});
- describe('requestLabels', () => {
- it('sets value of `state.labelsFetchInProgress` to `true`', (done) => {
- testAction(actions.requestLabels, {}, state, [{ type: types.REQUEST_LABELS }], [], done);
- });
- });
-
- describe('receiveLabelsSuccess', () => {
- it('sets provided labels to `state.labels`', (done) => {
- const labels = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }];
-
- testAction(
- actions.receiveLabelsSuccess,
- labels,
- state,
- [{ type: types.RECEIVE_SET_LABELS_SUCCESS, payload: labels }],
- [],
- done,
- );
- });
- });
-
- describe('receiveLabelsFailure', () => {
- it('sets value `state.labelsFetchInProgress` to `false`', (done) => {
- testAction(
- actions.receiveLabelsFailure,
- {},
- state,
- [{ type: types.RECEIVE_SET_LABELS_FAILURE }],
- [],
- done,
- );
- });
-
- it('shows flash error', () => {
- actions.receiveLabelsFailure({ commit: () => {} });
-
- expect(createFlash).toHaveBeenCalledWith({ message: 'Error fetching labels.' });
- });
- });
-
- describe('fetchLabels', () => {
- let mock;
-
- beforeEach(() => {
- mock = new MockAdapter(axios);
- state.labelsFetchPath = 'labels.json';
- });
-
- afterEach(() => {
- mock.restore();
- });
-
- describe('on success', () => {
- it('dispatches `requestLabels` & `receiveLabelsSuccess` actions', (done) => {
- const labels = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }];
- mock.onGet(/labels.json/).replyOnce(200, labels);
-
- testAction(
- actions.fetchLabels,
- {},
- state,
- [],
- [{ type: 'requestLabels' }, { type: 'receiveLabelsSuccess', payload: labels }],
- done,
- );
- });
- });
-
- describe('on failure', () => {
- it('dispatches `requestLabels` & `receiveLabelsFailure` actions', (done) => {
- mock.onGet(/labels.json/).replyOnce(500, {});
-
- testAction(
- actions.fetchLabels,
- {},
- state,
- [],
- [{ type: 'requestLabels' }, { type: 'receiveLabelsFailure' }],
- done,
- );
- });
- });
- });
-
describe('updateSelectedLabels', () => {
it('updates `state.labels` based on provided `labels` param', (done) => {
const labels = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }];
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/mutations_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/mutations_spec.js
index 9e965cb33e8..1f0e0eee420 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/mutations_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/mutations_spec.js
@@ -67,58 +67,6 @@ describe('LabelsSelect Mutations', () => {
});
});
- describe(`${types.REQUEST_LABELS}`, () => {
- it('sets value of `state.labelsFetchInProgress` to true', () => {
- const state = {
- labelsFetchInProgress: false,
- };
- mutations[types.REQUEST_LABELS](state);
-
- expect(state.labelsFetchInProgress).toBe(true);
- });
- });
-
- describe(`${types.RECEIVE_SET_LABELS_SUCCESS}`, () => {
- const selectedLabels = [{ id: 2 }, { id: 4 }];
- const labels = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }];
-
- it('sets value of `state.labelsFetchInProgress` to false', () => {
- const state = {
- selectedLabels,
- labelsFetchInProgress: true,
- };
- mutations[types.RECEIVE_SET_LABELS_SUCCESS](state, labels);
-
- expect(state.labelsFetchInProgress).toBe(false);
- });
-
- it('sets provided `labels` to `state.labels` along with `set` prop based on `state.selectedLabels`', () => {
- const selectedLabelIds = selectedLabels.map((label) => label.id);
- const state = {
- selectedLabels,
- labelsFetchInProgress: true,
- };
- mutations[types.RECEIVE_SET_LABELS_SUCCESS](state, labels);
-
- state.labels.forEach((label) => {
- if (selectedLabelIds.includes(label.id)) {
- expect(label.set).toBe(true);
- }
- });
- });
- });
-
- describe(`${types.RECEIVE_SET_LABELS_FAILURE}`, () => {
- it('sets value of `state.labelsFetchInProgress` to false', () => {
- const state = {
- labelsFetchInProgress: true,
- };
- mutations[types.RECEIVE_SET_LABELS_FAILURE](state);
-
- expect(state.labelsFetchInProgress).toBe(false);
- });
- });
-
describe(`${types.UPDATE_SELECTED_LABELS}`, () => {
let labels;
diff --git a/spec/frontend/vue_shared/components/url_sync_spec.js b/spec/frontend/vue_shared/components/url_sync_spec.js
index 86bbc146c5f..aefe6a5c3e8 100644
--- a/spec/frontend/vue_shared/components/url_sync_spec.js
+++ b/spec/frontend/vue_shared/components/url_sync_spec.js
@@ -1,5 +1,4 @@
import { shallowMount } from '@vue/test-utils';
-import setWindowLocation from 'helpers/set_window_location_helper';
import { historyPushState } from '~/lib/utils/common_utils';
import { mergeUrlParams } from '~/lib/utils/url_utility';
import UrlSyncComponent from '~/vue_shared/components/url_sync.vue';
@@ -15,9 +14,6 @@ jest.mock('~/lib/utils/common_utils', () => ({
describe('url sync component', () => {
let wrapper;
const mockQuery = { group_id: '5014437163714', project_ids: ['5014437608314'] };
- const TEST_HOST = 'http://testhost/';
-
- setWindowLocation(TEST_HOST);
const findButton = () => wrapper.find('button');
@@ -35,7 +31,9 @@ describe('url sync component', () => {
const expectUrlSync = (query, times, mergeUrlParamsReturnValue) => {
expect(mergeUrlParams).toHaveBeenCalledTimes(times);
- expect(mergeUrlParams).toHaveBeenCalledWith(query, TEST_HOST, { spreadArrays: true });
+ expect(mergeUrlParams).toHaveBeenCalledWith(query, window.location.href, {
+ spreadArrays: true,
+ });
expect(historyPushState).toHaveBeenCalledTimes(times);
expect(historyPushState).toHaveBeenCalledWith(mergeUrlParamsReturnValue);
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 d62c4a98b10..d3fec680b54 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
@@ -104,4 +104,15 @@ describe('User Avatar Link Component', () => {
);
});
});
+
+ describe('lazy', () => {
+ it('passes lazy prop to avatar image', () => {
+ createWrapper({
+ username: '',
+ lazy: true,
+ });
+
+ expect(wrapper.find(UserAvatarImage).props('lazy')).toBe(true);
+ });
+ });
});
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 0fd4d0dab87..5fe4eeb6061 100644
--- a/spec/frontend/vue_shared/components/web_ide_link_spec.js
+++ b/spec/frontend/vue_shared/components/web_ide_link_spec.js
@@ -85,6 +85,10 @@ describe('Web IDE link component', () => {
expectedActions: [ACTION_WEB_IDE, ACTION_EDIT],
},
{
+ props: { webIdeText: 'Test Web IDE' },
+ expectedActions: [{ ...ACTION_WEB_IDE_EDIT_FORK, text: 'Test Web IDE' }, ACTION_EDIT],
+ },
+ {
props: { isFork: true },
expectedActions: [ACTION_WEB_IDE_EDIT_FORK, ACTION_EDIT],
},
@@ -105,6 +109,10 @@ describe('Web IDE link component', () => {
expectedActions: [ACTION_WEB_IDE, ACTION_EDIT, ACTION_GITPOD_ENABLE],
},
{
+ props: { showEditButton: false, showGitpodButton: true, gitpodText: 'Test Gitpod' },
+ expectedActions: [ACTION_WEB_IDE, { ...ACTION_GITPOD_ENABLE, text: 'Test Gitpod' }],
+ },
+ {
props: { showEditButton: false },
expectedActions: [ACTION_WEB_IDE],
},