diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-06-05 21:09:44 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-06-05 21:09:44 +0300 |
commit | 2f1a81fd16ff9968d6b986f8a407d963bc2218f9 (patch) | |
tree | d079c1abc2bc282e749a676651c0f02d288874f3 /spec/frontend/pages | |
parent | 18e9429b63f9a095b1ba3606856537b9ca291eac (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend/pages')
3 files changed, 170 insertions, 0 deletions
diff --git a/spec/frontend/pages/projects/shared/permissions/components/ci_catalog_settings_spec.js b/spec/frontend/pages/projects/shared/permissions/components/ci_catalog_settings_spec.js new file mode 100644 index 00000000000..4ac3a511fa2 --- /dev/null +++ b/spec/frontend/pages/projects/shared/permissions/components/ci_catalog_settings_spec.js @@ -0,0 +1,147 @@ +import Vue from 'vue'; +import VueApollo from 'vue-apollo'; +import { GlBadge, GlLoadingIcon, GlModal, GlSprintf, GlToggle } from '@gitlab/ui'; + +import { createAlert } from '~/alert'; +import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; +import waitForPromises from 'helpers/wait_for_promises'; +import createMockApollo from 'helpers/mock_apollo_helper'; + +import catalogResourcesCreate from '~/pages/projects/shared/permissions/graphql/mutations/catalog_resources_create.mutation.graphql'; +import getCiCatalogSettingsQuery from '~/pages/projects/shared/permissions/graphql/queries/get_ci_catalog_settings.query.graphql'; +import CiCatalogSettings, { + i18n, +} from '~/pages/projects/shared/permissions/components/ci_catalog_settings.vue'; + +import { mockCiCatalogSettingsResponse } from './mock_data'; + +Vue.use(VueApollo); +jest.mock('~/alert'); + +describe('CiCatalogSettings', () => { + let wrapper; + let ciCatalogSettingsResponse; + let catalogResourcesCreateResponse; + + const fullPath = 'gitlab-org/gitlab'; + + const createComponent = ({ ciCatalogSettingsHandler = ciCatalogSettingsResponse } = {}) => { + const handlers = [ + [getCiCatalogSettingsQuery, ciCatalogSettingsHandler], + [catalogResourcesCreate, catalogResourcesCreateResponse], + ]; + const mockApollo = createMockApollo(handlers); + + wrapper = shallowMountExtended(CiCatalogSettings, { + propsData: { + fullPath, + }, + stubs: { + GlSprintf, + }, + apolloProvider: mockApollo, + }); + + return waitForPromises(); + }; + + const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon); + const findBadge = () => wrapper.findComponent(GlBadge); + const findModal = () => wrapper.findComponent(GlModal); + const findToggle = () => wrapper.findComponent(GlToggle); + + const findCiCatalogSettings = () => wrapper.findByTestId('ci-catalog-settings'); + + beforeEach(() => { + ciCatalogSettingsResponse = jest.fn().mockResolvedValue(mockCiCatalogSettingsResponse); + catalogResourcesCreateResponse = jest.fn(); + }); + + describe('when initial queries are loading', () => { + beforeEach(() => { + createComponent(); + }); + + it('shows a loading icon and no CI catalog settings', () => { + expect(findLoadingIcon().exists()).toBe(true); + expect(findCiCatalogSettings().exists()).toBe(false); + }); + }); + + describe('when queries have loaded', () => { + beforeEach(async () => { + await createComponent(); + }); + + it('does not show a loading icon', () => { + expect(findLoadingIcon().exists()).toBe(false); + }); + + it('renders the CI Catalog settings', () => { + expect(findCiCatalogSettings().exists()).toBe(true); + }); + + it('renders the experiment badge', () => { + expect(findBadge().exists()).toBe(true); + }); + + it('renders the toggle', () => { + expect(findToggle().exists()).toBe(true); + }); + + it('renders the modal', () => { + expect(findModal().exists()).toBe(true); + expect(findModal().attributes('title')).toBe(i18n.modal.title); + }); + + describe('when queries have loaded', () => { + beforeEach(() => { + catalogResourcesCreateResponse.mockResolvedValue(mockCiCatalogSettingsResponse); + }); + + it('shows the modal when the toggle is clicked', async () => { + expect(findModal().props('visible')).toBe(false); + + await findToggle().vm.$emit('change', true); + + expect(findModal().props('visible')).toBe(true); + expect(findModal().props('actionPrimary').text).toBe(i18n.modal.actionPrimary.text); + }); + + it('hides the modal when cancel is clicked', () => { + findToggle().vm.$emit('change', true); + findModal().vm.$emit('canceled'); + + expect(findModal().props('visible')).toBe(false); + expect(catalogResourcesCreateResponse).not.toHaveBeenCalled(); + }); + + it('calls the mutation with the correct input from the modal click', async () => { + expect(catalogResourcesCreateResponse).toHaveBeenCalledTimes(0); + + findToggle().vm.$emit('change', true); + findModal().vm.$emit('primary'); + await waitForPromises(); + + expect(catalogResourcesCreateResponse).toHaveBeenCalledTimes(1); + expect(catalogResourcesCreateResponse).toHaveBeenCalledWith({ + input: { + projectPath: fullPath, + }, + }); + }); + }); + }); + + describe('when the query is unsuccessful', () => { + const failedHandler = jest.fn().mockRejectedValue(new Error('GraphQL error')); + + it('throws an error', async () => { + await createComponent({ ciCatalogSettingsHandler: failedHandler }); + + await waitForPromises(); + + expect(createAlert).toHaveBeenCalledWith({ message: i18n.catalogResourceQueryError }); + }); + }); +}); diff --git a/spec/frontend/pages/projects/shared/permissions/components/mock_data.js b/spec/frontend/pages/projects/shared/permissions/components/mock_data.js new file mode 100644 index 00000000000..44bbf2a5eb2 --- /dev/null +++ b/spec/frontend/pages/projects/shared/permissions/components/mock_data.js @@ -0,0 +1,7 @@ +export const mockCiCatalogSettingsResponse = { + data: { + catalogResourcesCreate: { + errors: [], + }, + }, +}; diff --git a/spec/frontend/pages/projects/shared/permissions/components/settings_panel_spec.js b/spec/frontend/pages/projects/shared/permissions/components/settings_panel_spec.js index 16e23472eb9..02e510c9541 100644 --- a/spec/frontend/pages/projects/shared/permissions/components/settings_panel_spec.js +++ b/spec/frontend/pages/projects/shared/permissions/components/settings_panel_spec.js @@ -1,6 +1,7 @@ import { GlSprintf, GlToggle } from '@gitlab/ui'; import { shallowMount, mount } from '@vue/test-utils'; import ProjectFeatureSetting from '~/pages/projects/shared/permissions/components/project_feature_setting.vue'; +import CiCatalogSettings from '~/pages/projects/shared/permissions/components/ci_catalog_settings.vue'; import settingsPanel from '~/pages/projects/shared/permissions/components/settings_panel.vue'; import { featureAccessLevel, @@ -34,6 +35,7 @@ const defaultProps = { warnAboutPotentiallyUnwantedCharacters: true, }, isGitlabCom: true, + canAddCatalogResource: false, canDisableEmails: true, canChangeVisibilityLevel: true, allowedVisibilityOptions: [0, 10, 20], @@ -118,6 +120,7 @@ describe('Settings Panel', () => { const findPagesSettings = () => wrapper.findComponent({ ref: 'pages-settings' }); const findPagesAccessLevels = () => wrapper.find('[name="project[project_feature_attributes][pages_access_level]"]'); + const findCiCatalogSettings = () => wrapper.findComponent(CiCatalogSettings); const findEmailSettings = () => wrapper.findComponent({ ref: 'email-settings' }); const findShowDefaultAwardEmojis = () => wrapper.find('input[name="project[project_setting_attributes][show_default_award_emojis]"]'); @@ -647,6 +650,19 @@ describe('Settings Panel', () => { }); }); + describe('CI Catalog Settings', () => { + it('should show the CI Catalog settings if user has permission', () => { + wrapper = mountComponent({ canAddCatalogResource: true }); + + expect(findCiCatalogSettings().exists()).toBe(true); + }); + it('should not show the CI Catalog settings if user does not have permission', () => { + wrapper = mountComponent(); + + expect(findCiCatalogSettings().exists()).toBe(false); + }); + }); + describe('Email notifications', () => { it('should show the disable email notifications input if emails an be disabled', () => { wrapper = mountComponent({ canDisableEmails: true }); |