FEATURE: Include rejected queued posts in the user archive export (#10859)

Requested at https://meta.discourse.org/t/where-can-a-user-find-the-post-that-was-rejected-by-the-moderator/165671?u=riking

Field whitelisting is applied to the json field using Hash#slice, which was activesupport until Ruby 2.5.
This commit is contained in:
Kane York 2020-10-27 07:48:48 -07:00 committed by GitHub
parent 9648122b51
commit e35fcd3340
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 68 additions and 6 deletions

View File

@ -18,6 +18,7 @@ module Jobs
badges
bookmarks
category_preferences
queued_posts
visits
)
@ -29,6 +30,7 @@ module Jobs
badges: ['badge_id', 'badge_name', 'granted_at', 'post_id', 'seq', 'granted_manually', 'notification_id', 'featured_rank'],
bookmarks: ['post_id', 'topic_id', 'post_number', 'link', 'name', 'created_at', 'updated_at', 'reminder_type', 'reminder_at', 'reminder_last_sent_at', 'reminder_set_at', 'auto_delete_preference'],
category_preferences: ['category_id', 'category_names', 'notification_level', 'dismiss_new_timestamp'],
queued_posts: ['id', 'verdict', 'category_id', 'topic_id', 'post_raw', 'other_json'],
visits: ['visited_at', 'posts_read', 'mobile', 'time_read'],
)
@ -265,6 +267,25 @@ module Jobs
end
end
def queued_posts_export
return enum_for(:queued_posts_export) unless block_given?
# Most Reviewable fields staff-private, but post content needs to be exported.
ReviewableQueuedPost
.where(created_by: @current_user.id)
.each do |rev|
yield [
rev.id,
Reviewable.statuses[rev.status],
rev.category_id,
rev.topic_id,
rev.payload['raw'],
MultiJson.dump(rev.payload.slice(*queued_posts_payload_permitted_keys)),
]
end
end
def visits_export
return enum_for(:visits_export) unless block_given?
@ -354,6 +375,23 @@ module Jobs
user_archive_profile
end
def queued_posts_payload_permitted_keys
# Generated with:
#
# SELECT distinct json_object_keys(payload) from reviewables
# where type = 'ReviewableQueuedPost' and (payload->'old_queued_post_id') IS NULL
#
# except raw, created_topic_id, created_post_id
%w{
composer_open_duration_msecs
is_poll
reply_to_post_number
tags
title
typing_duration_msecs
}
end
def notify_user(upload, export_title)
post = nil

View File

@ -14,6 +14,10 @@ describe Jobs::ExportUserArchive do
}
let(:component) { raise 'component not set' }
let(:category) { Fabricate(:category_with_definition) }
let(:subcategory) { Fabricate(:category_with_definition, parent_category_id: category.id) }
let(:topic) { Fabricate(:topic, category: category) }
def make_component_csv
data_rows = []
csv_out = CSV.generate do |csv|
@ -90,13 +94,10 @@ describe Jobs::ExportUserArchive do
context 'user_archive posts' do
let(:component) { 'user_archive' }
let(:user2) { Fabricate(:user) }
let(:category) { Fabricate(:category_with_definition) }
let(:subcategory) { Fabricate(:category_with_definition, parent_category_id: category.id) }
let(:subsubcategory) { Fabricate(:category_with_definition, parent_category_id: subcategory.id) }
let(:subsubtopic) { Fabricate(:topic, category: subsubcategory) }
let(:subsubpost) { Fabricate(:post, user: user, topic: subsubtopic) }
let(:topic) { Fabricate(:topic, category: category) }
let(:normal_post) { Fabricate(:post, user: user, topic: topic) }
let(:reply) { PostCreator.new(user2, raw: 'asdf1234qwert7896', topic_id: topic.id, reply_to_post_number: normal_post.post_number).create }
@ -297,11 +298,8 @@ describe Jobs::ExportUserArchive do
context 'category_preferences' do
let(:component) { 'category_preferences' }
let(:category) { Fabricate(:category_with_definition) }
let(:subcategory) { Fabricate(:category_with_definition, parent_category_id: category.id) }
let(:subsubcategory) { Fabricate(:category_with_definition, parent_category_id: subcategory.id) }
let(:announcements) { Fabricate(:category_with_definition) }
let(:deleted_category) { Fabricate(:category) }
let(:reset_at) { DateTime.parse('2017-03-01 12:00') }
@ -353,6 +351,32 @@ describe Jobs::ExportUserArchive do
end
end
context 'queued posts' do
let(:component) { 'queued_posts' }
let(:reviewable_post) { Fabricate(:reviewable_queued_post, topic: topic, created_by: user) }
let(:reviewable_topic) { Fabricate(:reviewable_queued_post_topic, category: category, created_by: user) }
let(:admin) { Fabricate(:admin) }
it 'correctly exports queued posts' do
SiteSetting.tagging_enabled = true
reviewable_post.perform(admin, :reject_post)
reviewable_topic.payload['tags'] = ['example_tag']
result = reviewable_topic.perform(admin, :approve_post)
expect(result.success?).to eq(true)
data, csv_out = make_component_csv
expect(data.length).to eq(2)
data.sort { |e| e['id'].to_i }
expect(csv_out).to_not match(admin.username)
expect(data[0]['post_raw']).to eq('hello world post contents.')
expect(data[0]['other_json']).to match('reply_to_post_number')
expect(data[1]['other_json']).to match('example_tag')
end
end
context 'visits' do
let(:component) { 'visits' }
let(:user2) { Fabricate(:user) }