From 2e589c489365ec21a47a9f9e16e24e3c04963851 Mon Sep 17 00:00:00 2001 From: Paul Slaughter Date: Wed, 6 Feb 2019 02:26:23 -0600 Subject: [PATCH 1/4] Add MR widget components for multi approval rules **Note:** - This pushes the `approval_rules` flag to the FE on MR show --- .../components/approvals/index.js | 10 + .../components/approvals/messages.js | 9 + .../approvals/multiple_rule/approvals.vue | 179 ++++++++ .../multiple_rule/approvals_footer.vue | 82 ++++ .../multiple_rule/approvals_list.vue | 99 +++++ .../multiple_rule/approvals_summary.vue | 68 +++ .../approvals/multiple_rule/approved_icon.vue | 20 + .../approvals.vue} | 15 +- .../{ => single_rule}/approvals_body.vue | 3 +- .../{ => single_rule}/approvals_footer.vue | 3 +- .../mr_widget_options.vue | 6 +- .../services/mr_widget_service.js | 16 +- .../stores/mr_widget_store.js | 25 ++ .../ee/projects/merge_requests_controller.rb | 4 + .../multiple_rule/approvals_footer_spec.js | 201 +++++++++ .../multiple_rule/approvals_list_spec.js | 254 +++++++++++ .../approvals/multiple_rule/approvals_spec.js | 412 ++++++++++++++++++ .../multiple_rule/approvals_summary_spec.js | 97 +++++ .../multiple_rule/approved_icon_spec.js | 65 +++ .../{ => single_rule}/approvals_body_spec.js | 2 +- .../approvals_footer_spec.js | 2 +- .../ee_mr_widget_options_spec.js | 2 + locale/gitlab.pot | 52 +++ .../vue_mr_widget/mr_widget_options_spec.js | 2 + 24 files changed, 1613 insertions(+), 15 deletions(-) create mode 100644 ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/index.js create mode 100644 ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/messages.js create mode 100644 ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/multiple_rule/approvals.vue create mode 100644 ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/multiple_rule/approvals_footer.vue create mode 100644 ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/multiple_rule/approvals_list.vue create mode 100644 ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/multiple_rule/approvals_summary.vue create mode 100644 ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/multiple_rule/approved_icon.vue rename ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/{mr_widget_approvals.vue => single_rule/approvals.vue} (86%) rename ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/{ => single_rule}/approvals_body.vue (98%) rename ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/{ => single_rule}/approvals_footer.vue (97%) create mode 100644 ee/spec/javascripts/vue_mr_widget/components/approvals/multiple_rule/approvals_footer_spec.js create mode 100644 ee/spec/javascripts/vue_mr_widget/components/approvals/multiple_rule/approvals_list_spec.js create mode 100644 ee/spec/javascripts/vue_mr_widget/components/approvals/multiple_rule/approvals_spec.js create mode 100644 ee/spec/javascripts/vue_mr_widget/components/approvals/multiple_rule/approvals_summary_spec.js create mode 100644 ee/spec/javascripts/vue_mr_widget/components/approvals/multiple_rule/approved_icon_spec.js rename ee/spec/javascripts/vue_mr_widget/components/approvals/{ => single_rule}/approvals_body_spec.js (99%) rename ee/spec/javascripts/vue_mr_widget/components/approvals/{ => single_rule}/approvals_footer_spec.js (98%) diff --git a/ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/index.js b/ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/index.js new file mode 100644 index 00000000000000..dd562eac3ad5d0 --- /dev/null +++ b/ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/index.js @@ -0,0 +1,10 @@ +import MultipleRuleApprovals from './multiple_rule/approvals.vue'; +import SingleRuleApprovals from './single_rule/approvals.vue'; + +export default { + functional: true, + render(h, context) { + const component = gon.features.approvalRules ? MultipleRuleApprovals : SingleRuleApprovals; + return h(component, context.data, context.children); + }, +}; diff --git a/ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/messages.js b/ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/messages.js new file mode 100644 index 00000000000000..0538c38307b420 --- /dev/null +++ b/ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/messages.js @@ -0,0 +1,9 @@ +import { __, s__ } from '~/locale'; + +export const FETCH_LOADING = __('Checking approval status'); +export const FETCH_ERROR = s__( + 'mrWidget|An error occurred while retrieving approval data for this merge request.', +); +export const APPROVE_ERROR = s__('mrWidget|An error occurred while submitting your approval.'); +export const UNAPPROVE_ERROR = s__('mrWidget|An error occurred while removing your approval.'); +export const APPROVED_MESSAGE = s__('mrWidget|Merge request approved.'); diff --git a/ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/multiple_rule/approvals.vue b/ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/multiple_rule/approvals.vue new file mode 100644 index 00000000000000..9e0b7164f9b30a --- /dev/null +++ b/ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/multiple_rule/approvals.vue @@ -0,0 +1,179 @@ + + + diff --git a/ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/multiple_rule/approvals_footer.vue b/ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/multiple_rule/approvals_footer.vue new file mode 100644 index 00000000000000..ebf85e1eb43781 --- /dev/null +++ b/ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/multiple_rule/approvals_footer.vue @@ -0,0 +1,82 @@ + + + diff --git a/ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/multiple_rule/approvals_list.vue b/ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/multiple_rule/approvals_list.vue new file mode 100644 index 00000000000000..ea39779f806659 --- /dev/null +++ b/ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/multiple_rule/approvals_list.vue @@ -0,0 +1,99 @@ + + + diff --git a/ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/multiple_rule/approvals_summary.vue b/ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/multiple_rule/approvals_summary.vue new file mode 100644 index 00000000000000..11bfa19e545146 --- /dev/null +++ b/ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/multiple_rule/approvals_summary.vue @@ -0,0 +1,68 @@ + + + diff --git a/ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/multiple_rule/approved_icon.vue b/ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/multiple_rule/approved_icon.vue new file mode 100644 index 00000000000000..a31978b4969a4e --- /dev/null +++ b/ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/multiple_rule/approved_icon.vue @@ -0,0 +1,20 @@ + + + diff --git a/ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/mr_widget_approvals.vue b/ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/single_rule/approvals.vue similarity index 86% rename from ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/mr_widget_approvals.vue rename to ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/single_rule/approvals.vue index 0e8039e7963a60..92ae3edb1fe47e 100644 --- a/ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/mr_widget_approvals.vue +++ b/ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/single_rule/approvals.vue @@ -1,13 +1,13 @@ diff --git a/ee/app/assets/javascripts/approvals/components/mr_edit/mr_rules.vue b/ee/app/assets/javascripts/approvals/components/mr_edit/mr_rules.vue index b753233f5f2f73..f8dcb048d2daf2 100644 --- a/ee/app/assets/javascripts/approvals/components/mr_edit/mr_rules.vue +++ b/ee/app/assets/javascripts/approvals/components/mr_edit/mr_rules.vue @@ -33,11 +33,11 @@ export default { diff --git a/ee/app/assets/javascripts/approvals/components/project_settings/project_rules.vue b/ee/app/assets/javascripts/approvals/components/project_settings/project_rules.vue index 7c3a93dda440af..85b2df5b69e5f5 100644 --- a/ee/app/assets/javascripts/approvals/components/project_settings/project_rules.vue +++ b/ee/app/assets/javascripts/approvals/components/project_settings/project_rules.vue @@ -44,18 +44,18 @@ export default { diff --git a/ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/multiple_rule/approvals_list.vue b/ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/multiple_rule/approvals_list.vue index ea39779f806659..19ef579a79d970 100644 --- a/ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/multiple_rule/approvals_list.vue +++ b/ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/multiple_rule/approvals_list.vue @@ -65,8 +65,8 @@ export default { -
{{ rule.name }}
-
+
{{ rule.name }}
+
{{ summaryText(rule) }}
- +
- + {{ pendingApprovalsText(rule) }} - + diff --git a/ee/spec/javascripts/approvals/components/mr_edit/mr_rules_spec.js b/ee/spec/javascripts/approvals/components/mr_edit/mr_rules_spec.js index 481a020db5607c..0a0e3af19904d0 100644 --- a/ee/spec/javascripts/approvals/components/mr_edit/mr_rules_spec.js +++ b/ee/spec/javascripts/approvals/components/mr_edit/mr_rules_spec.js @@ -45,14 +45,14 @@ describe('EE Approvals MRRules', () => { }); const findHeaders = () => wrapper.findAll('thead th').wrappers.map(x => x.text()); - const findRuleName = () => wrapper.find('td[data-name=name]').text(); + const findRuleName = () => wrapper.find('td.js-name').text(); const findRuleMembers = () => wrapper - .find('td[data-name=members]') + .find('td.js-members') .find(UserAvatarList) .props('items'); - const findRuleApprovalsRequired = () => wrapper.find('td[data-name=approvals_required] input'); - const findRuleControls = () => wrapper.find('td[data-name=controls]').find(RuleControls); + const findRuleApprovalsRequired = () => wrapper.find('td.js-approvals-required input'); + const findRuleControls = () => wrapper.find('td.js-controls').find(RuleControls); it('renders headers', () => { factory(); diff --git a/ee/spec/javascripts/approvals/components/project_settings/project_rules_spec.js b/ee/spec/javascripts/approvals/components/project_settings/project_rules_spec.js index 806af5bb149608..3e83ba8278a248 100644 --- a/ee/spec/javascripts/approvals/components/project_settings/project_rules_spec.js +++ b/ee/spec/javascripts/approvals/components/project_settings/project_rules_spec.js @@ -10,13 +10,13 @@ const TEST_RULES = createProjectRules(); const localVue = createLocalVue(); localVue.use(Vuex); -const findCell = (tr, name) => tr.find(`td[data-name=${name}]`); +const findCell = (tr, name) => tr.find(`td.js-${name}`); const getRowData = tr => { const name = findCell(tr, 'name'); const members = findCell(tr, 'members'); const controls = findCell(tr, 'controls'); - const approvalsRequired = findCell(tr, 'approvals_required'); + const approvalsRequired = findCell(tr, 'approvals-required'); return { name: name.find('.d-sm-block.d-none').text(), diff --git a/ee/spec/javascripts/vue_mr_widget/components/approvals/multiple_rule/approvals_list_spec.js b/ee/spec/javascripts/vue_mr_widget/components/approvals/multiple_rule/approvals_list_spec.js index c163c068af6f98..59d1af917aa676 100644 --- a/ee/spec/javascripts/vue_mr_widget/components/approvals/multiple_rule/approvals_list_spec.js +++ b/ee/spec/javascripts/vue_mr_widget/components/approvals/multiple_rule/approvals_list_spec.js @@ -50,7 +50,7 @@ describe('EE MRWidget approvals list', () => { }; const findRows = () => wrapper.findAll('tbody tr'); - const findRowElement = (row, name) => row.find(`[data-name="${name}"]`); + const findRowElement = (row, name) => row.find(`.js-${name}`); const findRowIcon = row => row.find(ApprovedIcon); afterEach(() => { -- GitLab From 129b663ef967779eb8f572706a33c1c9e4421e48 Mon Sep 17 00:00:00 2001 From: Paul Slaughter Date: Tue, 12 Feb 2019 10:56:48 -0600 Subject: [PATCH 4/4] Fill in empty `describe` descriptions --- .../approvals/multiple_rule/approvals_footer_spec.js | 2 +- .../approvals/multiple_rule/approvals_spec.js | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ee/spec/javascripts/vue_mr_widget/components/approvals/multiple_rule/approvals_footer_spec.js b/ee/spec/javascripts/vue_mr_widget/components/approvals/multiple_rule/approvals_footer_spec.js index b756ded49ebc46..dd9209b0e11e97 100644 --- a/ee/spec/javascripts/vue_mr_widget/components/approvals/multiple_rule/approvals_footer_spec.js +++ b/ee/spec/javascripts/vue_mr_widget/components/approvals/multiple_rule/approvals_footer_spec.js @@ -40,7 +40,7 @@ describe('EE MRWidget approvals footer', () => { }); describe('when expanded', () => { - describe('', () => { + describe('and has rules', () => { beforeEach(() => { createComponent(); }); diff --git a/ee/spec/javascripts/vue_mr_widget/components/approvals/multiple_rule/approvals_spec.js b/ee/spec/javascripts/vue_mr_widget/components/approvals/multiple_rule/approvals_spec.js index 1b694f3856f060..158c429acf8729 100644 --- a/ee/spec/javascripts/vue_mr_widget/components/approvals/multiple_rule/approvals_spec.js +++ b/ee/spec/javascripts/vue_mr_widget/components/approvals/multiple_rule/approvals_spec.js @@ -168,7 +168,7 @@ describe('EE MRWidget approvals', () => { mr.approvals.user_can_approve = true; }); - describe('', () => { + describe('and MR is unapproved', () => { beforeEach(done => { createComponent(); waitForTick(done); @@ -221,7 +221,7 @@ describe('EE MRWidget approvals', () => { .catch(done.fail); }); - describe('', () => { + describe('and after loading', () => { beforeEach(done => { findAction().vm.$emit('click'); waitForTick(done); @@ -276,7 +276,7 @@ describe('EE MRWidget approvals', () => { }); describe('when revoke action is clicked', () => { - describe('', () => { + describe('and successful', () => { beforeEach(done => { findAction().vm.$emit('click'); waitForTick(done); @@ -360,7 +360,7 @@ describe('EE MRWidget approvals', () => { }); describe('when opened', () => { - describe('', () => { + describe('and loading', () => { beforeEach(done => { service.fetchApprovalSettings.and.callFake(() => new Promise(() => {})); footer.vm.$emit('input', true); @@ -377,7 +377,7 @@ describe('EE MRWidget approvals', () => { }); }); - describe('', () => { + describe('and finished loading', () => { beforeEach(done => { footer.vm.$emit('input', true); waitForTick(done); -- GitLab