diff --git a/app/models/concerns/work_item_resource_event.rb b/app/models/concerns/work_item_resource_event.rb index ddf39787f63b88c4e66be0cc38faf43a51ed143f..d3f8419a77eea16c549a5e8fbf36bfa897dd6088 100644 --- a/app/models/concerns/work_item_resource_event.rb +++ b/app/models/concerns/work_item_resource_event.rb @@ -20,8 +20,10 @@ def trigger_note_subscription_create(events: self) end def work_item_synthetic_system_note(events: nil) - # System notes for label resource events are handled in batches, so that we have single system note for multiple - # label changes. + return unless synthetic_note_class + + # System notes for label resource events are handled in batches, + # so that we have single system note for multiple label changes. if is_a?(ResourceLabelEvent) && events.present? return synthetic_note_class.from_events(events, resource: work_item, resource_parent: work_item.project) end @@ -29,7 +31,12 @@ def work_item_synthetic_system_note(events: nil) synthetic_note_class.from_event(self, resource: work_item, resource_parent: work_item.project) end + # Class used to create the even synthetic note + # If the event does not require a synthetic note the method must return false def synthetic_note_class - raise NoMethodError, 'must implement `synthetic_note_class` method' + raise NoMethodError, <<~MESSAGE.squish + `#{self.class.name}#synthetic_note_class` method must be implemented + (return nil if event does not require a note) + MESSAGE end end diff --git a/app/models/resource_event.rb b/app/models/resource_event.rb index 551ea98413295d5f2790d80a03fcdc588d526ba7..88c1576a41bf424851d3349861c70d3136120c40 100644 --- a/app/models/resource_event.rb +++ b/app/models/resource_event.rb @@ -21,7 +21,7 @@ def discussion_id end def issuable - raise NoMethodError, 'must implement `issuable` method' + raise NoMethodError, "`#{self.class.name}#issuable` method must be implemented" end private diff --git a/app/models/work_items/resource_link_event.rb b/app/models/work_items/resource_link_event.rb index 6725acf8c68c9f47574daed3784372209be39b55..b0f52b447e50d355015dbd19eb3ad93188d3521a 100644 --- a/app/models/work_items/resource_link_event.rb +++ b/app/models/work_items/resource_link_event.rb @@ -10,6 +10,10 @@ class ResourceLinkEvent < ResourceEvent add: 1, remove: 2 } + + def synthetic_note_class + nil + end end end diff --git a/spec/models/resource_event_spec.rb b/spec/models/resource_event_spec.rb index 62bd5314b69320e8f304f3526f98be9aa6d303d8..e141c2e4632ffea7dacfb9fac4c6b73da0319271 100644 --- a/spec/models/resource_event_spec.rb +++ b/spec/models/resource_event_spec.rb @@ -3,17 +3,62 @@ require 'spec_helper' RSpec.describe ResourceEvent, feature_category: :team_planning, type: :model do - let(:dummy_resource_label_event_class) do - Class.new(ResourceEvent) do - self.table_name = 'resource_label_events' + context 'when inheriting from ResourceEvent' do + context 'when it does not implement the #issuable method' do + let(:dummy_resource_label_event_class) do + Class.new(ResourceEvent) do + self.table_name = 'resource_label_events' + + def self.name + 'DummyResourceLabelEventClass' + end + end + end + + it 'raises error on not implemented `issuable` method' do + expect { dummy_resource_label_event_class.new.issuable } + .to raise_error( + NoMethodError, + "`DummyResourceLabelEventClass#issuable` method must be implemented" + ) + end end - end - it 'raises error on not implemented `issuable` method' do - expect { dummy_resource_label_event_class.new.issuable }.to raise_error(NoMethodError) - end + context 'when it does not implement the #synthetic_note_class method' do + let(:dummy_resource_label_event_class) do + Class.new(ResourceEvent) do + self.table_name = 'resource_label_events' + + def self.name + 'DummyResourceLabelEventClass' + end + + def issuable + :issuable + end + end + end - it 'raises error on not implemented `synthetic_note_class` method' do - expect { dummy_resource_label_event_class.new.synthetic_note_class }.to raise_error(NoMethodError) + it 'raises error on not implemented `issuable` method' do + expect { dummy_resource_label_event_class.new.synthetic_note_class } + .to raise_error(NoMethodError, <<~MESSAGE.squish) + `DummyResourceLabelEventClass#synthetic_note_class` method must be implemented + (return nil if event does not require a note) + MESSAGE + end + end + + it 'must implement #synthetic_note_class method', :aggregate_failures do + Dir['{ee/,}app/models/**/resource*event.rb'].each do |klass| + require(Rails.root.join(klass)) + end + + described_class.subclasses.each do |klass| + next if klass.abstract_class? + + expect { klass.new.synthetic_note_class } + .not_to(raise_error) + end + end end end diff --git a/spec/support/shared_examples/models/resource_event_shared_examples.rb b/spec/support/shared_examples/models/resource_event_shared_examples.rb index 853d6635305ea4782ab91e25244213474ce12f46..b3cd7281a3070a60c2bbe3c93f2741e4f4de3b80 100644 --- a/spec/support/shared_examples/models/resource_event_shared_examples.rb +++ b/spec/support/shared_examples/models/resource_event_shared_examples.rb @@ -53,6 +53,13 @@ expect(events).to be_empty end end + + describe '#synthetic_note_class' do + it 'must implement #synthetic_note_class method' do + expect { described_class.new.synthetic_note_class } + .not_to raise_error + end + end end RSpec.shared_examples 'a resource event that responds to imported' do