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:
parent
9648122b51
commit
e35fcd3340
|
@ -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
|
||||
|
||||
|
|
|
@ -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) }
|
||||
|
|
Loading…
Reference in New Issue