Add minimum coverage threshold (5/6): Frontend

What does this MR do and why?

This is MR 5 of 6 in a stacked series that adds a minimum coverage threshold to the Coverage-Check approval rule.

MR Branch Base Content
1 6284-coverage-threshold-1-db-model-ff master DB migration & model validation (!226363 (merged))
2 6284-coverage-threshold-2-service-rest 6284-coverage-threshold-1-db-model-ff Service logic, REST API & feature flag (!226370 (merged))
3 6284-coverage-threshold-3-graphql 6284-coverage-threshold-2-service-rest GraphQL mutations & fields (!226372 (merged))
4 6284-coverage-threshold-4-blockage-reason 6284-coverage-threshold-3-graphql blockage_reason feature & GraphQL exposure (!226394)
5 (this MR) 6284-coverage-threshold-5-frontend 6284-coverage-threshold-4-blockage-reason Frontend: Settings UI + MR widget feedback
6 6284-coverage-threshold-6-docs master Documentation (standalone, no dependency)

This MR replaces !224368 (closed). Splitting was discussed and agreed upon with @kherman1 and @hfyngvason in !224343 (closed).

This MR includes:

  • Rule Form: Optional threshold input field (0-100) when creating/editing a Coverage-Check rule, with client-side validation
  • Settings Rule List: Displays the configured threshold value under the rule name
  • MR Widget: Shows the blockage reason in the Coverage-Check help popover
  • GraphQL Fragment: Added blockageReason to the MergeRequestApprovalRule fragment
  • Description Update: Updated Coverage-Check description to mention threshold capability
  • Frontend test coverage for all new components and behaviors

Files to review in this MR

Note: This is a stacked MR. The diff shows cumulative changes against master. Please focus your review on the files listed below, which are the ones introduced in this MR.

  • ee/app/assets/javascripts/approvals/components/rules/rule_form.vue - Threshold input field + validation
  • ee/app/assets/javascripts/approvals/components/mr_widget_approval_check/approval_check_popover.vue - Blockage reason display
  • ee/app/assets/javascripts/approvals/components/mr_widget_approval_check/approval_check_rule_popover.vue - Passes blockageReason to popover
  • ee/app/assets/javascripts/approvals/components/security_configuration/unconfigured_security_rules.vue - Updated description
  • ee/app/assets/javascripts/approvals/project_settings/project_rules.vue - Threshold display in rules list
  • ee/app/assets/javascripts/graphql_shared/fragments/merge_request.approval_rule.fragment.graphql - Added blockageReason field
  • ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/approvals_list.vue - Passes blockageReason to popover
  • ee/app/assets/javascripts/vue_merge_request_widget/components/approvals/queries/approvals.query.graphql - Query includes blockageReason
  • ee/spec/frontend/approvals/components/mr_widget_approval_check/approval_check_popover_spec.js
  • ee/spec/frontend/approvals/components/mr_widget_approval_check/approval_check_rule_popover_spec.js
  • ee/spec/frontend/approvals/components/rules/rule_form_spec.js
  • ee/spec/frontend/approvals/project_settings/project_rules_spec.js
  • ee/spec/frontend/vue_merge_request_widget/components/approvals/approvals_list_spec.js
  • ee/spec/frontend/vue_merge_request_widget/components/approvals/approvals_spec.js
  • locale/gitlab.pot - i18n strings

Screenshots

Before After
image image image image

Related to #6284 Extracted from !224343 (closed)

How to set up and validate locally

Prerequisites

1. Test the threshold input in project settings

  1. Navigate to your project: Settings > Merge requests > Approval rules
  2. Click Add approval rule
  3. Set the name to exactly Coverage-Check
  4. A new field "Minimum coverage threshold (%)" should appear below the approvals required field
  5. Enter a value (e.g. 80) and save the rule
  6. The rules list should display "Minimum coverage threshold: 80%" under the rule name

2. Test validation

  1. Edit the Coverage-Check rule
  2. Enter an invalid threshold (e.g. 150 or -5)
  3. The form should show a validation error: "Coverage threshold must be between 0 and 100"
  4. Clear the field (leave it empty/null) - this should be valid (threshold is optional)

3. Test blockage reason in MR widget

  1. Create a merge request with a pipeline that has coverage below the configured threshold
  2. The Coverage-Check approval rule should show as blocking in the MR widget
  3. Hover over the info icon next to the Coverage-Check rule name
  4. The popover should display the blockage reason (e.g. "Coverage falls below the minimum threshold of 80.0% (current: 70.0%)")

4. Run the frontend specs

yarn jest ee/spec/frontend/approvals/components/rules/rule_form_spec.js
# Expected: 60 passed

yarn jest ee/spec/frontend/approvals/components/mr_widget_approval_check/
# Expected: 15 passed

yarn jest ee/spec/frontend/vue_merge_request_widget/components/approvals/
# Expected: 90 passed

yarn jest ee/spec/frontend/approvals/project_settings/project_rules_spec.js
# Expected: 18 passed

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

  • The change is backwards compatible. Threshold field only appears for Coverage-Check rules. When not set, behavior is unchanged.
  • Client-side validation matches server-side validation (0-100 range, nil allowed).
  • blockageReason is read from the existing GraphQL field added in MR 4, no new queries introduced.
  • All i18n strings are externalized via locale/gitlab.pot.
  • Frontend test coverage for form, validation, display, and MR widget integration.
  • Manually tested in GDK with real pipeline coverage data.

Related to #6284

Edited by Norman Debald

Merge request reports

Loading