diff --git a/app/controllers/discourse_assign/assign_controller.rb b/app/controllers/discourse_assign/assign_controller.rb index 3c340d1..031e231 100644 --- a/app/controllers/discourse_assign/assign_controller.rb +++ b/app/controllers/discourse_assign/assign_controller.rb @@ -2,6 +2,7 @@ module DiscourseAssign class AssignController < ApplicationController + requires_plugin DiscourseAssign::PLUGIN_NAME requires_login before_action :ensure_logged_in, :ensure_assign_allowed diff --git a/lib/discourse_calendar.rb b/lib/discourse_assign/discourse_calendar.rb similarity index 100% rename from lib/discourse_calendar.rb rename to lib/discourse_assign/discourse_calendar.rb diff --git a/lib/discourse_assign/engine.rb b/lib/discourse_assign/engine.rb deleted file mode 100644 index 2e2caa3..0000000 --- a/lib/discourse_assign/engine.rb +++ /dev/null @@ -1,8 +0,0 @@ -# frozen_string_literal: true - -module ::DiscourseAssign - class Engine < ::Rails::Engine - engine_name "discourse_assign" - isolate_namespace DiscourseAssign - end -end diff --git a/lib/discourse_assign/group_extension.rb b/lib/discourse_assign/group_extension.rb new file mode 100644 index 0000000..628c882 --- /dev/null +++ b/lib/discourse_assign/group_extension.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +module DiscourseAssign + module GroupExtension + def self.prepended(base) + base.class_eval do + scope :assignable, + ->(user) { + where( + "assignable_level in (:levels) OR + ( + assignable_level = #{Group::ALIAS_LEVELS[:members_mods_and_admins]} AND id in ( + SELECT group_id FROM group_users WHERE user_id = :user_id) + ) OR ( + assignable_level = #{Group::ALIAS_LEVELS[:owners_mods_and_admins]} AND id in ( + SELECT group_id FROM group_users WHERE user_id = :user_id AND owner IS TRUE) + )", + levels: alias_levels(user), + user_id: user&.id, + ) + } + end + end + end +end diff --git a/lib/discourse_assign/list_controller_extension.rb b/lib/discourse_assign/list_controller_extension.rb new file mode 100644 index 0000000..654d63f --- /dev/null +++ b/lib/discourse_assign/list_controller_extension.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +module DiscourseAssign + module ListControllerExtension + def self.prepended(base) + base.class_eval { generate_message_route(:private_messages_assigned) } + end + end +end diff --git a/lib/discourse_assign/post_extension.rb b/lib/discourse_assign/post_extension.rb new file mode 100644 index 0000000..c6c8ab6 --- /dev/null +++ b/lib/discourse_assign/post_extension.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +module DiscourseAssign + module PostExtension + def self.prepended(base) + base.class_eval { has_one :assignment, as: :target, dependent: :destroy } + end + end +end diff --git a/lib/discourse_assign/topic_extension.rb b/lib/discourse_assign/topic_extension.rb new file mode 100644 index 0000000..5c6c60b --- /dev/null +++ b/lib/discourse_assign/topic_extension.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +module DiscourseAssign + module TopicExtension + def self.prepended(base) + base.class_eval { has_one :assignment, as: :target, dependent: :destroy } + end + end +end diff --git a/lib/discourse_assign/web_hook_extension.rb b/lib/discourse_assign/web_hook_extension.rb new file mode 100644 index 0000000..d685b4f --- /dev/null +++ b/lib/discourse_assign/web_hook_extension.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module DiscourseAssign + module WebHookExtension + def self.prepended(base) + base.class_eval do + def self.enqueue_assign_hooks(event, payload) + if active_web_hooks("assign").exists? + WebHook.enqueue_hooks(:assign, event, payload: payload) + end + end + end + end + end +end diff --git a/plugin.rb b/plugin.rb index dc05551..4b2321c 100644 --- a/plugin.rb +++ b/plugin.rb @@ -14,74 +14,80 @@ register_asset "stylesheets/mobile/assigns.scss", :mobile %w[user-plus user-times group-plus group-times].each { |i| register_svg_icon(i) } -load File.expand_path("../lib/discourse_assign/engine.rb", __FILE__) -load File.expand_path("../lib/discourse_assign/helpers.rb", __FILE__) -load File.expand_path("../lib/validators/assign_statuses_validator.rb", __FILE__) -load File.expand_path("../lib/discourse_calendar.rb", __FILE__) - -Discourse::Application.routes.append do - mount ::DiscourseAssign::Engine, at: "/assign" - get "topics/private-messages-assigned/:username" => "list#private_messages_assigned", - :as => "topics_private_messages_assigned", - :constraints => { - username: ::RouteFormat.username, - } - get "/topics/messages-assigned/:username" => "list#messages_assigned", - :constraints => { - username: ::RouteFormat.username, - }, - :as => "messages_assigned" - get "/topics/group-topics-assigned/:groupname" => "list#group_topics_assigned", - :constraints => { - username: ::RouteFormat.username, - }, - :as => "group_topics_assigned" - get "/g/:id/assigned" => "groups#index" - get "/g/:id/assigned/:route_type" => "groups#index" -end +require_relative "app/models/assign_mailer_site_settings.rb" +require_relative "app/models/remind_assigns_frequency_site_settings.rb" +require_relative "lib/validators/assign_statuses_validator.rb" after_initialize do - require File.expand_path("../jobs/scheduled/enqueue_reminders.rb", __FILE__) - require File.expand_path("../jobs/regular/remind_user.rb", __FILE__) - require File.expand_path("../jobs/regular/assign_notification.rb", __FILE__) - require File.expand_path("../jobs/regular/unassign_notification.rb", __FILE__) - require "topic_assigner" - require "assigner" - require "pending_assigns_reminder" + module ::DiscourseAssign + PLUGIN_NAME = "discourse-assign" + + class Engine < ::Rails::Engine + engine_name DiscourseAssign::PLUGIN_NAME + isolate_namespace DiscourseAssign + end + end + + require_relative "app/controllers/discourse_assign/assign_controller.rb" + require_relative "app/mailers/assign_mailer.rb" + require_relative "app/models/assign_mailer_site_settings.rb" + require_relative "app/models/assignment.rb" + require_relative "app/models/remind_assigns_frequency_site_settings.rb" + require_relative "app/serializers/assigned_group_serializer.rb" + require_relative "app/serializers/assigned_topic_serializer.rb" + require_relative "app/serializers/group_user_assigned_serializer.rb" + require_relative "config/routes.rb" + require_relative "jobs/regular/assign_notification.rb" + require_relative "jobs/regular/remind_user.rb" + require_relative "jobs/regular/unassign_notification.rb" + require_relative "jobs/scheduled/enqueue_reminders.rb" + require_relative "lib/assigner.rb" + require_relative "lib/discourse_assign/discourse_calendar.rb" + require_relative "lib/discourse_assign/group_extension.rb" + require_relative "lib/discourse_assign/helpers.rb" + require_relative "lib/discourse_assign/list_controller_extension.rb" + require_relative "lib/discourse_assign/post_extension.rb" + require_relative "lib/discourse_assign/topic_extension.rb" + require_relative "lib/discourse_assign/web_hook_extension.rb" + require_relative "lib/pending_assigns_reminder.rb" + require_relative "lib/random_assign_utils.rb" + require_relative "lib/topic_assigner.rb" + require_relative "lib/validators/assign_statuses_validator.rb" + + Discourse::Application.routes.append do + mount ::DiscourseAssign::Engine, at: "/assign" + + get "topics/private-messages-assigned/:username" => "list#private_messages_assigned", + :as => "topics_private_messages_assigned", + :constraints => { + username: ::RouteFormat.username, + } + get "/topics/messages-assigned/:username" => "list#messages_assigned", + :constraints => { + username: ::RouteFormat.username, + }, + :as => "messages_assigned" + get "/topics/group-topics-assigned/:groupname" => "list#group_topics_assigned", + :constraints => { + username: ::RouteFormat.username, + }, + :as => "group_topics_assigned" + get "/g/:id/assigned" => "groups#index" + get "/g/:id/assigned/:route_type" => "groups#index" + end + + reloadable_patch do |plugin| + Group.class_eval { prepend DiscourseAssign::GroupExtension } + Post.class_eval { prepend DiscourseAssign::PostExtension } + Topic.class_eval { prepend DiscourseAssign::TopicExtension } + WebHook.class_eval { prepend DiscourseAssign::WebHookExtension } + end register_group_param(:assignable_level) register_groups_callback_for_users_search_controller_action(:assignable_groups) do |groups, user| groups.assignable(user) end - reloadable_patch do |plugin| - class ::Topic - has_one :assignment, as: :target, dependent: :destroy - end - - class ::Post - has_one :assignment, as: :target, dependent: :destroy - end - - class ::Group - scope :assignable, - ->(user) { - where( - "assignable_level in (:levels) OR - ( - assignable_level = #{ALIAS_LEVELS[:members_mods_and_admins]} AND id in ( - SELECT group_id FROM group_users WHERE user_id = :user_id) - ) OR ( - assignable_level = #{ALIAS_LEVELS[:owners_mods_and_admins]} AND id in ( - SELECT group_id FROM group_users WHERE user_id = :user_id AND owner IS TRUE) - )", - levels: alias_levels(user), - user_id: user && user.id, - ) - } - end - end - frequency_field = PendingAssignsReminder::REMINDERS_FREQUENCY register_editable_user_custom_field frequency_field User.register_custom_field_type frequency_field, :integer @@ -328,7 +334,6 @@ after_initialize do end # TopicQuery - require_dependency "topic_query" TopicQuery.add_custom_filter(:assigned) do |results, topic_query| name = topic_query.options[:assigned] next results if name.blank? @@ -449,11 +454,6 @@ after_initialize do end # ListController - require_dependency "list_controller" - class ::ListController - generate_message_route(:private_messages_assigned) - end - add_to_class(:list_controller, :messages_assigned) do user = User.find_by_username(params[:username]) raise Discourse::NotFound unless user @@ -921,12 +921,6 @@ after_initialize do end end - class ::WebHook - def self.enqueue_assign_hooks(event, payload) - WebHook.enqueue_hooks(:assign, event, payload: payload) if active_web_hooks("assign").exists? - end - end - register_search_advanced_filter(/in:assigned/) do |posts| posts.where(<<~SQL) if @guardian.can_assign? topics.id IN ( @@ -962,8 +956,6 @@ after_initialize do end if defined?(DiscourseAutomation) - require "random_assign_utils" - add_automation_scriptable("random_assign") do field :assignees_group, component: :group, required: true field :assigned_topic, component: :text, required: true diff --git a/spec/lib/random_assign_utils_spec.rb b/spec/lib/random_assign_utils_spec.rb index 500a545..ca96627 100644 --- a/spec/lib/random_assign_utils_spec.rb +++ b/spec/lib/random_assign_utils_spec.rb @@ -2,7 +2,6 @@ require "rails_helper" require_relative "../support/assign_allowed_group" -require "random_assign_utils" describe RandomAssignUtils do before do diff --git a/spec/requests/assign_controller_spec.rb b/spec/requests/assign_controller_spec.rb index 3f8bae9..7aeefc4 100644 --- a/spec/requests/assign_controller_spec.rb +++ b/spec/requests/assign_controller_spec.rb @@ -502,10 +502,10 @@ RSpec.describe DiscourseAssign::AssignController do expect(response.status).to eq(403) end - it "responds with 403 if the assign_enabled setting is disabled" do + it "responds with 404 if the assign_enabled setting is disabled" do SiteSetting.assign_enabled = false get "/assign/user-menu-assigns.json" - expect(response.status).to eq(403) + expect(response.status).to eq(404) end it "sends an array of unread assigned notifications" do