diff options
Diffstat (limited to 'spec/frontend/packages_and_registries/settings/group/components/package_settings_spec.js')
-rw-r--r-- | spec/frontend/packages_and_registries/settings/group/components/package_settings_spec.js | 277 |
1 files changed, 277 insertions, 0 deletions
diff --git a/spec/frontend/packages_and_registries/settings/group/components/package_settings_spec.js b/spec/frontend/packages_and_registries/settings/group/components/package_settings_spec.js new file mode 100644 index 00000000000..693af21e24a --- /dev/null +++ b/spec/frontend/packages_and_registries/settings/group/components/package_settings_spec.js @@ -0,0 +1,277 @@ +import { GlSprintf, GlLink } from '@gitlab/ui'; +import { createLocalVue } from '@vue/test-utils'; +import VueApollo from 'vue-apollo'; +import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; +import createMockApollo from 'helpers/mock_apollo_helper'; +import waitForPromises from 'helpers/wait_for_promises'; +import DuplicatesSettings from '~/packages_and_registries/settings/group/components/duplicates_settings.vue'; +import GenericSettings from '~/packages_and_registries/settings/group/components/generic_settings.vue'; +import component from '~/packages_and_registries/settings/group/components/packages_settings.vue'; +import MavenSettings from '~/packages_and_registries/settings/group/components/maven_settings.vue'; +import { + PACKAGE_SETTINGS_HEADER, + PACKAGE_SETTINGS_DESCRIPTION, + PACKAGES_DOCS_PATH, +} from '~/packages_and_registries/settings/group/constants'; + +import updateNamespacePackageSettings from '~/packages_and_registries/settings/group/graphql/mutations/update_group_packages_settings.mutation.graphql'; +import getGroupPackagesSettingsQuery from '~/packages_and_registries/settings/group/graphql/queries/get_group_packages_settings.query.graphql'; +import SettingsBlock from '~/vue_shared/components/settings/settings_block.vue'; +import { updateGroupPackagesSettingsOptimisticResponse } from '~/packages_and_registries/settings/group/graphql/utils/optimistic_responses'; +import { + packageSettings, + groupPackageSettingsMock, + groupPackageSettingsMutationMock, + groupPackageSettingsMutationErrorMock, +} from '../mock_data'; + +jest.mock('~/flash'); +jest.mock('~/packages_and_registries/settings/group/graphql/utils/optimistic_responses'); + +const localVue = createLocalVue(); + +describe('Packages Settings', () => { + let wrapper; + let apolloProvider; + + const defaultProvide = { + defaultExpanded: false, + groupPath: 'foo_group_path', + }; + + const mountComponent = ({ + mutationResolver = jest.fn().mockResolvedValue(groupPackageSettingsMutationMock()), + } = {}) => { + localVue.use(VueApollo); + + const requestHandlers = [[updateNamespacePackageSettings, mutationResolver]]; + + apolloProvider = createMockApollo(requestHandlers); + + wrapper = shallowMountExtended(component, { + localVue, + apolloProvider, + provide: defaultProvide, + propsData: { + packageSettings: packageSettings(), + }, + stubs: { + GlSprintf, + SettingsBlock, + MavenSettings, + GenericSettings, + }, + }); + }; + + afterEach(() => { + wrapper.destroy(); + }); + + const findSettingsBlock = () => wrapper.findComponent(SettingsBlock); + const findDescription = () => wrapper.findByTestId('description'); + const findLink = () => wrapper.findComponent(GlLink); + const findMavenSettings = () => wrapper.findComponent(MavenSettings); + const findMavenDuplicatedSettings = () => findMavenSettings().findComponent(DuplicatesSettings); + const findGenericSettings = () => wrapper.findComponent(GenericSettings); + const findGenericDuplicatedSettings = () => + findGenericSettings().findComponent(DuplicatesSettings); + + const fillApolloCache = () => { + apolloProvider.defaultClient.cache.writeQuery({ + query: getGroupPackagesSettingsQuery, + variables: { + fullPath: defaultProvide.groupPath, + }, + ...groupPackageSettingsMock, + }); + }; + + const emitMavenSettingsUpdate = (override) => { + findMavenDuplicatedSettings().vm.$emit('update', { + mavenDuplicateExceptionRegex: ')', + ...override, + }); + }; + + it('renders a settings block', () => { + mountComponent(); + + expect(findSettingsBlock().exists()).toBe(true); + }); + + it('passes the correct props to settings block', () => { + mountComponent(); + + expect(findSettingsBlock().props('defaultExpanded')).toBe(false); + }); + + it('has the correct header text', () => { + mountComponent(); + + expect(wrapper.text()).toContain(PACKAGE_SETTINGS_HEADER); + }); + + it('has the correct description text', () => { + mountComponent(); + + expect(findDescription().text()).toMatchInterpolatedText(PACKAGE_SETTINGS_DESCRIPTION); + }); + + it('has the correct link', () => { + mountComponent(); + + expect(findLink().attributes()).toMatchObject({ + href: PACKAGES_DOCS_PATH, + target: '_blank', + }); + expect(findLink().text()).toBe('Learn more.'); + }); + + describe('maven settings', () => { + it('exists', () => { + mountComponent(); + + expect(findMavenSettings().exists()).toBe(true); + }); + + it('assigns duplication allowness and exception props', async () => { + mountComponent(); + + const { mavenDuplicatesAllowed, mavenDuplicateExceptionRegex } = packageSettings(); + + expect(findMavenDuplicatedSettings().props()).toMatchObject({ + duplicatesAllowed: mavenDuplicatesAllowed, + duplicateExceptionRegex: mavenDuplicateExceptionRegex, + duplicateExceptionRegexError: '', + loading: false, + }); + }); + + it('on update event calls the mutation', () => { + const mutationResolver = jest.fn().mockResolvedValue(groupPackageSettingsMutationMock()); + mountComponent({ mutationResolver }); + + fillApolloCache(); + + emitMavenSettingsUpdate(); + + expect(mutationResolver).toHaveBeenCalledWith({ + input: { mavenDuplicateExceptionRegex: ')', namespacePath: 'foo_group_path' }, + }); + }); + }); + + describe('generic settings', () => { + it('exists', () => { + mountComponent(); + + expect(findGenericSettings().exists()).toBe(true); + }); + + it('assigns duplication allowness and exception props', async () => { + mountComponent(); + + const { genericDuplicatesAllowed, genericDuplicateExceptionRegex } = packageSettings(); + + expect(findGenericDuplicatedSettings().props()).toMatchObject({ + duplicatesAllowed: genericDuplicatesAllowed, + duplicateExceptionRegex: genericDuplicateExceptionRegex, + duplicateExceptionRegexError: '', + loading: false, + }); + }); + + it('on update event calls the mutation', async () => { + const mutationResolver = jest.fn().mockResolvedValue(groupPackageSettingsMutationMock()); + mountComponent({ mutationResolver }); + + fillApolloCache(); + + findMavenDuplicatedSettings().vm.$emit('update', { + genericDuplicateExceptionRegex: ')', + }); + + expect(mutationResolver).toHaveBeenCalledWith({ + input: { genericDuplicateExceptionRegex: ')', namespacePath: 'foo_group_path' }, + }); + }); + }); + + describe('settings update', () => { + describe('success state', () => { + it('emits a success event', async () => { + mountComponent(); + + fillApolloCache(); + emitMavenSettingsUpdate(); + + await waitForPromises(); + + expect(wrapper.emitted('success')).toEqual([[]]); + }); + + it('has an optimistic response', () => { + const mavenDuplicateExceptionRegex = 'latest[main]something'; + mountComponent(); + + fillApolloCache(); + + expect(findMavenDuplicatedSettings().props('duplicateExceptionRegex')).toBe(''); + + emitMavenSettingsUpdate({ mavenDuplicateExceptionRegex }); + + expect(updateGroupPackagesSettingsOptimisticResponse).toHaveBeenCalledWith({ + ...packageSettings(), + mavenDuplicateExceptionRegex, + }); + }); + }); + + describe('errors', () => { + it('mutation payload with root level errors', async () => { + // note this is a complex test that covers all the path around errors that are shown in the form + // it's one single it case, due to the expensive preparation and execution + const mutationResolver = jest.fn().mockResolvedValue(groupPackageSettingsMutationErrorMock); + mountComponent({ mutationResolver }); + + fillApolloCache(); + + emitMavenSettingsUpdate(); + + await waitForPromises(); + + // errors are bound to the component + expect(findMavenDuplicatedSettings().props('duplicateExceptionRegexError')).toBe( + groupPackageSettingsMutationErrorMock.errors[0].extensions.problems[0].message, + ); + + // general error message is shown + + expect(wrapper.emitted('error')).toEqual([[]]); + + emitMavenSettingsUpdate(); + + await wrapper.vm.$nextTick(); + + // errors are reset on mutation call + expect(findMavenDuplicatedSettings().props('duplicateExceptionRegexError')).toBe(''); + }); + + it.each` + type | mutationResolver + ${'local'} | ${jest.fn().mockResolvedValue(groupPackageSettingsMutationMock({ errors: ['foo'] }))} + ${'network'} | ${jest.fn().mockRejectedValue()} + `('mutation payload with $type error', async ({ mutationResolver }) => { + mountComponent({ mutationResolver }); + + fillApolloCache(); + emitMavenSettingsUpdate(); + + await waitForPromises(); + + expect(wrapper.emitted('error')).toEqual([[]]); + }); + }); + }); +}); |