Hide low quality comments from an article page (#20541)

* Hide low-score (< -50) comments for signed in users on article page

* Use low quality threshold

* Show deleted message for low-quality for signed-in users + hide if no children

* Remove irrelevant changes

* Skip view test for low-quality

* Removed irrelevant (yet) tests

* Fixed low score threshold in specs descriptions
This commit is contained in:
Anna Buianova 2024-01-23 23:33:12 +03:00 committed by GitHub
parent d86689f63d
commit 321540ec08
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 105 additions and 42 deletions

View file

@ -1,2 +1,4 @@
<% comment, sub_comments = comment_node %>
<%= nested_comments(tree: { comment => sub_comments }, commentable: @article, is_view_root: true) %>
<% unless comment.decorate.low_quality && sub_comments.empty? %>
<%= nested_comments(tree: { comment => sub_comments }, commentable: @article, is_view_root: true) %>
<% end %>

View file

@ -5,7 +5,7 @@
<div class="inner-comment comment__details">
<div class="comment__content crayons-card">
<% if comment.deleted %>
<% if comment.deleted || decorated_comment.low_quality %>
<div class="p-6 align-center opacity-50 fs-s">
<span class="js-comment-username">
<%= t("views.comments.delete.comment_deleted") %>

View file

@ -6,43 +6,43 @@
<% end %>
<% if @commentable %>
<%= content_for :page_meta do %>
<meta name="description" content="<%= @commentable.description || t("views.comments.meta.description") %>">
<%= meta_keywords_article %>
<%= content_for :page_meta do %>
<meta name="description" content="<%= @commentable.description || t("views.comments.meta.description") %>">
<%= meta_keywords_article %>
<meta property="og:type" content="article" />
<meta property="og:title" content="<%= t("views.comments.meta.og.title", title: @commentable.title) %>" />
<meta property="og:description" content="<%= @commentable.description || t("views.comments.meta.og.description", site: community_name) %>" />
<meta property="og:site_name" content="<%= community_name %>" />
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@<%= Settings::General.social_media_handles["twitter"] %>">
<meta name="twitter:creator" content="@<%= @user.twitter_username %>">
<meta name="twitter:title" content="<%= @commentable.title %>">
<meta name="twitter:description" content="<%= @commentable.description || t("views.comments.meta.og.description", site: community_name) %>">
<meta property="og:type" content="article" />
<meta property="og:title" content="<%= t("views.comments.meta.og.title", title: @commentable.title) %>" />
<meta property="og:description" content="<%= @commentable.description || t("views.comments.meta.og.description", site: community_name) %>" />
<meta property="og:site_name" content="<%= community_name %>" />
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@<%= Settings::General.social_media_handles["twitter"] %>">
<meta name="twitter:creator" content="@<%= @user.twitter_username %>">
<meta name="twitter:title" content="<%= @commentable.title %>">
<meta name="twitter:description" content="<%= @commentable.description || t("views.comments.meta.og.description", site: community_name) %>">
<% if @root_comment.present? %>
<link rel="canonical" href="<%= app_url(@root_comment.path) %>" />
<meta property="og:url" content="<%= app_url(@root_comment.path) %>" />
<meta property="og:title" content="<%= t("views.comments.meta.og.title_rel", root: truncate(strip_tags(@root_comment.processed_html), length: 50), site: community_name) %>" />
<meta name="twitter:title" content="<%= t("views.comments.meta.og.title_rel", root: truncate(strip_tags(@root_comment.processed_html), length: 50), site: community_name) %>">
<meta property="og:image" content="<%= Settings::General.main_social_image %>">
<meta name="twitter:image:src" content="<%= Settings::General.main_social_image %>">
<% if @root_comment.score < 0 || @commentable.score < 0 %>
<meta name="googlebot" content="noindex">
<meta name="googlebot" content="nofollow">
<% end %>
<% else %>
<link rel="canonical" href="<%= app_url("#{@commentable.path}/comments") %>" />
<meta property="og:url" content="<%= app_url("#{@commentable.path}/comments") %>" />
<meta property="og:title" content="<%= t("views.comments.meta.og.title_root", title: @commentable.title, site: community_name) %>" />
<meta name="twitter:title" content="<%= t("views.comments.meta.og.title_root", title: @commentable.title, site: community_name) %>">
<% if @commentable.class.name == "Article" && @commentable.published %>
<% if @root_comment.present? %>
<link rel="canonical" href="<%= app_url(@root_comment.path) %>" />
<meta property="og:url" content="<%= app_url(@root_comment.path) %>" />
<meta property="og:title" content="<%= t("views.comments.meta.og.title_rel", root: truncate(strip_tags(@root_comment.processed_html), length: 50), site: community_name) %>" />
<meta name="twitter:title" content="<%= t("views.comments.meta.og.title_rel", root: truncate(strip_tags(@root_comment.processed_html), length: 50), site: community_name) %>">
<meta property="og:image" content="<%= Settings::General.main_social_image %>">
<meta name="twitter:image:src" content="<%= Settings::General.main_social_image %>">
<% if @root_comment.score < 0 || @commentable.score < 0 %>
<meta name="googlebot" content="noindex">
<meta name="googlebot" content="nofollow">
<% end %>
<% else %>
<link rel="canonical" href="<%= app_url("#{@commentable.path}/comments") %>" />
<meta property="og:url" content="<%= app_url("#{@commentable.path}/comments") %>" />
<meta property="og:title" content="<%= t("views.comments.meta.og.title_root", title: @commentable.title, site: community_name) %>" />
<meta name="twitter:title" content="<%= t("views.comments.meta.og.title_root", title: @commentable.title, site: community_name) %>">
<% if @commentable.class.name == "Article" && @commentable.published %>
<meta property="og:image" content="<%= Settings::General.main_social_image %>">
<meta name="twitter:image:src" content="<%= Settings::General.main_social_image %>">
<% end %>
<% end %>
<% end %>
<% end %>
<% end %>
<%= javascript_packs_with_chunks_tag "commentDropdowns", "followButtons", defer: true %>
@ -92,15 +92,15 @@
<%= javascript_packs_with_chunks_tag "commentsDisplay", defer: true %>
<header class="p-2 pb-4 m:p-6 m:pb-6 crayons-card crayons-card--secondary crayons-layout__content s:mx-2 m:mx-4 -mb-1 z-0">
<% if @commentable %>
<h1 class="crayons-subtitle-1 mb-4">
<%= t("views.comments.parent.subtitle_html",
start: tag("span", { class: %w[fw-normal color-base-60] }, true),
end: "</span>".html_safe,
title: tag.span(@commentable.title)) %>
</h1>
<div class="flex">
<a class="crayons-btn crayons-btn--outlined mr-2" href="<%= @commentable.path %>"><%= t("views.comments.parent.view") %></a>
</div>
<h1 class="crayons-subtitle-1 mb-4">
<%= t("views.comments.parent.subtitle_html",
start: tag("span", { class: %w[fw-normal color-base-60] }, true),
end: "</span>".html_safe,
title: tag.span(@commentable.title)) %>
</h1>
<div class="flex">
<a class="crayons-btn crayons-btn--outlined mr-2" href="<%= @commentable.path %>"><%= t("views.comments.parent.view") %></a>
</div>
<% else %>
<%= t("views.comments.orphan.deleted") %>
<% end %>

View file

@ -181,6 +181,67 @@ RSpec.describe "ArticlesShow" do
end
end
context "with comments" do
let!(:spam_comment) { create(:comment, score: -80, commentable: article, body_markdown: "Spam comment") }
before do
create(:comment, score: 10, commentable: article, body_markdown: "Good comment")
create(:comment, score: -10, commentable: article, body_markdown: "Bad comment")
end
context "when user signed in" do
before do
sign_in user
end
it "shows positive comments" do
get article.path
expect(response.body).to include("Good comment")
end
it "shows comments with score from -75 (low quality threshold) to 0" do
get article.path
expect(response.body).to include("Bad comment")
end
it "hides comments with score < -75 and no comment deleted message" do
get article.path
expect(response.body).not_to include("Spam comment")
expect(response.body).not_to include("Comment deleted")
end
it "displays children of a low-quality comment and comment deleted message" do
create(:comment, score: 0, commentable: article, parent: spam_comment, body_markdown: "Child comment")
get article.path
expect(response.body).to include("Child comment")
expect(response.body).to include("Comment deleted") # instead of the low quality one
end
end
context "when user not signed in" do
it "shows positive comments" do
get article.path
expect(response.body).to include("Good comment")
end
it "hides comments with score from -75 to 0" do
get article.path
expect(response.body).not_to include("Bad comment")
end
it "hides comments with score < -75" do
get article.path
expect(response.body).not_to include("Spam comment")
end
it "doesn't show children of a low-quality comment" do
create(:comment, score: 0, commentable: article, parent: spam_comment, body_markdown: "Child comment")
get article.path
expect(response.body).not_to include("Child comment")
end
end
end
context "when user not signed in but internal nav triggered" do
before do
get "#{article.path}?i=i"

View file

@ -2,7 +2,7 @@ require "rails_helper"
RSpec.describe "rendering locals in a partial" do
context "when comment is low-quality" do
it "renders the comment with low-quality marker" do
it "renders the comment with low-quality marker", skip: "hiding low-quality for now" do
allow(Settings::General).to receive(:mascot_image_url).and_return("https://i.imgur.com/fKYKgo4.png")
comment = create(:comment, processed_html: "hi", score: CommentDecorator::LOW_QUALITY_THRESHOLD - 100)
article = create(:article)