diff --git a/app/controllers/projects/settings/branch_rules_controller.rb b/app/controllers/projects/settings/branch_rules_controller.rb index ec8877b0ad81acd10c13126fa648addc9a01dff9..ab537ea42b73d28e6472f2ffe9e6f08edfbf8c94 100644 --- a/app/controllers/projects/settings/branch_rules_controller.rb +++ b/app/controllers/projects/settings/branch_rules_controller.rb @@ -5,7 +5,6 @@ module Settings class BranchRulesController < Projects::ApplicationController before_action :authorize_admin_project! before_action do - push_frontend_feature_flag(:approval_rules_drawer, @project) push_frontend_feature_flag(:edit_branch_rules, @project) end diff --git a/app/controllers/projects/settings/merge_requests_controller.rb b/app/controllers/projects/settings/merge_requests_controller.rb index 8b3700df7d05f0abd4de51a5041084181b18c89b..2724e2d9eecede70e1037452e1c99b4b1e180e25 100644 --- a/app/controllers/projects/settings/merge_requests_controller.rb +++ b/app/controllers/projects/settings/merge_requests_controller.rb @@ -11,10 +11,6 @@ class MergeRequestsController < Projects::ApplicationController feature_category :code_review_workflow - before_action do - push_frontend_feature_flag(:approval_rules_drawer, @project) - end - def update result = ::Projects::UpdateService.new(@project, current_user, project_params).execute diff --git a/config/feature_flags/beta/approval_rules_drawer.yml b/config/feature_flags/beta/approval_rules_drawer.yml deleted file mode 100644 index dead46d69dc0b96b9de6540b6dc3964aedfe17a8..0000000000000000000000000000000000000000 --- a/config/feature_flags/beta/approval_rules_drawer.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -name: approval_rules_drawer -feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/439397 -introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/146502 -rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/444628 -milestone: '16.10' -group: group::source code -type: beta -default_enabled: true diff --git a/doc/user/project/merge_requests/approvals/rules.md b/doc/user/project/merge_requests/approvals/rules.md index 33518b71fd6fd7f08a26247f68f983783d540b61..11c4026790f16abbf0b2aec92810dab2134d8578 100644 --- a/doc/user/project/merge_requests/approvals/rules.md +++ b/doc/user/project/merge_requests/approvals/rules.md @@ -49,7 +49,7 @@ To add a merge request approval rule: 1. Select **Settings > Merge requests**. 1. In the **Merge request approvals** section, in the **Approval rules** section, select **Add approval rule**. -1. Complete the fields: +1. On the right sidebar, complete the fields: - In **Approvals required**, a value of `0` makes [the rule optional](#configure-optional-approval-rules), and any number greater than `0` creates a required rule. @@ -57,7 +57,7 @@ To add a merge request approval rule: - From **Add approvers**, select users or groups that are [eligible to approve](#eligible-approvers). GitLab suggests approvers based on previous authors of the files changed by the merge request. -1. Select **Add approval rule**. You can add [multiple approval rules](#multiple-approval-rules). +1. Select **Save changes**. You can add [multiple approval rules](#multiple-approval-rules). Your configuration for approval rule overrides determines if the new rule is applied to existing merge requests: @@ -83,14 +83,14 @@ To edit a merge request approval rule: 1. On the left sidebar, select **Search or go to** and find your project. 1. Select **Settings > Merge requests**. 1. In the **Merge request approvals** section, in the **Approval rules** section, next to the rule you want to edit, select **Edit**. -1. Edit the fields: +1. On the right sidebar, edit the fields: - In **Approvals required**, a value of `0` makes [the rule optional](#configure-optional-approval-rules), and any number greater than `0` creates a required rule. Maximum number of required approvals is `100`. - To remove users or groups, identify the group or user to remove, and select **Remove** (**{remove}**). -1. Select **Update approval rule**. +1. Select **Save changes**. ## Delete an approval rule @@ -213,8 +213,8 @@ To enable approval permissions for these users without granting them push access 1. In the **Merge request approvals** section, in the **Approval rules** section: - For a new rule, select **Add approval rule** and target the protected branch. - For an existing rule, select **Edit** and target the protected branch. -1. In **Add approvers**, select the group you created. -1. Select **Add approval rule** or **Update approval rule**. +1. On the right sidebar, in **Add approvers**, select the group you created. +1. Select **Save changes**. ## Edit or override merge request approval rules @@ -302,21 +302,6 @@ on the merge request to indicate which steps are needed to proceed. These policies are both created and edited in the [security policy editor](../../../application_security/policies/index.md#policy-editor). -## Edit approval rules in a drawer - -DETAILS: -**Status:** Beta - -> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/439397) in GitLab 16.11 [with a flag](../../../../administration/feature_flags.md) named `approval_rules_drawer`. Enabled by default. This feature is in [beta](../../../../policy/experiment-beta-support.md). - -FLAG: -On self-managed GitLab, by default this feature is available. -To hide the feature, an administrator can [disable the feature flag](../../../../administration/feature_flags.md) named `approval_rules_drawer`. -On GitLab.com and GitLab Dedicated, this feature is available. - -When this feature is enabled, the dialog to [add](#add-an-approval-rule) or -[edit an approval](#edit-an-approval-rule) rule opens in a drawer on the right. - ## Troubleshooting ### Approval rule name can't be blank diff --git a/ee/app/assets/javascripts/approvals/components/approval_rules_app.vue b/ee/app/assets/javascripts/approvals/components/approval_rules_app.vue index 2a780107edc09ac12e7110e070eaf17ae3f81af0..277a6dbd90e93920cae0ee48b1dcc34c192682cf 100644 --- a/ee/app/assets/javascripts/approvals/components/approval_rules_app.vue +++ b/ee/app/assets/javascripts/approvals/components/approval_rules_app.vue @@ -6,14 +6,12 @@ import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import { __ } from '~/locale'; import showToast from '~/vue_shared/plugins/global_toast'; import DrawerRuleCreate from './rule_drawer/create_rule.vue'; -import ModalRuleCreate from './rule_modal/create_rule.vue'; import ModalRuleRemove from './rule_modal/remove_rule.vue'; export default { name: 'ApprovalRulesApp', components: { DrawerRuleCreate, - ModalRuleCreate, ModalRuleRemove, GlButton, GlCard, @@ -43,9 +41,6 @@ export default { hasLoaded: (state) => state.approvals.hasLoaded, targetBranch: (state) => state.approvals.targetBranch, }), - createModalId() { - return `${this.settings.prefix}-approvals-create-modal`; - }, removeModalId() { return `${this.settings.prefix}-approvals-remove-modal`; }, @@ -63,7 +58,6 @@ export default { }, methods: { ...mapActions(['fetchRules', 'undoRulesChange']), - ...mapActions({ openCreateModal: 'createModal/open' }), ...mapActions({ openCreateDrawer: 'openCreateDrawer' }), ...mapActions({ closeCreateDrawer: 'closeCreateDrawer' }), resetToProjectDefaults() { @@ -82,11 +76,7 @@ export default { }); }, handleAddRule() { - if (this.glFeatures.approvalRulesDrawer) { - this.openCreateDrawer(); - return; - } - this.openCreateModal(null); + this.openCreateDrawer(); }, }, }; @@ -145,20 +135,12 @@ export default { <slot name="footer"></slot> </template> <drawer-rule-create - v-if="glFeatures.approvalRulesDrawer" :is-mr-edit="isMrEdit" :is-branch-rules-edit="isBranchRulesEdit" :is-open="drawerOpen" v-on="$listeners" @close="closeCreateDrawer" /> - <modal-rule-create - v-else - :modal-id="createModalId" - :is-mr-edit="isMrEdit" - :is-branch-rules-edit="isBranchRulesEdit" - v-on="$listeners" - /> <modal-rule-remove :modal-id="removeModalId" /> </gl-card> </template> diff --git a/ee/app/assets/javascripts/approvals/components/rule_modal/create_rule.vue b/ee/app/assets/javascripts/approvals/components/rule_modal/create_rule.vue deleted file mode 100644 index 79e9d96b1c4882878720e472db50080b9c0bd616..0000000000000000000000000000000000000000 --- a/ee/app/assets/javascripts/approvals/components/rule_modal/create_rule.vue +++ /dev/null @@ -1,78 +0,0 @@ -<script> -// eslint-disable-next-line no-restricted-imports -import { mapState } from 'vuex'; -import { __ } from '~/locale'; -import GlModalVuex from '~/vue_shared/components/gl_modal_vuex.vue'; -import RuleForm from '../rules/rule_form.vue'; - -export default { - components: { - GlModalVuex, - RuleForm, - }, - props: { - modalId: { - type: String, - required: true, - }, - isMrEdit: { - type: Boolean, - default: true, - required: false, - }, - isBranchRulesEdit: { - type: Boolean, - default: false, - required: false, - }, - }, - computed: { - ...mapState('createModal', { - rule: 'data', - }), - title() { - return !this.rule || this.defaultRuleName - ? __('Add approval rule') - : __('Update approval rule'); - }, - defaultRuleName() { - return this.rule?.defaultRuleName; - }, - primaryActionProps() { - return { - text: this.title, - attributes: { variant: 'confirm' }, - }; - }, - }, - methods: { - submit() { - this.$refs.form.submit(); - }, - }, - cancelActionProps: { - text: __('Cancel'), - }, -}; -</script> - -<template> - <gl-modal-vuex - modal-module="createModal" - :modal-id="modalId" - :title="title" - :action-primary="primaryActionProps" - :action-cancel="$options.cancelActionProps" - size="sm" - @ok.prevent="submit" - > - <rule-form - ref="form" - :init-rule="rule" - :is-mr-edit="isMrEdit" - :is-branch-rules-edit="isBranchRulesEdit" - :default-rule-name="defaultRuleName" - v-on="$listeners" - /> - </gl-modal-vuex> -</template> diff --git a/ee/app/assets/javascripts/approvals/components/rules/empty_rule.vue b/ee/app/assets/javascripts/approvals/components/rules/empty_rule.vue index 612007805b6081a2efaaf70ad750ec5d297a3524..6044c7e08b1c5c925080ea7d242280a67b925533 100644 --- a/ee/app/assets/javascripts/approvals/components/rules/empty_rule.vue +++ b/ee/app/assets/javascripts/approvals/components/rules/empty_rule.vue @@ -59,14 +59,9 @@ export default { }, }, methods: { - ...mapActions({ openCreateModal: 'createModal/open' }), ...mapActions({ openCreateDrawer: 'openCreateDrawer' }), handleAddRule() { - if (this.glFeatures.approvalRulesDrawer) { - this.openCreateDrawer(); - return; - } - this.openCreateModal(null); + this.openCreateDrawer(); }, }, }; diff --git a/ee/app/assets/javascripts/approvals/components/security_configuration/unconfigured_security_rules.vue b/ee/app/assets/javascripts/approvals/components/security_configuration/unconfigured_security_rules.vue index ecfe003fe295cfd8a2c1c1a089a68b16a83c9138..6ce38dfb2198b316f4577fad36d14a7e41a96373 100644 --- a/ee/app/assets/javascripts/approvals/components/security_configuration/unconfigured_security_rules.vue +++ b/ee/app/assets/javascripts/approvals/components/security_configuration/unconfigured_security_rules.vue @@ -49,15 +49,10 @@ export default { }, }, methods: { - ...mapActions({ openCreateModal: 'createModal/open' }), ...mapActions({ openCreateDrawer: 'openCreateDrawer' }), handleAddRule(ruleName) { const rule = { defaultRuleName: ruleName }; - if (this.glFeatures.approvalRulesDrawer) { - this.openCreateDrawer(rule); - return; - } - this.openCreateModal(rule); + this.openCreateDrawer(rule); }, hasApprovalRuleDefined(matchRule) { return this.rules.some((rule) => { diff --git a/ee/app/assets/javascripts/approvals/stores/index.js b/ee/app/assets/javascripts/approvals/stores/index.js index e0902e101ad34130c4960bfc0d1fc3973c125754..bf950870c65b8d9090e721910e3dfa2b774259ed 100644 --- a/ee/app/assets/javascripts/approvals/stores/index.js +++ b/ee/app/assets/javascripts/approvals/stores/index.js @@ -7,7 +7,6 @@ export const createStoreOptions = (approvalsModules, settings) => ({ state: state(settings), modules: { ...approvalsModules, - createModal: modalModule(), deleteModal: modalModule(), }, }); diff --git a/ee/app/assets/javascripts/approvals/stores/modules/mr_edit/actions.js b/ee/app/assets/javascripts/approvals/stores/modules/mr_edit/actions.js index 65ce377735dd273c374376db63a5b020f43620ea..be02285ad30a92394a65ec0b5172cc6aded9f0e8 100644 --- a/ee/app/assets/javascripts/approvals/stores/modules/mr_edit/actions.js +++ b/ee/app/assets/javascripts/approvals/stores/modules/mr_edit/actions.js @@ -89,12 +89,11 @@ export const fetchRules = ( .catch(() => dispatch('receiveRulesError')); }; -export const postRule = ({ commit, dispatch }, rule) => +export const postRule = ({ commit }, rule) => seedLocalRule(rule) .then(seedNewRule) .then((newRule) => { commit(types.POST_RULE, newRule); - dispatch('createModal/close'); }) .catch((e) => { createAlert({ @@ -103,11 +102,10 @@ export const postRule = ({ commit, dispatch }, rule) => throw e; }); -export const putRule = ({ commit, dispatch }, rule) => +export const putRule = ({ commit }, rule) => seedLocalRule(rule) .then((newRule) => { commit(types.PUT_RULE, newRule); - dispatch('createModal/close'); }) .catch((e) => { createAlert({ @@ -121,9 +119,8 @@ export const deleteRule = ({ commit, dispatch }, id) => { dispatch('deleteModal/close'); }; -export const putFallbackRule = ({ commit, dispatch }, fallback) => { +export const putFallbackRule = ({ commit }, fallback) => { commit(types.SET_FALLBACK_RULE, fallback); - dispatch('createModal/close'); }; export const openCreateDrawer = ({ commit }, rule) => { @@ -137,24 +134,19 @@ export const closeCreateDrawer = ({ commit }) => { }; export const requestEditRule = ({ dispatch }, rule) => { - if (gon.features.approvalRulesDrawer) { - dispatch('openCreateDrawer', rule); - } else { - dispatch('createModal/open', rule); - } + dispatch('openCreateDrawer', rule); }; export const requestDeleteRule = ({ dispatch }, rule) => { dispatch('deleteRule', rule.id); }; -export const postRegularRule = ({ commit, dispatch }, rule) => +export const postRegularRule = ({ commit }, rule) => seedLocalRule(rule) .then(seedNewRule) .then((newRule) => { commit(types.POST_REGULAR_RULE, newRule); commit(types.DELETE_ANY_RULE); - dispatch('createModal/close'); }) .catch((e) => { createAlert({ diff --git a/ee/app/assets/javascripts/approvals/stores/modules/project_settings/actions.js b/ee/app/assets/javascripts/approvals/stores/modules/project_settings/actions.js index 8541770055c3407ec4489156a1efb821afabd7ea..ff3e9be286fbb72fd712c5f2d9737bcdc264a0ae 100644 --- a/ee/app/assets/javascripts/approvals/stores/modules/project_settings/actions.js +++ b/ee/app/assets/javascripts/approvals/stores/modules/project_settings/actions.js @@ -46,7 +46,7 @@ export const fetchRules = ({ rootState, dispatch }) => { const { rulesPath } = rootState.settings; const { rulesPagination: p, rules: rulesInState, rulesFilter: filter } = rootState.approvals; - const params = { page: p.nextPage }; + const params = { page: p.nextPage || 1 }; return axios .get(rulesPath, { params }) @@ -83,7 +83,6 @@ export const updateRules = ({ rootState, dispatch }, updatedRule) => { }; export const postRuleSuccess = ({ dispatch }, updatedRule) => { - dispatch('createModal/close'); dispatch('updateRules', updatedRule); }; @@ -130,7 +129,6 @@ export const deleteRule = ({ rootState, dispatch }, id) => { }; export const putFallbackRuleSuccess = ({ dispatch }) => { - dispatch('createModal/close'); dispatch('fetchRules'); }; @@ -143,11 +141,7 @@ export const putFallbackRule = ({ rootState, dispatch }, fallback) => { }; export const requestEditRule = ({ dispatch }, rule) => { - if (gon.features.approvalRulesDrawer) { - dispatch('openCreateDrawer', rule); - } else { - dispatch('createModal/open', rule); - } + dispatch('openCreateDrawer', rule); }; export const requestDeleteRule = ({ dispatch }, rule) => { diff --git a/ee/app/controllers/ee/projects/merge_requests/creations_controller.rb b/ee/app/controllers/ee/projects/merge_requests/creations_controller.rb index 7ced80ccfcf96082b7dfbcd1177e27fdc657f340..ff54fbc43a4dd94903ee3be89dd8171a9adb54f2 100644 --- a/ee/app/controllers/ee/projects/merge_requests/creations_controller.rb +++ b/ee/app/controllers/ee/projects/merge_requests/creations_controller.rb @@ -9,10 +9,6 @@ module CreationsController prepended do before_action :disable_query_limiting, only: [:create] before_action :check_for_saml_authorization, only: [:new] - - before_action do - push_frontend_feature_flag(:approval_rules_drawer, @project) - end end private diff --git a/ee/app/controllers/ee/projects/merge_requests_controller.rb b/ee/app/controllers/ee/projects/merge_requests_controller.rb index 1ef9e0e0635ae4da38c55be5bb44df501c3e091a..0c38d46705faa603da7fc93fa20c9712e3de1f98 100644 --- a/ee/app/controllers/ee/projects/merge_requests_controller.rb +++ b/ee/app/controllers/ee/projects/merge_requests_controller.rb @@ -19,8 +19,6 @@ module MergeRequestsController if can?(current_user, :fill_in_merge_request_template, project) push_frontend_feature_flag(:fill_in_mr_template, project) end - - push_frontend_feature_flag(:approval_rules_drawer, @project) end before_action :authorize_read_pipeline!, only: [:metrics_reports] diff --git a/ee/spec/features/projects/settings/merge_request_approvals_settings_spec.rb b/ee/spec/features/projects/settings/merge_request_approvals_settings_spec.rb index 2f294b023a6e2dbe3ebcf59d6ca6a02150f23e8e..c4ae7d786cec8f3ff5eadc50b84ccca26b8a60dd 100644 --- a/ee/spec/features/projects/settings/merge_request_approvals_settings_spec.rb +++ b/ee/spec/features/projects/settings/merge_request_approvals_settings_spec.rb @@ -95,56 +95,4 @@ expect_avatar(find_by_testid('approvals-table-members'), [non_group_approver]) end end - - context 'with approval_rules_drawer feature flag disabled' do - before do - stub_feature_flags(approval_rules_drawer: false) - end - - it 'adds approver' do - visit project_settings_merge_requests_path(project) - - open_modal(text: 'Add approval rule', expand: false) - click_button 'Search users or groups' - - expect_listbox_item(user.name) - expect_no_listbox_item(non_member.name) - - select_listbox_item(user.name) - - expect(find('.content-list')).to have_content(user.name) - - click_button 'Search users or groups' - - expect_no_listbox_item(user.name) - - within('.modal-content') do - click_button 'Add approval rule' - end - wait_for_requests - - expect_avatar(find_by_testid('approvals-table-members'), user) - end - - it 'adds approver group' do - visit project_settings_merge_requests_path(project) - - open_modal(text: 'Add approval rule', expand: false) - click_button 'Search users or groups' - - expect_listbox_item(group.name) - - select_listbox_item(group.name) - - expect(find('.content-list')).to have_content(group.name) - - within('.modal-content') do - click_button 'Add approval rule' - end - wait_for_requests - - group_users = group.group_members.preload_users.map(&:user) - expect_avatar(find_by_testid('approvals-table-members'), group_users) - end - end end diff --git a/ee/spec/frontend/approvals/components/approval_rules_app_spec.js b/ee/spec/frontend/approvals/components/approval_rules_app_spec.js index 831cc7b91dc2f82918c123b53ee5f0627e6df176..2f28d69ed34eb62a8134925bb3ff5d49bd6bbfca 100644 --- a/ee/spec/frontend/approvals/components/approval_rules_app_spec.js +++ b/ee/spec/frontend/approvals/components/approval_rules_app_spec.js @@ -5,7 +5,6 @@ import Vuex from 'vuex'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import ApprovalRulesApp from 'ee/approvals/components/approval_rules_app.vue'; import DrawerRuleCreate from 'ee/approvals/components/rule_drawer/create_rule.vue'; -import ModalRuleCreate from 'ee/approvals/components/rule_modal/create_rule.vue'; import ModalRuleRemove from 'ee/approvals/components/rule_modal/remove_rule.vue'; import { createStoreOptions } from 'ee/approvals/stores'; import settingsModule from 'ee/approvals/stores/modules/project_settings'; @@ -24,11 +23,10 @@ describe('EE Approvals App', () => { let slots; const targetBranchName = 'development'; - const factory = (approvalRulesDrawer = false, propsData = {}) => { + const factory = (propsData = {}) => { wrapper = shallowMountExtended(ApprovalRulesApp, { slots, store: new Vuex.Store(store), - provide: { glFeatures: { approvalRulesDrawer } }, propsData, stubs: { GlCard, @@ -68,7 +66,6 @@ describe('EE Approvals App', () => { jest.spyOn(store.modules.approvals.actions, 'fetchRules'); jest.spyOn(store.modules.approvals.actions, 'openCreateDrawer'); jest.spyOn(store.modules.approvals.actions, 'closeCreateDrawer'); - jest.spyOn(store.modules.createModal.actions, 'open'); }); describe('targetBranch', () => { @@ -116,13 +113,12 @@ describe('EE Approvals App', () => { expect(store.modules.approvals.actions.fetchRules).toHaveBeenCalledTimes(1); }); - it('renders create modal', () => { + it('renders create drawer', () => { factory(); - const modal = wrapper.findComponent(ModalRuleCreate); + const drawer = findRuleCreateDrawer(); - expect(modal.exists()).toBe(true); - expect(modal.props('modalId')).toBe(`${APP_PREFIX}-approvals-create-modal`); + expect(drawer.exists()).toBe(true); }); it('renders delete modal', () => { @@ -199,7 +195,7 @@ describe('EE Approvals App', () => { it('when renders on the `Merge requests` project settings page', () => { store.modules.approvals.state.rulesPagination.total = 25; - factory(false, { isMrEdit: false }); + factory({ isMrEdit: false }); expect(findRulesCount().text()).toBe('25'); }); @@ -220,36 +216,17 @@ describe('EE Approvals App', () => { expect(button.text()).toBe('Add approval rule'); }); - it('opens create modal when add button is clicked', () => { + it('opens create drawer when add button is clicked', () => { factory(); findAddButton().vm.$emit('click'); - expect(store.modules.createModal.actions.open).toHaveBeenCalledWith( - expect.anything(), - null, - ); - }); - }); - - describe('approvalRulesDrawer feature flag enabled', () => { - beforeEach(() => factory(true)); - - it('renders a RuleCreateDrawer drawer component with correct props', () => { - expect(findRuleCreateDrawer().props()).toEqual({ - isBranchRulesEdit: false, - isMrEdit: true, - isOpen: false, - }); - }); - - it('opens the drawer when a rule is added', () => { - findAddButton().vm.$emit('click'); - expect(store.modules.approvals.actions.openCreateDrawer).toHaveBeenCalled(); }); it('closes the drawer when a close event is emitted', () => { + factory(); + findRuleCreateDrawer().vm.$emit('close'); expect(store.modules.approvals.actions.closeCreateDrawer).toHaveBeenCalled(); @@ -301,7 +278,7 @@ describe('EE Approvals App', () => { describe('when isBranchRulesEdit is set to `true`', () => { it('does not call fetchRules', async () => { - factory(false, { isBranchRulesEdit: true }); + factory({ isBranchRulesEdit: true }); await nextTick(); expect(store.modules.approvals.actions.fetchRules).not.toHaveBeenCalled(); diff --git a/ee/spec/frontend/approvals/components/rule_modal/create_rule_spec.js b/ee/spec/frontend/approvals/components/rule_modal/create_rule_spec.js deleted file mode 100644 index 6628aa506131cecd8d8036a5501b8ccd12403a3b..0000000000000000000000000000000000000000 --- a/ee/spec/frontend/approvals/components/rule_modal/create_rule_spec.js +++ /dev/null @@ -1,153 +0,0 @@ -import { shallowMount } from '@vue/test-utils'; -import Vue from 'vue'; -// eslint-disable-next-line no-restricted-imports -import Vuex from 'vuex'; -import ModalRuleCreate from 'ee/approvals/components/rule_modal/create_rule.vue'; -import { stubComponent } from 'helpers/stub_component'; -import RuleForm from 'ee/approvals/components/rules/rule_form.vue'; -import GlModalVuex from '~/vue_shared/components/gl_modal_vuex.vue'; - -const TEST_MODAL_ID = 'test-modal-create-id'; -const TEST_RULE = { id: 7 }; -const MODAL_MODULE = 'createModal'; - -Vue.use(Vuex); - -describe('Approvals ModalRuleCreate', () => { - let createModalState; - let wrapper; - let modal; - let form; - let submitMock; - - const findModal = () => wrapper.findComponent(GlModalVuex); - const findForm = () => wrapper.findComponent(RuleForm); - - const factory = (options = {}) => { - submitMock = jest.fn(); - - const RuleFormStub = stubComponent(RuleForm, { - template: `<span />`, - methods: { - submit: submitMock, - }, - }); - - const store = new Vuex.Store({ - modules: { - [MODAL_MODULE]: { - namespaced: true, - state: createModalState, - }, - }, - }); - - const propsData = { - modalId: TEST_MODAL_ID, - ...options.propsData, - }; - - wrapper = shallowMount(ModalRuleCreate, { - ...options, - store, - propsData, - stubs: { - GlModalVuex: stubComponent(GlModalVuex, { - props: ['modalModule', 'modalId', 'actionPrimary', 'actionCancel'], - }), - RuleForm: RuleFormStub, - }, - }); - }; - - beforeEach(() => { - createModalState = {}; - }); - - describe('without data', () => { - beforeEach(() => { - createModalState.data = null; - factory(); - modal = findModal(); - form = findForm(); - }); - - it('renders modal', () => { - expect(modal.exists()).toBe(true); - expect(modal.props('modalModule')).toEqual(MODAL_MODULE); - expect(modal.props('modalId')).toEqual(TEST_MODAL_ID); - expect(modal.props('actionPrimary')).toStrictEqual({ - text: 'Add approval rule', - attributes: { variant: 'confirm' }, - }); - expect(modal.props('actionCancel')).toStrictEqual({ text: 'Cancel' }); - expect(modal.attributes('title')).toEqual('Add approval rule'); - }); - - it('renders form', () => { - expect(form.exists()).toBe(true); - expect(form.props('initRule')).toEqual(null); - }); - - it('when modal emits ok, submits form', () => { - // An instance of Event is passed to handle .prevent vue event modifier - modal.vm.$emit('ok', new Event('ok')); - - expect(submitMock).toHaveBeenCalled(); - }); - }); - - describe('with data', () => { - beforeEach(() => { - createModalState.data = TEST_RULE; - factory(); - modal = findModal(); - form = findForm(); - }); - - it('renders modal', () => { - expect(modal.exists()).toBe(true); - expect(modal.attributes('title')).toEqual('Update approval rule'); - expect(modal.props('actionPrimary')).toStrictEqual({ - text: 'Update approval rule', - attributes: { variant: 'confirm' }, - }); - expect(modal.props('actionCancel')).toStrictEqual({ text: 'Cancel' }); - }); - - it('renders form', () => { - expect(form.exists()).toBe(true); - expect(form.props('initRule')).toEqual(TEST_RULE); - }); - }); - - describe('with approval suggestions', () => { - beforeEach(() => { - createModalState.data = { ...TEST_RULE, defaultRuleName: 'Coverage-Check' }; - - factory(); - modal = findModal(); - form = findForm(); - }); - - it('renders add rule modal', () => { - expect(modal.exists()).toBe(true); - expect(modal.attributes('title')).toEqual('Add approval rule'); - expect(modal.props('actionPrimary')).toStrictEqual({ - text: 'Add approval rule', - attributes: { variant: 'confirm' }, - }); - expect(modal.props('actionCancel')).toStrictEqual({ text: 'Cancel' }); - }); - - it('renders form with defaultRuleName', () => { - expect(form.props('defaultRuleName')).toBe('Coverage-Check'); - expect(form.exists()).toBe(true); - }); - - it('renders the form when passing in an existing rule', () => { - expect(form.exists()).toBe(true); - expect(form.props('initRule')).toEqual(createModalState.data); - }); - }); -}); diff --git a/ee/spec/frontend/approvals/components/security_configuration/unconfigured_security_rules_spec.js b/ee/spec/frontend/approvals/components/security_configuration/unconfigured_security_rules_spec.js index d87e0c0b4645c48f3878b6a9439bd5d1f43340bc..73050e16099296d078150b060ea2561fad8c5c73 100644 --- a/ee/spec/frontend/approvals/components/security_configuration/unconfigured_security_rules_spec.js +++ b/ee/spec/frontend/approvals/components/security_configuration/unconfigured_security_rules_spec.js @@ -16,10 +16,9 @@ describe('UnconfiguredSecurityRules component', () => { const TEST_PROJECT_ID = '7'; - const createWrapper = (props = {}, approvalRulesDrawer = false) => { + const createWrapper = (props = {}) => { wrapper = shallowMount(UnconfiguredSecurityRules, { store: new Vuex.Store(store), - provide: { glFeatures: { approvalRulesDrawer } }, propsData: { ...props, }, @@ -61,12 +60,10 @@ describe('UnconfiguredSecurityRules component', () => { }); }); - describe('approvalRulesDrawer feature flag enabled', () => { - it('opens the drawer when a rule is Enabled', () => { - createWrapper({}, true); - wrapper.findComponent(UnconfiguredSecurityRule).vm.$emit('enable'); + it('opens the drawer when a rule is Enabled', () => { + createWrapper(); + wrapper.findComponent(UnconfiguredSecurityRule).vm.$emit('enable'); - expect(store.modules.approvals.actions.openCreateDrawer).toHaveBeenCalled(); - }); + expect(store.modules.approvals.actions.openCreateDrawer).toHaveBeenCalled(); }); }); diff --git a/ee/spec/frontend/approvals/stores/modules/project_settings/actions_spec.js b/ee/spec/frontend/approvals/stores/modules/project_settings/actions_spec.js index aef0d8d999b3159e6c9868261367217f09847304..556ae0c02463503e3c45c5671bd0cfa7b40c4d0a 100644 --- a/ee/spec/frontend/approvals/stores/modules/project_settings/actions_spec.js +++ b/ee/spec/frontend/approvals/stores/modules/project_settings/actions_spec.js @@ -236,6 +236,14 @@ describe('EE approvals project settings module actions', () => { }; }); + it('defaults to page 1 if pagination information is not available', () => { + jest.spyOn(axios, 'get'); + state.approvals.rulesPagination = {}; + actions.fetchRules({ rootState: state, dispatch: jest.fn() }); + + expect(axios.get).toHaveBeenCalledWith(TEST_RULES_PATH, { params: { page: 1 } }); + }); + it('dispatches request/receive', async () => { const data = [TEST_RULE_RESPONSE]; @@ -283,7 +291,7 @@ describe('EE approvals project settings module actions', () => { null, {}, [], - [{ type: 'createModal/close' }, { type: 'updateRules', payload: null }], + [{ type: 'updateRules', payload: null }], ); }); }); diff --git a/locale/gitlab.pot b/locale/gitlab.pot index e73db3c4a1ac01bbcd5a5c824aea3130198c0711..12b92c71410f62d33a2342eec340bb18cee9614f 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -55541,9 +55541,6 @@ msgstr "" msgid "Update appearance settings" msgstr "" -msgid "Update approval rule" -msgstr "" - msgid "Update approvers" msgstr ""