mirror of
https://github.com/discourse/discourse.git
synced 2026-08-09 21:45:25 +08:00
RSpec setup becomes harder to follow at either extreme: trivial fixture wrappers hide lifecycle and intent, while forcing every named operation inline repeats low-level protocol and configuration details. This change documents and applies a test-setup hierarchy: - use `fab!`, `let`, `let!`, `subject`, and inline `Fabricate` according to lifecycle and role; - use a small example-group method when parameterized behavior gives one spec useful vocabulary; - move helpers into auto-loaded `spec/support` only when they are shared across spec files; - use fabricators and page objects for the data shapes and system-test interfaces they own. Core and plugin support files are loaded centrally by `rails_helper`, so plugin-specific support loaders are unnecessary. The migration specs encountered during the sweep are removed according to repository policy; production migrations are unchanged.
141 lines
4.5 KiB
Ruby
Vendored
141 lines
4.5 KiB
Ruby
Vendored
# frozen_string_literal: true
|
|
|
|
RSpec.describe TopicsController do
|
|
include_context "with group that is allowed to assign"
|
|
|
|
fab!(:actor, :user)
|
|
fab!(:allowed_user, :user)
|
|
fab!(:topic1) { Fabricate(:post).topic }
|
|
fab!(:topic2) { Fabricate(:post).topic }
|
|
|
|
before do
|
|
SiteSetting.assign_enabled = true
|
|
SiteSetting.enable_assign_status = true
|
|
assign_allowed_group.add(actor)
|
|
sign_in(actor)
|
|
end
|
|
|
|
def bulk_assign(operation, ids: [topic1.id, topic2.id])
|
|
put "/topics/bulk.json", params: { topic_ids: ids, operation: }
|
|
end
|
|
|
|
describe "#bulk with the assign operation" do
|
|
it "assigns the selected topics to a group, carrying the note and the status" do
|
|
bulk_assign(
|
|
{
|
|
type: "assign",
|
|
group_name: assign_allowed_group.name,
|
|
note: "handle this",
|
|
status: "In Progress",
|
|
},
|
|
)
|
|
|
|
expect(response.status).to eq(200)
|
|
expect(response.parsed_body["topic_ids"]).to contain_exactly(topic1.id, topic2.id)
|
|
expect(topic1.reload.assignment).to have_attributes(
|
|
assigned_to: assign_allowed_group,
|
|
assigned_to_type: "Group",
|
|
note: "handle this",
|
|
status: "In Progress",
|
|
)
|
|
expect(topic2.reload.assignment.assigned_to).to eq(assign_allowed_group)
|
|
end
|
|
|
|
it "returns a 400 when the operation names no assignee" do
|
|
bulk_assign({ type: "assign" })
|
|
|
|
expect(response.status).to eq(400)
|
|
expect(Assignment.count).to eq(0)
|
|
end
|
|
|
|
it "returns a 404 when the group name matches no group" do
|
|
bulk_assign({ type: "assign", group_name: "no-such-group" })
|
|
|
|
expect(response.status).to eq(404)
|
|
end
|
|
|
|
it "returns a 422 when the status is not one of the configured statuses" do
|
|
bulk_assign({ type: "assign", group_name: assign_allowed_group.name, status: "Bogus" })
|
|
|
|
expect(response.status).to eq(422)
|
|
expect(Assignment.count).to eq(0)
|
|
end
|
|
|
|
it "returns a 403 without disclosing a group the acting user cannot see" do
|
|
hidden_group =
|
|
Fabricate(
|
|
:group,
|
|
visibility_level: Group.visibility_levels[:staff],
|
|
assignable_level: Group::ALIAS_LEVELS[:everyone],
|
|
)
|
|
|
|
bulk_assign({ type: "assign", group_name: hidden_group.name })
|
|
|
|
expect(response.status).to eq(403)
|
|
expect(response.body).not_to include(hidden_group.name)
|
|
expect(Assignment.count).to eq(0)
|
|
end
|
|
|
|
it "returns a 403 when the acting user is not allowed to assign" do
|
|
sign_in(Fabricate(:user))
|
|
|
|
bulk_assign({ type: "assign", group_name: assign_allowed_group.name })
|
|
|
|
expect(response.status).to eq(403)
|
|
expect(Assignment.count).to eq(0)
|
|
end
|
|
|
|
it "returns the per-topic failures alongside the topics that succeeded" do
|
|
assign_allowed_group.add(allowed_user)
|
|
private_group = Fabricate(:group, users: [actor])
|
|
hidden_topic = Fabricate(:topic, category: Fabricate(:private_category, group: private_group))
|
|
|
|
bulk_assign(
|
|
{ type: "assign", username: allowed_user.username },
|
|
ids: [hidden_topic.id, topic2.id],
|
|
)
|
|
|
|
expect(response.status).to eq(200)
|
|
expect(response.parsed_body["topic_ids"]).to contain_exactly(topic2.id)
|
|
expect(response.parsed_body["errors"]).to eq(
|
|
I18n.t(
|
|
"discourse_assign.forbidden_assignee_cant_see_topic",
|
|
username: allowed_user.username,
|
|
) =>
|
|
1,
|
|
)
|
|
end
|
|
|
|
it "reports the topics already assigned to the same assignee as succeeded" do
|
|
Assigner.new(topic1, actor).assign(assign_allowed_group)
|
|
|
|
bulk_assign({ type: "assign", group_name: assign_allowed_group.name })
|
|
|
|
expect(response.status).to eq(200)
|
|
expect(response.parsed_body["topic_ids"]).to contain_exactly(topic1.id, topic2.id)
|
|
expect(response.parsed_body["errors"]).to be_blank
|
|
end
|
|
|
|
it "keeps assigning the rest of the selection when a PM invite is refused" do
|
|
SiteSetting.invite_on_assign = true
|
|
pm = Fabricate(:private_message_topic, user: actor, recipient: allowed_user)
|
|
Fabricate(:post, topic: pm)
|
|
assign_allowed_group.add(Fabricate(:user))
|
|
|
|
bulk_assign(
|
|
{ type: "assign", group_name: assign_allowed_group.name },
|
|
ids: [topic1.id, pm.id],
|
|
)
|
|
|
|
expect(response.status).to eq(200)
|
|
expect(response.parsed_body["topic_ids"]).to contain_exactly(topic1.id)
|
|
expect(response.parsed_body["errors"]).to eq(
|
|
I18n.t(
|
|
"discourse_assign.forbidden_group_assignee_not_pm_participant",
|
|
group: assign_allowed_group.name,
|
|
) =>
|
|
1,
|
|
)
|
|
end
|
|
end
|
|
end
|