DEV: Add reviewables tab to the new user menu (#17630)

This commit is a subset of the changes proposed in https://github.com/discourse/discourse/pull/17379.
This commit is contained in:
Osama Sayegh
2022-07-28 11:16:33 +03:00
committed by GitHub
parent f4b45df83f
commit 988a175e94
38 changed files with 935 additions and 26 deletions

View File

@@ -244,6 +244,87 @@ RSpec.describe Reviewable, type: :model do
end
end
describe ".recent_list_with_pending_first" do
fab!(:pending_reviewable1) do
Fabricate(
:reviewable,
score: 150,
created_at: 7.minutes.ago,
status: Reviewable.statuses[:pending]
)
end
fab!(:pending_reviewable2) do
Fabricate(
:reviewable,
score: 100,
status: Reviewable.statuses[:pending]
)
end
fab!(:approved_reviewable1) do
Fabricate(
:reviewable,
created_at: 1.minutes.ago,
score: 300,
status: Reviewable.statuses[:approved]
)
end
fab!(:approved_reviewable2) do
Fabricate(
:reviewable,
created_at: 5.minutes.ago,
score: 200,
status: Reviewable.statuses[:approved]
)
end
fab!(:admin) { Fabricate(:admin) }
it "returns a list of reviewables with pending items first" do
list = Reviewable.recent_list_with_pending_first(admin)
expect(list.map(&:id)).to eq([
pending_reviewable1.id,
pending_reviewable2.id,
approved_reviewable1.id,
approved_reviewable2.id
])
pending_reviewable1.update!(status: Reviewable.statuses[:rejected])
rejected_reviewable = pending_reviewable1
list = Reviewable.recent_list_with_pending_first(admin)
expect(list.map(&:id)).to eq([
pending_reviewable2.id,
approved_reviewable1.id,
approved_reviewable2.id,
rejected_reviewable.id,
])
end
it "only includes reviewables whose score is above the minimum or are forced for review" do
SiteSetting.reviewable_default_visibility = 'high'
Reviewable.set_priorities({ high: 200 })
list = Reviewable.recent_list_with_pending_first(admin)
expect(list.map(&:id)).to eq([
approved_reviewable1.id,
approved_reviewable2.id,
])
pending_reviewable1.update!(force_review: true)
list = Reviewable.recent_list_with_pending_first(admin)
expect(list.map(&:id)).to eq([
pending_reviewable1.id,
approved_reviewable1.id,
approved_reviewable2.id,
])
end
it "accepts a limit argument to limit the number of returned records" do
expect(Reviewable.recent_list_with_pending_first(admin, limit: 2).size).to eq(2)
end
end
it "valid_types returns the appropriate types" do
expect(Reviewable.valid_type?('ReviewableUser')).to eq(true)
expect(Reviewable.valid_type?('ReviewableQueuedPost')).to eq(true)

View File

@@ -254,6 +254,73 @@ RSpec.describe ReviewablesController do
end
end
describe "#user_menu_list" do
it "renders each reviewable with its basic serializers" do
reviewable_user = Fabricate(:reviewable_user, payload: { username: "someb0dy" })
reviewable_flagged_post = Fabricate(:reviewable_flagged_post)
reviewable_queued_post = Fabricate(:reviewable_queued_post)
get "/review/user-menu-list.json"
expect(response.status).to eq(200)
reviewables = response.parsed_body["reviewables"]
reviewable_queued_post_json = reviewables.find { |r| r["id"] == reviewable_queued_post.id }
expect(reviewable_queued_post_json["is_new_topic"]).to eq(false)
expect(reviewable_queued_post_json["topic_fancy_title"]).to eq(
reviewable_queued_post.topic.fancy_title
)
reviewable_flagged_post_json = reviewables.find { |r| r["id"] == reviewable_flagged_post.id }
expect(reviewable_flagged_post_json["post_number"]).to eq(
reviewable_flagged_post.post.post_number
)
expect(reviewable_flagged_post_json["topic_fancy_title"]).to eq(
reviewable_flagged_post.topic.fancy_title
)
reviewable_user_json = reviewables.find { |r| r["id"] == reviewable_user.id }
expect(reviewable_user_json["username"]).to eq("someb0dy")
end
it "returns JSON containing basic information of reviewables" do
reviewable1 = Fabricate(:reviewable)
reviewable2 = Fabricate(:reviewable, status: Reviewable.statuses[:approved])
get "/review/user-menu-list.json"
expect(response.status).to eq(200)
reviewables = response.parsed_body["reviewables"]
expect(reviewables.size).to eq(2)
expect(reviewables[0]["flagger_username"]).to eq(reviewable1.created_by.username)
expect(reviewables[0]["id"]).to eq(reviewable1.id)
expect(reviewables[0]["type"]).to eq(reviewable1.type)
expect(reviewables[0]["pending"]).to eq(true)
expect(reviewables[1]["flagger_username"]).to eq(reviewable2.created_by.username)
expect(reviewables[1]["id"]).to eq(reviewable2.id)
expect(reviewables[1]["type"]).to eq(reviewable2.type)
expect(reviewables[1]["pending"]).to eq(false)
end
it "puts pending reviewables on top" do
approved1 = Fabricate(
:reviewable,
status: Reviewable.statuses[:approved]
)
pending = Fabricate(
:reviewable,
status: Reviewable.statuses[:pending]
)
approved2 = Fabricate(
:reviewable,
status: Reviewable.statuses[:approved]
)
get "/review/user-menu-list.json"
expect(response.status).to eq(200)
reviewables = response.parsed_body["reviewables"]
expect(reviewables.map { |r| r["id"] }).to eq([pending.id, approved2.id, approved1.id])
end
end
describe "#show" do
context "basics" do
fab!(:reviewable) { Fabricate(:reviewable) }

View File

@@ -0,0 +1,36 @@
# frozen_string_literal: true
describe BasicReviewableFlaggedPostSerializer do
fab!(:topic) { Fabricate(:topic, title: "safe title <a> hello world") }
fab!(:post) { Fabricate(:post, topic: topic) }
fab!(:reviewable) do
ReviewableFlaggedPost.needs_review!(target: post, topic: topic, created_by: Discourse.system_user)
end
subject { described_class.new(reviewable, root: false).as_json }
include_examples "basic reviewable attributes"
describe "#post_number" do
it "equals the post_number of the post" do
expect(subject[:post_number]).to eq(post.post_number)
end
it "is not included if the reviewable is associated with no post" do
reviewable.update!(target: nil)
expect(subject.key?(:post_number)).to eq(false)
end
end
describe "#topic_fancy_title" do
it "equals the fancy_title of the topic" do
expect(subject[:topic_fancy_title]).to eq("Safe title &lt;a&gt; hello world")
end
it "is not included if the reviewable is associated with no topic" do
reviewable.update!(topic: nil)
expect(subject.key?(:topic_fancy_title)).to eq(false)
end
end
end

View File

@@ -0,0 +1,49 @@
# frozen_string_literal: true
describe BasicReviewableQueuedPostSerializer do
fab!(:topic) { Fabricate(:topic, title: "safe title <a> existing topic") }
fab!(:reviewable) do
ReviewableQueuedPost.create!(
created_by: Discourse.system_user,
topic_id: topic.id,
payload: { raw: "new post 123", title: "unsafe title <a>" }
)
end
subject { described_class.new(reviewable, root: false).as_json }
include_examples "basic reviewable attributes"
describe "#topic_fancy_title" do
it "equals the topic's fancy_title" do
expect(subject[:topic_fancy_title]).to eq("Safe title &lt;a&gt; existing topic")
end
it "is not included if the reviewable is associated with no topic" do
reviewable.update!(topic: nil)
expect(subject.key?(:topic_fancy_title)).to eq(false)
end
end
describe "#is_new_topic" do
it "is true if the reviewable's payload has a title attribute" do
expect(subject[:is_new_topic]).to eq(true)
end
it "is false if the reviewable's payload doesn't have a title attribute" do
reviewable.update!(payload: { raw: "new post 123" })
expect(subject[:is_new_topic]).to eq(false)
end
end
describe "#payload_title" do
it "equals the title in the reviewable's payload" do
expect(subject[:payload_title]).to eq("unsafe title <a>")
end
it "is not included if the reviewable's payload doesn't have a title attribute" do
reviewable.update!(payload: { raw: "new post 123" })
expect(subject.key?(:payload_title)).to eq(false)
end
end
end

View File

@@ -0,0 +1,8 @@
# frozen_string_literal: true
describe BasicReviewableSerializer do
fab!(:reviewable) { Fabricate(:reviewable) }
subject { described_class.new(reviewable, root: false).as_json }
include_examples "basic reviewable attributes"
end

View File

@@ -0,0 +1,29 @@
# frozen_string_literal: true
describe BasicReviewableUserSerializer do
fab!(:user) { Fabricate(:user) }
fab!(:reviewable) do
ReviewableUser.needs_review!(
target: user,
created_by: Discourse.system_user,
payload: {
username: user.username,
name: user.name,
email: user.email,
bio: "blah whatever",
website: "ff.website.com"
}
)
end
subject { described_class.new(reviewable, root: false).as_json }
include_examples "basic reviewable attributes"
describe "#username" do
it "equals the username in the reviewable's payload" do
expect(subject[:username]).to eq(user.username)
end
end
end

View File

@@ -0,0 +1,41 @@
# frozen_string_literal: true
shared_examples "basic reviewable attributes" do
describe "#id" do
it "equals the reviewable's id" do
expect(subject[:id]).to eq(reviewable.id)
end
end
describe "#type" do
it "is the reviewable's type" do
expect(subject[:type]).to eq(reviewable.type)
end
end
describe "#pending" do
it "is false if the reviewable is approved" do
reviewable.update!(status: Reviewable.statuses[:approved])
expect(subject[:pending]).to eq(false)
end
it "is false if the reviewable is rejected" do
reviewable.update!(status: Reviewable.statuses[:rejected])
expect(subject[:pending]).to eq(false)
end
it "is true if the reviewable is pending" do
reviewable.update!(status: Reviewable.statuses[:pending])
expect(subject[:pending]).to eq(true)
end
end
describe "#flagger_username" do
it "equals to the username of the user who created the reviewable" do
reviewable.update!(
created_by: Fabricate(:user, username: "gg.osama")
)
expect(subject[:flagger_username]).to eq("gg.osama")
end
end
end