diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-06-24 18:08:50 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-06-24 18:08:50 +0300 |
commit | 4c5468b40825debc2b7bbe08b975dedd2f7f1523 (patch) | |
tree | ee64e91b6d014f452e9c9dce6ad9f747a5929108 /spec/frontend | |
parent | d081e00aa79079792b040af3323883f1f43830c5 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend')
9 files changed, 148 insertions, 31 deletions
diff --git a/spec/frontend/alert_management/components/alert_management_list_spec.js b/spec/frontend/alert_management/components/alert_management_list_spec.js index 541f78fb5d8..456e5ecb2c2 100644 --- a/spec/frontend/alert_management/components/alert_management_list_spec.js +++ b/spec/frontend/alert_management/components/alert_management_list_spec.js @@ -15,7 +15,6 @@ import { } from '@gitlab/ui'; import { visitUrl } from '~/lib/utils/url_utility'; import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue'; -import createFlash from '~/flash'; import AlertManagementList from '~/alert_management/components/alert_management_list.vue'; import { ALERTS_STATUS_TABS, @@ -26,8 +25,6 @@ import updateAlertStatus from '~/alert_management/graphql/mutations/update_alert import mockAlerts from '../mocks/alerts.json'; import Tracking from '~/tracking'; -jest.mock('~/flash'); - jest.mock('~/lib/utils/url_utility', () => ({ visitUrl: jest.fn().mockName('visitUrlMock'), joinPaths: jest.requireActual('~/lib/utils/url_utility').joinPaths, @@ -391,14 +388,15 @@ describe('AlertManagementList', () => { }); }); - it('calls `createFlash` when request fails', () => { + it('shows an error when request fails', () => { jest.spyOn(wrapper.vm.$apollo, 'mutate').mockReturnValue(Promise.reject(new Error())); findFirstStatusOption().vm.$emit('click'); + wrapper.setData({ + errored: true, + }); - setImmediate(() => { - expect(createFlash).toHaveBeenCalledWith( - 'There was an error while updating the status of the alert. Please try again.', - ); + wrapper.vm.$nextTick(() => { + expect(wrapper.find('[data-testid="alert-error"]').exists()).toBe(true); }); }); }); diff --git a/spec/frontend/alert_management/components/alert_sidebar_status_spec.js b/spec/frontend/alert_management/components/alert_sidebar_status_spec.js index 94643966a43..aa0cb230e5b 100644 --- a/spec/frontend/alert_management/components/alert_sidebar_status_spec.js +++ b/spec/frontend/alert_management/components/alert_sidebar_status_spec.js @@ -1,4 +1,4 @@ -import { shallowMount } from '@vue/test-utils'; +import { mount } from '@vue/test-utils'; import { GlDropdownItem, GlLoadingIcon } from '@gitlab/ui'; import { trackAlertStatusUpdateOptions } from '~/alert_management/constants'; import AlertSidebarStatus from '~/alert_management/components/sidebar/sidebar_status.vue'; @@ -14,7 +14,7 @@ describe('Alert Details Sidebar Status', () => { const findStatusLoadingIcon = () => wrapper.find(GlLoadingIcon); function mountComponent({ data, sidebarCollapsed = true, loading = false, stubs = {} } = {}) { - wrapper = shallowMount(AlertSidebarStatus, { + wrapper = mount(AlertSidebarStatus, { propsData: { alert: { ...mockAlert }, ...data, diff --git a/spec/frontend/diffs/components/diff_gutter_avatars_spec.js b/spec/frontend/diffs/components/diff_gutter_avatars_spec.js index da18d8e7894..61e110b345a 100644 --- a/spec/frontend/diffs/components/diff_gutter_avatars_spec.js +++ b/spec/frontend/diffs/components/diff_gutter_avatars_spec.js @@ -110,7 +110,7 @@ describe('DiffGutterAvatars', () => { it('returns truncated version of comment if it is longer than max length', () => { const note = wrapper.vm.discussions[0].notes[1]; - expect(wrapper.vm.getTooltipText(note)).toEqual('Fatih Acet: comment 2 is r...'); + expect(wrapper.vm.getTooltipText(note)).toEqual('Fatih Acet: comment 2 is rea…'); }); }); }); diff --git a/spec/frontend/helpers/event_hub_factory_spec.js b/spec/frontend/helpers/event_hub_factory_spec.js index d29b9ddba34..c4f63ff6049 100644 --- a/spec/frontend/helpers/event_hub_factory_spec.js +++ b/spec/frontend/helpers/event_hub_factory_spec.js @@ -1,17 +1,21 @@ import createEventHub from '~/helpers/event_hub_factory'; const TEST_EVENT = 'foobar'; +const TEST_EVENT_2 = 'testevent'; describe('event bus factory', () => { let eventBus; let handler; + let otherHandlers; beforeEach(() => { eventBus = createEventHub(); handler = jest.fn(); + otherHandlers = [jest.fn(), jest.fn()]; }); afterEach(() => { + eventBus.dispose(); eventBus = null; }); @@ -48,22 +52,6 @@ describe('event bus factory', () => { expect(handler).toHaveBeenCalledTimes(2); }); - - it('does not call handler after $off with handler', () => { - eventBus.$off(TEST_EVENT, handler); - - eventBus.$emit(TEST_EVENT); - - expect(handler).not.toHaveBeenCalled(); - }); - - it('does not call handler after $off', () => { - eventBus.$off(TEST_EVENT); - - eventBus.$emit(TEST_EVENT); - - expect(handler).not.toHaveBeenCalled(); - }); }); describe('$once', () => { @@ -102,4 +90,55 @@ describe('event bus factory', () => { }); }); }); + + describe('$off', () => { + beforeEach(() => { + otherHandlers.forEach(x => eventBus.$on(TEST_EVENT, x)); + eventBus.$on(TEST_EVENT, handler); + }); + + it('can be called on event with no handlers', () => { + expect(() => { + eventBus.$off(TEST_EVENT_2); + }).not.toThrow(); + }); + + it('can be called on event with no handlers, with a handler', () => { + expect(() => { + eventBus.$off(TEST_EVENT_2, handler); + }).not.toThrow(); + }); + + it('with a handler, will no longer call that handler', () => { + eventBus.$off(TEST_EVENT, handler); + + eventBus.$emit(TEST_EVENT); + + expect(handler).not.toHaveBeenCalled(); + expect(otherHandlers.map(x => x.mock.calls.length)).toEqual(otherHandlers.map(() => 1)); + }); + + it('without a handler, will no longer call any handlers', () => { + eventBus.$off(TEST_EVENT); + + eventBus.$emit(TEST_EVENT); + + expect(handler).not.toHaveBeenCalled(); + expect(otherHandlers.map(x => x.mock.calls.length)).toEqual(otherHandlers.map(() => 0)); + }); + }); + + describe('$emit', () => { + beforeEach(() => { + otherHandlers.forEach(x => eventBus.$on(TEST_EVENT_2, x)); + eventBus.$on(TEST_EVENT, handler); + }); + + it('only calls handlers for given type', () => { + eventBus.$emit(TEST_EVENT, 'arg1'); + + expect(handler).toHaveBeenCalledWith('arg1'); + expect(otherHandlers.map(x => x.mock.calls.length)).toEqual(otherHandlers.map(() => 0)); + }); + }); }); diff --git a/spec/frontend/lib/utils/text_utility_spec.js b/spec/frontend/lib/utils/text_utility_spec.js index 76e0e435860..285f7d04c3b 100644 --- a/spec/frontend/lib/utils/text_utility_spec.js +++ b/spec/frontend/lib/utils/text_utility_spec.js @@ -145,6 +145,56 @@ describe('text_utility', () => { }); }); + describe('truncate', () => { + it('returns the original string when str length is less than maxLength', () => { + const str = 'less than 20 chars'; + expect(textUtils.truncate(str, 20)).toEqual(str); + }); + + it('returns truncated string when str length is more than maxLength', () => { + const str = 'more than 10 chars'; + expect(textUtils.truncate(str, 10)).toEqual(`${str.substring(0, 10 - 1)}…`); + }); + + it('returns the original string when rendered width is exactly equal to maxWidth', () => { + const str = 'Exactly 16 chars'; + expect(textUtils.truncate(str, 16)).toEqual(str); + }); + }); + + describe('truncateWidth', () => { + const clientWidthDescriptor = Object.getOwnPropertyDescriptor(Element.prototype, 'clientWidth'); + + beforeAll(() => { + // Mock measured width of ' ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' + Object.defineProperty(Element.prototype, 'clientWidth', { + value: 431, + writable: false, + }); + }); + + afterAll(() => { + Object.defineProperty(Element.prototype, 'clientWidth', clientWidthDescriptor); + }); + + it('returns the original string when rendered width is less than maxWidth', () => { + const str = '< 80px'; + expect(textUtils.truncateWidth(str)).toEqual(str); + }); + + it('returns truncated string when rendered width is more than maxWidth', () => { + const str = 'This is wider than 80px'; + expect(textUtils.truncateWidth(str)).toEqual(`${str.substring(0, 10)}…`); + }); + + it('returns the original string when rendered width is exactly equal to maxWidth', () => { + const str = 'Exactly 159.62962962962965px'; + expect(textUtils.truncateWidth(str, { maxWidth: 159.62962962962965, fontSize: 10 })).toEqual( + str, + ); + }); + }); + describe('truncateSha', () => { it('shortens SHAs to 8 characters', () => { expect(textUtils.truncateSha('verylongsha')).toBe('verylong'); diff --git a/spec/frontend/releases/components/release_block_assets_spec.js b/spec/frontend/releases/components/release_block_assets_spec.js index 44b190b0d19..a85532a8118 100644 --- a/spec/frontend/releases/components/release_block_assets_spec.js +++ b/spec/frontend/releases/components/release_block_assets_spec.js @@ -4,6 +4,7 @@ import ReleaseBlockAssets from '~/releases/components/release_block_assets.vue'; import { ASSET_LINK_TYPE } from '~/releases/constants'; import { trimText } from 'helpers/text_helper'; import { assets } from '../mock_data'; +import { cloneDeep } from 'lodash'; describe('Release block assets', () => { let wrapper; @@ -30,7 +31,7 @@ describe('Release block assets', () => { wrapper.findAll('h5').filter(h5 => h5.text() === sections[type]); beforeEach(() => { - defaultProps = { assets }; + defaultProps = { assets: cloneDeep(assets) }; }); describe('with default props', () => { @@ -96,6 +97,35 @@ describe('Release block assets', () => { }); }); + describe('sources', () => { + const testSources = ({ shouldSourcesBeRendered }) => { + assets.sources.forEach(s => { + expect(wrapper.find(`a[href="${s.url}"]`).exists()).toBe(shouldSourcesBeRendered); + }); + }; + + describe('when the release has sources', () => { + beforeEach(() => { + createComponent(defaultProps); + }); + + it('renders sources', () => { + testSources({ shouldSourcesBeRendered: true }); + }); + }); + + describe('when the release does not have sources', () => { + beforeEach(() => { + delete defaultProps.assets.sources; + createComponent(defaultProps); + }); + + it('does not render any sources', () => { + testSources({ shouldSourcesBeRendered: false }); + }); + }); + }); + describe('external vs internal links', () => { const containsExternalSourceIndicator = () => wrapper.contains('[data-testid="external-link-indicator"]'); diff --git a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/build_uneditable_token_spec.js b/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/build_uneditable_token_spec.js index 89cc7ea1390..2daca6500c5 100644 --- a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/build_uneditable_token_spec.js +++ b/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/build_uneditable_token_spec.js @@ -2,7 +2,7 @@ import { buildUneditableOpenTokens, buildUneditableCloseToken, buildUneditableTokens, -} from '~/vue_shared/components/rich_content_editor/services/renderers//build_uneditable_token'; +} from '~/vue_shared/components/rich_content_editor/services/renderers/build_uneditable_token'; import { originToken, diff --git a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_kramdown_list_spec.js b/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_kramdown_list_spec.js index 76a918234fe..8b8a8459ca2 100644 --- a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_kramdown_list_spec.js +++ b/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_kramdown_list_spec.js @@ -2,7 +2,7 @@ import renderer from '~/vue_shared/components/rich_content_editor/services/rende import { buildUneditableOpenTokens, buildUneditableCloseToken, -} from '~/vue_shared/components/rich_content_editor/services/renderers//build_uneditable_token'; +} from '~/vue_shared/components/rich_content_editor/services/renderers/build_uneditable_token'; import { kramdownListNode, normalListNode } from '../../mock_data'; diff --git a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_kramdown_text_spec.js b/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_kramdown_text_spec.js index e4b2ac26b63..d52febad436 100644 --- a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_kramdown_text_spec.js +++ b/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_kramdown_text_spec.js @@ -1,5 +1,5 @@ import renderer from '~/vue_shared/components/rich_content_editor/services/renderers/render_kramdown_text'; -import { buildUneditableTokens } from '~/vue_shared/components/rich_content_editor/services/renderers//build_uneditable_token'; +import { buildUneditableTokens } from '~/vue_shared/components/rich_content_editor/services/renderers/build_uneditable_token'; import { kramdownTextNode, normalTextNode } from '../../mock_data'; |