FIX: transfer posts by duplicated staged users to original

This commit is contained in:
Leo McArdle 2017-08-22 09:58:51 +01:00
parent 93fe76fc02
commit be1df3ba75
2 changed files with 30 additions and 12 deletions

View File

@ -2,18 +2,25 @@ module Jobs
class FixPrimaryEmailsForStagedUsers < Jobs::Onceoff class FixPrimaryEmailsForStagedUsers < Jobs::Onceoff
def execute_onceoff(args) def execute_onceoff(args)
users = User.where(active: false, staged: true).joins(:email_tokens) users = User.where(active: false, staged: true).joins(:email_tokens)
destroyer = UserDestroyer.new(Discourse.system_user) acting_user = Discourse.system_user
destroyer = UserDestroyer.new(acting_user)
users.group("email_tokens.email") users.group("email_tokens.email")
.having("COUNT(email_tokens.email) > 1") .having("COUNT(email_tokens.email) > 1")
.count .count
.each_key do |email| .each_key do |email|
users.where("email_tokens.email = ?", email) query = users.where("email_tokens.email = ?", email)
.order(id: :asc) .order(id: :asc)
.offset(1)
original_user = query.first
query.offset(1)
.each do |user| .each do |user|
user.posts.each do |post|
post.set_owner(original_user, acting_user)
end
destroyer.destroy(user) destroyer.destroy(user)
end end
end end

View File

@ -1,25 +1,36 @@
require 'rails_helper' require 'rails_helper'
RSpec.describe Jobs::FixPrimaryEmailsForStagedUsers do RSpec.describe Jobs::FixPrimaryEmailsForStagedUsers do
it 'should clean up duplicated staged users' do let(:common_email) { 'test@reply' }
common_email = 'test@reply' let(:staged_user) { Fabricate(:user, staged: true, active: false) }
let(:staged_user2) { Fabricate(:user, staged: true, active: false) }
staged_user = Fabricate(:user, staged: true, active: false) let(:staged_user3) { Fabricate(:user, staged: true, active: false) }
staged_user2 = Fabricate(:user, staged: true, active: false) let(:active_user) { Fabricate(:coding_horror) }
staged_user3 = Fabricate(:user, staged: true, active: false)
before do
[staged_user, staged_user2, staged_user3].each do |user| [staged_user, staged_user2, staged_user3].each do |user|
user.email_tokens = [Fabricate.create(:email_token, email: common_email, user: user)] user.email_tokens = [Fabricate.create(:email_token, email: common_email, user: user)]
end end
active_user = Fabricate(:coding_horror)
UserEmail.delete_all UserEmail.delete_all
end
it 'should clean up duplicated staged users' do
expect { described_class.new.execute_onceoff({}) } expect { described_class.new.execute_onceoff({}) }
.to change { User.count }.by(-2) .to change { User.count }.by(-2)
expect(User.all).to contain_exactly(Discourse.system_user, staged_user, active_user) expect(User.all).to contain_exactly(Discourse.system_user, staged_user, active_user)
expect(staged_user.reload.email).to eq(common_email) expect(staged_user.reload.email).to eq(common_email)
end end
it 'should move posts owned by duplicate users to the original' do
post1 = Fabricate(:post, user: staged_user2)
post2 = Fabricate(:post, user: staged_user2)
post3 = Fabricate(:post, user: staged_user3)
expect { described_class.new.execute_onceoff({}) }
.to change { staged_user.posts.count }.by(+3)
expect(staged_user.posts.all).to contain_exactly(post1, post2, post3)
end
end end