Recount closed blockers when a blocked issue is closed or reopened
What does this MR do and why?
Closing or reopening an issue refreshes issues.blocking_issues_count on the issue and on its blockers in refresh_blocking_and_blocked_issues_cache!, but the blockers came from blocking_issues_ids, which returns only open ones. A closed blocker kept counting the issue: its count stayed too high when the blocked issue was closed, and too low when the blocked issue was reopened. GraphQL blockingCount, the work items REST API's blocking_count and the BLOCKING_ISSUES_* sorts read the column for closed issues too.
This MR reads the blockers from the blocks links that point at the issue, bounded by MAX_LINKS_COUNT as the refresh on delete is, so closed blockers are recounted as well: closed issues are to be kept up to date, as Heinrich Lee Yu confirmed in !266012 (comment 4190451933). The fix and its two specs come from Abdul Wadood's database review in !266012 (comment 4148836140), and the commit credits Abdul as co-author. The only change to them is described_class for Issue in the specs, which RuboCop asks for.
Both new examples fail on master without the model change and pass with it.
What I ran (Ruby 3.3.11)
On master at 5670247b:
- the context
when changing state of blocking issuesofee/spec/models/issue_spec.rbwith the model change reverted: 4 examples, 2 failures, the two new ones ("did not change"); - the same context with the change: 4 examples, 0 failures;
- the whole
ee/spec/models/issue_spec.rbwithout the:elasticexamples, which need Elasticsearch: 202 examples, 0 failures; - the specs that close, reopen or move issues,
spec/services/issues/close_service_spec.rb,spec/services/issues/reopen_service_spec.rb,ee/spec/services/ee/issues/close_service_spec.rb,ee/spec/services/ee/issues/reopen_service_spec.rb,ee/spec/models/work_item_spec.rb, bothwork_items/data_sync/move_service_spec.rbandspec/services/issuable/bulk_update_service_spec.rb: 563 examples, 2 failures, bothreturns a new work item with the same attributesin the move service spec, onupdated_at; - both move service specs again, with and without the model change: 135 examples, 0 failures with it, and the same 2 failures without it. On a slow host the example runs more than a minute after
let_it_becreated the original, soThrottledTouchtouches the new work item; - RuboCop on both files and the commit linter: no offenses.
References
Closes #639147 (closed)
- !266012 (merged) repairs the counts that are already wrong, and merges after this MR.
- !265408 (merged) added the refresh on delete whose lookup this MR reuses.
Screenshots or screen recordings
Not applicable: backend change, no UI change of its own.
How to set up and validate locally
- On Premium or Ultimate, create issues A and B, and add B to A's linked items as blocks.
- Close A, then close B. In the Rails console,
Issue.find(<A id>).blocking_issues_countis0on this branch and1onmaster. - With a new pair where A blocks B, close B, close A, then reopen B. A's count is
1on this branch and0onmaster.
I followed these steps through the model specs above, not on a GDK.
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.