diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-06-01 09:08:28 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-06-01 09:08:28 +0000 |
commit | c6e6762bbf9fa3e38f37a886237c6e920f6c409c (patch) | |
tree | df600ebc6d4531716502797999e1f8d1797e669a /spec/frontend | |
parent | ec884edd4678e35a8c011242aa8bc92ec35fdac5 (diff) | |
download | gitlab-ce-c6e6762bbf9fa3e38f37a886237c6e920f6c409c.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend')
6 files changed, 201 insertions, 46 deletions
diff --git a/spec/frontend/clusters/components/applications_spec.js b/spec/frontend/clusters/components/applications_spec.js index 33b30891d5e..81b84d4d1e2 100644 --- a/spec/frontend/clusters/components/applications_spec.js +++ b/spec/frontend/clusters/components/applications_spec.js @@ -13,6 +13,14 @@ import FluentdOutputSettings from '~/clusters/components/fluentd_output_settings describe('Applications', () => { let vm; let Applications; + const ApplicationRowStub = { + name: 'application-row-stub', + template: ` + <div> + <slot name="description"></slot> + </div> + `, + }; beforeEach(() => { Applications = Vue.extend(applications); @@ -202,7 +210,12 @@ describe('Applications', () => { let wrapper; beforeEach(() => { - wrapper = shallowMount(Applications, { propsData }); + wrapper = shallowMount(Applications, { + propsData, + stubs: { + ApplicationRow: ApplicationRowStub, + }, + }); }); afterEach(() => { wrapper.destroy(); @@ -436,7 +449,10 @@ describe('Applications', () => { let knativeDomainEditor; beforeEach(() => { - wrapper = shallowMount(Applications, { propsData }); + wrapper = shallowMount(Applications, { + propsData, + stubs: { ApplicationRow: ApplicationRowStub }, + }); jest.spyOn(eventHub, '$emit'); knativeDomainEditor = wrapper.find(KnativeDomainEditor); @@ -504,7 +520,10 @@ describe('Applications', () => { let wrapper; beforeEach(() => { - wrapper = shallowMount(Applications, { propsData }); + wrapper = shallowMount(Applications, { + propsData, + stubs: { ApplicationRow: ApplicationRowStub }, + }); }); afterEach(() => { wrapper.destroy(); @@ -563,7 +582,10 @@ describe('Applications', () => { let wrapper; beforeEach(() => { - wrapper = shallowMount(Applications, { propsData }); + wrapper = shallowMount(Applications, { + propsData, + stubs: { ApplicationRow: ApplicationRowStub }, + }); }); afterEach(() => { wrapper.destroy(); diff --git a/spec/frontend/design_management/pages/design/index_spec.js b/spec/frontend/design_management/pages/design/index_spec.js index 9e2f071a983..17fdfb6c14f 100644 --- a/spec/frontend/design_management/pages/design/index_spec.js +++ b/spec/frontend/design_management/pages/design/index_spec.js @@ -1,4 +1,5 @@ -import { shallowMount } from '@vue/test-utils'; +import { shallowMount, createLocalVue } from '@vue/test-utils'; +import VueRouter from 'vue-router'; import { GlAlert } from '@gitlab/ui'; import { ApolloMutation } from 'vue-apollo'; import createFlash from '~/flash'; @@ -17,6 +18,9 @@ import { DESIGN_VERSION_NOT_EXIST_ERROR, } from '~/design_management/utils/error_messages'; import { DESIGNS_ROUTE_NAME } from '~/design_management/router/constants'; +import createRouter from '~/design_management/router'; +import * as utils from '~/design_management/utils/design_management_utils'; +import { DESIGN_DETAIL_LAYOUT_CLASSLIST } from '~/design_management/constants'; jest.mock('~/flash'); jest.mock('mousetrap', () => ({ @@ -24,8 +28,13 @@ jest.mock('mousetrap', () => ({ unbind: jest.fn(), })); +const localVue = createLocalVue(); +localVue.use(VueRouter); + describe('Design management design index page', () => { let wrapper; + let router; + const newComment = 'new comment'; const annotationCoordinates = { x: 10, @@ -62,14 +71,13 @@ describe('Design management design index page', () => { }; const mutate = jest.fn().mockResolvedValue(); - const routerPush = jest.fn(); const findDiscussions = () => wrapper.findAll(DesignDiscussion); const findDiscussionForm = () => wrapper.find(DesignReplyForm); const findParticipants = () => wrapper.find(Participants); const findDiscussionsWrapper = () => wrapper.find('.image-notes'); - function createComponent(loading = false, data = {}, { routeQuery = {} } = {}) { + function createComponent(loading = false, data = {}) { const $apollo = { queries: { design: { @@ -79,17 +87,11 @@ describe('Design management design index page', () => { mutate, }; - const $router = { - push: routerPush, - }; - - const $route = { - query: routeQuery, - }; + router = createRouter(); wrapper = shallowMount(DesignIndex, { propsData: { id: '1' }, - mocks: { $apollo, $router, $route }, + mocks: { $apollo }, stubs: { ApolloMutation, DesignDiscussion, @@ -104,6 +106,8 @@ describe('Design management design index page', () => { ...data, }; }, + localVue, + router, }); } @@ -111,6 +115,23 @@ describe('Design management design index page', () => { wrapper.destroy(); }); + describe('when navigating', () => { + it('applies fullscreen layout', () => { + const mockEl = { + classList: { + add: jest.fn(), + remove: jest.fn(), + }, + }; + jest.spyOn(utils, 'getPageLayoutElement').mockReturnValue(mockEl); + createComponent(true); + + wrapper.vm.$router.push('/designs/test'); + expect(mockEl.classList.add).toHaveBeenCalledTimes(1); + expect(mockEl.classList.add).toHaveBeenCalledWith(...DESIGN_DETAIL_LAYOUT_CLASSLIST); + }); + }); + it('sets loading state', () => { createComponent(true); @@ -269,31 +290,35 @@ describe('Design management design index page', () => { describe('with no designs', () => { it('redirects to /designs', () => { createComponent(true); + router.push = jest.fn(); wrapper.vm.onDesignQueryResult({ data: mockResponseNoDesigns, loading: false }); return wrapper.vm.$nextTick().then(() => { expect(createFlash).toHaveBeenCalledTimes(1); expect(createFlash).toHaveBeenCalledWith(DESIGN_NOT_FOUND_ERROR); - expect(routerPush).toHaveBeenCalledTimes(1); - expect(routerPush).toHaveBeenCalledWith({ name: DESIGNS_ROUTE_NAME }); + expect(router.push).toHaveBeenCalledTimes(1); + expect(router.push).toHaveBeenCalledWith({ name: DESIGNS_ROUTE_NAME }); }); }); }); describe('when no design exists for given version', () => { it('redirects to /designs', () => { - // attempt to query for a version of the design that doesn't exist - createComponent(true, {}, { routeQuery: { version: '999' } }); + createComponent(true); wrapper.setData({ allVersions: mockAllVersions, }); + // attempt to query for a version of the design that doesn't exist + router.push({ query: { version: '999' } }); + router.push = jest.fn(); + wrapper.vm.onDesignQueryResult({ data: mockResponseWithDesigns, loading: false }); return wrapper.vm.$nextTick().then(() => { expect(createFlash).toHaveBeenCalledTimes(1); expect(createFlash).toHaveBeenCalledWith(DESIGN_VERSION_NOT_EXIST_ERROR); - expect(routerPush).toHaveBeenCalledTimes(1); - expect(routerPush).toHaveBeenCalledWith({ name: DESIGNS_ROUTE_NAME }); + expect(router.push).toHaveBeenCalledTimes(1); + expect(router.push).toHaveBeenCalledWith({ name: DESIGNS_ROUTE_NAME }); }); }); }); diff --git a/spec/frontend/design_management/pages/index_spec.js b/spec/frontend/design_management/pages/index_spec.js index 2299b858da9..d4e9bae3e89 100644 --- a/spec/frontend/design_management/pages/index_spec.js +++ b/spec/frontend/design_management/pages/index_spec.js @@ -2,7 +2,6 @@ import { createLocalVue, shallowMount } from '@vue/test-utils'; import { ApolloMutation } from 'vue-apollo'; import VueRouter from 'vue-router'; import { GlEmptyState } from '@gitlab/ui'; - import Index from '~/design_management/pages/index.vue'; import uploadDesignQuery from '~/design_management/graphql/mutations/uploadDesign.mutation.graphql'; import DesignDestroyer from '~/design_management/components/design_destroyer.vue'; @@ -14,20 +13,21 @@ import { EXISTING_DESIGN_DROP_INVALID_FILENAME_MESSAGE, } from '~/design_management/utils/error_messages'; import createFlash from '~/flash'; +import createRouter from '~/design_management/router'; +import * as utils from '~/design_management/utils/design_management_utils'; +import { DESIGN_DETAIL_LAYOUT_CLASSLIST } from '~/design_management/constants'; + +jest.mock('~/flash.js'); +const mockPageEl = { + classList: { + remove: jest.fn(), + }, +}; +jest.spyOn(utils, 'getPageLayoutElement').mockReturnValue(mockPageEl); const localVue = createLocalVue(); +const router = createRouter(); localVue.use(VueRouter); -const router = new VueRouter({ - routes: [ - { - name: DESIGNS_ROUTE_NAME, - path: '/designs', - component: Index, - }, - ], -}); - -jest.mock('~/flash.js'); const mockDesigns = [ { @@ -530,4 +530,14 @@ describe('Design management index page', () => { expect(wrapper.vm.onUploadDesign).not.toHaveBeenCalled(); }); }); + + describe('when navigating', () => { + it('ensures fullscreen layout is not applied', () => { + createComponent(true); + + wrapper.vm.$router.push('/designs'); + expect(mockPageEl.classList.remove).toHaveBeenCalledTimes(1); + expect(mockPageEl.classList.remove).toHaveBeenCalledWith(...DESIGN_DETAIL_LAYOUT_CLASSLIST); + }); + }); }); diff --git a/spec/frontend/releases/components/asset_links_form_spec.js b/spec/frontend/releases/components/asset_links_form_spec.js index 44542868cfe..e1f8592270e 100644 --- a/spec/frontend/releases/components/asset_links_form_spec.js +++ b/spec/frontend/releases/components/asset_links_form_spec.js @@ -3,6 +3,7 @@ import { mount, createLocalVue } from '@vue/test-utils'; import AssetLinksForm from '~/releases/components/asset_links_form.vue'; import { release as originalRelease } from '../mock_data'; import * as commonUtils from '~/lib/utils/common_utils'; +import { ASSET_LINK_TYPE, DEFAULT_ASSET_LINK_TYPE } from '~/releases/constants'; const localVue = createLocalVue(); localVue.use(Vuex); @@ -24,6 +25,7 @@ describe('Release edit component', () => { addEmptyAssetLink: jest.fn(), updateAssetLinkUrl: jest.fn(), updateAssetLinkName: jest.fn(), + updateAssetLinkType: jest.fn(), removeAssetLink: jest.fn().mockImplementation((_context, linkId) => { state.release.assets.links = state.release.assets.links.filter(l => l.id !== linkId); }), @@ -51,6 +53,11 @@ describe('Release edit component', () => { wrapper = mount(AssetLinksForm, { localVue, store, + provide: { + glFeatures: { + releaseAssetLinkType: true, + }, + }, }); }; @@ -103,7 +110,7 @@ describe('Release edit component', () => { ); }); - it('calls the "updateAssetLinName" store method when text is entered into the "Link title" input field', () => { + it('calls the "updateAssetLinkName" store method when text is entered into the "Link title" input field', () => { const linkIdToUpdate = release.assets.links[0].id; const newName = 'updated name'; @@ -121,6 +128,31 @@ describe('Release edit component', () => { undefined, ); }); + + it('calls the "updateAssetLinkType" store method when an option is selected from the "Type" dropdown', () => { + const linkIdToUpdate = release.assets.links[0].id; + const newType = ASSET_LINK_TYPE.RUNBOOK; + + expect(actions.updateAssetLinkType).not.toHaveBeenCalled(); + + wrapper.find({ ref: 'typeSelect' }).vm.$emit('change', newType); + + expect(actions.updateAssetLinkType).toHaveBeenCalledTimes(1); + expect(actions.updateAssetLinkType).toHaveBeenCalledWith( + expect.anything(), + { + linkIdToUpdate, + newType, + }, + undefined, + ); + }); + + it('selects the default asset type if no type was provided by the backend', () => { + const selected = wrapper.find({ ref: 'typeSelect' }).element.value; + + expect(selected).toBe(DEFAULT_ASSET_LINK_TYPE); + }); }); describe('validation', () => { diff --git a/spec/frontend/releases/stores/modules/detail/actions_spec.js b/spec/frontend/releases/stores/modules/detail/actions_spec.js index 854f06821be..345be2acc71 100644 --- a/spec/frontend/releases/stores/modules/detail/actions_spec.js +++ b/spec/frontend/releases/stores/modules/detail/actions_spec.js @@ -10,6 +10,7 @@ import createFlash from '~/flash'; import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; import { redirectTo } from '~/lib/utils/url_utility'; import api from '~/api'; +import { ASSET_LINK_TYPE } from '~/releases/constants'; jest.mock('~/flash', () => jest.fn()); @@ -130,6 +131,54 @@ describe('Release detail actions', () => { }); }); + describe('updateAssetLinkUrl', () => { + it(`commits ${types.UPDATE_ASSET_LINK_URL} with the updated link URL`, () => { + const params = { + linkIdToUpdate: 2, + newUrl: 'https://example.com/updated', + }; + + return testAction(actions.updateAssetLinkUrl, params, state, [ + { type: types.UPDATE_ASSET_LINK_URL, payload: params }, + ]); + }); + }); + + describe('updateAssetLinkName', () => { + it(`commits ${types.UPDATE_ASSET_LINK_NAME} with the updated link name`, () => { + const params = { + linkIdToUpdate: 2, + newName: 'Updated link name', + }; + + return testAction(actions.updateAssetLinkName, params, state, [ + { type: types.UPDATE_ASSET_LINK_NAME, payload: params }, + ]); + }); + }); + + describe('updateAssetLinkType', () => { + it(`commits ${types.UPDATE_ASSET_LINK_TYPE} with the updated link type`, () => { + const params = { + linkIdToUpdate: 2, + newType: ASSET_LINK_TYPE.RUNBOOK, + }; + + return testAction(actions.updateAssetLinkType, params, state, [ + { type: types.UPDATE_ASSET_LINK_TYPE, payload: params }, + ]); + }); + }); + + describe('removeAssetLink', () => { + it(`commits ${types.REMOVE_ASSET_LINK} with the ID of the asset link to remove`, () => { + const idToRemove = 2; + return testAction(actions.removeAssetLink, idToRemove, state, [ + { type: types.REMOVE_ASSET_LINK, payload: idToRemove }, + ]); + }); + }); + describe('updateReleaseMilestones', () => { it(`commits ${types.UPDATE_RELEASE_MILESTONES} with the updated release milestones`, () => { const newReleaseMilestones = ['v0.0', 'v0.1']; diff --git a/spec/frontend/releases/stores/modules/detail/mutations_spec.js b/spec/frontend/releases/stores/modules/detail/mutations_spec.js index f3f7ca797b4..a34c1be64d9 100644 --- a/spec/frontend/releases/stores/modules/detail/mutations_spec.js +++ b/spec/frontend/releases/stores/modules/detail/mutations_spec.js @@ -3,6 +3,7 @@ import mutations from '~/releases/stores/modules/detail/mutations'; import * as types from '~/releases/stores/modules/detail/mutation_types'; import { release as originalRelease } from '../../../mock_data'; import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; +import { ASSET_LINK_TYPE, DEFAULT_ASSET_LINK_TYPE } from '~/releases/constants'; describe('Release detail mutations', () => { let state; @@ -24,7 +25,7 @@ describe('Release detail mutations', () => { it('set state.isFetchingRelease to true', () => { mutations[types.REQUEST_RELEASE](state); - expect(state.isFetchingRelease).toEqual(true); + expect(state.isFetchingRelease).toBe(true); }); }); @@ -32,9 +33,9 @@ describe('Release detail mutations', () => { it('handles a successful response from the server', () => { mutations[types.RECEIVE_RELEASE_SUCCESS](state, release); - expect(state.fetchError).toEqual(undefined); + expect(state.fetchError).toBeUndefined(); - expect(state.isFetchingRelease).toEqual(false); + expect(state.isFetchingRelease).toBe(false); expect(state.release).toEqual(release); @@ -47,7 +48,7 @@ describe('Release detail mutations', () => { const error = { message: 'An error occurred!' }; mutations[types.RECEIVE_RELEASE_ERROR](state, error); - expect(state.isFetchingRelease).toEqual(false); + expect(state.isFetchingRelease).toBe(false); expect(state.release).toBeUndefined(); @@ -61,7 +62,7 @@ describe('Release detail mutations', () => { const newTitle = 'The new release title'; mutations[types.UPDATE_RELEASE_TITLE](state, newTitle); - expect(state.release.name).toEqual(newTitle); + expect(state.release.name).toBe(newTitle); }); }); @@ -71,7 +72,7 @@ describe('Release detail mutations', () => { const newNotes = 'The new release notes'; mutations[types.UPDATE_RELEASE_NOTES](state, newNotes); - expect(state.release.description).toEqual(newNotes); + expect(state.release.description).toBe(newNotes); }); }); @@ -79,7 +80,7 @@ describe('Release detail mutations', () => { it('set state.isUpdatingRelease to true', () => { mutations[types.REQUEST_UPDATE_RELEASE](state); - expect(state.isUpdatingRelease).toEqual(true); + expect(state.isUpdatingRelease).toBe(true); }); }); @@ -87,9 +88,9 @@ describe('Release detail mutations', () => { it('handles a successful response from the server', () => { mutations[types.RECEIVE_UPDATE_RELEASE_SUCCESS](state, release); - expect(state.updateError).toEqual(undefined); + expect(state.updateError).toBeUndefined(); - expect(state.isUpdatingRelease).toEqual(false); + expect(state.isUpdatingRelease).toBe(false); }); }); @@ -98,7 +99,7 @@ describe('Release detail mutations', () => { const error = { message: 'An error occurred!' }; mutations[types.RECEIVE_UPDATE_RELEASE_ERROR](state, error); - expect(state.isUpdatingRelease).toEqual(false); + expect(state.isUpdatingRelease).toBe(false); expect(state.updateError).toEqual(error); }); @@ -118,6 +119,7 @@ describe('Release detail mutations', () => { id: expect.stringMatching(/^new-link-/), url: '', name: '', + linkType: DEFAULT_ASSET_LINK_TYPE, }, ]); }); @@ -134,7 +136,7 @@ describe('Release detail mutations', () => { newUrl, }); - expect(state.release.assets.links[0].url).toEqual(newUrl); + expect(state.release.assets.links[0].url).toBe(newUrl); }); }); @@ -149,7 +151,22 @@ describe('Release detail mutations', () => { newName, }); - expect(state.release.assets.links[0].name).toEqual(newName); + expect(state.release.assets.links[0].name).toBe(newName); + }); + }); + + describe(`${types.UPDATE_ASSET_LINK_TYPE}`, () => { + it('updates an asset link with a new type', () => { + state.release = release; + + const newType = ASSET_LINK_TYPE.RUNBOOK; + + mutations[types.UPDATE_ASSET_LINK_TYPE](state, { + linkIdToUpdate: state.release.assets.links[0].id, + newType, + }); + + expect(state.release.assets.links[0].linkType).toBe(newType); }); }); |