FEATURE: Prevents assign notification & change status on solved (#285)

* FEATURE: Prevents assign notification & change status on solved

Relates to this [topic](https://meta.discourse.org/t/assign-plugin-for-informatica/256974/94)

Add an event listener to `accepted_solution` event

Add `assigns_reminder_assigned_topics_query` modifier to not notify if
`prevent_assign_notification` setting is on.

Add settings to prevent assign notification and change status on solved

* DEV: Address review comments

Update SiteSettings names.

* DEV(WIP): Add tests for integration with discourse-assign

Add test for integration with discourse-assign plugin
checks if the assignment status is moved to `Done`

* DEV: lint solved_spec.rb

* DEV: Update test where it updates all assignments

Change `on(:accepted_solution)` is defined

Update test to use acting_user instead of admin

* DEV: lint & add tests for assigns_reminder_assigned_topics_query

Linted and added tests for `assigns_reminder_assigned_topics_query` modifier.

* DEV: Update tests based on review feedback

change plugin_initializer location

update spec with new tests to test integration with discourse-assign

* DEV: Add describe to spec for discourse-assign integration tests

* DEV: update describe name for discourse-assing spec integration

* DEV: Add more tests to spec for discourse-assign integration

* DEV: Lint solved_spec

* DEV: Lint and update spec to not have `p1` topic inside
This commit is contained in:
Gabriel Grubba 2024-04-26 18:21:09 +02:00 committed by GitHub
parent 2c96c5b67c
commit 2b6e17d1d5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 114 additions and 0 deletions

7
about.json Normal file
View File

@ -0,0 +1,7 @@
{
"tests": {
"requiredPlugins": [
"https://github.com/discourse/discourse-assign"
]
}
}

View File

@ -0,0 +1,30 @@
# frozen_string_literal: true
module DiscourseSolved
class PluginInitializer
attr_reader :plugin
def initialize(plugin)
@plugin = plugin
end
def apply_plugin_api
# this method should be overridden by subclasses
raise NotImplementedError
end
end
class AssignsReminderForTopicsQuery < PluginInitializer
def apply_plugin_api
plugin.register_modifier(:assigns_reminder_assigned_topics_query) do |query|
next query if !SiteSetting.ignore_solved_topics_in_assigned_reminder
query.where.not(
id:
TopicCustomField.where(
name: ::DiscourseSolved::ACCEPTED_ANSWER_POST_ID_CUSTOM_FIELD,
).pluck(:topic_id),
)
end
end
end
end

View File

@ -11,6 +11,8 @@ en:
solved_topics_auto_close_hours: "Auto close topic (n) hours after the last reply once the topic has been marked as solved. Set to 0 to disable auto closing." solved_topics_auto_close_hours: "Auto close topic (n) hours after the last reply once the topic has been marked as solved. Set to 0 to disable auto closing."
show_filter_by_solved_status: "Show a dropdown to filter a topic list by solved status." show_filter_by_solved_status: "Show a dropdown to filter a topic list by solved status."
notify_on_staff_accept_solved: "Send notification to the topic creator when a post is marked as solution by a staff." notify_on_staff_accept_solved: "Send notification to the topic creator when a post is marked as solution by a staff."
ignore_solved_topics_in_assigned_reminder: "Prevent assigned reminder from including solved topics. only relevant when discourse-assign."
assignment_status_on_solve: "When a topic is solved update all assignments to this status"
disable_solved_education_message: "Disable education message for solved topics." disable_solved_education_message: "Disable education message for solved topics."
accept_solutions_topic_author: "Allow the topic author to accept a solution." accept_solutions_topic_author: "Allow the topic author to accept a solution."
solved_add_schema_markup: "Add QAPage schema markup to HTML." solved_add_schema_markup: "Add QAPage schema markup to HTML."

View File

@ -32,6 +32,11 @@ discourse_solved:
client: true client: true
notify_on_staff_accept_solved: notify_on_staff_accept_solved:
default: false default: false
ignore_solved_topics_in_assigned_reminder:
default: false
assignment_status_on_solve:
type: string
default: ""
disable_solved_education_message: disable_solved_education_message:
default: false default: false
accept_solutions_topic_author: accept_solutions_topic_author:

View File

@ -45,6 +45,8 @@ after_initialize do
require_relative "app/lib/web_hook_extension" require_relative "app/lib/web_hook_extension"
require_relative "app/serializers/concerns/topic_answer_mixin" require_relative "app/serializers/concerns/topic_answer_mixin"
require_relative "app/lib/plugin_initializers/assigned_reminder_exclude_solved"
DiscourseSolved::AssignsReminderForTopicsQuery.new(self).apply_plugin_api
module ::DiscourseSolved module ::DiscourseSolved
def self.accept_answer!(post, acting_user, topic: nil) def self.accept_answer!(post, acting_user, topic: nil)
topic ||= post.topic topic ||= post.topic
@ -585,4 +587,14 @@ after_initialize do
required: true required: true
end end
end end
if defined?(DiscourseAssign)
on(:accepted_solution) do |post|
next if SiteSetting.assignment_status_on_solve.blank?
Assigner.new(post.topic, post.acting_user).assign(
post.acting_user,
status: SiteSetting.assignment_status_on_solve,
)
end
end
end end

View File

@ -428,4 +428,62 @@ RSpec.describe "Managing Posts solved status" do
expect(response.status).to eq(200) expect(response.status).to eq(200)
end end
end end
context "with discourse-assign installed", if: defined?(DiscourseAssign) do
let(:admin) { Fabricate(:admin) }
fab!(:group)
before do
SiteSetting.solved_enabled = true
SiteSetting.assign_enabled = true
SiteSetting.enable_assign_status = true
SiteSetting.assign_allowed_on_groups = "#{group.id}"
SiteSetting.assigns_public = true
SiteSetting.assignment_status_on_solve = "Done"
SiteSetting.ignore_solved_topics_in_assigned_reminder = false
group.add(p1.acting_user)
group.add(user)
sign_in(user)
end
describe "updating assignment status on solve when assignment_status_on_solve is set" do
it "update all assignments to this status when a post is accepted" do
assigner = Assigner.new(p1.topic, user)
result = assigner.assign(user)
expect(result[:success]).to eq(true)
expect(p1.topic.assignment.status).to eq("New")
DiscourseSolved.accept_answer!(p1, user)
expect(p1.reload.custom_fields["is_accepted_answer"]).to eq("true")
expect(p1.topic.assignment.reload.status).to eq("Done")
end
describe "assigned topic reminder"
it "excludes solved topics when ignore_solved_topics_in_assigned_reminder is false" do
other_topic = Fabricate(:topic, title: "Topic that should be there")
post = Fabricate(:post, topic: other_topic, user: user)
other_topic2 = Fabricate(:topic, title: "Topic that should be there2")
post2 = Fabricate(:post, topic: other_topic2, user: user)
Assigner.new(post.topic, user).assign(user)
Assigner.new(post2.topic, user).assign(user)
reminder = PendingAssignsReminder.new
topics = reminder.send(:assigned_topics, user, order: :asc)
expect(topics.to_a.length).to eq(2)
DiscourseSolved.accept_answer!(post2, Discourse.system_user)
topics = reminder.send(:assigned_topics, user, order: :asc)
expect(topics.to_a.length).to eq(2)
expect(topics).to include(other_topic2)
SiteSetting.ignore_solved_topics_in_assigned_reminder = true
topics = reminder.send(:assigned_topics, user, order: :asc)
expect(topics.to_a.length).to eq(1)
expect(topics).not_to include(other_topic2)
expect(topics).to include(other_topic)
end
end
end
end end