require 'spec_helper'

require 'carrierwave/test/matchers'

describe JamTrack do
  include CarrierWave::Test::Matchers
  include UsesTempFiles

  let(:user) {FactoryGirl.create(:user)}

  it "created" do
    jam_track = FactoryGirl.create(:jam_track)
    jam_track.licensor.should_not be_nil
    jam_track.licensor.jam_tracks.should == [jam_track]
    jam_track.genres.length.should eq(1)
  end

  describe 'sync_reproduction_royalty' do
    it "all possible conditions" do
      jam_track = FactoryGirl.create(:jam_track)
      jam_track.reproduction_royalty_amount.should be_nil

      jam_track.duration = 0
      jam_track.save!
      jam_track.reproduction_royalty_amount.to_f.should eq(0.091)

      jam_track.duration = 1
      jam_track.save!
      jam_track.reproduction_royalty_amount.to_f.should eq(0.091)

      jam_track.duration = 5 * 60 - 1 # just under 5 minutes
      jam_track.save!
      jam_track.reproduction_royalty_amount.to_f.should eq(0.091)

      jam_track.duration = 5 * 60
      jam_track.save!
      jam_track.reproduction_royalty_amount.to_f.should eq(0.091)

      jam_track.duration = 6 * 60 - 1 # just under 6 minutes
      jam_track.save!
      jam_track.reproduction_royalty_amount.should eq(0.091 + 0.0175)

      jam_track.duration = 6 * 60
      jam_track.save!
      jam_track.reproduction_royalty_amount.should eq(0.091 + 0.0175)

      jam_track.duration = 7 * 60 - 1
      jam_track.save!
      jam_track.reproduction_royalty_amount.should eq(0.091 + 0.0175 * 2)

      jam_track.duration = 7 * 60
      jam_track.save!
      jam_track.reproduction_royalty_amount.should eq(0.091 + 0.0175 * 2)

      jam_track.duration = 8 * 60 - 1
      jam_track.save!
      jam_track.reproduction_royalty_amount.should eq((0.091 + 0.0175 * 3).round(5))

      jam_track.duration = 8 * 60
      jam_track.save!
      jam_track.reproduction_royalty_amount.should eq((0.091 + 0.0175 * 3).round(5))

      jam_track.duration = 9 * 60 - 1
      jam_track.save!
      jam_track.reproduction_royalty_amount.should eq(0.091 + 0.0175 * 4)

      jam_track.duration = 9 * 60
      jam_track.save!
      jam_track.reproduction_royalty_amount.should eq(0.091 + 0.0175 * 4)

      jam_track.duration = 10 * 60 - 1
      jam_track.save!
      jam_track.reproduction_royalty_amount.should eq(0.091 + 0.0175 * 5)

      jam_track.duration = 10 * 60
      jam_track.save!
      jam_track.reproduction_royalty_amount.should eq(0.091 + 0.0175 * 5)

      jam_track.duration = 11 * 60 - 1
      jam_track.save!
      jam_track.reproduction_royalty_amount.should eq(0.091 + 0.0175 * 6)

      jam_track.duration = 11 * 60
      jam_track.save!
      jam_track.reproduction_royalty_amount.should eq(0.091 + 0.0175 * 6)

      jam_track.duration = 12 * 60 - 1
      jam_track.save!
      jam_track.reproduction_royalty_amount.should eq((0.091 + 0.0175 * 7).round(5))

      jam_track.duration = 12 * 60
      jam_track.save!
      jam_track.reproduction_royalty_amount.should eq((0.091 + 0.0175 * 7).round(5))

      jam_track.duration = 13 * 60
      jam_track.save!
      jam_track.reproduction_royalty_amount.should eq((0.091 + 0.0175 * 8).round(5))
    end
  end

  describe 'plays' do
    it "creates played instance properly" do 
      @jam_track = FactoryGirl.create(:jam_track)
      play = PlayablePlay.new

      # VRFS-2916 jam_tracks.id is varchar: REMOVE
      # play.jam_track = @jam_track
      # VRFS-2916 jam_tracks.id is varchar: ADD
      play.playable = @jam_track

      play.user = user
      play.save!
      expect(@jam_track.plays.count).to eq(1)
      expect(@jam_track.plays[0].user.id).to eq(user.id)
      expect(user.jam_tracks_played.count).to eq(1)
    end
    it "handles played errors" do 
      play = PlayablePlay.new
      play.user = user
      play.save
      expect(play.errors.count).to eq(1)
    end
  end

  describe "artist_index" do
    before :each do 
      JamTrack.delete_all
    end

    it "empty query" do
      query, pager = JamTrack.artist_index({}, user)
      query.size.should == 0
    end

    it "groups" do
      jam_track1 = FactoryGirl.create(:jam_track_with_tracks, original_artist: 'artist', name: 'a')
      jam_track2 = FactoryGirl.create(:jam_track_with_tracks, original_artist: 'artist', name: 'b')

      query, pager = JamTrack.artist_index({}, user)
      query.size.should == 1

      query[0].original_artist.should eq('artist')
      query[0]['song_count'].should eq(2)
    end

    it "sorts by name" do
      jam_track1 = FactoryGirl.create(:jam_track_with_tracks, original_artist: 'blartist', name: 'a')
      jam_track2 = FactoryGirl.create(:jam_track_with_tracks, original_artist: 'artist', name: 'b')

      query, pager = JamTrack.artist_index({}, user)
      query.size.should == 2

      query[0].original_artist.should eq('artist')
      query[0]['song_count'].should eq(1)
      query[1].original_artist.should eq('blartist')
      query[1]['song_count'].should eq(1)
    end
  end

  describe "index" do
    it "empty query" do
      query, pager, count = JamTrack.index({}, user)
      count.should == 0
    end

    it "sorts by name" do
      jam_track1 = FactoryGirl.create(:jam_track_with_tracks, original_artist: 'artist', name: 'a')
      jam_track2 = FactoryGirl.create(:jam_track_with_tracks, original_artist: 'artist', name: 'b')

      query, pager = JamTrack.index({}, user)
      query.size.should == 2

      query[0].should eq(jam_track1)
      query[1].should eq(jam_track2)

      # flip order by mucking with name
      jam_track1.name = 'c'
      jam_track1.save!

      query, pager = JamTrack.index({}, user)
      query[0].should eq(jam_track2)
      query[1].should eq(jam_track1)
    end

    it "queries on genre" do
      jam_track1 = FactoryGirl.create(:jam_track_with_tracks, original_artist: 'artist', name: 'a')
      jam_track2 = FactoryGirl.create(:jam_track_with_tracks, original_artist: 'artist', name: 'b')
      jam_track1.genres = [Genre.find('rock')]
      jam_track2.genres = [Genre.find('asian')]
      jam_track1.save!
      jam_track2.save!

      query, pager, count = JamTrack.index({genre: 'rock'}, user)
      count.should == 1
      query[0].should eq(jam_track1)

      query, pager, count = JamTrack.index({genre: 'asian'}, user)
      count.should == 1
      query[0].should eq(jam_track2)

      query, pager, count = JamTrack.index({genre: 'african'}, user)
      count.should == 0
    end

    it "supports showing purchased only" do
      jam_track1 = FactoryGirl.create(:jam_track_with_tracks, name: 'a')

      # no results yet
      query, pager, count = JamTrack.index({show_purchased_only:true}, user)
      count.should == 0

      # but after the user buys it, it is returned
      FactoryGirl.create(:jam_track_right, jam_track: jam_track1, user: user)
      query, pager = JamTrack.index({show_purchased_only:true}, user)
      query.size.should == 1
      query[0].should eq(jam_track1)
    end

    it "full text search" do
      jam_track1 = FactoryGirl.create(:jam_track_with_tracks, name: 'Take a Chance On Me', original_artist: 'ABBA')
      jam_track2 = FactoryGirl.create(:jam_track_with_tracks, name: 'Nothing Chance', original_artist: 'ABBA')

      query, pager = JamTrack.index({search: 'Take'}, user)
      query.size.should == 1
      query[0].should eq(jam_track1)

      query, pager = JamTrack.index({search: 'ABB'}, user)
      query.size.should == 2

      query, pager = JamTrack.index({search: 'Chance'}, user)
      query.size.should == 2

      query, pager = JamTrack.index({search: 'Chan'}, user)
      query.size.should == 2

    end

    it "deals with aggregration (regression)" do

      query, pager, count =  JamTrack.index({sort_by: 'jamtrack', artist: 'K.C. And The Sunshine Band'}, user)
      count.should == 0

      jam_track1 = FactoryGirl.create(:jam_track_with_tracks, name: 'Take a Chance On Me', original_artist: 'K.C. And The Sunshine Band')

      query, pager, count =  JamTrack.index({sort_by: 'jamtrack', artist: 'K.C. And The Sunshine Band'}, user)
      count.should == 1
    end
  end

  describe "validations" do

    describe "price" do

      it "0.99" do
        FactoryGirl.build(:jam_track, price: 0.99).valid?.should be_true
      end

      it "1" do
        FactoryGirl.build(:jam_track, price: 1).valid?.should be_true
      end

      it "100" do
        FactoryGirl.build(:jam_track, price: 100).valid?.should be_true
      end

      it "100.1" do
        FactoryGirl.build(:jam_track, price: 100.1).valid?.should be_true
      end

      it "100.12" do
        FactoryGirl.build(:jam_track, price: 100.12).valid?.should be_true
      end

      it "100.123" do
        jam_track = FactoryGirl.build(:jam_track, price: 100.123)
        jam_track.valid?.should be_false
        jam_track.errors[:price].should == ['is invalid']
      end
    end

    describe "reproduction_royalty_amount" do
      it "0.99" do
        FactoryGirl.build(:jam_track, reproduction_royalty_amount: 0.99).valid?.should be_true
      end

      it "1" do
        FactoryGirl.build(:jam_track, reproduction_royalty_amount: 1).valid?.should be_true
      end

      it "100" do
        FactoryGirl.build(:jam_track, reproduction_royalty_amount: 100).valid?.should be_true
      end

      it "100.1" do
        FactoryGirl.build(:jam_track, reproduction_royalty_amount: 100.1).valid?.should be_true
      end

      it "100.12" do
        FactoryGirl.build(:jam_track, reproduction_royalty_amount: 100.12).valid?.should be_true
      end

      it "100.123" do
        FactoryGirl.build(:jam_track, reproduction_royalty_amount: 100.123).valid?.should be_true
      end

      it "100.1234" do
        jam_track = FactoryGirl.build(:jam_track, reproduction_royalty_amount: 100.12345)
        jam_track.valid?.should be_false
        jam_track.errors[:reproduction_royalty_amount].should == ['is invalid']
      end
    end
  end
end