discourse/spec/serializers/post_serializer_spec.rb
Bianca Nenciu b160331d41
FIX: Move show like logic to client side (#18025)
The logic was added in commit ec8306835d,
to show the like action even if the user could not like the post. It is
not necessary for this logic to be implemented on the server side.
2022-08-22 18:40:09 +03:00

347 lines
12 KiB
Ruby

# frozen_string_literal: true
RSpec.describe PostSerializer do
fab!(:post) { Fabricate(:post) }
context "with a post with lots of actions" do
fab!(:actor) { Fabricate(:user) }
fab!(:admin) { Fabricate(:admin) }
let(:acted_ids) {
PostActionType.public_types.values
.concat([:notify_user, :spam].map { |k| PostActionType.types[k] })
}
def visible_actions_for(user)
serializer = PostSerializer.new(post, scope: Guardian.new(user), root: false)
# NOTE this is messy, we should extract all this logic elsewhere
serializer.post_actions = PostAction.counts_for([post], actor)[post.id] if user.try(:id) == actor.id
actions = serializer.as_json[:actions_summary]
lookup = PostActionType.types.invert
actions.keep_if { |a| (a[:count] || 0) > 0 }.map { |a| lookup[a[:id]] }
end
before do
acted_ids.each do |id|
PostActionCreator.new(actor, post, id).perform
end
post.reload
end
it "displays the correct info" do
expect(visible_actions_for(actor).sort).to eq([:like, :notify_user, :spam])
expect(visible_actions_for(post.user).sort).to eq([:like])
expect(visible_actions_for(nil).sort).to eq([:like])
expect(visible_actions_for(admin).sort).to eq([:like, :notify_user, :spam])
end
it "can't flag your own post to notify yourself" do
serializer = PostSerializer.new(post, scope: Guardian.new(post.user), root: false)
notify_user_action = serializer.actions_summary.find { |a| a[:id] == PostActionType.types[:notify_user] }
expect(notify_user_action).to be_blank
end
it "should not allow user to flag post and notify non human user" do
post.update!(user: Discourse.system_user)
serializer = PostSerializer.new(
post,
scope: Guardian.new(actor),
root: false
)
notify_user_action = serializer.actions_summary.find do |a|
a[:id] == PostActionType.types[:notify_user]
end
expect(notify_user_action).to eq(nil)
end
end
context "with a post with reviewable content" do
let!(:reviewable) { PostActionCreator.spam(Fabricate(:user), post).reviewable }
it "includes the reviewable data" do
json = PostSerializer.new(post, scope: Guardian.new(Fabricate(:moderator)), root: false).as_json
expect(json[:reviewable_id]).to eq(reviewable.id)
expect(json[:reviewable_score_count]).to eq(1)
expect(json[:reviewable_score_pending_count]).to eq(1)
end
end
context "with a post by a nuked user" do
before do
post.update!(
user_id: nil,
deleted_at: Time.zone.now
)
end
subject { PostSerializer.new(post, scope: Guardian.new(Fabricate(:admin)), root: false).as_json }
it "serializes correctly" do
[:name, :username, :display_username, :avatar_template, :user_title, :trust_level].each do |attr|
expect(subject[attr]).to be_nil
end
[:moderator, :staff, :yours].each do |attr|
expect(subject[attr]).to eq(false)
end
end
end
context "with a post by a suspended user" do
def subject
PostSerializer.new(post, scope: Guardian.new(Fabricate(:admin)), root: false).as_json
end
it "serializes correctly" do
expect(subject[:user_suspended]).to be_nil
post.user.update!(
suspended_till: 1.month.from_now,
)
expect(subject[:user_suspended]).to eq(true)
freeze_time (2.months.from_now)
expect(subject[:user_suspended]).to be_nil
end
end
describe "#display_username" do
let(:user) { post.user }
let(:serializer) { PostSerializer.new(post, scope: Guardian.new, root: false) }
let(:json) { serializer.as_json }
it "returns the display_username it when `enable_names` is on" do
SiteSetting.enable_names = true
expect(json[:display_username]).to be_present
end
it "doesn't return the display_username it when `enable_names` is off" do
SiteSetting.enable_names = false
expect(json[:display_username]).to be_blank
end
end
context "with a hidden post with add_raw enabled" do
let(:user) { Fabricate.build(:user, id: -99999) }
let(:raw) { "Raw contents of the post." }
context "with a public post" do
let(:post) { Fabricate.build(:post, raw: raw, user: user) }
it "includes the raw post for everyone" do
[nil, user, Fabricate(:user), Fabricate(:moderator), Fabricate(:admin)].each do |user|
expect(serialized_post_for_user(user)[:raw]).to eq(raw)
end
end
end
context "with a hidden post" do
let(:post) { Fabricate.build(:post, raw: raw, user: user, hidden: true, hidden_reason_id: Post.hidden_reasons[:flag_threshold_reached]) }
it "shows the raw post only if authorized to see it" do
expect(serialized_post_for_user(nil)[:raw]).to eq(nil)
expect(serialized_post_for_user(Fabricate(:user))[:raw]).to eq(nil)
expect(serialized_post_for_user(user)[:raw]).to eq(raw)
expect(serialized_post_for_user(Fabricate(:moderator))[:raw]).to eq(raw)
expect(serialized_post_for_user(Fabricate(:admin))[:raw]).to eq(raw)
end
it "can view edit history only if authorized" do
expect(serialized_post_for_user(nil)[:can_view_edit_history]).to eq(false)
expect(serialized_post_for_user(Fabricate(:user))[:can_view_edit_history]).to eq(false)
expect(serialized_post_for_user(user)[:can_view_edit_history]).to eq(true)
expect(serialized_post_for_user(Fabricate(:moderator))[:can_view_edit_history]).to eq(true)
expect(serialized_post_for_user(Fabricate(:admin))[:can_view_edit_history]).to eq(true)
end
end
context "with a hidden revised post" do
fab!(:post) { Fabricate(:post, raw: 'Hello world!', hidden: true) }
before do
SiteSetting.editing_grace_period_max_diff = 1
revisor = PostRevisor.new(post)
revisor.revise!(post.user, raw: 'Hello, everyone!')
end
it "will not leak version to users" do
json = PostSerializer.new(post, scope: Guardian.new(user), root: false).as_json
expect(json[:version]).to eq(1)
end
it "will show real version to staff" do
json = PostSerializer.new(post, scope: Guardian.new(Fabricate(:admin)), root: false).as_json
expect(json[:version]).to eq(2)
end
end
context "with a public wiki post" do
let(:post) { Fabricate.build(:post, raw: raw, user: user, wiki: true) }
it "can view edit history" do
[nil, user, Fabricate(:user), Fabricate(:moderator), Fabricate(:admin)].each do |user|
expect(serialized_post_for_user(user)[:can_view_edit_history]).to eq(true)
end
end
end
context "with a hidden wiki post" do
let(:post) {
Fabricate.build(
:post,
raw: raw,
user: user,
wiki: true,
hidden: true,
hidden_reason_id: Post.hidden_reasons[:flag_threshold_reached])
}
it "can view edit history only if authorized" do
expect(serialized_post_for_user(nil)[:can_view_edit_history]).to eq(false)
expect(serialized_post_for_user(Fabricate(:user))[:can_view_edit_history]).to eq(false)
expect(serialized_post_for_user(user)[:can_view_edit_history]).to eq(true)
expect(serialized_post_for_user(Fabricate(:moderator))[:can_view_edit_history]).to eq(true)
expect(serialized_post_for_user(Fabricate(:admin))[:can_view_edit_history]).to eq(true)
end
end
end
context "with a post with notices" do
fab!(:user) { Fabricate(:user, trust_level: 1) }
fab!(:user_tl1) { Fabricate(:user, trust_level: 1) }
fab!(:user_tl2) { Fabricate(:user, trust_level: 2) }
let(:post) {
post = Fabricate(:post, user: user)
post.custom_fields[Post::NOTICE] = { type: Post.notices[:returning_user], last_posted_at: 1.day.ago }
post.save_custom_fields
post
}
def json_for_user(user)
PostSerializer.new(post, scope: Guardian.new(user), root: false).as_json
end
it "is visible for TL2+ users (except poster)" do
expect(json_for_user(nil)[:notice]).to eq(nil)
expect(json_for_user(user)[:notice]).to eq(nil)
SiteSetting.returning_user_notice_tl = 2
expect(json_for_user(user_tl1)[:notice]).to eq(nil)
expect(json_for_user(user_tl2)[:notice][:type]).to eq(Post.notices[:returning_user])
SiteSetting.returning_user_notice_tl = 1
expect(json_for_user(user_tl1)[:notice][:type]).to eq(Post.notices[:returning_user])
expect(json_for_user(user_tl2)[:notice][:type]).to eq(Post.notices[:returning_user])
end
end
context "with a post with bookmarks" do
let(:current_user) { Fabricate(:user) }
let(:topic_view) { TopicView.new(post.topic, current_user) }
let(:serialized) do
s = serialized_post(current_user)
s.post_actions = PostAction.counts_for([post], current_user)[post.id]
s.topic_view = topic_view
s
end
context "when a Bookmark record exists for the user on the post" do
let!(:bookmark) { Fabricate(:bookmark_next_business_day_reminder, user: current_user, bookmarkable: post) }
context "with bookmarks with reminders" do
it "returns true" do
expect(serialized.as_json[:bookmarked]).to eq(true)
end
it "returns the reminder_at for the bookmark" do
expect(serialized.as_json[:bookmark_reminder_at]).to eq(bookmark.reminder_at.iso8601)
end
end
end
end
context "with posts when group moderation is enabled" do
fab!(:topic) { Fabricate(:topic) }
fab!(:group_user) { Fabricate(:group_user) }
fab!(:post) { Fabricate(:post, topic: topic) }
before do
SiteSetting.enable_category_group_moderation = true
topic.category.update!(reviewable_by_group_id: group_user.group.id)
end
it "does nothing for regular users" do
expect(serialized_post_for_user(nil)[:group_moderator]).to eq(nil)
end
it "returns a group_moderator attribute for category group moderators" do
post.update!(user: group_user.user)
expect(serialized_post_for_user(nil)[:group_moderator]).to eq(true)
end
end
context "with a post with small action" do
fab!(:post) { Fabricate(:small_action, action_code: "public_topic") }
it "returns `action_code` based on `login_required` site setting" do
expect(serialized_post_for_user(nil)[:action_code]).to eq("public_topic")
SiteSetting.login_required = true
expect(serialized_post_for_user(nil)[:action_code]).to eq("open_topic")
end
end
describe "#user_status" do
fab!(:user_status) { Fabricate(:user_status) }
fab!(:user) { Fabricate(:user, user_status: user_status) }
fab!(:post) { Fabricate(:post, user: user) }
let(:serializer) { described_class.new(post, scope: Guardian.new(user), root: false) }
it "adds user status when enabled" do
SiteSetting.enable_user_status = true
json = serializer.as_json
expect(json[:user_status]).to_not be_nil do |status|
expect(status.description).to eq(user_status.description)
expect(status.emoji).to eq(user_status.emoji)
end
end
it "doesn't add user status when disabled" do
SiteSetting.enable_user_status = false
json = serializer.as_json
expect(json.keys).not_to include :user_status
end
it "doesn't add status if user doesn't have it" do
SiteSetting.enable_user_status = true
user.clear_status!
user.reload
json = serializer.as_json
expect(json.keys).not_to include :user_status
end
end
def serialized_post(u)
s = PostSerializer.new(post, scope: Guardian.new(u), root: false)
s.add_raw = true
s
end
def serialized_post_for_user(u)
s = serialized_post(u)
s.as_json
end
end