Skip to content
Snippets Groups Projects
Commit d98890e4 authored by Ezekiel Kigbo's avatar Ezekiel Kigbo :two: Committed by Natalia Tepluhina
Browse files

Minor refactor clone_dropdown component

Move the clone_dropdown component into a new
folder and extracts the clone_dropdown_item for
reuse.

Update clone dropdown jest tests

Adds tests for the clone_dropdown_item component
and cleans up the clone_dropdown specs
parent 14bfdd9d
No related branches found
No related tags found
2 merge requests!122839Refactor clone dropdown,!119439Draft: Prevent file variable content expansion in downstream pipeline
Showing with 219 additions and 119 deletions
......@@ -7,7 +7,7 @@ import {
} from '~/performance/constants';
import { performanceMarkAndMeasure } from '~/performance/utils';
import { VISIBILITY_LEVEL_PUBLIC_STRING } from '~/visibility_level/constants';
import CloneDropdownButton from '~/vue_shared/components/clone_dropdown.vue';
import CloneDropdownButton from '~/vue_shared/components/clone_dropdown/clone_dropdown.vue';
import { getSnippetMixin } from '../mixins/snippets';
import { markBlobPerformance } from '../utils/blob';
......
import CloneDropdown from './clone_dropdown.vue';
export default {
component: CloneDropdown,
title: 'vue_shared/components/clone_dropdown',
};
const Template = (args, { argTypes }) => ({
components: { CloneDropdown },
props: Object.keys(argTypes),
template: '<clone-dropdown v-bind="$props" />',
});
const sshLink = 'ssh://some-ssh-link';
const httpLink = 'https://some-http-link';
export const Default = Template.bind({});
Default.args = {
sshLink,
httpLink,
};
export const HttpLink = Template.bind({});
HttpLink.args = {
httpLink,
sshLink: '',
};
export const SSHLink = Template.bind({});
SSHLink.args = {
sshLink,
httpLink: '',
};
<script>
import {
GlButton,
GlDisclosureDropdown,
GlDisclosureDropdownItem,
GlFormGroup,
GlFormInputGroup,
GlTooltipDirective,
} from '@gitlab/ui';
import { GlDisclosureDropdown, GlTooltipDirective } from '@gitlab/ui';
import { getHTTPProtocol } from '~/lib/utils/url_utility';
import { __, sprintf } from '~/locale';
import CloneDropdownItem from './clone_dropdown_item.vue';
export default {
components: {
GlDisclosureDropdown,
GlDisclosureDropdownItem,
GlFormGroup,
GlFormInputGroup,
GlButton,
CloneDropdownItem,
},
directives: {
GlTooltip: GlTooltipDirective,
......@@ -43,7 +34,6 @@ export default {
defaultLabel: __('Clone'),
ssh: __('Clone with SSH'),
},
copyURLTooltip: __('Copy URL'),
};
</script>
<template>
......@@ -53,39 +43,17 @@ export default {
variant="confirm"
placement="right"
>
<gl-disclosure-dropdown-item v-if="sshLink">
<gl-form-group :label="$options.labels.ssh" class="gl-px-3 gl-my-3">
<gl-form-input-group :value="sshLink" readonly select-on-click>
<template #append>
<gl-button
v-gl-tooltip.hover
:title="$options.copyURLTooltip"
:aria-label="$options.copyURLTooltip"
:data-clipboard-text="sshLink"
data-qa-selector="copy_ssh_url_button"
icon="copy-to-clipboard"
class="gl-display-inline-flex"
/>
</template>
</gl-form-input-group>
</gl-form-group>
</gl-disclosure-dropdown-item>
<gl-disclosure-dropdown-item v-if="httpLink">
<gl-form-group :label="httpLabel" class="gl-px-3 gl-mb-3">
<gl-form-input-group :value="httpLink" readonly select-on-click>
<template #append>
<gl-button
v-gl-tooltip.hover
:title="$options.copyURLTooltip"
:aria-label="$options.copyURLTooltip"
:data-clipboard-text="httpLink"
data-qa-selector="copy_http_url_button"
icon="copy-to-clipboard"
class="gl-display-inline-flex"
/>
</template>
</gl-form-input-group>
</gl-form-group>
</gl-disclosure-dropdown-item>
<clone-dropdown-item
v-if="sshLink"
:label="$options.labels.ssh"
:link="sshLink"
qa-selector="copy_ssh_url_button"
/>
<clone-dropdown-item
v-if="httpLink"
:label="httpLabel"
:link="httpLink"
qa-selector="copy_http_url_button"
/>
</gl-disclosure-dropdown>
</template>
<script>
import {
GlButton,
GlDisclosureDropdownItem,
GlFormGroup,
GlFormInputGroup,
GlTooltipDirective,
} from '@gitlab/ui';
import { __ } from '~/locale';
export default {
components: {
GlDisclosureDropdownItem,
GlFormGroup,
GlFormInputGroup,
GlButton,
},
directives: {
GlTooltip: GlTooltipDirective,
},
props: {
label: {
type: String,
required: true,
},
link: {
type: String,
required: true,
},
qaSelector: {
type: String,
required: true,
},
},
copyURLTooltip: __('Copy URL'),
};
</script>
<template>
<gl-disclosure-dropdown-item>
<gl-form-group :label="label" class="gl-px-3 gl-mb-3">
<gl-form-input-group :value="link" readonly select-on-click>
<template #append>
<gl-button
v-gl-tooltip.hover
:title="$options.copyURLTooltip"
:aria-label="$options.copyURLTooltip"
:data-clipboard-text="link"
:data-qa-selector="qaSelector"
icon="copy-to-clipboard"
class="gl-display-inline-flex"
/>
</template>
</gl-form-input-group>
</gl-form-group>
</gl-disclosure-dropdown-item>
</template>
......@@ -43,7 +43,7 @@ def self.included(base)
element :snippet_embed_dropdown
end
base.view 'app/assets/javascripts/vue_shared/components/clone_dropdown.vue' do
base.view 'app/assets/javascripts/vue_shared/components/clone_dropdown/clone_dropdown.vue' do
element :copy_http_url_button
element :copy_ssh_url_button
end
......
......@@ -11,7 +11,7 @@ import {
VISIBILITY_LEVEL_PRIVATE_STRING,
VISIBILITY_LEVEL_PUBLIC_STRING,
} from '~/visibility_level/constants';
import CloneDropdownButton from '~/vue_shared/components/clone_dropdown.vue';
import CloneDropdownButton from '~/vue_shared/components/clone_dropdown/clone_dropdown.vue';
import { stubPerformanceWebAPI } from 'helpers/performance';
describe('Snippet view app', () => {
......
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Clone Dropdown Button rendering matches the snapshot 1`] = `
<gl-disclosure-dropdown-stub
autoclose="true"
category="primary"
icon=""
items=""
placement="right"
positioningstrategy="absolute"
size="medium"
toggleid="dropdown-toggle-btn-2"
toggletext="Clone"
variant="confirm"
>
<gl-disclosure-dropdown-item-stub>
<gl-form-group-stub
class="gl-px-3 gl-my-3"
label="Clone with SSH"
labeldescription=""
optionaltext="(optional)"
>
<b-input-group-stub
readonly=""
tag="div"
>
<!---->
<b-form-input-stub
class="gl-form-input"
debounce="0"
formatter="[Function]"
readonly="true"
type="text"
value="ssh://foo.bar"
/>
<b-input-group-append-stub
tag="div"
>
<gl-button-stub
aria-label="Copy URL"
buttontextclasses=""
category="primary"
class="gl-display-inline-flex"
data-clipboard-text="ssh://foo.bar"
data-qa-selector="copy_ssh_url_button"
icon="copy-to-clipboard"
size="medium"
title="Copy URL"
variant="default"
/>
</b-input-group-append-stub>
</b-input-group-stub>
</gl-form-group-stub>
</gl-disclosure-dropdown-item-stub>
<gl-disclosure-dropdown-item-stub>
<gl-form-group-stub
class="gl-px-3 gl-mb-3"
label="Clone with HTTP"
labeldescription=""
optionaltext="(optional)"
>
<b-input-group-stub
readonly=""
tag="div"
>
<!---->
<b-form-input-stub
class="gl-form-input"
debounce="0"
formatter="[Function]"
readonly="true"
type="text"
value="http://foo.bar"
/>
<b-input-group-append-stub
tag="div"
>
<gl-button-stub
aria-label="Copy URL"
buttontextclasses=""
category="primary"
class="gl-display-inline-flex"
data-clipboard-text="http://foo.bar"
data-qa-selector="copy_http_url_button"
icon="copy-to-clipboard"
size="medium"
title="Copy URL"
variant="default"
/>
</b-input-group-append-stub>
</b-input-group-stub>
</gl-form-group-stub>
</gl-disclosure-dropdown-item-stub>
</gl-disclosure-dropdown-stub>
`;
import { GlButton, GlFormGroup, GlFormInputGroup } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import CloneDropdownItem from '~/vue_shared/components/clone_dropdown/clone_dropdown_item.vue';
describe('Clone Dropdown Button', () => {
let wrapper;
const link = 'ssh://foo.bar';
const label = 'SSH';
const qaSelector = 'some-selector';
const defaultPropsData = {
link,
label,
qaSelector,
};
const findCopyButton = () => wrapper.findComponent(GlButton);
const createComponent = (propsData = defaultPropsData) => {
wrapper = shallowMount(CloneDropdownItem, {
propsData,
stubs: {
GlFormInputGroup,
},
});
};
beforeEach(() => {
createComponent();
});
describe('default', () => {
it('sets form group label', () => {
expect(wrapper.findComponent(GlFormGroup).attributes('label')).toBe(label);
});
it('sets form input group link', () => {
expect(wrapper.findComponent(GlFormInputGroup).props('value')).toBe(link);
});
it('sets the copy tooltip text', () => {
expect(findCopyButton().attributes('title')).toBe('Copy URL');
});
it('sets the copy tooltip link', () => {
expect(findCopyButton().attributes('data-clipboard-text')).toBe(link);
});
it('sets the qa selector', () => {
expect(findCopyButton().attributes('data-qa-selector')).toBe(qaSelector);
});
});
});
import { GlFormGroup, GlFormInputGroup } from '@gitlab/ui';
import { GlFormInputGroup } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import CloneDropdown from '~/vue_shared/components/clone_dropdown.vue';
import CloneDropdown from '~/vue_shared/components/clone_dropdown/clone_dropdown.vue';
import CloneDropdownItem from '~/vue_shared/components/clone_dropdown/clone_dropdown_item.vue';
describe('Clone Dropdown Button', () => {
let wrapper;
......@@ -12,30 +13,28 @@ describe('Clone Dropdown Button', () => {
httpLink,
};
const findCloneDropdownItems = () => wrapper.findAllComponents(CloneDropdownItem);
const findCloneDropdownItemAtIndex = (index) => findCloneDropdownItems().at(index);
const createComponent = (propsData = defaultPropsData) => {
wrapper = shallowMount(CloneDropdown, {
propsData,
stubs: {
'gl-form-input-group': GlFormInputGroup,
GlFormInputGroup,
},
});
};
describe('rendering', () => {
it('matches the snapshot', () => {
createComponent();
expect(wrapper.element).toMatchSnapshot();
});
it.each`
name | index | value
name | index | link
${'SSH'} | ${0} | ${sshLink}
${'HTTP'} | ${1} | ${httpLink}
`('renders correct link and a copy-button for $name', ({ index, value }) => {
`('renders correct link and a copy-button for $name', ({ index, link }) => {
createComponent();
const group = wrapper.findAllComponents(GlFormInputGroup).at(index);
expect(group.props('value')).toBe(value);
expect(group.findComponent(GlFormInputGroup).exists()).toBe(true);
const group = findCloneDropdownItemAtIndex(index);
expect(group.props('link')).toBe(link);
});
it.each`
......@@ -45,7 +44,7 @@ describe('Clone Dropdown Button', () => {
`('does not fail if only $name is set', ({ name, value }) => {
createComponent({ [name]: value });
expect(wrapper.findComponent(GlFormInputGroup).props('value')).toBe(value);
expect(findCloneDropdownItemAtIndex(0).props('link')).toBe(value);
});
});
......@@ -57,12 +56,13 @@ describe('Clone Dropdown Button', () => {
`('allows null values for the props', ({ name, value }) => {
createComponent({ ...defaultPropsData, [name]: value });
expect(wrapper.findAllComponents(GlFormGroup).length).toBe(1);
expect(findCloneDropdownItems().length).toBe(1);
});
it('correctly calculates httpLabel for HTTPS protocol', () => {
createComponent({ httpLink: httpsLink });
expect(wrapper.findComponent(GlFormGroup).attributes('label')).toContain('HTTPS');
expect(findCloneDropdownItemAtIndex(0).attributes('label')).toContain('HTTPS');
});
});
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment