diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2019-11-22 09:06:20 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2019-11-22 09:06:20 +0000 |
commit | 8a3fdede9607c806d88856d46d4f5394b630a006 (patch) | |
tree | 869139549ac3bd687fcf1286d6dd50b1d785702e /spec/frontend | |
parent | 8e75748aabcbcea411f8bbc68936805bc2b5ff0c (diff) | |
download | gitlab-ce-8a3fdede9607c806d88856d46d4f5394b630a006.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend')
15 files changed, 327 insertions, 10 deletions
diff --git a/spec/frontend/monitoring/store/actions_spec.js b/spec/frontend/monitoring/store/actions_spec.js index d4bc613ffea..467e0445a90 100644 --- a/spec/frontend/monitoring/store/actions_spec.js +++ b/spec/frontend/monitoring/store/actions_spec.js @@ -1,4 +1,5 @@ import MockAdapter from 'axios-mock-adapter'; +import Tracking from '~/tracking'; import { TEST_HOST } from 'helpers/test_constants'; import testAction from 'helpers/vuex_action_helper'; import axios from '~/lib/utils/axios_utils'; @@ -226,12 +227,14 @@ describe('Monitoring store actions', () => { let state; const response = metricsDashboardResponse; beforeEach(() => { + jest.spyOn(Tracking, 'event'); dispatch = jest.fn(); state = storeState(); state.dashboardEndpoint = '/dashboard'; }); it('dispatches receive and success actions', done => { const params = {}; + document.body.dataset.page = 'projects:environments:metrics'; mock.onGet(state.dashboardEndpoint).reply(200, response); fetchDashboard( { @@ -246,6 +249,17 @@ describe('Monitoring store actions', () => { response, params, }); + }) + .then(() => { + expect(Tracking.event).toHaveBeenCalledWith( + document.body.dataset.page, + 'dashboard_fetch', + { + label: 'custom_metrics_dashboard', + property: 'count', + value: 0, + }, + ); done(); }) .catch(done.fail); diff --git a/spec/frontend/releases/list/components/evidence_block_spec.js b/spec/frontend/releases/list/components/evidence_block_spec.js new file mode 100644 index 00000000000..e8a3eace216 --- /dev/null +++ b/spec/frontend/releases/list/components/evidence_block_spec.js @@ -0,0 +1,77 @@ +import { mount, createLocalVue } from '@vue/test-utils'; +import { GlLink } from '@gitlab/ui'; +import { truncateSha } from '~/lib/utils/text_utility'; +import Icon from '~/vue_shared/components/icon.vue'; +import { release } from '../../mock_data'; +import EvidenceBlock from '~/releases/list/components/evidence_block.vue'; +import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; + +describe('Evidence Block', () => { + let wrapper; + + const factory = (options = {}) => { + const localVue = createLocalVue(); + + wrapper = mount(localVue.extend(EvidenceBlock), { + localVue, + ...options, + }); + }; + + beforeEach(() => { + factory({ + propsData: { + release, + }, + }); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + it('renders the evidence icon', () => { + expect(wrapper.find(Icon).props('name')).toBe('review-list'); + }); + + it('renders the title for the dowload link', () => { + expect(wrapper.find(GlLink).text()).toBe(`${release.tag_name}-evidence.json`); + }); + + it('renders the correct hover text for the download', () => { + expect(wrapper.find(GlLink).attributes('data-original-title')).toBe('Download evidence JSON'); + }); + + it('renders the correct file link for download', () => { + expect(wrapper.find(GlLink).attributes().download).toBe(`${release.tag_name}-evidence.json`); + }); + + describe('sha text', () => { + it('renders the short sha initially', () => { + expect(wrapper.find('.js-short').text()).toBe(truncateSha(release.evidence_sha)); + }); + + it('renders the long sha after expansion', () => { + wrapper.find('.js-text-expander-prepend').trigger('click'); + expect(wrapper.find('.js-expanded').text()).toBe(release.evidence_sha); + }); + }); + + describe('copy to clipboard button', () => { + it('renders button', () => { + expect(wrapper.find(ClipboardButton).exists()).toBe(true); + }); + + it('renders the correct hover text', () => { + expect(wrapper.find(ClipboardButton).attributes('data-original-title')).toBe( + 'Copy commit SHA', + ); + }); + + it('copies the sha', () => { + expect(wrapper.find(ClipboardButton).attributes('data-clipboard-text')).toBe( + release.evidence_sha, + ); + }); + }); +}); diff --git a/spec/frontend/releases/list/components/release_block_spec.js b/spec/frontend/releases/list/components/release_block_spec.js index b63ef068d8e..5b589aaabe8 100644 --- a/spec/frontend/releases/list/components/release_block_spec.js +++ b/spec/frontend/releases/list/components/release_block_spec.js @@ -1,4 +1,5 @@ import { mount } from '@vue/test-utils'; +import EvidenceBlock from '~/releases/list/components/evidence_block.vue'; import ReleaseBlock from '~/releases/list/components/release_block.vue'; import ReleaseBlockFooter from '~/releases/list/components/release_block_footer.vue'; import timeagoMixin from '~/vue_shared/mixins/timeago'; @@ -220,6 +221,26 @@ describe('Release block', () => { }); }); + describe('evidence block', () => { + it('renders the evidence block when the evidence is available and the feature flag is true', () => + factory(releaseClone, { releaseEvidenceCollection: true }).then(() => + expect(wrapper.find(EvidenceBlock).exists()).toBe(true), + )); + + it('does not render the evidence block when the evidence is available but the feature flag is false', () => + factory(releaseClone, { releaseEvidenceCollection: true }).then(() => + expect(wrapper.find(EvidenceBlock).exists()).toBe(true), + )); + + it('does not render the evidence block when there is no evidence', () => { + releaseClone.evidence_sha = null; + + return factory(releaseClone).then(() => { + expect(wrapper.find(EvidenceBlock).exists()).toBe(false); + }); + }); + }); + describe('anchor scrolling', () => { beforeEach(() => { scrollToElement.mockClear(); diff --git a/spec/frontend/releases/mock_data.js b/spec/frontend/releases/mock_data.js index 61d95b86b1c..e1830b494bc 100644 --- a/spec/frontend/releases/mock_data.js +++ b/spec/frontend/releases/mock_data.js @@ -35,6 +35,7 @@ export const release = { description_html: '<p data-sourcepos="1:1-1:21" dir="auto">A super nice release!</p>', created_at: '2019-08-26T17:54:04.952Z', released_at: '2019-08-26T17:54:04.807Z', + evidence_sha: 'fb3a125fd69a0e5048ebfb0ba43eb32ce4911520dd8d', author: { id: 1, name: 'Administrator', @@ -62,6 +63,8 @@ export const release = { milestones, assets: { count: 5, + evidence_file_path: + 'https://20592.qa-tunnel.gitlab.info/root/test-deployments/-/releases/v1.1.2/evidence.json', sources: [ { format: 'zip', diff --git a/spec/frontend/vue_shared/components/__snapshots__/expand_button_spec.js.snap b/spec/frontend/vue_shared/components/__snapshots__/expand_button_spec.js.snap new file mode 100644 index 00000000000..cf71aefebe8 --- /dev/null +++ b/spec/frontend/vue_shared/components/__snapshots__/expand_button_spec.js.snap @@ -0,0 +1,5 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Expand button on click when short text is provided renders button after text 1`] = `"<span><button aria-label=\\"Click to expand text\\" type=\\"button\\" class=\\"btn js-text-expander-prepend text-expander btn-blank btn-secondary\\" style=\\"display: none;\\"><svg aria-hidden=\\"true\\" class=\\"s12 ic-ellipsis_h\\"><use xlink:href=\\"#ellipsis_h\\"></use></svg></button> <!----> <span><p>Expanded!</p></span> <button aria-label=\\"Click to expand text\\" type=\\"button\\" class=\\"btn js-text-expander-append text-expander btn-blank btn-secondary\\" style=\\"\\"><svg aria-hidden=\\"true\\" class=\\"s12 ic-ellipsis_h\\"><use xlink:href=\\"#ellipsis_h\\"></use></svg></button></span>"`; + +exports[`Expand button when short text is provided renders button before text 1`] = `"<span><button aria-label=\\"Click to expand text\\" type=\\"button\\" class=\\"btn js-text-expander-prepend text-expander btn-blank btn-secondary\\"><svg aria-hidden=\\"true\\" class=\\"s12 ic-ellipsis_h\\"><use xlink:href=\\"#ellipsis_h\\"></use></svg></button> <span><p>Short</p></span> <!----> <button aria-label=\\"Click to expand text\\" type=\\"button\\" class=\\"btn js-text-expander-append text-expander btn-blank btn-secondary\\" style=\\"display: none;\\"><svg aria-hidden=\\"true\\" class=\\"s12 ic-ellipsis_h\\"><use xlink:href=\\"#ellipsis_h\\"></use></svg></button></span>"`; 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 d5861b18318..2fabbe3d0f6 100644 --- a/spec/frontend/vue_shared/components/changed_file_icon_spec.js +++ b/spec/frontend/vue_shared/components/changed_file_icon_spec.js @@ -19,6 +19,7 @@ describe('Changed file icon', () => { ...props, }, sync: false, + attachToDocument: true, }); }; diff --git a/spec/frontend/vue_shared/components/commit_spec.js b/spec/frontend/vue_shared/components/commit_spec.js index 77d8e00cf00..67262eec0a5 100644 --- a/spec/frontend/vue_shared/components/commit_spec.js +++ b/spec/frontend/vue_shared/components/commit_spec.js @@ -13,6 +13,7 @@ describe('Commit component', () => { wrapper = shallowMount(CommitComponent, { propsData, sync: false, + attachToDocument: true, }); }; diff --git a/spec/frontend/vue_shared/components/expand_button_spec.js b/spec/frontend/vue_shared/components/expand_button_spec.js new file mode 100644 index 00000000000..a501e6695d5 --- /dev/null +++ b/spec/frontend/vue_shared/components/expand_button_spec.js @@ -0,0 +1,188 @@ +import Vue from 'vue'; +import { mount, createLocalVue } from '@vue/test-utils'; +import ExpandButton from '~/vue_shared/components/expand_button.vue'; + +const text = { + expanded: 'Expanded!', + short: 'Short', +}; + +describe('Expand button', () => { + let wrapper; + + const expanderPrependEl = () => wrapper.find('.js-text-expander-prepend'); + const expanderAppendEl = () => wrapper.find('.js-text-expander-append'); + + const factory = (options = {}) => { + const localVue = createLocalVue(); + + wrapper = mount(localVue.extend(ExpandButton), { + localVue, + ...options, + }); + }; + + beforeEach(() => { + factory({ + slots: { + expanded: `<p>${text.expanded}</p>`, + }, + }); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + it('renders the prepended collapse button', () => { + expect(expanderPrependEl().isVisible()).toBe(true); + expect(expanderAppendEl().isVisible()).toBe(false); + }); + + it('renders no text when short text is not provided', () => { + expect(wrapper.find(ExpandButton).text()).toBe(''); + }); + + it('does not render expanded text', () => { + expect( + wrapper + .find(ExpandButton) + .text() + .trim(), + ).not.toBe(text.short); + }); + + describe('when short text is provided', () => { + beforeEach(() => { + factory({ + slots: { + expanded: `<p>${text.expanded}</p>`, + short: `<p>${text.short}</p>`, + }, + }); + }); + + it('renders short text', () => { + expect( + wrapper + .find(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).html()).toMatchSnapshot(); + }); + }); + + describe('on click', () => { + beforeEach(done => { + expanderPrependEl().trigger('click'); + Vue.nextTick(done); + }); + + afterEach(() => { + expanderAppendEl().trigger('click'); + }); + + it('renders only the append collapse button', () => { + expect(expanderAppendEl().isVisible()).toBe(true); + expect(expanderPrependEl().isVisible()).toBe(false); + }); + + it('renders the expanded text', () => { + expect(wrapper.find(ExpandButton).text()).toContain(text.expanded); + }); + + describe('when short text is provided', () => { + beforeEach(done => { + factory({ + slots: { + expanded: `<p>${text.expanded}</p>`, + short: `<p>${text.short}</p>`, + }, + }); + + expanderPrependEl().trigger('click'); + Vue.nextTick(done); + }); + + it('only renders expanded text', () => { + expect( + wrapper + .find(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).html()).toMatchSnapshot(); + }); + }); + }); + + describe('append button', () => { + beforeEach(done => { + expanderPrependEl().trigger('click'); + Vue.nextTick(done); + }); + + it('clicking hides itself and shows prepend', () => { + expect(expanderAppendEl().isVisible()).toBe(true); + expanderAppendEl().trigger('click'); + expect(expanderPrependEl().isVisible()).toBe(true); + }); + + it('clicking hides expanded text', () => { + expect( + wrapper + .find(ExpandButton) + .text() + .trim(), + ).toBe(text.expanded); + expanderAppendEl().trigger('click'); + expect( + wrapper + .find(ExpandButton) + .text() + .trim(), + ).not.toBe(text.expanded); + }); + + describe('when short text is provided', () => { + beforeEach(done => { + factory({ + slots: { + expanded: `<p>${text.expanded}</p>`, + short: `<p>${text.short}</p>`, + }, + }); + + expanderPrependEl().trigger('click'); + Vue.nextTick(done); + }); + + it('clicking reveals short text', () => { + expect( + wrapper + .find(ExpandButton) + .text() + .trim(), + ).toBe(text.expanded); + expanderAppendEl().trigger('click'); + expect( + wrapper + .find(ExpandButton) + .text() + .trim(), + ).toBe(text.short); + }); + }); + }); +}); diff --git a/spec/frontend/vue_shared/components/issue/issue_assignees_spec.js b/spec/frontend/vue_shared/components/issue/issue_assignees_spec.js index 9e6b5286899..dcae2f12833 100644 --- a/spec/frontend/vue_shared/components/issue/issue_assignees_spec.js +++ b/spec/frontend/vue_shared/components/issue/issue_assignees_spec.js @@ -18,6 +18,7 @@ describe('IssueAssigneesComponent', () => { ...props, }, sync: false, + attachToDocument: true, }); vm = wrapper.vm; // eslint-disable-line }; diff --git a/spec/frontend/vue_shared/components/issue/issue_milestone_spec.js b/spec/frontend/vue_shared/components/issue/issue_milestone_spec.js index 2e93ec412b9..4a66330ac30 100644 --- a/spec/frontend/vue_shared/components/issue/issue_milestone_spec.js +++ b/spec/frontend/vue_shared/components/issue/issue_milestone_spec.js @@ -1,18 +1,20 @@ import Vue from 'vue'; -import { mount } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; import IssueMilestone from '~/vue_shared/components/issue/issue_milestone.vue'; +import Icon from '~/vue_shared/components/icon.vue'; import { mockMilestone } from '../../../../javascripts/boards/mock_data'; const createComponent = (milestone = mockMilestone) => { const Component = Vue.extend(IssueMilestone); - return mount(Component, { + return shallowMount(Component, { propsData: { milestone, }, sync: false, + attachToDocument: true, }); }; @@ -156,7 +158,7 @@ describe('IssueMilestoneComponent', () => { }); it('renders milestone icon', () => { - expect(vm.$el.querySelector('svg use').getAttribute('xlink:href')).toContain('clock'); + expect(wrapper.find(Icon).props('name')).toBe('clock'); }); it('renders milestone title', () => { 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 b85e2673624..cc9b569793d 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 @@ -35,6 +35,7 @@ describe('RelatedIssuableItem', () => { localVue, slots, sync: false, + attachToDocument: true, propsData: props, }); }); 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 9e0b98ecef9..71f9b5e3244 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 @@ -21,6 +21,7 @@ describe('Suggestion Diff component', () => { }, localVue, sync: false, + attachToDocument: true, }); }; diff --git a/spec/frontend/vue_shared/components/modal_copy_button_spec.js b/spec/frontend/vue_shared/components/modal_copy_button_spec.js index d8c55bee8e0..3c71cb16bd5 100644 --- a/spec/frontend/vue_shared/components/modal_copy_button_spec.js +++ b/spec/frontend/vue_shared/components/modal_copy_button_spec.js @@ -16,6 +16,8 @@ describe('modal copy button', () => { text: 'copy me', title: 'Copy this value', }, + attachToDocument: true, + sync: false, }); }); diff --git a/spec/frontend/vue_shared/components/paginated_list_spec.js b/spec/frontend/vue_shared/components/paginated_list_spec.js index 31ac362d35f..92b48ce9974 100644 --- a/spec/frontend/vue_shared/components/paginated_list_spec.js +++ b/spec/frontend/vue_shared/components/paginated_list_spec.js @@ -26,6 +26,8 @@ describe('Pagination links component', () => { list: [{ id: 'foo' }, { id: 'bar' }], props, }, + attachToDocument: true, + sync: false, }); [glPaginatedList] = wrapper.vm.$children; diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select/base_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select/base_spec.js index 6aee616c324..91865dcea0a 100644 --- a/spec/frontend/vue_shared/components/sidebar/labels_select/base_spec.js +++ b/spec/frontend/vue_shared/components/sidebar/labels_select/base_spec.js @@ -1,22 +1,20 @@ import Vue from 'vue'; import LabelsSelect from '~/labels_select'; -import baseComponent from '~/vue_shared/components/sidebar/labels_select/base.vue'; +import BaseComponent from '~/vue_shared/components/sidebar/labels_select/base.vue'; -import { mount } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; import { mockConfig, mockLabels, } from '../../../../../javascripts/vue_shared/components/sidebar/labels_select/mock_data'; -const createComponent = (config = mockConfig) => { - const Component = Vue.extend(baseComponent); - - return mount(Component, { +const createComponent = (config = mockConfig) => + shallowMount(BaseComponent, { propsData: config, sync: false, + attachToDocument: true, }); -}; describe('BaseComponent', () => { let wrapper; |