From e7407d0adc7a3d9cace7fe464a0aea75a5b3d816 Mon Sep 17 00:00:00 2001 From: Vinoth Kannan Date: Tue, 27 Mar 2018 11:53:35 +0530 Subject: [PATCH] FEATURE: Webhook for group and category events --- app/controllers/admin/groups_controller.rb | 5 ++- app/controllers/categories_controller.rb | 2 ++ app/controllers/groups_controller.rb | 1 + app/models/category.rb | 13 ++++++++ app/models/group.rb | 13 ++++++++ app/models/web_hook_event_type.rb | 2 ++ config/initializers/012-web_hook_events.rb | 20 ++++++++++++ config/locales/client.en.yml | 6 ++++ db/fixtures/007_web_hook_event_types.rb | 10 ++++++ spec/models/category_spec.rb | 20 +++++++++++- spec/models/group_spec.rb | 36 ++++++++++++++++----- spec/requests/categories_controller_spec.rb | 24 ++++++++++++++ spec/requests/groups_controller_spec.rb | 9 ++++++ 13 files changed, 151 insertions(+), 10 deletions(-) create mode 100644 spec/requests/categories_controller_spec.rb diff --git a/app/controllers/admin/groups_controller.rb b/app/controllers/admin/groups_controller.rb index 8a6a7a72394..cb784c14d14 100644 --- a/app/controllers/admin/groups_controller.rb +++ b/app/controllers/admin/groups_controller.rb @@ -55,7 +55,10 @@ class Admin::GroupsController < Admin::AdminController # group rename is ignored for automatic groups group.name = group_params[:name] if group_params[:name] && !group.automatic - save_group(group) { |g| GroupActionLogger.new(current_user, g).log_change_group_settings } + save_group(group) do |group| + GroupActionLogger.new(current_user, group).log_change_group_settings + DiscourseEvent.trigger(:group_updated, group) + end end def save_group(group) diff --git a/app/controllers/categories_controller.rb b/app/controllers/categories_controller.rb index aaaf1ec7bd6..e2fa98fda1a 100644 --- a/app/controllers/categories_controller.rb +++ b/app/controllers/categories_controller.rb @@ -149,6 +149,7 @@ class CategoriesController < ApplicationController old_permissions = cat.permissions_params if result = cat.update(category_params) + DiscourseEvent.trigger(:category_updated, cat) Scheduler::Defer.later "Log staff action change category settings" do @staff_action_logger.log_category_settings_change(@category, category_params, old_permissions) end @@ -165,6 +166,7 @@ class CategoriesController < ApplicationController custom_slug = params[:slug].to_s if custom_slug.present? && @category.update_attributes(slug: custom_slug) + DiscourseEvent.trigger(:category_updated, @category) render json: success_json else render_json_error(@category) diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index 70d219afc09..3f5ac6bbe88 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -122,6 +122,7 @@ class GroupsController < ApplicationController if group.update_attributes(group_params) GroupActionLogger.new(current_user, group).log_change_group_settings + DiscourseEvent.trigger(:group_updated, group) render json: success_json else diff --git a/app/models/category.rb b/app/models/category.rb index e551227ed6f..130eb6ff120 100644 --- a/app/models/category.rb +++ b/app/models/category.rb @@ -61,6 +61,9 @@ class Category < ActiveRecord::Base after_update :rename_category_definition, if: :saved_change_to_name? after_update :create_category_permalink, if: :saved_change_to_slug? + after_commit :trigger_category_created_event, on: :create + after_commit :trigger_category_destroyed_event, on: :destroy + belongs_to :parent_category, class_name: 'Category' has_many :subcategories, class_name: 'Category', foreign_key: 'parent_category_id' @@ -511,6 +514,16 @@ SQL def subcategory_list_includes_topics? subcategory_list_style.end_with?("with_featured_topics") end + + def trigger_category_created_event + DiscourseEvent.trigger(:category_created, self) + true + end + + def trigger_category_destroyed_event + DiscourseEvent.trigger(:category_destroyed, self) + true + end end # == Schema Information diff --git a/app/models/group.rb b/app/models/group.rb index 90bb845f63f..c3e13992274 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -35,6 +35,9 @@ class Group < ActiveRecord::Base after_save :expire_cache after_destroy :expire_cache + after_commit :trigger_group_created_event, on: :create + after_commit :trigger_group_destroyed_event, on: :destroy + def expire_cache ApplicationSerializer.expire_cache_fragment!("group_names") end @@ -571,6 +574,16 @@ class Group < ActiveRecord::Base self.member_of(groups, user).where("gu.owner") end + def trigger_group_created_event + DiscourseEvent.trigger(:group_created, self) + true + end + + def trigger_group_destroyed_event + DiscourseEvent.trigger(:group_destroyed, self) + true + end + protected def name_format_validator diff --git a/app/models/web_hook_event_type.rb b/app/models/web_hook_event_type.rb index d3596bfdaf5..a98bd5a99d0 100644 --- a/app/models/web_hook_event_type.rb +++ b/app/models/web_hook_event_type.rb @@ -2,6 +2,8 @@ class WebHookEventType < ActiveRecord::Base TOPIC = 1 POST = 2 USER = 3 + GROUP = 4 + CATEGORY = 5 has_and_belongs_to_many :web_hooks diff --git a/config/initializers/012-web_hook_events.rb b/config/initializers/012-web_hook_events.rb index 7e29c2d3011..158d09e3f0f 100644 --- a/config/initializers/012-web_hook_events.rb +++ b/config/initializers/012-web_hook_events.rb @@ -42,3 +42,23 @@ end WebHook.enqueue_hooks(:user, user_id: user.id, event_name: event.to_s) end end + +%i( + group_created + group_updated + group_destroyed +).each do |event| + DiscourseEvent.on(event) do |group| + WebHook.enqueue_hooks(:group, group_id: group.id, event_name: event.to_s) + end +end + +%i( + category_created + category_updated + category_destroyed +).each do |event| + DiscourseEvent.on(event) do |category| + WebHook.enqueue_hooks(:category, category_id: category.id, event_name: event.to_s) + end +end diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 8b4f2ff8136..2cfd5e1a1eb 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -2915,6 +2915,12 @@ en: user_event: name: "User Event" details: "When a user logs in, logs out, is created, approved or updated." + group_event: + name: "Group Event" + details: "When a group is created, updated or destroyed." + category_event: + name: "Category Event" + details: "When a category is created, updated or destroyed." delivery_status: title: "Delivery Status" inactive: "Inactive" diff --git a/db/fixtures/007_web_hook_event_types.rb b/db/fixtures/007_web_hook_event_types.rb index d91b5f09a1a..c3f8b8b1509 100644 --- a/db/fixtures/007_web_hook_event_types.rb +++ b/db/fixtures/007_web_hook_event_types.rb @@ -12,3 +12,13 @@ WebHookEventType.seed do |b| b.id = WebHookEventType::USER b.name = "user" end + +WebHookEventType.seed do |b| + b.id = WebHookEventType::GROUP + b.name = "group" +end + +WebHookEventType.seed do |b| + b.id = WebHookEventType::CATEGORY + b.name = "category" +end diff --git a/spec/models/category_spec.rb b/spec/models/category_spec.rb index 9f756f394f1..51992b1ce56 100644 --- a/spec/models/category_spec.rb +++ b/spec/models/category_spec.rb @@ -368,6 +368,17 @@ describe Category do end end + describe 'new' do + subject { Fabricate.build(:category, user: Fabricate(:user)) } + + it 'triggers a extensibility event' do + event = DiscourseEvent.track_events { subject.save! }.last + + expect(event[:event_name]).to eq(:category_created) + expect(event[:params].first).to eq(subject) + end + end + describe "update" do it "should enforce uniqueness of slug" do Fabricate(:category, slug: "the-slug") @@ -384,14 +395,21 @@ describe Category do @category_id = @category.id @topic_id = @category.topic_id SiteSetting.shared_drafts_category = @category.id.to_s - @category.destroy end it 'is deleted correctly' do + @category.destroy expect(Category.exists?(id: @category_id)).to be false expect(Topic.exists?(id: @topic_id)).to be false expect(SiteSetting.shared_drafts_category).to be_blank end + + it 'triggers a extensibility event' do + event = DiscourseEvent.track_events { @category.destroy }.first + + expect(event[:event_name]).to eq(:category_destroyed) + expect(event[:params].first).to eq(@category) + end end describe 'latest' do diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb index 20b1e242d14..255b1d245e2 100644 --- a/spec/models/group_spec.rb +++ b/spec/models/group_spec.rb @@ -411,17 +411,37 @@ describe Group do expect(g.usernames.split(",").sort).to eq usernames.split(",").sort end - it "correctly destroys groups" do + describe 'new' do + subject { Fabricate.build(:group) } - g = Fabricate(:group) - u1 = Fabricate(:user) - g.add(u1) - g.save! + it 'triggers a extensibility event' do + event = DiscourseEvent.track_events { subject.save! }.first - g.destroy + expect(event[:event_name]).to eq(:group_created) + expect(event[:params].first).to eq(subject) + end + end - expect(User.where(id: u1.id).count).to eq 1 - expect(GroupUser.where(group_id: g.id).count).to eq 0 + describe 'destroy' do + let(:user) { Fabricate(:user) } + let(:group) { Fabricate(:group, users: [user]) } + + before do + group.add(user) + end + + it "it deleted correctly" do + group.destroy! + expect(User.where(id: user.id).count).to eq 1 + expect(GroupUser.where(group_id: group.id).count).to eq 0 + end + + it 'triggers a extensibility event' do + event = DiscourseEvent.track_events { group.destroy! }.first + + expect(event[:event_name]).to eq(:group_destroyed) + expect(event[:params].first).to eq(group) + end end it "has custom fields" do diff --git a/spec/requests/categories_controller_spec.rb b/spec/requests/categories_controller_spec.rb new file mode 100644 index 00000000000..9934db2450a --- /dev/null +++ b/spec/requests/categories_controller_spec.rb @@ -0,0 +1,24 @@ +require 'rails_helper' + +describe GroupsController do + let(:admin) { Fabricate(:admin) } + let(:category) { Fabricate(:category, user: admin) } + + before do + category + sign_in(admin) + end + + it "triggers a extensibility event" do + event = DiscourseEvent.track_events { + put "/categories/#{category.id}.json", params: { + name: 'hello', + color: 'ff0', + text_color: 'fff' + } + }.last + + expect(event[:event_name]).to eq(:category_updated) + expect(event[:params].first).to eq(category) + end +end diff --git a/spec/requests/groups_controller_spec.rb b/spec/requests/groups_controller_spec.rb index 494d1499899..57f12c1e578 100644 --- a/spec/requests/groups_controller_spec.rb +++ b/spec/requests/groups_controller_spec.rb @@ -321,6 +321,15 @@ describe GroupsController do expect(response).to be_success expect(group.reload.flair_color).to eq('BBB') end + + it 'triggers a extensibility event' do + event = DiscourseEvent.track_events { + put "/groups/#{group.id}.json", params: { group: { flair_color: 'BBB' } } + }.last + + expect(event[:event_name]).to eq(:group_updated) + expect(event[:params].first).to eq(group) + end end context "when user is not a group owner or admin" do