FIX: Broken posts when assigning a closed topic (#425)

The previous behavior was:
1. Assign a topic to someone
2. Close the topic with the setting unassign_on_close enabled
3. Assign the topic to the same user as before

This caused small broken or empty posts to be displayed.

This commit also introduces system specs
This commit is contained in:
Jan Cernik 2023-01-17 08:09:35 -03:00 committed by GitHub
parent 6672ad1ff4
commit 896d0e3445
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 188 additions and 1 deletions

View File

@ -811,6 +811,11 @@ function initialize(api) {
});
this.appEvents.trigger("post-stream:refresh", { id: data.post_id });
}
if (topic.closed) {
this.appEvents.trigger("post-stream:refresh", {
id: topic.postStream.posts[0].id,
});
}
}
this.appEvents.trigger("header:update-topic", topic);
});

View File

@ -261,7 +261,7 @@ class ::Assigner
forbidden_reasons(assign_to: assign_to, type: assigned_to_type, note: note, status: status)
return { success: false, reason: forbidden_reason } if forbidden_reason
if no_assignee_change?(assign_to)
if no_assignee_change?(assign_to) && details_change?(note, status)
return update_details(assign_to, note, status, skip_small_action_post: skip_small_action_post)
end
@ -536,6 +536,10 @@ class ::Assigner
@target.assignment&.assigned_to_id == assignee.id
end
def details_change?(note, status)
note.present? || @target.assignment&.status != status
end
def assignment_eq?(assignment, assign_to, type, note, status)
return false if !assignment&.active
return false if assignment.assigned_to_id != assign_to.id

View File

@ -0,0 +1,114 @@
# frozen_string_literal: true
describe "Assign | Assigning topics", type: :system, js: true do
let(:topic_page) { PageObjects::Pages::Topic.new }
let(:assign_modal) { PageObjects::Modals::Assign.new }
fab!(:staff_user) { Fabricate(:user, groups: [Group[:staff]]) }
fab!(:admin) { Fabricate(:admin) }
fab!(:topic) { Fabricate(:topic) }
fab!(:post) { Fabricate(:post, topic: topic) }
before do
SiteSetting.assign_enabled = true
sign_in(admin)
end
describe "with open topic" do
it "can assign and unassign" do
visit "/t/#{topic.id}"
topic_page.click_assign_topic
assign_modal.assignee = staff_user
assign_modal.confirm
expect(topic_page).to have_assigned(user: staff_user, at_post: 2)
expect(find("#topic .assigned-to")).to have_content(staff_user.username)
topic_page.click_unassign_topic
expect(topic_page).to have_unassigned(user: staff_user, at_post: 3)
expect(page).to have_no_css("#topic .assigned-to")
end
context "when unassign_on_close is set to true" do
before { SiteSetting.unassign_on_close = true }
it "unassigns the topic on close" do
visit "/t/#{topic.id}"
topic_page.click_assign_topic
assign_modal.assignee = staff_user
assign_modal.confirm
expect(topic_page).to have_assigned(user: staff_user, at_post: 2)
find(".topic-footer-main-buttons .toggle-admin-menu").click
find(".topic-admin-close").click
expect(find("#post_3")).to have_content(
I18n.t("js.action_codes.closed.enabled", when: "just now"),
)
expect(page).to have_no_css("#post_4")
expect(page).to have_no_css("#topic .assigned-to")
end
it "can assign the previous assignee" do
visit "/t/#{topic.id}"
topic_page.click_assign_topic
assign_modal.assignee = staff_user
assign_modal.confirm
expect(topic_page).to have_assigned(user: staff_user, at_post: 2)
find(".topic-footer-main-buttons .toggle-admin-menu").click
find(".topic-admin-close").click
expect(find("#post_3")).to have_content(
I18n.t("js.action_codes.closed.enabled", when: "just now"),
)
expect(page).to have_no_css("#post_4")
expect(page).to have_no_css("#topic .assigned-to")
topic_page.click_assign_topic
assign_modal.assignee = staff_user
assign_modal.confirm
expect(page).to have_no_css("#post_4")
expect(find("#topic .assigned-to")).to have_content(staff_user.username)
end
context "when reassign_on_open is set to true" do
before { SiteSetting.reassign_on_open = true }
it "reassigns the topic on open" do
visit "/t/#{topic.id}"
topic_page.click_assign_topic
assign_modal.assignee = staff_user
assign_modal.confirm
expect(topic_page).to have_assigned(user: staff_user, at_post: 2)
find(".topic-footer-main-buttons .toggle-admin-menu").click
find(".topic-admin-close").click
expect(find("#post_3")).to have_content(
I18n.t("js.action_codes.closed.enabled", when: "just now"),
)
expect(page).to have_no_css("#post_4")
expect(page).to have_no_css("#topic .assigned-to")
find(".topic-footer-main-buttons .toggle-admin-menu").click
find(".topic-admin-open").click
expect(find("#post_4")).to have_content(
I18n.t("js.action_codes.closed.disabled", when: "just now"),
)
expect(page).to have_no_css("#post_5")
expect(find("#topic .assigned-to")).to have_content(staff_user.username)
end
end
end
end
end

View File

@ -0,0 +1,27 @@
# frozen_string_literal: true
module PageObjects
module Modals
class Assign < PageObjects::Modals::Base
def assignee=(assignee)
assignee = assignee.is_a?(Group) ? assignee.name : assignee.username
find(".control-group .multi-select").click
find(".control-group input").fill_in(with: assignee)
find("li[data-value='#{assignee}']").click
end
def status=(status)
find("#assign-status").click
find("[data-value='#{status}']").click
end
def note=(note)
find("#assign-modal-note").fill_in(with: note)
end
def confirm
find(".modal-footer .btn-primary").click
end
end
end
end

View File

@ -0,0 +1,37 @@
# frozen_string_literal: true
module PageObjects
module Pages
class Topic < PageObjects::Pages::Base
def click_assign_topic
find("#topic-footer-button-assign").click
end
def click_unassign_topic
find("#topic-footer-dropdown-reassign").click
find("[data-value='unassign']").click
end
def click_edit_topic_assignment
find("#topic-footer-dropdown-reassign").click
find("[data-value='reassign']").click
end
def has_assigned?(args)
has_assignment_action?(action: "assigned", **args)
end
def has_unassigned?(args)
has_assignment_action?(action: "unassigned", **args)
end
def has_assignment_action?(args)
assignee = args[:group]&.name || args[:user]&.username
container = args[:at_post] ? find("#post_#{args[:at_post]}") : page
container.has_content?(
I18n.t("js.action_codes.#{args[:action]}", who: "@#{assignee}", when: "just now"),
)
end
end
end
end