+
{{ s__('FeatureFlags|Status') }}
-
-
+
diff --git a/changelogs/unreleased/cngo-migrate-feature-flag-toggles-to-gl-toggle.yml b/changelogs/unreleased/cngo-migrate-feature-flag-toggles-to-gl-toggle.yml
new file mode 100644
index 00000000000..c60aa1cdbef
--- /dev/null
+++ b/changelogs/unreleased/cngo-migrate-feature-flag-toggles-to-gl-toggle.yml
@@ -0,0 +1,5 @@
+---
+title: Migrate feature flags page toggles to GlToggle
+merge_request: 52728
+author:
+type: changed
diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md
index 3111bd5b763..b7d5f64c0a6 100644
--- a/doc/ci/yaml/README.md
+++ b/doc/ci/yaml/README.md
@@ -1393,7 +1393,9 @@ job:
- Dockerfile
```
-You can also use glob patterns to match multiple files in any directory in the repository:
+Paths are relative to the project directory (`$CI_PROJECT_DIR`) and can't directly link outside it.
+
+You can use glob patterns to match multiple files in any directory in the repository:
```yaml
job:
@@ -1403,6 +1405,9 @@ job:
- spec/**.rb
```
+Glob patterns are interpreted with Ruby [File.fnmatch](https://docs.ruby-lang.org/en/2.7.0/File.html#method-c-fnmatch)
+with the flags `File::FNM_PATHNAME | File::FNM_DOTMATCH | File::FNM_EXTGLOB`.
+
For performance reasons, using `exists` with patterns is limited to 10,000
checks. After the 10,000th check, rules with patterned globs always match.
diff --git a/scripts/trigger-build b/scripts/trigger-build
index aeea25f9ad8..84a970860b0 100755
--- a/scripts/trigger-build
+++ b/scripts/trigger-build
@@ -231,7 +231,7 @@ module Trigger
# Remove a remote branch in gitlab-docs.
#
def cleanup!
- Gitlab.delete_branch(downstream_project_path, ref)
+ gitlab_client(:downstream).delete_branch(downstream_project_path, ref)
puts "=> Remote branch '#{downstream_project_path}' deleted"
end
@@ -275,7 +275,7 @@ module Trigger
end
def create_remote_branch!
- Gitlab.create_branch(downstream_project_path, ref, 'master')
+ gitlab_client(:downstream).create_branch(downstream_project_path, ref, 'master')
puts "=> Remote branch '#{ref}' created"
rescue Gitlab::Error::BadRequest
puts "=> Remote branch '#{ref}' already exists!"
@@ -288,7 +288,7 @@ module Trigger
loop do
sleep 1
puts "=> Waiting for pipeline to start..."
- pipelines = Gitlab.pipelines(downstream_project_path, { ref: ref })
+ pipelines = gitlab_client(:downstream).pipelines(downstream_project_path, { ref: ref })
break if pipelines.any?
end
@@ -296,7 +296,7 @@ module Trigger
pipeline_id = pipelines.first.id
# Cancel the pipeline
- Gitlab.cancel_pipeline(downstream_project_path, pipeline_id)
+ gitlab_client(:downstream).cancel_pipeline(downstream_project_path, pipeline_id)
end
def display_success_message
diff --git a/spec/frontend/feature_flags/components/form_spec.js b/spec/frontend/feature_flags/components/form_spec.js
index 3a057aedde9..6c9ccba5181 100644
--- a/spec/frontend/feature_flags/components/form_spec.js
+++ b/spec/frontend/feature_flags/components/form_spec.js
@@ -1,6 +1,7 @@
import { uniqueId } from 'lodash';
import { shallowMount } from '@vue/test-utils';
-import { GlFormTextarea, GlFormCheckbox, GlButton } from '@gitlab/ui';
+import { GlFormTextarea, GlFormCheckbox, GlButton, GlToggle } from '@gitlab/ui';
+import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import Api from '~/api';
import Form from '~/feature_flags/components/form.vue';
import EnvironmentsDropdown from '~/feature_flags/components/environments_dropdown.vue';
@@ -14,7 +15,6 @@ import {
NEW_VERSION_FLAG,
} from '~/feature_flags/constants';
import RelatedIssuesRoot from '~/related_issues/components/related_issues_root.vue';
-import ToggleButton from '~/vue_shared/components/toggle_button.vue';
import { featureFlag, userList, allUsersStrategy } from '../mock_data';
jest.mock('~/api.js');
@@ -35,14 +35,19 @@ describe('feature flag form', () => {
},
};
+ const findAddNewScopeRow = () => wrapper.findByTestId('add-new-scope');
+ const findGlToggle = () => wrapper.find(GlToggle);
+
const factory = (props = {}, provide = {}) => {
- wrapper = shallowMount(Form, {
- propsData: { ...requiredProps, ...props },
- provide: {
- ...requiredInjections,
- ...provide,
- },
- });
+ wrapper = extendedWrapper(
+ shallowMount(Form, {
+ propsData: { ...requiredProps, ...props },
+ provide: {
+ ...requiredInjections,
+ ...provide,
+ },
+ }),
+ );
};
beforeEach(() => {
@@ -102,13 +107,13 @@ describe('feature flag form', () => {
});
it('should render scopes table with a new row ', () => {
- expect(wrapper.find('.js-add-new-scope').exists()).toBe(true);
+ expect(findAddNewScopeRow().exists()).toBe(true);
});
describe('status toggle', () => {
describe('without filled text input', () => {
it('should add a new scope with the text value empty and the status', () => {
- wrapper.find(ToggleButton).vm.$emit('change', true);
+ findGlToggle().vm.$emit('change', true);
expect(wrapper.vm.formScopes).toHaveLength(1);
expect(wrapper.vm.formScopes[0].active).toEqual(true);
@@ -121,7 +126,7 @@ describe('feature flag form', () => {
it('should be disabled if the feature flag is not active', (done) => {
wrapper.setProps({ active: false });
wrapper.vm.$nextTick(() => {
- expect(wrapper.find(ToggleButton).props('disabledInput')).toBe(true);
+ expect(findGlToggle().props('disabled')).toBe(true);
done();
});
});
@@ -166,11 +171,11 @@ describe('feature flag form', () => {
describe('scopes', () => {
it('should be possible to remove a scope', () => {
- expect(wrapper.find('.js-feature-flag-delete').exists()).toEqual(true);
+ expect(wrapper.findByTestId('feature-flag-delete').exists()).toEqual(true);
});
it('renders empty row to add a new scope', () => {
- expect(wrapper.find('.js-add-new-scope').exists()).toEqual(true);
+ expect(findAddNewScopeRow().exists()).toEqual(true);
});
it('renders the user id checkbox', () => {
@@ -186,7 +191,7 @@ describe('feature flag form', () => {
describe('update scope', () => {
describe('on click on toggle', () => {
it('should update the scope', () => {
- wrapper.find(ToggleButton).vm.$emit('change', false);
+ findGlToggle().vm.$emit('change', false);
expect(wrapper.vm.formScopes[0].active).toBe(false);
});
@@ -195,7 +200,7 @@ describe('feature flag form', () => {
wrapper.setProps({ active: false });
wrapper.vm.$nextTick(() => {
- expect(wrapper.find(ToggleButton).props('disabledInput')).toBe(true);
+ expect(findGlToggle().props('disabled')).toBe(true);
done();
});
});
@@ -294,7 +299,7 @@ describe('feature flag form', () => {
const row = wrapper.findAll('.gl-responsive-table-row').at(2);
expect(row.find(EnvironmentsDropdown).vm.disabled).toBe(true);
- expect(row.find(ToggleButton).vm.disabledInput).toBe(true);
+ expect(row.find(GlToggle).props('disabled')).toBe(true);
expect(row.find('.js-delete-scope').exists()).toBe(false);
});
});
@@ -347,10 +352,10 @@ describe('feature flag form', () => {
return wrapper.vm.$nextTick();
})
.then(() => {
- wrapper.find('.js-add-new-scope').find(ToggleButton).vm.$emit('change', true);
+ findAddNewScopeRow().find(GlToggle).vm.$emit('change', true);
})
.then(() => {
- wrapper.find(ToggleButton).vm.$emit('change', true);
+ findGlToggle().vm.$emit('change', true);
return wrapper.vm.$nextTick();
})