From ff508d1ae53fea9a8fe49b3b0c37ecedbd74530e Mon Sep 17 00:00:00 2001 From: Jarek Radosz Date: Mon, 9 Jan 2023 11:26:39 +0100 Subject: [PATCH] FIX: Correctly support DiscourseEvent kwargs (#19788) Fixes the support for kwargs in `DiscourseEvent.trigger()` on Ruby 3, e.g. ```rb DiscourseEvent.trigger(:before_system_message_sent, message_type: type, recipient: @recipient, post_creator_args: post_creator_args, params: method_params) ``` Fixes https://github.com/discourse/discourse-local-site-contacts --- lib/discourse_event.rb | 4 ++-- spec/lib/discourse_event_spec.rb | 21 +++++++++++++-------- spec/lib/system_message_spec.rb | 16 ++++++++++++++-- spec/support/discourse_event_helper.rb | 6 +++--- 4 files changed, 32 insertions(+), 15 deletions(-) diff --git a/lib/discourse_event.rb b/lib/discourse_event.rb index c2db7d10025..4d7f30e27a1 100644 --- a/lib/discourse_event.rb +++ b/lib/discourse_event.rb @@ -9,9 +9,9 @@ class DiscourseEvent @events ||= Hash.new { |hash, key| hash[key] = Set.new } end - def self.trigger(event_name, *params) + def self.trigger(event_name, *args, **kwargs) events[event_name].each do |event| - event.call(*params) + event.call(*args, **kwargs) end end diff --git a/spec/lib/discourse_event_spec.rb b/spec/lib/discourse_event_spec.rb index b3e49e5f96a..f48fc5a743c 100644 --- a/spec/lib/discourse_event_spec.rb +++ b/spec/lib/discourse_event_spec.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true RSpec.describe DiscourseEvent do - describe "#events" do it "defaults to {}" do begin @@ -21,7 +20,6 @@ RSpec.describe DiscourseEvent do end context 'when calling events' do - let(:harvey) { OpenStruct.new( name: 'Harvey Dent', @@ -42,15 +40,12 @@ RSpec.describe DiscourseEvent do end context 'when event does not exist' do - it "does not raise an error" do DiscourseEvent.trigger(:missing_event) end - end context 'when single event exists' do - it "doesn't raise an error" do DiscourseEvent.trigger(:acid_face, harvey) end @@ -59,11 +54,9 @@ RSpec.describe DiscourseEvent do DiscourseEvent.trigger(:acid_face, harvey) expect(harvey.name).to eq('Two Face') end - end context 'when multiple events exist' do - let(:event_handler_2) do Proc.new { |user| user.job = 'Supervillain' } end @@ -84,7 +77,6 @@ RSpec.describe DiscourseEvent do end describe '#all_off' do - let(:event_handler_2) do Proc.new { |user| user.job = 'Supervillain' } end @@ -99,7 +91,20 @@ RSpec.describe DiscourseEvent do DiscourseEvent.trigger(:acid_face, harvey) # Doesn't change anything expect(harvey.job).to eq('gardening') end + end + end + it "allows using kwargs" do + begin + handler = Proc.new do |name:, message:| + expect(name).to eq("Supervillain") + expect(message).to eq("Two Face") + end + + DiscourseEvent.on(:acid_face, &handler) + DiscourseEvent.trigger(:acid_face, name: "Supervillain", message: "Two Face") + ensure + DiscourseEvent.off(:acid_face, &handler) end end end diff --git a/spec/lib/system_message_spec.rb b/spec/lib/system_message_spec.rb index 65062a0951f..160343d97ff 100644 --- a/spec/lib/system_message_spec.rb +++ b/spec/lib/system_message_spec.rb @@ -4,9 +4,7 @@ require 'system_message' require 'topic_subtype' RSpec.describe SystemMessage do - describe '#create' do - fab!(:admin) { Fabricate(:admin) } fab!(:user) { Fabricate(:user) } @@ -81,12 +79,26 @@ RSpec.describe SystemMessage do it 'sends event with post object' do system_message = SystemMessage.new(user) + event = DiscourseEvent.track(:system_message_sent) { system_message.create(:tl2_promotion_message) } + expect(event[:event_name]).to eq(:system_message_sent) expect(event[:params].first[:post]).to eq(Post.last) expect(event[:params].first[:message_type]).to eq(:tl2_promotion_message) end + + it 'sends an event before the system message is sent' do + system_message = SystemMessage.new(user) + + event = DiscourseEvent.track(:before_system_message_sent) { + system_message.create(:tl2_promotion_message) + } + + expect(event[:event_name]).to eq(:before_system_message_sent) + expect(event[:params].first[:message_type]).to eq(:tl2_promotion_message) + expect(event[:params].first[:recipient]).to eq(user) + end end end diff --git a/spec/support/discourse_event_helper.rb b/spec/support/discourse_event_helper.rb index 978be3c659b..a0531b8ca95 100644 --- a/spec/support/discourse_event_helper.rb +++ b/spec/support/discourse_event_helper.rb @@ -1,10 +1,11 @@ # frozen_string_literal: true module DiscourseEvent::TestHelper - def trigger(event_name, *params) - super(event_name, *params) + def trigger(event_name, *params, **kwargs) + super(event_name, *params, **kwargs) if @events_trigger + params << kwargs if kwargs != {} @events_trigger << { event_name: event_name, params: params } end end @@ -29,7 +30,6 @@ module DiscourseEvent::TestHelper events = track_events(event_name, args: args) { yield } events.first end - end DiscourseEvent.singleton_class.prepend DiscourseEvent::TestHelper