From be1df3ba7586637935c715c7a813eaf5df6fb2fe Mon Sep 17 00:00:00 2001 From: Leo McArdle Date: Tue, 22 Aug 2017 09:58:51 +0100 Subject: [PATCH] FIX: transfer posts by duplicated staged users to original --- .../fix_primary_emails_for_staged_users.rb | 15 ++++++++--- ...ix_primary_emails_for_staged_users_spec.rb | 27 +++++++++++++------ 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/app/jobs/onceoff/fix_primary_emails_for_staged_users.rb b/app/jobs/onceoff/fix_primary_emails_for_staged_users.rb index a4c64188c26..303dc3ffeff 100644 --- a/app/jobs/onceoff/fix_primary_emails_for_staged_users.rb +++ b/app/jobs/onceoff/fix_primary_emails_for_staged_users.rb @@ -2,18 +2,25 @@ module Jobs class FixPrimaryEmailsForStagedUsers < Jobs::Onceoff def execute_onceoff(args) 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") .having("COUNT(email_tokens.email) > 1") .count .each_key do |email| - users.where("email_tokens.email = ?", email) - .order(id: :asc) - .offset(1) + query = users.where("email_tokens.email = ?", email) + .order(id: :asc) + + original_user = query.first + + query.offset(1) .each do |user| + user.posts.each do |post| + post.set_owner(original_user, acting_user) + end destroyer.destroy(user) end end diff --git a/spec/jobs/fix_primary_emails_for_staged_users_spec.rb b/spec/jobs/fix_primary_emails_for_staged_users_spec.rb index 1951c3b6506..fc938e42028 100644 --- a/spec/jobs/fix_primary_emails_for_staged_users_spec.rb +++ b/spec/jobs/fix_primary_emails_for_staged_users_spec.rb @@ -1,25 +1,36 @@ require 'rails_helper' RSpec.describe Jobs::FixPrimaryEmailsForStagedUsers do - it 'should clean up duplicated staged users' do - common_email = 'test@reply' - - staged_user = Fabricate(:user, staged: true, active: false) - staged_user2 = Fabricate(:user, staged: true, active: false) - staged_user3 = Fabricate(:user, staged: true, active: false) + let(:common_email) { 'test@reply' } + let(:staged_user) { Fabricate(:user, staged: true, active: false) } + let(:staged_user2) { Fabricate(:user, staged: true, active: false) } + let(:staged_user3) { Fabricate(:user, staged: true, active: false) } + let(:active_user) { Fabricate(:coding_horror) } + before do [staged_user, staged_user2, staged_user3].each do |user| user.email_tokens = [Fabricate.create(:email_token, email: common_email, user: user)] end - active_user = Fabricate(:coding_horror) - UserEmail.delete_all + end + it 'should clean up duplicated staged users' do expect { described_class.new.execute_onceoff({}) } .to change { User.count }.by(-2) expect(User.all).to contain_exactly(Discourse.system_user, staged_user, active_user) expect(staged_user.reload.email).to eq(common_email) 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