diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-03-10 09:08:10 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-03-10 09:08:10 +0000 |
commit | 82fa8a3d1e8466ef36b58604d20fcc145ea12118 (patch) | |
tree | c5c0286537405c2fa7719ecce3ed0d73d947c555 /spec/frontend/pages | |
parent | 232655bf32cd474d54de357b65ef43d77271117c (diff) | |
download | gitlab-ce-82fa8a3d1e8466ef36b58604d20fcc145ea12118.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend/pages')
3 files changed, 621 insertions, 0 deletions
diff --git a/spec/frontend/pages/projects/shared/permissions/components/project_feature_settings_spec.js b/spec/frontend/pages/projects/shared/permissions/components/project_feature_settings_spec.js new file mode 100644 index 00000000000..8ab5426a005 --- /dev/null +++ b/spec/frontend/pages/projects/shared/permissions/components/project_feature_settings_spec.js @@ -0,0 +1,124 @@ +import { mount, shallowMount } from '@vue/test-utils'; + +import projectFeatureSetting from '~/pages/projects/shared/permissions/components/project_feature_setting.vue'; +import projectFeatureToggle from '~/vue_shared/components/toggle_button.vue'; + +describe('Project Feature Settings', () => { + const defaultProps = { + name: 'Test', + options: [[1, 1], [2, 2], [3, 3], [4, 4], [5, 5]], + value: 1, + disabledInput: false, + }; + let wrapper; + + const mountComponent = customProps => { + const propsData = { ...defaultProps, ...customProps }; + return shallowMount(projectFeatureSetting, { propsData }); + }; + + beforeEach(() => { + wrapper = mountComponent(); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + describe('Hidden name input', () => { + it('should set the hidden name input if the name exists', () => { + expect(wrapper.find({ name: 'Test' }).props().value).toBe(1); + }); + + it('should not set the hidden name input if the name does not exist', () => { + wrapper.setProps({ name: null }); + + return wrapper.vm.$nextTick(() => { + expect(wrapper.find({ name: 'Test' }).exists()).toBe(false); + }); + }); + }); + + describe('Feature toggle', () => { + it('should enable the feature toggle if the value is not 0', () => { + expect(wrapper.find(projectFeatureToggle).props().value).toBe(true); + }); + + it('should enable the feature toggle if the value is less than 0', () => { + wrapper.setProps({ value: -1 }); + + return wrapper.vm.$nextTick(() => { + expect(wrapper.find(projectFeatureToggle).props().value).toBe(true); + }); + }); + + it('should disable the feature toggle if the value is 0', () => { + wrapper.setProps({ value: 0 }); + + return wrapper.vm.$nextTick(() => { + expect(wrapper.find(projectFeatureToggle).props().value).toBe(false); + }); + }); + + it('should disable the feature toggle if disabledInput is set', () => { + wrapper.setProps({ disabledInput: true }); + + return wrapper.vm.$nextTick(() => { + expect(wrapper.find(projectFeatureToggle).props().disabledInput).toBe(true); + }); + }); + + it('should emit a change event when the feature toggle changes', () => { + // Needs to be fully mounted to be able to trigger the click event on the internal button + wrapper = mount(projectFeatureSetting, { propsData: defaultProps }); + + expect(wrapper.emitted().change).toBeUndefined(); + wrapper + .find(projectFeatureToggle) + .find('button') + .trigger('click'); + + return wrapper.vm.$nextTick().then(() => { + expect(wrapper.emitted().change.length).toBe(1); + expect(wrapper.emitted().change[0]).toEqual([0]); + }); + }); + }); + + describe('Project repo select', () => { + it.each` + disabledInput | value | options | isDisabled + ${true} | ${0} | ${[[1, 1]]} | ${true} + ${true} | ${1} | ${[[1, 1], [2, 2], [3, 3]]} | ${true} + ${false} | ${0} | ${[[1, 1], [2, 2], [3, 3]]} | ${true} + ${false} | ${1} | ${[[1, 1]]} | ${true} + ${false} | ${1} | ${[[1, 1], [2, 2], [3, 3]]} | ${false} + `( + 'should set disabled to $isDisabled when disabledInput is $disabledInput, the value is $value and options are $options', + ({ disabledInput, value, options, isDisabled }) => { + wrapper.setProps({ disabledInput, value, options }); + + return wrapper.vm.$nextTick(() => { + if (isDisabled) { + expect(wrapper.find('select').attributes().disabled).toEqual('disabled'); + } else { + expect(wrapper.find('select').attributes().disabled).toBeUndefined(); + } + }); + }, + ); + + it('should emit the change when a new option is selected', () => { + expect(wrapper.emitted().change).toBeUndefined(); + wrapper + .findAll('option') + .at(1) + .trigger('change'); + + return wrapper.vm.$nextTick().then(() => { + expect(wrapper.emitted().change.length).toBe(1); + expect(wrapper.emitted().change[0]).toEqual([2]); + }); + }); + }); +}); diff --git a/spec/frontend/pages/projects/shared/permissions/components/project_setting_row_spec.js b/spec/frontend/pages/projects/shared/permissions/components/project_setting_row_spec.js new file mode 100644 index 00000000000..7cbcbdcdd1f --- /dev/null +++ b/spec/frontend/pages/projects/shared/permissions/components/project_setting_row_spec.js @@ -0,0 +1,63 @@ +import { shallowMount } from '@vue/test-utils'; + +import projectSettingRow from '~/pages/projects/shared/permissions/components/project_setting_row.vue'; + +describe('Project Setting Row', () => { + let wrapper; + + const mountComponent = (customProps = {}) => { + const propsData = { ...customProps }; + return shallowMount(projectSettingRow, { propsData }); + }; + + beforeEach(() => { + wrapper = mountComponent(); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + it('should show the label if it is set', () => { + wrapper.setProps({ label: 'Test label' }); + + return wrapper.vm.$nextTick(() => { + expect(wrapper.find('label').text()).toEqual('Test label'); + }); + }); + + it('should hide the label if it is not set', () => { + expect(wrapper.find('label').exists()).toBe(false); + }); + + it('should show the help icon with the correct help path if it is set', () => { + wrapper.setProps({ label: 'Test label', helpPath: '/123' }); + + return wrapper.vm.$nextTick(() => { + const link = wrapper.find('a'); + + expect(link.exists()).toBe(true); + expect(link.attributes().href).toEqual('/123'); + }); + }); + + it('should hide the help icon if no help path is set', () => { + wrapper.setProps({ label: 'Test label' }); + + return wrapper.vm.$nextTick(() => { + expect(wrapper.find('a').exists()).toBe(false); + }); + }); + + it('should show the help text if it is set', () => { + wrapper.setProps({ helpText: 'Test text' }); + + return wrapper.vm.$nextTick(() => { + expect(wrapper.find('span').text()).toEqual('Test text'); + }); + }); + + it('should hide the help text if it is set', () => { + expect(wrapper.find('span').exists()).toBe(false); + }); +}); 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 new file mode 100644 index 00000000000..c304dfd2048 --- /dev/null +++ b/spec/frontend/pages/projects/shared/permissions/components/settings_panel_spec.js @@ -0,0 +1,434 @@ +import { shallowMount } from '@vue/test-utils'; + +import settingsPanel from '~/pages/projects/shared/permissions/components/settings_panel.vue'; +import { + featureAccessLevel, + visibilityLevelDescriptions, + visibilityOptions, +} from '~/pages/projects/shared/permissions/constants'; + +const defaultProps = { + currentSettings: { + visibilityLevel: 10, + requestAccessEnabled: true, + issuesAccessLevel: 20, + repositoryAccessLevel: 20, + forkingAccessLevel: 20, + mergeRequestsAccessLevel: 20, + buildsAccessLevel: 20, + wikiAccessLevel: 20, + snippetsAccessLevel: 20, + pagesAccessLevel: 10, + containerRegistryEnabled: true, + lfsEnabled: true, + emailsDisabled: false, + packagesEnabled: true, + }, + canDisableEmails: true, + canChangeVisibilityLevel: true, + allowedVisibilityOptions: [0, 10, 20], + visibilityHelpPath: '/help/public_access/public_access', + registryAvailable: false, + registryHelpPath: '/help/user/packages/container_registry/index', + lfsAvailable: true, + lfsHelpPath: '/help/workflow/lfs/manage_large_binaries_with_git_lfs', + pagesAvailable: true, + pagesAccessControlEnabled: false, + pagesAccessControlForced: false, + pagesHelpPath: '/help/user/project/pages/introduction#gitlab-pages-access-control-core', + packagesAvailable: false, + packagesHelpPath: '/help/user/packages/index', +}; + +describe('Settings Panel', () => { + let wrapper; + + const mountComponent = customProps => { + const propsData = { ...defaultProps, ...customProps }; + return shallowMount(settingsPanel, { propsData }); + }; + + const overrideCurrentSettings = (currentSettingsProps, extraProps = {}) => { + return mountComponent({ + ...extraProps, + currentSettings: { + ...defaultProps.currentSettings, + ...currentSettingsProps, + }, + }); + }; + + beforeEach(() => { + wrapper = mountComponent(); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + describe('Project Visibility', () => { + it('should set the project visibility help path', () => { + expect(wrapper.find({ ref: 'project-visibility-settings' }).props().helpPath).toBe( + defaultProps.visibilityHelpPath, + ); + }); + + it('should not disable the visibility level dropdown', () => { + wrapper.setProps({ canChangeVisibilityLevel: true }); + + return wrapper.vm.$nextTick(() => { + expect( + wrapper.find('[name="project[visibility_level]"]').attributes().disabled, + ).toBeUndefined(); + }); + }); + + it('should disable the visibility level dropdown', () => { + wrapper.setProps({ canChangeVisibilityLevel: false }); + + return wrapper.vm.$nextTick(() => { + expect(wrapper.find('[name="project[visibility_level]"]').attributes().disabled).toBe( + 'disabled', + ); + }); + }); + + it.each` + option | allowedOptions | disabled + ${visibilityOptions.PRIVATE} | ${[visibilityOptions.PRIVATE, visibilityOptions.INTERNAL, visibilityOptions.PUBLIC]} | ${false} + ${visibilityOptions.PRIVATE} | ${[visibilityOptions.INTERNAL, visibilityOptions.PUBLIC]} | ${true} + ${visibilityOptions.INTERNAL} | ${[visibilityOptions.PRIVATE, visibilityOptions.INTERNAL, visibilityOptions.PUBLIC]} | ${false} + ${visibilityOptions.INTERNAL} | ${[visibilityOptions.PRIVATE, visibilityOptions.PUBLIC]} | ${true} + ${visibilityOptions.PUBLIC} | ${[visibilityOptions.PRIVATE, visibilityOptions.INTERNAL, visibilityOptions.PUBLIC]} | ${false} + ${visibilityOptions.PUBLIC} | ${[visibilityOptions.PRIVATE, visibilityOptions.INTERNAL]} | ${true} + `( + 'sets disabled to $disabled for the visibility option $option when given $allowedOptions', + ({ option, allowedOptions, disabled }) => { + wrapper.setProps({ allowedVisibilityOptions: allowedOptions }); + + return wrapper.vm.$nextTick(() => { + const attributeValue = wrapper + .find(`[name="project[visibility_level]"] option[value="${option}"]`) + .attributes().disabled; + + if (disabled) { + expect(attributeValue).toBe('disabled'); + } else { + expect(attributeValue).toBeUndefined(); + } + }); + }, + ); + + it('should set the visibility level description based upon the selected visibility level', () => { + wrapper.find('[name="project[visibility_level]"]').setValue(visibilityOptions.INTERNAL); + + expect(wrapper.find({ ref: 'project-visibility-settings' }).text()).toContain( + visibilityLevelDescriptions[visibilityOptions.INTERNAL], + ); + }); + + it('should show the request access checkbox if the visibility level is not private', () => { + wrapper = overrideCurrentSettings({ visibilityLevel: visibilityOptions.INTERNAL }); + + expect(wrapper.find('[name="project[request_access_enabled]"]').exists()).toBe(true); + }); + + it('should not show the request access checkbox if the visibility level is private', () => { + wrapper = overrideCurrentSettings({ visibilityLevel: visibilityOptions.PRIVATE }); + + expect(wrapper.find('[name="project[request_access_enabled]"]').exists()).toBe(false); + }); + }); + + describe('Repository', () => { + it('should set the repository help text when the visibility level is set to private', () => { + wrapper = overrideCurrentSettings({ visibilityLevel: visibilityOptions.PRIVATE }); + + expect(wrapper.find({ ref: 'repository-settings' }).props().helpText).toEqual( + 'View and edit files in this project', + ); + }); + + it('should set the repository help text with a read access warning when the visibility level is set to non-private', () => { + wrapper = overrideCurrentSettings({ visibilityLevel: visibilityOptions.PUBLIC }); + + expect(wrapper.find({ ref: 'repository-settings' }).props().helpText).toEqual( + 'View and edit files in this project. Non-project members will only have read access', + ); + }); + }); + + describe('Merge requests', () => { + it('should enable the merge requests access level input when the repository is enabled', () => { + wrapper = overrideCurrentSettings({ repositoryAccessLevel: featureAccessLevel.EVERYONE }); + + expect( + wrapper + .find('[name="project[project_feature_attributes][merge_requests_access_level]"]') + .props().disabledInput, + ).toEqual(false); + }); + + it('should disable the merge requests access level input when the repository is disabled', () => { + wrapper = overrideCurrentSettings({ repositoryAccessLevel: featureAccessLevel.NOT_ENABLED }); + + expect( + wrapper + .find('[name="project[project_feature_attributes][merge_requests_access_level]"]') + .props().disabledInput, + ).toEqual(true); + }); + }); + + describe('Forks', () => { + it('should enable the forking access level input when the repository is enabled', () => { + wrapper = overrideCurrentSettings({ repositoryAccessLevel: featureAccessLevel.EVERYONE }); + + expect( + wrapper.find('[name="project[project_feature_attributes][forking_access_level]"]').props() + .disabledInput, + ).toEqual(false); + }); + + it('should disable the forking access level input when the repository is disabled', () => { + wrapper = overrideCurrentSettings({ repositoryAccessLevel: featureAccessLevel.NOT_ENABLED }); + + expect( + wrapper.find('[name="project[project_feature_attributes][forking_access_level]"]').props() + .disabledInput, + ).toEqual(true); + }); + }); + + describe('Pipelines', () => { + it('should enable the builds access level input when the repository is enabled', () => { + wrapper = overrideCurrentSettings({ repositoryAccessLevel: featureAccessLevel.EVERYONE }); + + expect( + wrapper.find('[name="project[project_feature_attributes][builds_access_level]"]').props() + .disabledInput, + ).toEqual(false); + }); + + it('should disable the builds access level input when the repository is disabled', () => { + wrapper = overrideCurrentSettings({ repositoryAccessLevel: featureAccessLevel.NOT_ENABLED }); + + expect( + wrapper.find('[name="project[project_feature_attributes][builds_access_level]"]').props() + .disabledInput, + ).toEqual(true); + }); + }); + + describe('Container registry', () => { + it('should show the container registry settings if the registry is available', () => { + wrapper.setProps({ registryAvailable: true }); + + return wrapper.vm.$nextTick(() => { + expect(wrapper.find({ ref: 'container-registry-settings' }).exists()).toBe(true); + }); + }); + + it('should hide the container registry settings if the registry is not available', () => { + wrapper.setProps({ registryAvailable: false }); + + return wrapper.vm.$nextTick(() => { + expect(wrapper.find({ ref: 'container-registry-settings' }).exists()).toBe(false); + }); + }); + + it('should set the container registry settings help path', () => { + wrapper.setProps({ registryAvailable: true }); + + return wrapper.vm.$nextTick(() => { + expect(wrapper.find({ ref: 'container-registry-settings' }).props().helpPath).toBe( + defaultProps.registryHelpPath, + ); + }); + }); + + it('should show the container registry public note if the visibility level is public and the registry is available', () => { + wrapper = overrideCurrentSettings( + { visibilityLevel: visibilityOptions.PUBLIC }, + { registryAvailable: true }, + ); + + expect(wrapper.find({ ref: 'container-registry-settings' }).text()).toContain( + 'Note: the container registry is always visible when a project is public', + ); + }); + + it('should hide the container registry public note if the visibility level is private and the registry is available', () => { + wrapper = overrideCurrentSettings( + { visibilityLevel: visibilityOptions.PRIVATE }, + { registryAvailable: true }, + ); + + expect(wrapper.find({ ref: 'container-registry-settings' }).text()).not.toContain( + 'Note: the container registry is always visible when a project is public', + ); + }); + + it('should enable the container registry input when the repository is enabled', () => { + wrapper = overrideCurrentSettings( + { repositoryAccessLevel: featureAccessLevel.EVERYONE }, + { registryAvailable: true }, + ); + + expect( + wrapper.find('[name="project[container_registry_enabled]"]').props().disabledInput, + ).toEqual(false); + }); + + it('should disable the container registry input when the repository is disabled', () => { + wrapper = overrideCurrentSettings( + { repositoryAccessLevel: featureAccessLevel.NOT_ENABLED }, + { registryAvailable: true }, + ); + + expect( + wrapper.find('[name="project[container_registry_enabled]"]').props().disabledInput, + ).toEqual(true); + }); + }); + + describe('Git Large File Storage', () => { + it('should show the LFS settings if LFS is available', () => { + wrapper.setProps({ lfsAvailable: true }); + + return wrapper.vm.$nextTick(() => { + expect(wrapper.find({ ref: 'git-lfs-settings' }).exists()).toEqual(true); + }); + }); + + it('should hide the LFS settings if LFS is not available', () => { + wrapper.setProps({ lfsAvailable: false }); + + return wrapper.vm.$nextTick(() => { + expect(wrapper.find({ ref: 'git-lfs-settings' }).exists()).toEqual(false); + }); + }); + + it('should set the LFS settings help path', () => { + expect(wrapper.find({ ref: 'git-lfs-settings' }).props().helpPath).toBe( + defaultProps.lfsHelpPath, + ); + }); + + it('should enable the LFS input when the repository is enabled', () => { + wrapper = overrideCurrentSettings( + { repositoryAccessLevel: featureAccessLevel.EVERYONE }, + { lfsAvailable: true }, + ); + + expect(wrapper.find('[name="project[lfs_enabled]"]').props().disabledInput).toEqual(false); + }); + + it('should disable the LFS input when the repository is disabled', () => { + wrapper = overrideCurrentSettings( + { repositoryAccessLevel: featureAccessLevel.NOT_ENABLED }, + { lfsAvailable: true }, + ); + + expect(wrapper.find('[name="project[lfs_enabled]"]').props().disabledInput).toEqual(true); + }); + }); + + describe('Packages', () => { + it('should show the packages settings if packages are available', () => { + wrapper.setProps({ packagesAvailable: true }); + + return wrapper.vm.$nextTick(() => { + expect(wrapper.find({ ref: 'package-settings' }).exists()).toEqual(true); + }); + }); + + it('should hide the packages settings if packages are not available', () => { + wrapper.setProps({ packagesAvailable: false }); + + return wrapper.vm.$nextTick(() => { + expect(wrapper.find({ ref: 'package-settings' }).exists()).toEqual(false); + }); + }); + + it('should set the package settings help path', () => { + wrapper.setProps({ packagesAvailable: true }); + + return wrapper.vm.$nextTick(() => { + expect(wrapper.find({ ref: 'package-settings' }).props().helpPath).toBe( + defaultProps.packagesHelpPath, + ); + }); + }); + + it('should enable the packages input when the repository is enabled', () => { + wrapper = overrideCurrentSettings( + { repositoryAccessLevel: featureAccessLevel.EVERYONE }, + { packagesAvailable: true }, + ); + + expect(wrapper.find('[name="project[packages_enabled]"]').props().disabledInput).toEqual( + false, + ); + }); + + it('should disable the packages input when the repository is disabled', () => { + wrapper = overrideCurrentSettings( + { repositoryAccessLevel: featureAccessLevel.NOT_ENABLED }, + { packagesAvailable: true }, + ); + + expect(wrapper.find('[name="project[packages_enabled]"]').props().disabledInput).toEqual( + true, + ); + }); + }); + + describe('Pages', () => { + it.each` + pagesAvailable | pagesAccessControlEnabled | visibility + ${true} | ${true} | ${'show'} + ${true} | ${false} | ${'hide'} + ${false} | ${true} | ${'hide'} + ${false} | ${false} | ${'hide'} + `( + 'should $visibility the page settings if pagesAvailable is $pagesAvailable and pagesAccessControlEnabled is $pagesAccessControlEnabled', + ({ pagesAvailable, pagesAccessControlEnabled, visibility }) => { + wrapper.setProps({ pagesAvailable, pagesAccessControlEnabled }); + + return wrapper.vm.$nextTick(() => { + expect(wrapper.find({ ref: 'pages-settings' }).exists()).toBe(visibility === 'show'); + }); + }, + ); + + it('should set the pages settings help path', () => { + wrapper.setProps({ pagesAvailable: true, pagesAccessControlEnabled: true }); + + return wrapper.vm.$nextTick(() => { + expect(wrapper.find({ ref: 'pages-settings' }).props().helpPath).toBe( + defaultProps.pagesHelpPath, + ); + }); + }); + }); + + describe('Email notifications', () => { + it('should show the disable email notifications input if emails an be disabled', () => { + wrapper.setProps({ canDisableEmails: true }); + + return wrapper.vm.$nextTick(() => { + expect(wrapper.find({ ref: 'email-settings' }).exists()).toBe(true); + }); + }); + + it('should hide the disable email notifications input if emails cannot be disabled', () => { + wrapper.setProps({ canDisableEmails: false }); + + return wrapper.vm.$nextTick(() => { + expect(wrapper.find({ ref: 'email-settings' }).exists()).toBe(false); + }); + }); + }); +}); |