require 'spec_helper'

describe EmailBatchNewMusician do

  after(:each) do
    Timecop.return
  end

  before(:each) do
    UserMailer.deliveries.clear
  end

  describe 'daily scheduled' do
    # before { pending }

    let (:batch_created_at) { 
      Time.now - 1.day
      # FactoryGirl.create(:email_batch_new_musician, :created_at => Time.now - 1.day) 
    }

    let (:receiver_date) { 
      batch_created_at - (EmailBatchNewMusician::SINCE_DAYS.days + 1.day) 
    }

    let (:receiver1) { 
      FactoryGirl.create(:user,
                         :created_at => receiver_date,
                         :last_jam_locidispid => 1,
                         :last_jam_addr => 1
                         )
    }
    let (:receiver2) { 
      FactoryGirl.create(:user,
                         :created_at => receiver_date,
                         :last_jam_locidispid => 3,
                         :last_jam_addr => 3
                         )
    }

    let (:drummer) { FactoryGirl.create(:user, :last_jam_locidispid => 1, :created_at => batch_created_at - 1.hour) }
    let (:guitarist) { FactoryGirl.create(:user, :last_jam_locidispid => 1, :created_at => batch_created_at - 1.hour) }
    let (:bassist) { FactoryGirl.create(:user, :last_jam_locidispid => 1, :created_at => batch_created_at - 1.hour) }
    let (:vocalist) { FactoryGirl.create(:user, :last_jam_locidispid => 1, :created_at => batch_created_at - 1.hour) }
    let (:loser) { FactoryGirl.create(:user, :last_jam_locidispid => 2, :created_at => batch_created_at - 1.hour) }
    let (:drummer3) { FactoryGirl.create(:user, :last_jam_locidispid => 3, :created_at => batch_created_at - 1.hour) }
    let (:guitarist3) { FactoryGirl.create(:user, :last_jam_locidispid => 3, :created_at => batch_created_at - 1.hour) }
    let (:bassist3) { FactoryGirl.create(:user, :last_jam_locidispid => 3, :created_at => batch_created_at - 1.hour) }
    let (:vocalist3) { FactoryGirl.create(:user, :last_jam_locidispid => 3, :created_at => batch_created_at - 1.hour) }

    before(:each) do
      drummer; guitarist; bassist; vocalist; loser
      drummer3; guitarist3; bassist3; vocalist3
      receiver1; receiver2
      EmailBatchNewMusician.delete_all
      JamRuby::Score.delete_all
      JamRuby::Score.connection.execute('delete from current_network_scores').check
      JamRuby::Score.createx(1, 'a', 1, 1, 'a', 1, 10)
      JamRuby::Score.createx(1, 'a', 1, 2, 'a', 2, Score::MAX_YELLOW_LATENCY + 1)
    end
    
    it 'sets up data properly' do
      ebatch0 = FactoryGirl.create(:email_batch_new_musician, 
                                   :created_at => batch_created_at) 
      results = ebatch0.fetch_recipients

      num = User.where(:last_jam_locidispid => 1)
        .where("created_at < ?",ebatch0.time_since_last_batch(EmailBatchNewMusician::SINCE_DAYS))
        .count
      expect(num).to be > 0
      expect(results.count).to eq(num)
      
      user, new_musicians = results[0]
      expect(user.id).to eq(receiver1.id)
      num = User.where(:last_jam_locidispid => 1)
        .where("created_at >= ?",ebatch0.time_since_last_batch(EmailBatchNewMusician::SINCE_DAYS))
        .count
      expect(num).to be > 0
      expect(new_musicians.count).to eq(num)
    end

    it 'sends email' do
      ebatch0 = FactoryGirl.create(:email_batch_new_musician, 
                                   :created_at => batch_created_at) 
      ebatch0.deliver_batch
      num = User.where(:last_jam_locidispid => 1)
        .where("created_at < ?",ebatch0.time_since_last_batch(EmailBatchNewMusician::SINCE_DAYS))
        .count
      expect(num).to be > 0
      expect(UserMailer.deliveries.length).to eq(num)

      ebatch1 = FactoryGirl.create(:email_batch_new_musician, 
                                   :created_at => ebatch0.created_at + 1.day) 
      # new musicians
      FactoryGirl.create(:user, 
                         :last_jam_locidispid => 5,
                         :created_at => ebatch0.created_at + 1.minute)
      FactoryGirl.create(:user, 
                         :last_jam_locidispid => 5,
                         :created_at => ebatch1.created_at - 1.minute)
      JamRuby::Score.createx(1, 'a', 1, 5, 'a', 5, 10)
      # decoy
      JamRuby::Score.createx(1, 'a', 1, 3, 'a', 3, Score::MAX_YELLOW_LATENCY + 1)
      FactoryGirl.create(:user, 
                         :last_jam_locidispid => 2,
                         :created_at => ebatch1.created_at - 1.minute)
      FactoryGirl.create(:user, 
                         :last_jam_locidispid => 3,
                         :created_at => ebatch1.created_at - 1.minute)

      # all 1's receive emails
      num = User.where(:last_jam_locidispid => 1)
        .where("created_at <= ?", ebatch1.time_since_last_batch(EmailBatchNewMusician::SINCE_DAYS))
        .count
      expect(num).to be > 0
      results = ebatch1.fetch_recipients
      expect(results.count).to eq(num)

      # all 5's are new
      newm = User.where(:last_jam_locidispid => 5)
        .where("created_at > ?", ebatch1.time_since_last_batch(EmailBatchNewMusician::SINCE_DAYS))
        .where("created_at <= ?", ebatch1.created_at)
        .count
      expect(newm).to be > 0
      expect(results[0][1].count).to eq(newm)

      UserMailer.deliveries.clear
      ebatch1.deliver_batch
      expect(UserMailer.deliveries.length).to eq(num)
    end

    it 'sends batch as if from queue' do
      EmailBatchNewMusician.send_new_musician_batch
      num = User.where(:last_jam_locidispid => 1)
        .where("created_at < ?", EmailBatchNewMusician.first.time_since_last_batch(EmailBatchNewMusician::SINCE_DAYS))
        .count
      expect(num).to be > 0
      expect(UserMailer.deliveries.length).to eq(num)
    end

    it 'handles multiple receivers' do
      JamRuby::Score.createx(1, 'a', 1, 3, 'a', 3, 10)
      JamRuby::Score.createx(1, 'a', 1, 4, 'a', 4, 10)
      JamRuby::Score.createx(2, 'a', 2, 4, 'a', 4, 10)

      ebatch0 = FactoryGirl.create(:email_batch_new_musician, :created_at => batch_created_at) 
      results = ebatch0.fetch_recipients
      expect(results.count).to eq(2)
      user, new_musicians = results.detect { |rr| rr[0].id == receiver1.id }
      expect(new_musicians.count).to eq(8)
      user, new_musicians = results.detect { |rr| rr[0].id == receiver2.id }
      expect(new_musicians.count).to eq(4)
    end

    it 'handles large batches' do
      ebatch0 = FactoryGirl.create(:email_batch_new_musician, :created_at => receiver_date) 
      dd = ebatch0.created_at - 1.day
      20.downto(1) do |nn|
        FactoryGirl.create(:user, :last_jam_locidispid => 5, :created_at => dd)
      end
      10.downto(1) do |nn|
        FactoryGirl.create(:user, :last_jam_locidispid => 6, 
                           :created_at => ebatch0.created_at + 1.hour) 
      end
      JamRuby::Score.delete_all
      JamRuby::Score.connection.execute('delete from current_network_scores').check
      JamRuby::Score.createx(5, 'a', 5, 6, 'a', 6, 10)
      JamRuby::Score.createx(5, 'a', 5, 7, 'a', 7, Score::MAX_YELLOW_LATENCY + 1)
      FactoryGirl.create(:user, :last_jam_locidispid => 8, :created_at => dd) 
      FactoryGirl.create(:user, :last_jam_locidispid => 7) 

      receivers = []
      ebatch0.fetch_recipients(3) do |uu, newm|
        receivers << uu
        expect(newm.count).to eq(10)
      end
      expect(receivers.count).to eq(User.where(["created_at <= ? AND last_jam_addr = ?",dd,5]).count)
    end

  end
end
