FEATURE: Publish WebHook event when solving/unsolving (#85)

* FEATURE: Publish WebHook event when solving/unsolving

This feature will publish a post edit webhook event whenever a solution
is accepted or unaccepted.

I went ahead and used the existing post-edit webhook because all the
post custom fields for the solved plugin are already included in the
post-edit serializer.

* Create Solved Event Webhook

This commit adds a solved event webhook that will only trigger when an
answer has been marked as accepted or unaccepted.

It uses 100 as the webhook ID. This way any new webhooks in core can
keep using lower numbers like 11, 12, 13, but plugins can use 101, 102,
etc.

* Removed functionality that was added to core

This [PR][1] to discourse core adds what what removed in this commit.

It is better to have this logic in core so that it is discoverable and
future webhooks won't end up accidentally using the same ID.

[1]: https://github.com/discourse/discourse/pull/9110

* UX: Add "solved" status filter in advanced search page.

And rename `in:solved` to `status:solved`.

* FEATURE: Publish WebHook event when solving/unsolving

This feature will publish a post edit webhook event whenever a solution
is accepted or unaccepted.

I went ahead and used the existing post-edit webhook because all the
post custom fields for the solved plugin are already included in the
post-edit serializer.

* Create Solved Event Webhook

This commit adds a solved event webhook that will only trigger when an
answer has been marked as accepted or unaccepted.

It uses 100 as the webhook ID. This way any new webhooks in core can
keep using lower numbers like 11, 12, 13, but plugins can use 101, 102,
etc.

* Removed functionality that was added to core

This [PR][1] to discourse core adds what what removed in this commit.

It is better to have this logic in core so that it is discoverable and
future webhooks won't end up accidentally using the same ID.

[1]: https://github.com/discourse/discourse/pull/9110

Co-authored-by: Vinoth Kannan <vinothkannan@vinkas.com>
This commit is contained in:
Blake Erickson 2020-03-06 11:28:29 -07:00 committed by GitHub
parent f4aea44db8
commit 8d883fba93
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 66 additions and 0 deletions

View File

@ -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."

View File

@ -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

View File

@ -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

View File

@ -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