diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-09-09 18:08:47 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-09-09 18:08:47 +0300 |
commit | 825e4190a30a745adb37ab822eb8f9d845b462e7 (patch) | |
tree | 2588f929e0dc2bd97bf9b57eee596ae65315144c /spec/frontend | |
parent | d022b7432efd720f0cf5f8d2a2cdaac7619bab57 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend')
6 files changed, 181 insertions, 34 deletions
diff --git a/spec/frontend/packages/details/components/app_spec.js b/spec/frontend/packages/details/components/app_spec.js index 2a60fd91e14..e82c74e56e5 100644 --- a/spec/frontend/packages/details/components/app_spec.js +++ b/spec/frontend/packages/details/components/app_spec.js @@ -34,12 +34,15 @@ describe('PackagesApp', () => { let wrapper; let store; const fetchPackageVersions = jest.fn(); + const deletePackage = jest.fn(); + const defaultProjectName = 'bar'; + const { location } = window; function createComponent({ packageEntity = mavenPackage, packageFiles = mavenFiles, isLoading = false, - oneColumnView = false, + projectName = defaultProjectName, } = {}) { store = new Vuex.Store({ state: { @@ -47,14 +50,15 @@ describe('PackagesApp', () => { packageEntity, packageFiles, canDelete: true, - destroyPath: 'destroy-package-path', emptySvgPath: 'empty-illustration', npmPath: 'foo', npmHelpPath: 'foo', - projectName: 'bar', - oneColumnView, + projectName, + projectListUrl: 'project_url', + groupListUrl: 'group_url', }, actions: { + deletePackage, fetchPackageVersions, }, getters, @@ -95,8 +99,14 @@ describe('PackagesApp', () => { const findAdditionalMetadata = () => wrapper.find(AdditionalMetadata); const findInstallationCommands = () => wrapper.find(InstallationCommands); + beforeEach(() => { + delete window.location; + window.location = { replace: jest.fn() }; + }); + afterEach(() => { wrapper.destroy(); + window.location = location; }); it('renders the app and displays the package title', () => { @@ -240,44 +250,94 @@ describe('PackagesApp', () => { }); }); - describe('tracking', () => { - let eventSpy; - let utilSpy; - const category = 'foo'; + describe('tracking and delete', () => { + const doDelete = async () => { + deleteButton().trigger('click'); + await wrapper.vm.$nextTick(); + modalDeleteButton().trigger('click'); + }; + + describe('delete', () => { + const originalReferrer = document.referrer; + const setReferrer = (value = defaultProjectName) => { + Object.defineProperty(document, 'referrer', { + value, + configurable: true, + }); + }; + + afterEach(() => { + Object.defineProperty(document, 'referrer', { + value: originalReferrer, + configurable: true, + }); + }); - beforeEach(() => { - eventSpy = jest.spyOn(Tracking, 'event'); - utilSpy = jest.spyOn(SharedUtils, 'packageTypeToTrackCategory').mockReturnValue(category); - }); + it('calls the proper vuex action', async () => { + createComponent({ packageEntity: npmPackage }); + await doDelete(); + expect(deletePackage).toHaveBeenCalled(); + }); - it('tracking category calls packageTypeToTrackCategory', () => { - createComponent({ packageEntity: conanPackage }); - expect(wrapper.vm.tracking.category).toBe(category); - expect(utilSpy).toHaveBeenCalledWith('conan'); + it('when referrer contains project name calls window.replace with project url', async () => { + setReferrer(); + deletePackage.mockResolvedValue(); + createComponent({ packageEntity: npmPackage }); + await doDelete(); + await deletePackage(); + expect(window.location.replace).toHaveBeenCalledWith( + 'project_url?showSuccessDeleteAlert=true', + ); + }); + + it('when referrer does not contain project name calls window.replace with group url', async () => { + setReferrer('baz'); + deletePackage.mockResolvedValue(); + createComponent({ packageEntity: npmPackage }); + await doDelete(); + await deletePackage(); + expect(window.location.replace).toHaveBeenCalledWith( + 'group_url?showSuccessDeleteAlert=true', + ); + }); }); - it(`delete button on delete modal call event with ${TrackingActions.DELETE_PACKAGE}`, () => { - createComponent({ packageEntity: conanPackage }); - deleteButton().trigger('click'); - return wrapper.vm.$nextTick().then(() => { - modalDeleteButton().trigger('click'); + describe('tracking', () => { + let eventSpy; + let utilSpy; + const category = 'foo'; + + beforeEach(() => { + eventSpy = jest.spyOn(Tracking, 'event'); + utilSpy = jest.spyOn(SharedUtils, 'packageTypeToTrackCategory').mockReturnValue(category); + }); + + it('tracking category calls packageTypeToTrackCategory', () => { + createComponent({ packageEntity: conanPackage }); + expect(wrapper.vm.tracking.category).toBe(category); + expect(utilSpy).toHaveBeenCalledWith('conan'); + }); + + it(`delete button on delete modal call event with ${TrackingActions.DELETE_PACKAGE}`, async () => { + createComponent({ packageEntity: npmPackage }); + await doDelete(); expect(eventSpy).toHaveBeenCalledWith( category, TrackingActions.DELETE_PACKAGE, expect.any(Object), ); }); - }); - it(`file download link call event with ${TrackingActions.PULL_PACKAGE}`, () => { - createComponent({ packageEntity: conanPackage }); + it(`file download link call event with ${TrackingActions.PULL_PACKAGE}`, () => { + createComponent({ packageEntity: conanPackage }); - firstFileDownloadLink().vm.$emit('click'); - expect(eventSpy).toHaveBeenCalledWith( - category, - TrackingActions.PULL_PACKAGE, - expect.any(Object), - ); + firstFileDownloadLink().vm.$emit('click'); + expect(eventSpy).toHaveBeenCalledWith( + category, + TrackingActions.PULL_PACKAGE, + expect.any(Object), + ); + }); }); }); }); diff --git a/spec/frontend/packages/details/store/actions_spec.js b/spec/frontend/packages/details/store/actions_spec.js index 6dfb2b63f85..70f87d18bcb 100644 --- a/spec/frontend/packages/details/store/actions_spec.js +++ b/spec/frontend/packages/details/store/actions_spec.js @@ -1,9 +1,10 @@ import testAction from 'helpers/vuex_action_helper'; import Api from '~/api'; import { deprecatedCreateFlash as createFlash } from '~/flash'; -import fetchPackageVersions from '~/packages/details/store/actions'; +import { fetchPackageVersions, deletePackage } from '~/packages/details/store/actions'; import * as types from '~/packages/details/store/mutation_types'; import { FETCH_PACKAGE_VERSIONS_ERROR } from '~/packages/details/constants'; +import { DELETE_PACKAGE_ERROR_MESSAGE } from '~/packages/shared/constants'; import { npmPackage as packageEntity } from '../../mock_data'; jest.mock('~/flash.js'); @@ -73,4 +74,25 @@ describe('Actions Package details store', () => { ); }); }); + + describe('deletePackage', () => { + it('should call Api.deleteProjectPackage', done => { + Api.deleteProjectPackage = jest.fn().mockResolvedValue(); + testAction(deletePackage, undefined, { packageEntity }, [], [], () => { + expect(Api.deleteProjectPackage).toHaveBeenCalledWith( + packageEntity.project_id, + packageEntity.id, + ); + done(); + }); + }); + it('should create flash on API error', done => { + Api.deleteProjectPackage = jest.fn().mockRejectedValue(); + + testAction(deletePackage, undefined, { packageEntity }, [], [], () => { + expect(createFlash).toHaveBeenCalledWith(DELETE_PACKAGE_ERROR_MESSAGE); + done(); + }); + }); + }); }); diff --git a/spec/frontend/packages/list/components/packages_list_app_spec.js b/spec/frontend/packages/list/components/packages_list_app_spec.js index 31bab3886c1..19ff4290f50 100644 --- a/spec/frontend/packages/list/components/packages_list_app_spec.js +++ b/spec/frontend/packages/list/components/packages_list_app_spec.js @@ -1,7 +1,14 @@ import Vuex from 'vuex'; import { shallowMount, createLocalVue } from '@vue/test-utils'; import { GlEmptyState, GlTab, GlTabs, GlSprintf, GlLink } from '@gitlab/ui'; +import * as commonUtils from '~/lib/utils/common_utils'; +import createFlash from '~/flash'; import PackageListApp from '~/packages/list/components/packages_list_app.vue'; +import { SHOW_DELETE_SUCCESS_ALERT } from '~/packages/shared/constants'; +import { DELETE_PACKAGE_SUCCESS_MESSAGE } from '~/packages/list/constants'; + +jest.mock('~/lib/utils/common_utils'); +jest.mock('~/flash'); const localVue = createLocalVue(); localVue.use(Vuex); @@ -145,4 +152,46 @@ describe('packages_list_app', () => { ); }); }); + + describe('delete alert handling', () => { + const { location } = window.location; + const search = `?${SHOW_DELETE_SUCCESS_ALERT}=true`; + + beforeEach(() => { + createStore('foo'); + jest.spyOn(commonUtils, 'historyReplaceState').mockImplementation(() => {}); + delete window.location; + window.location = { + href: `foo_bar_baz${search}`, + search, + }; + }); + + afterEach(() => { + window.location = location; + }); + + it(`creates a flash if the query string contains ${SHOW_DELETE_SUCCESS_ALERT}`, () => { + mountComponent(); + + expect(createFlash).toHaveBeenCalledWith({ + message: DELETE_PACKAGE_SUCCESS_MESSAGE, + type: 'notice', + }); + }); + + it('calls historyReplaceState with a clean url', () => { + mountComponent(); + + expect(commonUtils.historyReplaceState).toHaveBeenCalledWith('foo_bar_baz'); + }); + + it(`does nothing if the query string does not contain ${SHOW_DELETE_SUCCESS_ALERT}`, () => { + window.location.search = ''; + mountComponent(); + + expect(createFlash).not.toHaveBeenCalled(); + expect(commonUtils.historyReplaceState).not.toHaveBeenCalled(); + }); + }); }); diff --git a/spec/frontend/packages/list/stores/actions_spec.js b/spec/frontend/packages/list/stores/actions_spec.js index faa629cc01f..cf205ecbac4 100644 --- a/spec/frontend/packages/list/stores/actions_spec.js +++ b/spec/frontend/packages/list/stores/actions_spec.js @@ -5,7 +5,8 @@ import Api from '~/api'; import { deprecatedCreateFlash as createFlash } from '~/flash'; import * as actions from '~/packages/list/stores/actions'; import * as types from '~/packages/list/stores/mutation_types'; -import { MISSING_DELETE_PATH_ERROR, DELETE_PACKAGE_ERROR_MESSAGE } from '~/packages/list/constants'; +import { MISSING_DELETE_PATH_ERROR } from '~/packages/list/constants'; +import { DELETE_PACKAGE_ERROR_MESSAGE } from '~/packages/shared/constants'; jest.mock('~/flash.js'); jest.mock('~/api.js'); diff --git a/spec/frontend/static_site_editor/services/formatter_spec.js b/spec/frontend/static_site_editor/services/formatter_spec.js index b7600798db9..9e9c4bbd171 100644 --- a/spec/frontend/static_site_editor/services/formatter_spec.js +++ b/spec/frontend/static_site_editor/services/formatter_spec.js @@ -1,6 +1,6 @@ import formatter from '~/static_site_editor/services/formatter'; -describe('formatter', () => { +describe('static_site_editor/services/formatter', () => { const source = `Some text <br> @@ -23,4 +23,17 @@ And even more text`; it('removes extraneous <br> tags', () => { expect(formatter(source)).toMatch(sourceWithoutBrTags); }); + + describe('ordered lists with incorrect content indentation', () => { + it.each` + input | result + ${'12. ordered list item\n13.Next ordered list item'} | ${'12. ordered list item\n13.Next ordered list item'} + ${'12. ordered list item\n - Next ordered list item'} | ${'12. ordered list item\n - Next ordered list item'} + ${'12. ordered list item\n - Next ordered list item'} | ${'12. ordered list item\n - Next ordered list item'} + ${'12. ordered list item\n Next ordered list item'} | ${'12. ordered list item\n Next ordered list item'} + ${'1. ordered list item\n Next ordered list item'} | ${'1. ordered list item\n Next ordered list item'} + `('\ntransforms\n$input \nto\n$result', ({ input, result }) => { + expect(formatter(input)).toBe(result); + }); + }); }); diff --git a/spec/frontend/vue_shared/components/rich_content_editor/services/build_html_to_markdown_renderer_spec.js b/spec/frontend/vue_shared/components/rich_content_editor/services/build_html_to_markdown_renderer_spec.js index 48653bce0fd..fd745c21bb6 100644 --- a/spec/frontend/vue_shared/components/rich_content_editor/services/build_html_to_markdown_renderer_spec.js +++ b/spec/frontend/vue_shared/components/rich_content_editor/services/build_html_to_markdown_renderer_spec.js @@ -178,7 +178,9 @@ describe('rich_content_editor/services/html_to_markdown_renderer', () => { }); it('returns raw text when pre node has sse-reference-definitions class', () => { - expect(htmlToMarkdownRenderer['PRE CODE'](node, subContent)).toBe(`\n\n${node.innerText}\n`); + expect(htmlToMarkdownRenderer['PRE CODE'](node, subContent)).toBe( + `\n\n${node.innerText}\n\n`, + ); }); it('returns base result when pre node does not have sse-reference-definitions class', () => { |