require 'rails_helper'

describe Dunlop::ExecutionBatch do
  let(:time) { '1981-03-09T13:33:04Z'.to_time }
  let(:model) { ExecutionBatch::MyBatch }
  before { Timecop.freeze time }
  after  { Timecop.return      }
  subject { model.create! }

  context "state machine behaviour", non_transactional: true do
    before { allow(subject).to receive(:process_steps).and_return(true) }

    it "transitions from new => processing => completed" do
      subject.state.should == "new"
      subject.execute_process
      subject.state.should == "completed"
    end

    it "logs all sorts of info" do
      subject.execute_process
      subject.log_entries.map(&:body).should == [
        "transition to processing",
        "transition to completed",
      ]
    end

    it "transitions to failed" do
      subject.update_attribute(:state, 'completed')
      subject.execute_process
      subject.state.should == "failed"
    end

    it "logs error when failing" do
      allow(subject).to receive(:process_steps).and_raise('boom')
      subject.execute_process
      subject.log_entries.count.should == 3
      subject.should have_log_entries 'transition to processing'
      subject.should have_log_entries 'transition to failed'
      subject.should have_log_entries /ERROR - boom/
    end
  end

  context ".execute_if_required" do

    it "processes if required" do
      create(:source_file_my_source, updated_at: 1.hour.ago)
      expect( model ).to receive(:create).exactly(1).times.and_return(double(execute_process: true))
      model.execute_if_required
    end

  end

  describe ".cleanup!" do
    it "cleans up olther than one month" do
      model.create! created_at: 1.week.ago
      model.create! created_at: 2.months.ago
      model.create! created_at: 3.weeks.ago
      expect { model.cleanup! }.to change { model.count }.by(-1)
    end

    it "works with a duration argument" do
      model.create! created_at: 1.week.ago
      model.create! created_at: 2.months.ago
      model.create! created_at: 3.weeks.ago
      expect { model.cleanup! 2.weeks }.to change { model.count }.by(-2)
    end

    it "works with a time argument" do
      model.create! created_at: 1.day.ago
      model.create! created_at: 1.week.ago
      model.create! created_at: 2.months.ago
      model.create! created_at: 3.weeks.ago
      expect { model.cleanup! 2.days.ago }.to change { model.count }.by(-3)
    end
  end

  describe "info_message" do
    it "sets and persists the info_message" do
      subject.execute_process
      subject.reload.info_message.should eq "I migth have processed 47 records"
    end
  end
end
