account_migration_spec.rb 7.46 KB
Newer Older
1 2
# frozen_string_literal: true

3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
require "integration/federation/federation_helper"

describe AccountMigration, type: :model do
  describe "create!" do
    include_context "with local old user"

    it "locks old local user after creation" do
      expect {
        AccountMigration.create!(old_person: old_person, new_person: FactoryGirl.create(:person))
      }.to change { old_user.reload.access_locked? }.to be_truthy
    end
  end

  let(:old_person) { FactoryGirl.create(:person) }
  let(:new_person) { FactoryGirl.create(:person) }
  let(:account_migration) {
    AccountMigration.create!(old_person: old_person, new_person: new_person)
  }

  describe "receive" do
    it "calls perform!" do
      expect(account_migration).to receive(:perform!)
      account_migration.receive
    end
  end

  describe "sender" do
    context "with remote old user" do
      include_context "with remote old user"

      it "creates ephemeral user when private key is provided" do
        account_migration.old_private_key = old_user.serialized_private_key
        sender = account_migration.sender
        expect(sender.id).to eq(old_user.diaspora_handle)
        expect(sender.diaspora_handle).to eq(old_user.diaspora_handle)
        expect(sender.encryption_key.to_s).to eq(old_user.encryption_key.to_s)
      end

      it "raises when no private key is provided" do
        expect {
          account_migration.sender
        }.to raise_error("can't build sender without old private key defined")
      end
    end

    context "with local old user" do
      include_context "with local old user"

      it "matches the old user" do
        expect(account_migration.sender).to eq(old_user)
      end
    end
  end

  describe "performed?" do
    it "is changed after perform!" do
      expect {
        account_migration.perform!
      }.to change(account_migration, :performed?).to be_truthy
    end

64 65 66 67 68 69 70 71
    it "is truthy when completed_at is set" do
      expect(FactoryGirl.create(:account_migration, completed_at: Time.zone.now).performed?).to be_truthy
    end

    it "is falsey when completed_at is null" do
      account_migration = FactoryGirl.create(:account_migration, completed_at: nil)
      account_migration.old_person.lock_access!
      expect(account_migration.performed?).to be_falsey
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
    end
  end

  context "with local new user" do
    include_context "with local new user"

    describe "subscribers" do
      it "picks remote subscribers of new user profile and old person" do
        _local_friend, remote_contact = DataGenerator.create(new_user, %i[mutual_friend remote_mutual_friend])
        expect(account_migration.new_person.owner.profile).to receive(:subscribers).and_call_original
        expect(account_migration.subscribers).to match_array([remote_contact.person, old_person])
      end

      context "with local old user" do
        include_context "with local old user"

        it "doesn't include old person" do
          expect(account_migration.subscribers).to be_empty
        end
      end
    end
  end

  describe "perform!" do
    # TODO: add references update tests
    # This spec is missing references update tests. We didn't come with a good idea of how to test it
    # and it is currently covered by integration tests. But it's beter to add these tests at some point
    # in future when we have more time to think about it.

    let(:embedded_account_deleter) { account_migration.send(:account_deleter) }

    it "raises if already performed" do
      expect(account_migration).to receive(:performed?).and_return(true)
      expect {
        account_migration.perform!
      }.to raise_error("already performed")
    end

    it "calls AccountDeleter#tombstone_person_and_profile" do
      expect(embedded_account_deleter).to receive(:tombstone_person_and_profile)
      account_migration.perform!
    end

    context "with local old and remote new users" do
      include_context "with local old user"

      it "calls AccountDeleter#close_user" do
        expect(embedded_account_deleter).to receive(:close_user)
        account_migration.perform!
      end

      it "resends contacts to the remote pod" do
        contact = FactoryGirl.create(:contact, person: old_person, sharing: true)
        expect(Diaspora::Federation::Dispatcher).to receive(:defer_dispatch).with(contact.user, contact)
        account_migration.perform!
      end
    end

    context "with local new and remote old users" do
      include_context "with remote old user"
      include_context "with local new user"

      it "dispatches account migration message" do
135
        expect(account_migration).to receive(:sender).twice.and_return(old_user)
136 137 138 139 140 141 142
        dispatcher = double
        expect(dispatcher).to receive(:dispatch)
        expect(Diaspora::Federation::Dispatcher).to receive(:build)
          .with(old_user, account_migration)
          .and_return(dispatcher)
        account_migration.perform!
      end
143 144 145 146 147 148 149 150

      it "doesn't run migration if old key is not provided" do
        expect(embedded_account_deleter).not_to receive(:tombstone_person_and_profile)

        expect {
          account_migration.perform!
        }.to raise_error "can't build sender without old private key defined"
      end
151 152 153 154 155 156 157 158 159 160 161
    end

    context "with local old and new users" do
      include_context "with local old user"
      include_context "with local new user"

      it "calls AccountDeleter#tombstone_user" do
        expect(embedded_account_deleter).to receive(:tombstone_user)
        account_migration.perform!
      end
    end
Senya's avatar
Senya committed
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212

    context "with remote account merging (non-empty new person)" do
      before do
        FactoryGirl.create(
          :contact,
          person: new_person,
          user:   FactoryGirl.create(:contact, person: old_person).user
        )
        FactoryGirl.create(
          :like,
          author: new_person,
          target: FactoryGirl.create(:like, author: old_person).target
        )
        FactoryGirl.create(
          :participation,
          author: new_person,
          target: FactoryGirl.create(:participation, author: old_person).target
        )
        FactoryGirl.create(
          :poll_participation,
          author:      new_person,
          poll_answer: FactoryGirl.create(:poll_participation, author: old_person).poll_answer
        )
      end

      it "runs without errors" do
        expect {
          account_migration.perform!
        }.not_to raise_error
        expect(new_person.likes.count).to eq(1)
        expect(new_person.participations.count).to eq(1)
        expect(new_person.poll_participations.count).to eq(1)
        expect(new_person.contacts.count).to eq(1)
      end
    end

    context "with local account merging (non-empty new user)" do
      include_context "with local old user"
      include_context "with local new user"

      before do
        FactoryGirl.create(
          :aspect,
          user: new_person.owner,
          name: FactoryGirl.create(:aspect, user: old_person.owner).name
        )
        FactoryGirl.create(
          :contact,
          user:   new_person.owner,
          person: FactoryGirl.create(:contact, user: old_person.owner).person
        )
213 214 215 216 217
        FactoryGirl.create(
          :tag_following,
          user: new_person.owner,
          tag:  FactoryGirl.create(:tag_following, user: old_person.owner).tag
        )
Senya's avatar
Senya committed
218 219 220 221 222 223 224 225 226 227
      end

      it "runs without errors" do
        expect {
          account_migration.perform!
        }.not_to raise_error
        expect(new_person.owner.contacts.count).to eq(1)
        expect(new_person.owner.aspects.count).to eq(1)
      end
    end
228 229
  end
end