describe AdministrateurDeletionService do
  let(:super_admin) { create(:super_admin) }
  let(:admin) { create(:administrateur) }
  let(:service) { create(:service, administrateur: admin) }
  let(:other_admin) { create(:administrateur) }
  let(:procedure) { create(:procedure, service: service, administrateurs: [admin, other_admin]) }
  let(:owned_procedure_service) { create(:service, administrateur: admin) }
  let(:owned_procedure) { create(:procedure, service: owned_procedure_service, administrateurs: [admin]) }

  describe '#call' do
    subject { AdministrateurDeletionService.new(super_admin, admin).call }

    context 'when admin can be deleted' do
      it 'removes admin procedures without dossiers' do
        owned_procedure
        subject
        expect(Procedure.find_by(id: owned_procedure.id)).to be_nil
      end

      it 'removes service admins without procedure' do
        owned_procedure
        subject
        expect(Service.find_by(id: owned_procedure_service.id)).to be_nil
      end

      it 'transfer services to other admin' do
        procedure
        subject
        expect(procedure.service.administrateur).to eq other_admin
      end

      it 'deletes admin' do
        procedure
        owned_procedure
        subject
        expect(Administrateur.find_by(id: admin.id)).to be_nil
      end
    end

    context 'when admin has some procedures with dossiers and only one admin' do
      let(:owned_procedure_with_dossier) { create(:procedure_with_dossiers, service: owned_procedure_service, administrateurs: [admin]) }

      it "doesn't destroy admin" do
        owned_procedure_with_dossier
        subject
        expect(Administrateur.find_by(id: admin.id)).to eq admin
        expect(subject.failure).to eq :cannot_be_deleted
      end
    end

    context "when there is a failure" do
      it 'rollbacks' do
        allow_any_instance_of(Service).to receive(:update).and_return(false)
        procedure
        owned_procedure
        subject
        expect(subject.failure).to eq :still_services
        expect(admin.procedures.count).to eq 2
        expect(procedure.administrateurs).to include(admin)
      end
    end
  end
end