discourse/spec/serializers/post_revision_serializer_spec.rb
Régis Hanol 22128ff1ab
FIX: post revision serializer when tags is a string (#27499)
In some instances, the `modifications` of `tags` hasn't been properly serialized as a Ruby array but rather as a string (I've seen `""`, `"[]"`, and `"[\"\"]"`).

This generates an error when we try to `filter_tags` and remove `hidden_tags` (which is an array) from `tags` which might be a string.

Internal ref - t/131126

I wasn't able to figure out the root cause of this so I reverted the behavior that was introduced ~6 years ago in f2c060bdf2
2024-06-21 08:09:21 +10:00

131 lines
3.6 KiB
Ruby

# frozen_string_literal: true
RSpec.describe PostRevisionSerializer do
fab!(:post) { Fabricate(:post, version: 2) }
context "with secured categories" do
fab!(:group)
fab!(:private_category) { Fabricate(:private_category, group: group) }
fab!(:post_revision) do
Fabricate(
:post_revision,
post: post,
modifications: {
"category_id" => [private_category.id, post.topic.category_id],
},
)
end
it "returns category changes to staff" do
json =
PostRevisionSerializer.new(
post_revision,
scope: Guardian.new(Fabricate(:admin)),
root: false,
).as_json
expect(json[:category_id_changes][:previous]).to eq(private_category.id)
expect(json[:category_id_changes][:current]).to eq(post.topic.category_id)
end
it "does not return all category changes to non-staff" do
json =
PostRevisionSerializer.new(
post_revision,
scope: Guardian.new(Fabricate(:user)),
root: false,
).as_json
expect(json[:category_id_changes][:previous]).to eq(nil)
expect(json[:category_id_changes][:current]).to eq(post.topic.category_id)
end
end
it "handles tags not being an array" do
pr = Fabricate(:post_revision, post: post, modifications: { "tags" => ["[]", ""] })
json =
PostRevisionSerializer.new(pr, scope: Guardian.new(Fabricate(:user)), root: false).as_json
expect(json[:tags_changes][:previous]).to eq("[]")
expect(json[:tags_changes][:current]).to eq([])
end
context "with hidden tags" do
fab!(:public_tag) { Fabricate(:tag, name: "public") }
fab!(:public_tag2) { Fabricate(:tag, name: "visible") }
fab!(:hidden_tag) { Fabricate(:tag, name: "hidden") }
fab!(:hidden_tag2) { Fabricate(:tag, name: "secret") }
fab!(:staff_tag_group) do
Fabricate(
:tag_group,
permissions: {
"staff" => 1,
},
tag_names: [hidden_tag.name, hidden_tag2.name],
)
end
let(:post_revision) do
Fabricate(
:post_revision,
post: post,
modifications: {
"tags" => [%w[public hidden], %w[visible hidden]],
},
)
end
let(:post_revision2) do
Fabricate(
:post_revision,
post: post,
modifications: {
"tags" => [%w[visible hidden secret], %w[visible hidden]],
},
)
end
before do
SiteSetting.tagging_enabled = true
post.topic.tags = [public_tag2, hidden_tag]
end
it "returns all tag changes to staff" do
json =
PostRevisionSerializer.new(
post_revision,
scope: Guardian.new(Fabricate(:admin)),
root: false,
).as_json
expect(json[:tags_changes][:previous]).to contain_exactly(public_tag.name, hidden_tag.name)
expect(json[:tags_changes][:current]).to contain_exactly(public_tag2.name, hidden_tag.name)
end
it "does not return hidden tags to non-staff" do
json =
PostRevisionSerializer.new(
post_revision,
scope: Guardian.new(Fabricate(:user)),
root: false,
).as_json
expect(json[:tags_changes][:previous]).to contain_exactly(public_tag.name)
expect(json[:tags_changes][:current]).to contain_exactly(public_tag2.name)
end
it "does not show tag modifications if changes are not visible to the user" do
json =
PostRevisionSerializer.new(
post_revision2,
scope: Guardian.new(Fabricate(:user)),
root: false,
).as_json
expect(json[:tags_changes]).to_not be_present
end
end
end