diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index b7bf1d2..4361381 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -32,3 +32,9 @@ en: advanced: statuses: solved: "are solved" + + admin: + web_hooks: + solved_event: + name: "Solved Event" + details: "When a user marks a post as the accepted or unaccepted answer." diff --git a/plugin.rb b/plugin.rb index 19af807..26c2378 100644 --- a/plugin.rb +++ b/plugin.rb @@ -20,6 +20,7 @@ register_asset 'stylesheets/solutions.scss' register_asset 'stylesheets/mobile/solutions.scss', :mobile after_initialize do + SeedFu.fixture_paths << Rails.root.join("plugins", "discourse-solved", "db", "fixtures").to_s [ @@ -138,6 +139,11 @@ SQL topic.save! post.save! + if WebHook.active_web_hooks(:solved).exists? + payload = WebHook.generate_payload(:post, post) + WebHook.enqueue_solved_hooks(:accepted_solution, post, payload) + end + DiscourseEvent.trigger(:accepted_solution, post) end @@ -172,6 +178,12 @@ SQL ) notification.destroy! if notification + + if WebHook.active_web_hooks(:solved).exists? + payload = WebHook.generate_payload(:post, post) + WebHook.enqueue_solved_hooks(:unaccepted_solution, post, payload) + end + DiscourseEvent.trigger(:unaccepted_solution, post) end end @@ -348,6 +360,21 @@ SQL end end + class ::WebHook + def self.enqueue_solved_hooks(event, post, payload = nil) + if active_web_hooks('solved').exists? && post.present? + payload ||= WebHook.generate_payload(:post, post) + + WebHook.enqueue_hooks(:solved, event, + id: post.id, + category_id: post.topic&.category_id, + tag_ids: post.topic&.tags&.pluck(:id), + payload: payload + ) + end + end + end + require_dependency 'topic_view_serializer' class ::TopicViewSerializer attributes :accepted_answer diff --git a/spec/fabricators/solved_hook_fabricator.rb b/spec/fabricators/solved_hook_fabricator.rb new file mode 100644 index 0000000..641fef8 --- /dev/null +++ b/spec/fabricators/solved_hook_fabricator.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +Fabricator(:solved_web_hook, from: :web_hook) do + transient solved_hook: WebHookEventType.find_by(name: 'solved') + + after_build do |web_hook, transients| + web_hook.web_hook_event_types = [transients[:solved_hook]] + end +end diff --git a/spec/integration/solved_spec.rb b/spec/integration/solved_spec.rb index fda575a..e39a87e 100644 --- a/spec/integration/solved_spec.rb +++ b/spec/integration/solved_spec.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require 'rails_helper' +require_relative '../fabricators/solved_hook_fabricator.rb' RSpec.describe "Managing Posts solved status" do let(:topic) { Fabricate(:topic) } @@ -98,6 +99,17 @@ RSpec.describe "Managing Posts solved status" do post "/solution/accept.json", params: { id: whisper.id } expect(response.status).to eq(403) end + + it 'triggers a webhook' do + Fabricate(:solved_web_hook) + post "/solution/accept.json", params: { id: p1.id } + + job_args = Jobs::EmitWebHookEvent.jobs[0]["args"].first + + expect(job_args["event_name"]).to eq("accepted_solution") + payload = JSON.parse(job_args["payload"]) + expect(payload["id"]).to eq(p1.id) + end end describe '#unaccept' do @@ -122,6 +134,18 @@ RSpec.describe "Managing Posts solved status" do expect(p1.custom_fields["is_accepted_answer"]).to eq(nil) expect(p1.topic.custom_fields["accepted_answer_post_id"]).to eq(nil) end + + end + + it 'triggers a webhook' do + Fabricate(:solved_web_hook) + post "/solution/unaccept.json", params: { id: p1.id } + + job_args = Jobs::EmitWebHookEvent.jobs[0]["args"].first + + expect(job_args["event_name"]).to eq("unaccepted_solution") + payload = JSON.parse(job_args["payload"]) + expect(payload["id"]).to eq(p1.id) end end end