Commit 3b9e5895 authored by Douwe Maan's avatar Douwe Maan

Merge branch 'fix-mentioned-users-on-diff-notes' into 'master'

Fix mentioned users on diff notes

## Summary

`DiffNote`, and `LegacyDiffNote` returns empty array for `mentionable_attrs`, because `mentionable_attrs` is not inheritable by subclasses. The problem can be illustrated with this small sample:

```ruby
module Mentionable
  extend ActiveSupport::Concern

  module ClassMethods
    def attr_mentionable(attr)
      mentionable_attrs << [attr.to_s]
    end

    def mentionable_attrs
      @mentionable_attrs ||= []
    end
  end
end

class A
  include Mentionable

  attr_mentionable :foo
end

class B < A
end

A.mentionable_attrs
=> [["foo", {}]]

B.mentionable_attrs
=> []
```

Possible solution using `cattr_accessor`:

```ruby
module Mentionable
  extend ActiveSupport::Concern

  module ClassMethods
    def attr_mentionable(attr)
      mentionable_attrs << [attr.to_s]
    end
  end

  included do
    cattr_accessor :mentionable_attrs, instance_accessor: false do
      []
    end
  end
end

class A
  include Mentionable

  attr_mentionable :foo
end

class B < A
end

A.mentionable_attrs
=> [["foo"]]

B.mentionable_attrs
=> [["foo"]]

B.mentionable_attrs < [:bar]
=> [["foo"], ["bar"]]

A.mentionable_attrs
=> [["foo"], ["bar"]]
```

`mentionable_attrs` is inheritable by subclasses. If a subclass changes the value then that would also change the value for parent class. Similarly if parent class changes the value then that would change the value of subclasses too.

## What are the relevant issue numbers?

Fixes #19807 

Fixes #18022

/cc @stanhu  @DouweM @rspeicher 

See merge request !5243
parents 263f005e efe18f05
...@@ -57,6 +57,7 @@ v 8.10.0 (unreleased) ...@@ -57,6 +57,7 @@ v 8.10.0 (unreleased)
- Throttle the update of `project.pushes_since_gc` to 1 minute. - Throttle the update of `project.pushes_since_gc` to 1 minute.
- Allow expanding and collapsing files in diff view (!4990) - Allow expanding and collapsing files in diff view (!4990)
- Collapse large diffs by default (!4990) - Collapse large diffs by default (!4990)
- Fix mentioned users list on diff notes
- Check for conflicts with existing Project's wiki path when creating a new project. - Check for conflicts with existing Project's wiki path when creating a new project.
- Show last push widget in upstream after push to fork - Show last push widget in upstream after push to fork
- Cache todos pending/done dashboard query counts. - Cache todos pending/done dashboard query counts.
......
...@@ -14,14 +14,14 @@ module Mentionable ...@@ -14,14 +14,14 @@ module Mentionable
attr = attr.to_s attr = attr.to_s
mentionable_attrs << [attr, options] mentionable_attrs << [attr, options]
end end
end
included do
# Accessor for attributes marked mentionable. # Accessor for attributes marked mentionable.
def mentionable_attrs cattr_accessor :mentionable_attrs, instance_accessor: false do
@mentionable_attrs ||= [] []
end
end end
included do
if self < Participable if self < Participable
participant -> (user, ext) { all_references(user, extractor: ext) } participant -> (user, ext) { all_references(user, extractor: ext) }
end end
......
...@@ -41,9 +41,12 @@ module Participable ...@@ -41,9 +41,12 @@ module Participable
def participant(attr) def participant(attr)
participant_attrs << attr participant_attrs << attr
end end
end
def participant_attrs included do
@participant_attrs ||= [] # Accessor for participant attributes.
cattr_accessor :participant_attrs, instance_accessor: false do
[]
end end
end end
......
...@@ -435,6 +435,24 @@ describe TodoService, services: true do ...@@ -435,6 +435,24 @@ describe TodoService, services: true do
should_create_todo(user: author, target: mr_unassigned, action: Todo::MARKED) should_create_todo(user: author, target: mr_unassigned, action: Todo::MARKED)
end end
end end
describe '#new_note' do
let(:mention) { john_doe.to_reference }
let(:diff_note_on_merge_request) { create(:diff_note_on_merge_request, project: project, noteable: mr_unassigned, author: author, note: "Hey #{mention}") }
let(:legacy_diff_note_on_merge_request) { create(:legacy_diff_note_on_merge_request, project: project, noteable: mr_unassigned, author: author, note: "Hey #{mention}") }
it 'creates a todo for mentioned user on new diff note' do
service.new_note(diff_note_on_merge_request, author)
should_create_todo(user: john_doe, target: mr_unassigned, author: author, action: Todo::MENTIONED, note: diff_note_on_merge_request)
end
it 'creates a todo for mentioned user on legacy diff note' do
service.new_note(legacy_diff_note_on_merge_request, author)
should_create_todo(user: john_doe, target: mr_unassigned, author: author, action: Todo::MENTIONED, note: legacy_diff_note_on_merge_request)
end
end
end end
it 'updates cached counts when a todo is created' do it 'updates cached counts when a todo is created' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment