require 'rails_helper'

class TestBlock
  attr_accessor :call_count

  def initialize
    @call_count       = 0
    @call_times       = []
  end

  def call(work_crew_member:, record:)
    @call_times << Time.now()
    @call_count += 1
  end
end

RSpec.describe 'WorkCrew::Helpers.destroy_dead_records' do
  let(:work_crew_member) { 'some object' }

  let(:action) {
    WorkCrew::Helpers.destroy_dead_records(
      work_crew_member:    work_crew_member,
      dead_records:        dead_records,
      dead_record_block:   dead_record_block,
    )
  }

  let(:dead_record_block) { TestBlock.new }

  let(:target_group_uuid) { SecureRandom.uuid.to_s }

  let(:records) {[
    create(:work_crew_member_data,
      group_uuid: target_group_uuid, instance_modulo: 2,
    ),
    create(:work_crew_member_data,
      group_uuid: target_group_uuid, instance_modulo: 0,
    ),
    create(:work_crew_member_data,
      group_uuid: target_group_uuid, instance_modulo: 1,
    ),
    create(:work_crew_member_data,
      group_uuid: target_group_uuid, instance_modulo: 3,
    ),
  ]}

  context 'when there are no dead records' do
    let(:dead_records) { [] }
    let(:live_records) { records }

    it 'no records should be destroyed' do
      expect{action}.to_not change{WorkCrew::MemberData.count}
    end

    it 'the dead_record_block should not be called' do
      action
      expect(dead_record_block.call_count).to eq(0)
    end
  end

  context 'when there are dead records' do
    let(:dead_records) { records.values_at(1,3) }
    let(:live_records) { records.values_at(0,2) }

    it 'the dead records should be destroyed' do
      action
      undead_records = WorkCrew::MemberData.where(group_uuid: target_group_uuid)
                                     .where(instance_modulo: dead_records.map(&:instance_modulo))
      expect(undead_records).to be_empty
    end

    it 'the other records should remain untouched' do
      action
      untouched_records = WorkCrew::MemberData.where(group_uuid: target_group_uuid)
                                        .where(instance_modulo: live_records.map(&:instance_modulo))
      expect(untouched_records.size).to be(live_records.size)
    end

    context 'when a dead_record_block is given' do
      it 'the dead_record_block should be called for each destroyed record' do
        action
        expect(dead_record_block.call_count).to eq(dead_records.count)
      end
    end

    context 'when no dead_record_block is given' do
      let(:dead_record_block) { }

      it 'nothing explodes' do
        action
      end
    end
  end
end
