Commit ab996b3e authored by Andrew Fontaine's avatar Andrew Fontaine

Merge branch 'refactor-sidebar-reference-widget' into 'master'

Use copyable_field component in sidebar_reference_widget.vue

See merge request gitlab-org/gitlab!56826
parents 3c7fea32 85d79a4f
<script> <script>
import { GlLoadingIcon } from '@gitlab/ui';
import { __ } from '~/locale'; import { __ } from '~/locale';
import { referenceQueries } from '~/sidebar/constants'; import { referenceQueries } from '~/sidebar/constants';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; import CopyableField from '~/vue_shared/components/sidebar/copyable_field.vue';
export default { export default {
i18n: {
copyReference: __('Copy reference'),
text: __('Reference'),
},
components: { components: {
ClipboardButton, CopyableField,
GlLoadingIcon,
}, },
inject: ['fullPath', 'iid'], inject: ['fullPath', 'iid'],
props: { props: {
...@@ -56,31 +50,10 @@ export default { ...@@ -56,31 +50,10 @@ export default {
</script> </script>
<template> <template>
<div class="sub-block"> <copyable-field
<clipboard-button class="sub-block"
v-if="!isLoading" :is-loading="isLoading"
:title="$options.i18n.copyReference" :name="__('Reference')"
:text="reference" :value="reference"
category="tertiary" />
css-class="sidebar-collapsed-icon dont-change-state"
tooltip-placement="left"
/>
<div
class="gl-display-flex gl-align-items-center gl-justify-content-space-between gl-mb-2 hide-collapsed"
>
<span class="gl-overflow-hidden gl-text-overflow-ellipsis gl-white-space-nowrap">
{{ $options.i18n.text }}: {{ reference }}
<gl-loading-icon v-if="isLoading" inline :label="$options.i18n.text" />
</span>
<clipboard-button
v-if="!isLoading"
:title="$options.i18n.copyReference"
:text="reference"
size="small"
category="tertiary"
css-class="gl-mr-1"
tooltip-placement="left"
/>
</div>
</div>
</template> </template>
...@@ -67,7 +67,7 @@ export default { ...@@ -67,7 +67,7 @@ export default {
<div> <div>
<clipboard-button <clipboard-button
v-if="!isLoading" v-if="!isLoading"
css-class="sidebar-collapsed-icon dont-change-state" css-class="sidebar-collapsed-icon dont-change-state gl-rounded-0! gl-hover-bg-transparent"
v-bind="clipboardProps" v-bind="clipboardProps"
/> />
......
import { GlLoadingIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import Vue from 'vue'; import Vue from 'vue';
import VueApollo from 'vue-apollo'; import VueApollo from 'vue-apollo';
...@@ -8,18 +7,21 @@ import { IssuableType } from '~/issue_show/constants'; ...@@ -8,18 +7,21 @@ import { IssuableType } from '~/issue_show/constants';
import SidebarReferenceWidget from '~/sidebar/components/reference/sidebar_reference_widget.vue'; import SidebarReferenceWidget from '~/sidebar/components/reference/sidebar_reference_widget.vue';
import issueReferenceQuery from '~/sidebar/queries/issue_reference.query.graphql'; import issueReferenceQuery from '~/sidebar/queries/issue_reference.query.graphql';
import mergeRequestReferenceQuery from '~/sidebar/queries/merge_request_reference.query.graphql'; import mergeRequestReferenceQuery from '~/sidebar/queries/merge_request_reference.query.graphql';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; import CopyableField from '~/vue_shared/components/sidebar/copyable_field.vue';
import { issueReferenceResponse } from '../../mock_data'; import { issueReferenceResponse } from '../../mock_data';
describe('Sidebar Reference Widget', () => { describe('Sidebar Reference Widget', () => {
let wrapper; let wrapper;
let fakeApollo; let fakeApollo;
const referenceText = 'reference';
const mockReferenceValue = 'reference-1234';
const findCopyableField = () => wrapper.findComponent(CopyableField);
const createComponent = ({ const createComponent = ({
issuableType, issuableType = IssuableType.Issue,
referenceQuery = issueReferenceQuery, referenceQuery = issueReferenceQuery,
referenceQueryHandler = jest.fn().mockResolvedValue(issueReferenceResponse(referenceText)), referenceQueryHandler = jest.fn().mockResolvedValue(issueReferenceResponse(mockReferenceValue)),
} = {}) => { } = {}) => {
Vue.use(VueApollo); Vue.use(VueApollo);
...@@ -39,14 +41,20 @@ describe('Sidebar Reference Widget', () => { ...@@ -39,14 +41,20 @@ describe('Sidebar Reference Widget', () => {
afterEach(() => { afterEach(() => {
wrapper.destroy(); wrapper.destroy();
wrapper = null; });
describe('when reference is loading', () => {
it('sets CopyableField `is-loading` prop to `true`', () => {
createComponent({ referenceQueryHandler: jest.fn().mockReturnValue(new Promise(() => {})) });
expect(findCopyableField().props('isLoading')).toBe(true);
});
}); });
describe.each([ describe.each([
[IssuableType.Issue, issueReferenceQuery], [IssuableType.Issue, issueReferenceQuery],
[IssuableType.MergeRequest, mergeRequestReferenceQuery], [IssuableType.MergeRequest, mergeRequestReferenceQuery],
])('when issuableType is %s', (issuableType, referenceQuery) => { ])('when issuableType is %s', (issuableType, referenceQuery) => {
it('displays the reference text', async () => { it('sets CopyableField `value` prop to reference value', async () => {
createComponent({ createComponent({
issuableType, issuableType,
referenceQuery, referenceQuery,
...@@ -54,40 +62,32 @@ describe('Sidebar Reference Widget', () => { ...@@ -54,40 +62,32 @@ describe('Sidebar Reference Widget', () => {
await waitForPromises(); await waitForPromises();
expect(wrapper.text()).toContain(referenceText); expect(findCopyableField().props('value')).toBe(mockReferenceValue);
}); });
it('displays loading icon while fetching and hides clipboard icon', async () => { describe('when error occurs', () => {
createComponent({ it('calls createFlash with correct parameters', async () => {
issuableType, const mockError = new Error('mayday');
referenceQuery,
});
expect(wrapper.find(GlLoadingIcon).exists()).toBe(true); createComponent({
expect(wrapper.find(ClipboardButton).exists()).toBe(false); issuableType,
}); referenceQuery,
referenceQueryHandler: jest.fn().mockRejectedValue(mockError),
});
it('calls createFlash with correct parameters', async () => { await waitForPromises();
const mockError = new Error('mayday');
createComponent({ const [
issuableType, [
referenceQuery, {
referenceQueryHandler: jest.fn().mockRejectedValue(mockError), message,
error: { networkError },
},
],
] = wrapper.emitted('fetch-error');
expect(message).toBe('An error occurred while fetching reference');
expect(networkError).toEqual(mockError);
}); });
await waitForPromises();
const [
[
{
message,
error: { networkError },
},
],
] = wrapper.emitted('fetch-error');
expect(message).toBe('An error occurred while fetching reference');
expect(networkError).toEqual(mockError);
}); });
}); });
}); });
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment