Commit 948e03df authored by Andrew Fontaine's avatar Andrew Fontaine

Merge branch 'cngo-migrate-project-settings-to-use-gl-toggle' into 'master'

Migrate project settings to use GlToggle

See merge request gitlab-org/gitlab!52729
parents fd226bfa 348f987b
<script>
import { GlIcon } from '@gitlab/ui';
import projectFeatureToggle from '~/vue_shared/components/toggle_button.vue';
import { GlIcon, GlToggle } from '@gitlab/ui';
import { featureAccessLevelNone } from '../constants';
export default {
components: {
GlIcon,
projectFeatureToggle,
GlToggle,
},
model: {
prop: 'value',
......@@ -78,11 +77,11 @@ export default {
class="project-feature-controls gl-display-flex gl-align-items-center gl-my-3 gl-mx-0"
>
<input v-if="name" :name="name" :value="value" type="hidden" />
<project-feature-toggle
<gl-toggle
v-if="showToggle"
class="gl-flex-grow-0 gl-mr-3"
class="gl-mr-3"
:value="featureEnabled"
:disabled-input="disabledInput"
:disabled="disabledInput"
@change="toggleFeature"
/>
<div class="select-wrapper gl-flex-fill-1">
......
<script>
import { GlIcon, GlSprintf, GlLink, GlFormCheckbox } from '@gitlab/ui';
import { GlIcon, GlSprintf, GlLink, GlFormCheckbox, GlToggle } from '@gitlab/ui';
import settingsMixin from 'ee_else_ce/pages/projects/shared/permissions/mixins/settings_pannel_mixin';
import { s__ } from '~/locale';
import projectFeatureToggle from '~/vue_shared/components/toggle_button.vue';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import {
visibilityOptions,
......@@ -22,12 +21,12 @@ const PAGE_FEATURE_ACCESS_LEVEL = s__('ProjectSettings|Everyone');
export default {
components: {
projectFeatureSetting,
projectFeatureToggle,
projectSettingRow,
GlIcon,
GlSprintf,
GlLink,
GlFormCheckbox,
GlToggle,
},
mixins: [settingsMixin, glFeatureFlagsMixin()],
......@@ -483,9 +482,10 @@ export default {
)
}}
</div>
<project-feature-toggle
<gl-toggle
v-model="containerRegistryEnabled"
:disabled-input="!repositoryEnabled"
class="gl-my-2"
:disabled="!repositoryEnabled"
name="project[container_registry_enabled]"
/>
</project-setting-row>
......@@ -498,9 +498,10 @@ export default {
s__('ProjectSettings|Manages large files such as audio, video, and graphics files.')
"
>
<project-feature-toggle
<gl-toggle
v-model="lfsEnabled"
:disabled-input="!repositoryEnabled"
class="gl-my-2"
:disabled="!repositoryEnabled"
name="project[lfs_enabled]"
/>
<p v-if="!lfsEnabled && lfsObjectsExist">
......@@ -530,9 +531,10 @@ export default {
s__('ProjectSettings|Every project can have its own space to store its packages.')
"
>
<project-feature-toggle
<gl-toggle
v-model="packagesEnabled"
:disabled-input="!repositoryEnabled"
class="gl-my-2"
:disabled="!repositoryEnabled"
name="project[packages_enabled]"
/>
</project-setting-row>
......
---
title: Migrate project settings to use GlToggle
merge_request: 52729
author:
type: changed
......@@ -22,7 +22,7 @@ RSpec.describe 'Project settings > Issues', :js do
expect(page).to have_content('Set a default description template to be used for new issues.')
within('.sharing-permissions-form') do
find('.project-feature-controls[data-for="project[project_feature_attributes][issues_access_level]"] .project-feature-toggle').click
find('.project-feature-controls[data-for="project[project_feature_attributes][issues_access_level]"] .gl-toggle').click
click_on('Save changes')
end
......@@ -41,7 +41,7 @@ RSpec.describe 'Project settings > Issues', :js do
expect(page).not_to have_content('Set a default description template to be used for new issues.')
within('.sharing-permissions-form') do
find('.project-feature-controls[data-for="project[project_feature_attributes][issues_access_level]"] .project-feature-toggle').click
find('.project-feature-controls[data-for="project[project_feature_attributes][issues_access_level]"] .gl-toggle').click
click_on('Save changes')
end
......
......@@ -187,7 +187,7 @@ RSpec.describe 'Edit Project Settings' do
click_button "Save changes"
end
expect(find(".sharing-permissions")).to have_selector(".project-feature-toggle.is-disabled", count: 4)
expect(find(".sharing-permissions")).to have_selector(".gl-toggle.is-disabled", minimum: 4)
end
it "shows empty features project homepage" do
......@@ -282,10 +282,10 @@ RSpec.describe 'Edit Project Settings' do
end
def toggle_feature_off(feature_name)
find(".project-feature-controls[data-for=\"#{feature_name}\"] .project-feature-toggle.is-checked").click
find(".project-feature-controls[data-for=\"#{feature_name}\"] .gl-toggle.is-checked").click
end
def toggle_feature_on(feature_name)
find(".project-feature-controls[data-for=\"#{feature_name}\"] .project-feature-toggle:not(.is-checked)").click
find(".project-feature-controls[data-for=\"#{feature_name}\"] .gl-toggle:not(.is-checked)").click
end
end
......@@ -39,7 +39,7 @@ RSpec.describe 'Projects settings' do
visit edit_project_path(project)
forking_enabled_input = find('input[name="project[project_feature_attributes][forking_access_level]"]', visible: :hidden)
forking_enabled_button = find('input[name="project[project_feature_attributes][forking_access_level]"] + label > button')
forking_enabled_button = find('[data-for="project[project_feature_attributes][forking_access_level]"] .gl-toggle')
expect(forking_enabled_input.value).to eq('20')
......
......@@ -51,7 +51,7 @@ RSpec.describe 'Projects > Settings > User manages merge request settings' do
expect(page).to have_content 'All discussions must be resolved'
within('.sharing-permissions-form') do
find('.project-feature-controls[data-for="project[project_feature_attributes][merge_requests_access_level]"] .project-feature-toggle').click
find('.project-feature-controls[data-for="project[project_feature_attributes][merge_requests_access_level]"] .gl-toggle').click
find('input[value="Save changes"]').send_keys(:return)
end
......@@ -71,7 +71,7 @@ RSpec.describe 'Projects > Settings > User manages merge request settings' do
expect(page).to have_content 'All discussions must be resolved'
within('.sharing-permissions-form') do
find('.project-feature-controls[data-for="project[project_feature_attributes][builds_access_level]"] .project-feature-toggle').click
find('.project-feature-controls[data-for="project[project_feature_attributes][builds_access_level]"] .gl-toggle').click
find('input[value="Save changes"]').send_keys(:return)
end
......@@ -92,7 +92,7 @@ RSpec.describe 'Projects > Settings > User manages merge request settings' do
expect(page).not_to have_content 'All discussions must be resolved'
within('.sharing-permissions-form') do
find('.project-feature-controls[data-for="project[project_feature_attributes][merge_requests_access_level]"] .project-feature-toggle').click
find('.project-feature-controls[data-for="project[project_feature_attributes][merge_requests_access_level]"] .gl-toggle').click
find('input[value="Save changes"]').send_keys(:return)
end
......
......@@ -30,7 +30,7 @@ RSpec.describe 'Projects > Settings > Visibility settings', :js do
context 'merge requests select' do
it 'hides merge requests section' do
find('.project-feature-controls[data-for="project[project_feature_attributes][merge_requests_access_level]"] .project-feature-toggle').click
find('.project-feature-controls[data-for="project[project_feature_attributes][merge_requests_access_level]"] .gl-toggle').click
expect(page).to have_selector('.merge-requests-feature', visible: false)
end
......@@ -46,7 +46,7 @@ RSpec.describe 'Projects > Settings > Visibility settings', :js do
context 'builds select' do
it 'hides builds select section' do
find('.project-feature-controls[data-for="project[project_feature_attributes][builds_access_level]"] .project-feature-toggle').click
find('.project-feature-controls[data-for="project[project_feature_attributes][builds_access_level]"] .gl-toggle').click
expect(page).to have_selector('.builds-feature', visible: false)
end
......
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';
import { GlToggle } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import ProjectFeatureSetting from '~/pages/projects/shared/permissions/components/project_feature_setting.vue';
describe('Project Feature Settings', () => {
const defaultProps = {
......@@ -19,81 +18,76 @@ describe('Project Feature Settings', () => {
};
let wrapper;
const mountComponent = (customProps) => {
const propsData = { ...defaultProps, ...customProps };
return shallowMount(projectFeatureSetting, { propsData });
};
const findHiddenInput = () => wrapper.find(`input[name=${defaultProps.name}]`);
const findToggle = () => wrapper.findComponent(GlToggle);
beforeEach(() => {
wrapper = mountComponent();
const mountComponent = (customProps = {}) =>
shallowMount(ProjectFeatureSetting, {
propsData: {
...defaultProps,
...customProps,
},
});
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
describe('Hidden name input', () => {
it('should set the hidden name input if the name exists', () => {
expect(wrapper.find(`input[name=${defaultProps.name}]`).attributes().value).toBe('1');
wrapper = mountComponent();
expect(findHiddenInput().attributes('value')).toBe('1');
});
it('should not set the hidden name input if the name does not exist', () => {
wrapper.setProps({ name: null });
wrapper = mountComponent({ name: null });
return wrapper.vm.$nextTick(() => {
expect(wrapper.find(`input[name=${defaultProps.name}]`).exists()).toBe(false);
});
expect(findHiddenInput().exists()).toBe(false);
});
});
describe('Feature toggle', () => {
it('should be hidden if "showToggle" is passed false', async () => {
wrapper.setProps({ showToggle: false });
await wrapper.vm.$nextTick();
it('should be hidden if "showToggle" is passed false', () => {
wrapper = mountComponent({ showToggle: false });
expect(wrapper.find(projectFeatureToggle).element).toBeUndefined();
expect(findToggle().exists()).toBe(false);
});
it('should enable the feature toggle if the value is not 0', () => {
expect(wrapper.find(projectFeatureToggle).props().value).toBe(true);
wrapper = mountComponent();
expect(findToggle().props('value')).toBe(true);
});
it('should enable the feature toggle if the value is less than 0', () => {
wrapper.setProps({ value: -1 });
wrapper = mountComponent({ value: -1 });
return wrapper.vm.$nextTick(() => {
expect(wrapper.find(projectFeatureToggle).props().value).toBe(true);
});
expect(findToggle().props('value')).toBe(true);
});
it('should disable the feature toggle if the value is 0', () => {
wrapper.setProps({ value: 0 });
wrapper = mountComponent({ value: 0 });
return wrapper.vm.$nextTick(() => {
expect(wrapper.find(projectFeatureToggle).props().value).toBe(false);
});
expect(findToggle().props('value')).toBe(false);
});
it('should disable the feature toggle if disabledInput is set', () => {
wrapper.setProps({ disabledInput: true });
wrapper = mountComponent({ disabledInput: true });
return wrapper.vm.$nextTick(() => {
expect(wrapper.find(projectFeatureToggle).props().disabledInput).toBe(true);
});
expect(findToggle().props('disabled')).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 });
wrapper = mountComponent({ propsData: defaultProps });
expect(wrapper.emitted().change).toBeUndefined();
wrapper.find(projectFeatureToggle).find('button').trigger('click');
expect(wrapper.emitted('change')).toBeUndefined();
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.emitted().change.length).toBe(1);
expect(wrapper.emitted().change[0]).toEqual([0]);
});
findToggle().vm.$emit('change', false);
expect(wrapper.emitted('change')).toHaveLength(1);
expect(wrapper.emitted('change')[0]).toEqual([0]);
});
});
......@@ -108,26 +102,23 @@ describe('Project Feature Settings', () => {
`(
'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();
}
});
wrapper = mountComponent({ disabledInput, value, options });
const expected = isDisabled ? 'disabled' : undefined;
expect(wrapper.find('select').attributes('disabled')).toBe(expected);
},
);
it('should emit the change when a new option is selected', () => {
expect(wrapper.emitted().change).toBeUndefined();
wrapper = mountComponent();
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]);
});
expect(wrapper.emitted('change')).toHaveLength(1);
expect(wrapper.emitted('change')[0]).toEqual([2]);
});
});
});
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment