Display information about "unpublish all" actions in the member manager (#18576)
* Query audit_log + target records for display in the member manager * Display information about logged unpublished articles and comments * Display information if the post was republished * Added specs for unpublish_log tab on user's page in the member manager * Fixed specs * Change the wording for displaying info about unpublish all actions
This commit is contained in:
parent
f839acacab
commit
9bb5b81fc5
8 changed files with 144 additions and 6 deletions
|
|
@ -73,6 +73,7 @@ module Admin
|
|||
def show
|
||||
@user = User.find(params[:id])
|
||||
set_current_tab(params[:tab])
|
||||
set_unpublish_all_log
|
||||
set_banishable_user
|
||||
set_feedback_messages
|
||||
set_related_reactions
|
||||
|
|
@ -392,7 +393,7 @@ module Admin
|
|||
end
|
||||
|
||||
def set_current_tab(current_tab = "overview")
|
||||
@current_tab = if current_tab.in? Constants::UserDetails::TAB_LIST.map(&:downcase)
|
||||
@current_tab = if current_tab.in? Constants::UserDetails::TAB_LIST.map(&:underscore)
|
||||
current_tab
|
||||
else
|
||||
"overview"
|
||||
|
|
@ -403,5 +404,11 @@ module Admin
|
|||
@banishable_user = (@user.comments.where("created_at < ?", 100.days.ago).empty? &&
|
||||
@user.created_at < 100.days.ago) || current_user.super_admin? || current_user.support_admin?
|
||||
end
|
||||
|
||||
def set_unpublish_all_log
|
||||
# in theory, there could be multiple "unpublish all" actions
|
||||
# but let's query and display the last one for now, that should be enough for most cases
|
||||
@unpublish_all_data = AuditLog::UnpublishAllsQuery.call(@user.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ module Constants
|
|||
Emails
|
||||
Reports
|
||||
Flags
|
||||
UnpublishLogs
|
||||
].freeze
|
||||
end
|
||||
end
|
||||
|
|
|
|||
36
app/queries/audit_log/unpublish_alls_query.rb
Normal file
36
app/queries/audit_log/unpublish_alls_query.rb
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
class AuditLog
|
||||
class UnpublishAllsQuery
|
||||
Result = Struct.new(:exists?, :audit_log, :target_articles, :target_comments, keyword_init: true)
|
||||
|
||||
def initialize(user_id)
|
||||
@user_id = user_id
|
||||
@target_articles = []
|
||||
@target_comments = []
|
||||
end
|
||||
|
||||
def self.call(...)
|
||||
new(...).call
|
||||
end
|
||||
|
||||
def call
|
||||
audit_log = AuditLog.where(slug: %w[api_user_unpublish unpublish_all_articles])
|
||||
.where("data @> '{\"target_user_id\": ?}'", user_id)
|
||||
.includes(:user)
|
||||
.order("created_at DESC")
|
||||
.first
|
||||
if audit_log
|
||||
target_articles = Article.where(id: audit_log.data["target_article_ids"], user_id: user_id)
|
||||
target_comments = Comment.where(id: audit_log.data["target_comment_ids"], user_id: user_id)
|
||||
end
|
||||
Result.new(
|
||||
exists?: audit_log.present?,
|
||||
audit_log: audit_log,
|
||||
target_articles: target_articles,
|
||||
target_comments: target_comments,
|
||||
)
|
||||
end
|
||||
|
||||
attr_reader :user_id
|
||||
attr_accessor :target_comments, :target_articles
|
||||
end
|
||||
end
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
<%= render "admin/users/show/profile" %>
|
||||
<%= render "admin/users/show/tabs" %>
|
||||
|
||||
<% if @current_tab == "overview" %>
|
||||
<% if @current_tab == "overview" %>
|
||||
<div class="crayons-card p-3 s:p-4 m:p-7">
|
||||
<%= render "admin/users/show/overview/stats" if @user.registered %>
|
||||
|
||||
|
|
@ -50,8 +50,12 @@
|
|||
<section class="crayons-card p-3 s:p-4 m:p-7">
|
||||
<%= render "admin/users/show/reports/index" %>
|
||||
</section>
|
||||
<% else @current_tab == "flags" %>
|
||||
<% elsif @current_tab == "flags" %>
|
||||
<section class="crayons-card p-3 s:p-4 m:p-7">
|
||||
<%= render "admin/users/show/flags/index" %>
|
||||
</section>
|
||||
<% elsif @current_tab == "unpublish_logs" %>
|
||||
<section class="crayons-card p-3 s:p-4 m:p-7">
|
||||
<%= render "admin/users/show/unpublish_logs/index" %>
|
||||
</section>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -5,5 +5,8 @@
|
|||
<li><%= link_to "Emails", admin_user_path(@user.id, tab: :emails), class: "crayons-navigation__item #{'crayons-navigation__item crayons-navigation__item--current' if @current_tab == 'emails'}", aria: @current_tab == "emails" ? { current: "page" } : {} %></li></li>
|
||||
<li><%= link_to "Reports", admin_user_path(@user.id, tab: :reports), class: "crayons-navigation__item #{'crayons-navigation__item crayons-navigation__item--current' if @current_tab == 'reports'}", aria: @current_tab == "reports" ? { current: "page" } : {} %></li></li>
|
||||
<li><%= link_to "Flags", admin_user_path(@user.id, tab: :flags), class: "crayons-navigation__item #{'crayons-navigation__item crayons-navigation__item--current' if @current_tab == 'flags'}", aria: @current_tab == "flags" ? { current: "page" } : {} %></li></li>
|
||||
<% if @unpublish_all_data.exists? %>
|
||||
<li><%= link_to "Unpublish All History", admin_user_path(@user.id, tab: :unpublish_logs), class: "crayons-navigation__item #{'crayons-navigation__item crayons-navigation__item--current' if @current_tab == 'unpublish_logs'}", aria: @current_tab == "flags" ? { current: "page" } : {} %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</nav>
|
||||
|
|
|
|||
29
app/views/admin/users/show/unpublish_logs/_index.html.erb
Normal file
29
app/views/admin/users/show/unpublish_logs/_index.html.erb
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<% if @unpublish_all_data.exists? %>
|
||||
<h2 class="fs-xl fw-normal mb-5">Unpublished by <%= link_to @unpublish_all_data.audit_log.user.username, @unpublish_all_data.audit_log.user.path %> on <%= @unpublish_all_data.audit_log.created_at.strftime("%Y-%m-%d, %H:%M") %></h3>
|
||||
<div class="crayons-card p-6 mb-5">
|
||||
<h4 class="mb-2">Posts:</h4>
|
||||
<% @unpublish_all_data.target_articles.each do |article| %>
|
||||
<div class="mb-1">
|
||||
<%= link_to article.title, article.current_state_path %>
|
||||
<a href="<%= article.path %>/edit" target="_blank" rel="noopener" class="c-link">Edit</a>
|
||||
<% if article.published %>
|
||||
<span class="color-base-60">(was republished)</span>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="crayons-card p-6">
|
||||
<h4 class="mb-2">Comments:</h4>
|
||||
<% @unpublish_all_data.target_comments.each do |comment| %>
|
||||
<div class="crayons-card p-3 mb-3">
|
||||
<div class="color-base-80">
|
||||
<%= truncate(strip_tags(comment.processed_html), length: 250).html_safe %>
|
||||
</div>
|
||||
<%= link_to "commentable", comment.commentable.current_state_path %>
|
||||
<p class="fs-s">
|
||||
Created at: <%= comment.created_at.strftime("%Y-%m-%d, %H:%M") %>
|
||||
</p>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
32
spec/queries/audit_log/unpublish_alls_query_spec.rb
Normal file
32
spec/queries/audit_log/unpublish_alls_query_spec.rb
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
require "rails_helper"
|
||||
|
||||
RSpec.describe AuditLog::UnpublishAllsQuery, type: :query do
|
||||
let(:user) { create(:user) }
|
||||
let!(:article) { create(:article, user: user) }
|
||||
|
||||
describe "::call" do
|
||||
context "when audit_log exists" do
|
||||
let!(:audit_log) do
|
||||
create(:audit_log, slug: "unpublish_all_articles",
|
||||
data: { target_user_id: user.id, target_article_ids: [article.id] })
|
||||
end
|
||||
|
||||
it "has articles and audit_log in the result" do
|
||||
res = described_class.call(user.id)
|
||||
expect(res.target_articles).to eq([article])
|
||||
expect(res.target_comments).to eq([])
|
||||
expect(res.audit_log).to eq(audit_log)
|
||||
end
|
||||
|
||||
it "exists?" do
|
||||
res = described_class.call(user.id)
|
||||
expect(res.exists?).to be true
|
||||
end
|
||||
end
|
||||
|
||||
it "doesn't exist when there is no related audit_log" do
|
||||
res = described_class.call(user.id)
|
||||
expect(res.exists?).to be false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -95,6 +95,30 @@ RSpec.describe "/admin/member_manager/users", type: :request do
|
|||
get admin_user_path(user.id)
|
||||
expect(response.body).to include(report.feedback_type)
|
||||
end
|
||||
|
||||
it "displays unpublish all data from logs when it exists on unpublish_alls tab" do
|
||||
article = create(:article, user: user, published: false)
|
||||
create(:audit_log, user: admin, slug: "unpublish_all_articles",
|
||||
data: { target_article_ids: [article.id], target_user_id: user.id })
|
||||
get "#{admin_user_path(user.id)}?tab=unpublish_logs"
|
||||
expect(response.body).to include("Unpublished by")
|
||||
expect(response.body).to include(CGI.escapeHTML(article.title))
|
||||
end
|
||||
|
||||
it "displays a label if an unpublished post was republished" do
|
||||
article = create(:article, user: user, published: true)
|
||||
create(:audit_log, user: admin, slug: "unpublish_all_articles",
|
||||
data: { target_article_ids: [article.id], target_user_id: user.id })
|
||||
get "#{admin_user_path(user.id)}?tab=unpublish_logs"
|
||||
expect(response.body).to include(CGI.escapeHTML(article.title))
|
||||
expect(response.body).to include("(was republished)")
|
||||
end
|
||||
|
||||
it "displays nothing on unpublish_alls tab if it the log doesn't exist" do
|
||||
get "#{admin_user_path(user.id)}?tab=unpublish_logs"
|
||||
expect(response).to be_successful
|
||||
expect(response.body).not_to include("Unpublished by")
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST /admin/member_manager/users/:id/banish" do
|
||||
|
|
@ -341,9 +365,11 @@ RSpec.describe "/admin/member_manager/users", type: :request do
|
|||
create(:article, user: target_user, published: false)
|
||||
create(:comment, user: target_user, deleted: true)
|
||||
|
||||
sidekiq_perform_enqueued_jobs(only: Moderator::UnpublishAllArticlesWorker) do
|
||||
post unpublish_all_articles_admin_user_path(target_user.id)
|
||||
end
|
||||
expect do
|
||||
sidekiq_perform_enqueued_jobs(only: Moderator::UnpublishAllArticlesWorker) do
|
||||
post unpublish_all_articles_admin_user_path(target_user.id)
|
||||
end
|
||||
end.to change(AuditLog, :count).by(1)
|
||||
|
||||
log = AuditLog.last
|
||||
expect(log.category).to eq(AuditLog::MODERATOR_AUDIT_LOG_CATEGORY)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue