require 'spec_helper'

describe Feed do

  before(:all) do
    MusicSession.delete_all
    Recording.delete_all
    IcecastMount.delete_all
  end


  let (:user1) { FactoryGirl.create(:user) }
  let (:user2) { FactoryGirl.create(:user) }
  let (:user3) { FactoryGirl.create(:user) }
  let (:user4) { FactoryGirl.create(:user) }
  let (:band)  { FactoryGirl.create(:band) }

  it "no result" do
    feeds, next_page = Feed.index(user1)
    feeds.length.should == 0
  end

  it "one claimed recording" do
    claimed_recording = FactoryGirl.create(:claimed_recording)
    MusicSessionUserHistory.delete_all # the factory makes a music_session while making the recording/claimed_recording
    MusicSession.delete_all # the factory makes a music_session while making the recording/claimed_recording
    feeds, next_page = Feed.index(user1)
    feeds.length.should == 1
    feeds[0].recording == claimed_recording.recording
  end

  it "two claimed recordings for the same recording should only return one" do
    recording = FactoryGirl.create(:claimed_recording).recording
    second_track = FactoryGirl.create(:recorded_track, recording: recording)
    recording.recorded_tracks << second_track
    FactoryGirl.create(:claimed_recording, recording: recording, user: second_track.user)
    MusicSessionUserHistory.delete_all # the factory makes a music_session while making the recording/claimed_recording
    MusicSession.delete_all

    # verify the mess above only made one recording
    Recording.count.should == 1

    feeds, next_page = Feed.index(user1)
    feeds.length.should == 1
  end

  it "one music session" do
    music_session = FactoryGirl.create(:active_music_session)
    feeds, next_page = Feed.index(user1)
    feeds.length.should == 1
    feeds[0].music_session == music_session.music_session
  end

  it "does not return a recording with no claimed recordings" do
    recording = FactoryGirl.create(:recording)
    MusicSessionUserHistory.delete_all # the factory makes a music_session while making the recording/claimed_recording
    MusicSession.delete_all

    feeds, next_page = Feed.index(user1)
    feeds.length.should == 0
  end

  describe "sorting" do
    before :each do
      ClaimedRecording.delete_all
    end

    it "sorts by active flag / index (date) DESC" do
      claimed_recording = FactoryGirl.create(:claimed_recording)

      feeds, next_page = Feed.index(user1)
      feeds.length.should == 2
      feeds[0].recording.should == claimed_recording.recording
      feeds[1].music_session.should == claimed_recording.recording.music_session.music_session
    end

    it "sort by active flag / plays DESC" do
      claimed_recording1 = FactoryGirl.create(:claimed_recording)
      claimed_recording2 = FactoryGirl.create(:claimed_recording)

      FactoryGirl.create(:playable_play, playable: claimed_recording1.recording, claimed_recording: claimed_recording1, user:claimed_recording1.user)

      feeds, next_page = Feed.index(user1, :sort => 'plays')
      feeds.length.should == 4

      FactoryGirl.create(:playable_play, playable: claimed_recording2.recording, claimed_recording: claimed_recording2, user:claimed_recording1.user)
      FactoryGirl.create(:playable_play, playable: claimed_recording2.recording, claimed_recording: claimed_recording2, user:claimed_recording2.user)
      claimed_recording2.recording.play_count += 2
      claimed_recording2.recording.save!

      feeds, next_page = Feed.index(user1, :sort => 'plays')

      feeds[0].recording.should == claimed_recording2.recording
      feeds[2].recording.should == claimed_recording1.recording

      FactoryGirl.create(:playable_play, playable: claimed_recording2.recording.music_session.music_session, user: user1)
      FactoryGirl.create(:playable_play, playable: claimed_recording2.recording.music_session.music_session, user: user2)
      FactoryGirl.create(:playable_play, playable: claimed_recording2.recording.music_session.music_session, user: user3)      
      claimed_recording2.recording.play_count+=3
      claimed_recording2.recording.save!

      feeds, next_page = Feed.index(user1, :sort => 'plays')
      feeds.length.should == 4
      feeds[0].recording.should == claimed_recording2.recording
      feeds[2].recording.should == claimed_recording1.recording
    end

    it "sort by active flag / likes DESC" do
      claimed_recording1 = FactoryGirl.create(:claimed_recording)
      claimed_recording2 = FactoryGirl.create(:claimed_recording)

      FactoryGirl.create(:recording_like, recording: claimed_recording1.recording, claimed_recording: claimed_recording1, user:claimed_recording1.user)

      feeds, next_page = Feed.index(user1, :sort => 'likes')
      feeds.length.should == 4

      FactoryGirl.create(:recording_like, recording: claimed_recording2.recording, claimed_recording: claimed_recording2, user:claimed_recording1.user)
      FactoryGirl.create(:recording_like, recording: claimed_recording2.recording, claimed_recording: claimed_recording2, user:claimed_recording2.user)

      feeds, next_page = Feed.index(user1, :sort => 'likes')
      feeds.length.should == 4
      feeds = feeds.where("feeds.music_session_id is null")
      feeds[0].recording.should == claimed_recording2.recording
      feeds[1].recording.should == claimed_recording1.recording

      FactoryGirl.create(:music_session_like, music_session: claimed_recording1.recording.music_session.music_session, user: user1)
      FactoryGirl.create(:music_session_like, music_session: claimed_recording1.recording.music_session.music_session, user: user2)
      FactoryGirl.create(:music_session_like, music_session: claimed_recording1.recording.music_session.music_session, user: user3)

      feeds, next_page = Feed.index(user1, :sort => 'likes')
      feeds.length.should == 4
      feeds[0].music_session.should == claimed_recording1.recording.music_session.music_session
      feeds[1].recording.should == claimed_recording2.recording
      feeds[2].recording.should == claimed_recording1.recording
    end
  end

  describe "type filters" do
    it "returns only sessions" do
      # creates both recording and history record in feed
      claimed_recording1 = FactoryGirl.create(:claimed_recording)

      feeds, next_page = Feed.index(user1, :type => 'music_session')
      feeds.length.should == 1
      feeds[0].music_session == claimed_recording1.recording.music_session.music_session
    end

    it "returns only sessions" do
      # creates both recording and history record in feed
      claimed_recording1 = FactoryGirl.create(:claimed_recording)

      feeds, next_page = Feed.index(user1, :type => 'music_session')
      feeds.length.should == 1
      feeds[0].music_session == claimed_recording1.recording.music_session.music_session
    end
  end

  describe "time ranges" do
    it "month" do
      # creates both recording and history record in feed
      claimed_recording1 = FactoryGirl.create(:claimed_recording)

      # move the feed entry created for the recording back more than a months ago
      claimed_recording1.recording.feed.created_at = 32.days.ago
      claimed_recording1.recording.feed.save!

      feeds, next_page = Feed.index(user1, :type => 'recording', time_range: 'month')
      feeds.length.should == 0
    end

    it "day" do
      # creates both recording and history record in feed
      claimed_recording1 = FactoryGirl.create(:claimed_recording)

      # move the feed entry created for the recording back more than a day  ago
      claimed_recording1.recording.feed.created_at = 48.hours.ago
      claimed_recording1.recording.feed.save!

      feeds, next_page = Feed.index(user1, :type => 'recording', time_range: 'today')
      feeds.length.should == 0
    end

    it "week" do
      # creates both recording and history record in feed
      claimed_recording1 = FactoryGirl.create(:claimed_recording)

      # move the feed entry created for the recording back more than a months ago
      claimed_recording1.recording.feed.created_at = 8.days.ago
      claimed_recording1.recording.feed.save!

      feeds, next_page = Feed.index(user1, :type => 'recording', time_range: 'week')
      feeds.length.should == 0
    end

    it "all" do
      # creates both recording and history record in feed
      claimed_recording1 = FactoryGirl.create(:claimed_recording)

      # move the feed entry created for the recording back more than a months ago
      claimed_recording1.recording.feed.created_at = 700.days.ago
      claimed_recording1.recording.feed.save!

      feeds, next_page = Feed.index(user1, :type => 'recording', time_range: 'all')
      feeds.length.should == 1
    end
  end

  describe "pagination" do
    it "supports date pagination" do
      claimed_recording = FactoryGirl.create(:claimed_recording)

      ams = ActiveMusicSession.find(claimed_recording.recording.music_session.music_session.id)
      ams.before_destroy

      options = {limit: 1}
      feeds, next_page = Feed.index(user1, options)
      feeds.length.should == 1
      feeds[0].recording.should == claimed_recording.recording
      next_page.should == 2

      options[:next_page] = next_page
      feeds, next_page = Feed.index(user1, options)
      feeds.length.should == 1
      feeds[0].music_session.should == claimed_recording.recording.music_session.music_session
      next_page.should == 3

      options[:next_page] = next_page
      feeds, next_page = Feed.index(user1, options)
      feeds.length.should == 0
      next_page.should be_nil
    end

    it "supports likes pagination" do
      claimed_recording1 = FactoryGirl.create(:claimed_recording)

      FactoryGirl.create(:music_session_like, music_session: claimed_recording1.recording.music_session.music_session, user: user1)

      options = {limit: 1, sort: 'likes'}
      feeds, next_page = Feed.index(user1, options)
      feeds.length.should == 1
      feeds[0].music_session.should == claimed_recording1.recording.music_session.music_session
      next_page.should == 2

      options[:next_page] = next_page
      feeds, next_page = Feed.index(user1, options)
      feeds.length.should == 1
      feeds[0].recording.should == claimed_recording1.recording
      next_page.should == 3

      options[:next_page] = next_page
      feeds, next_page = Feed.index(user1, options)
      feeds.length.should == 0
      next_page.should be_nil
    end

    it "supports plays pagination" do
      claimed_recording1 = FactoryGirl.create(:claimed_recording)

      FactoryGirl.create(:playable_play, playable: claimed_recording1.recording.music_session.music_session, user: user1)

      options = {limit: 1, sort: 'plays'}
      feeds, next_page = Feed.index(user1, options)
      feeds.length.should == 1
      feeds[0].music_session.should == claimed_recording1.recording.music_session.music_session
      next_page.should == 2

      options[:next_page] = next_page
      feeds, next_page = Feed.index(user1, options)
      feeds.length.should == 1
      feeds[0].recording.should == claimed_recording1.recording
      next_page.should == 3

      options[:next_page] = next_page
      feeds, next_page = Feed.index(user1, options)
      feeds.length.should == 0
      next_page.should be_nil
    end
  end

  describe "public feed" do
    it "public and private" do
      claimed_recording1 = FactoryGirl.create(:claimed_recording)
      claimed_recording1.is_public = false
      claimed_recording1.save!

      feeds, next_page = Feed.index(claimed_recording1.user)
      feeds.length.should == 1

      claimed_recording1.recording.music_session.music_session.fan_access = false
      claimed_recording1.recording.music_session.music_session.save!

      feeds, next_page = Feed.index(claimed_recording1.user)
      feeds.length.should == 1
    end
  end

  describe "band feeds" do
    it "does show other band's stuff in this feed" do
      other_band = FactoryGirl.create(:band)
      music_session = FactoryGirl.create(:active_music_session, band: other_band)
      FactoryGirl.create(:music_session_user_history, :history => music_session.music_session, :user => user1)

      claimed_recording1 = FactoryGirl.create(:claimed_recording)
      claimed_recording1.is_public = true
      claimed_recording1.recording.band = other_band
      claimed_recording1.recording.save!
      claimed_recording1.save!

      feeds, next_page = Feed.index(user1, band: band.id)
      feeds.length.should == 0
    end

    it "shows public recordings to you and to others" do
      user1.bands << band
      user1.save!
      music_session = FactoryGirl.create(:active_music_session, band: band)
      music_session.music_session.fan_access.should be_true

      feeds, next_page = Feed.index(user1, band: band.id)
      feeds.length.should == 1
      feeds[0].music_session.should == music_session.music_session

      feeds, next_page = Feed.index(user2, band: band.id)
      feeds.length.should == 1
      feeds[0].music_session.should == music_session.music_session
    end

    it "shows private sessions to you and to others" do
      user1.bands << band
      user1.save!
      music_session = FactoryGirl.create(:active_music_session, band: band, fan_access: false)
      music_session.music_session.fan_access.should be_false

      feeds, next_page = Feed.index(user1, band: band.id)
      feeds.length.should == 1
      feeds[0].music_session.should == music_session.music_session
      feeds[0].music_session.fan_access.should be_false


      feeds, next_page = Feed.index(user2, band: band.id)
      feeds.length.should == 1
    end

    it "shows public recordings to you and to others" do
      claimed_recording1 = FactoryGirl.create(:claimed_recording)
      claimed_recording1.is_public = true
      claimed_recording1.recording.band = band
      claimed_recording1.recording.save!
      claimed_recording1.save!

      feeds, next_page = Feed.index(claimed_recording1.user, band: band.id)
      feeds.length.should == 1
      feeds[0].recording.should == claimed_recording1.recording

      feeds, next_page = Feed.index(user1, band: band.id)
      feeds.length.should == 1
      feeds[0].recording.should == claimed_recording1.recording
    end

    it "shows private recordings to you and to others" do
      claimed_recording1 = FactoryGirl.create(:claimed_recording)
      claimed_recording1.is_public = false
      claimed_recording1.recording.band = band
      claimed_recording1.recording.save!
      claimed_recording1.save!

      claimed_recording1.user.bands << band
      claimed_recording1.user.save!

      feeds, next_page = Feed.index(claimed_recording1.user, band: band.id)
      feeds.length.should == 1
      feeds[0].recording.should == claimed_recording1.recording

      feeds, next_page = Feed.index(user1, band: band.id)
      feeds.length.should == 1
    end
  end

  describe "user feeds" do
    it "does not show stuff from other people" do
      music_session = FactoryGirl.create(:active_music_session)
      FactoryGirl.create(:music_session_user_history, :history => music_session.music_session, :user => user2)

      claimed_recording1 = FactoryGirl.create(:claimed_recording)
      claimed_recording1.is_public = true
      claimed_recording1.save!

      feeds, next_page = Feed.index(user1, user: user1.id)
      feeds.length.should == 0
    end

    it "shows public sessions to you and to others" do
      music_session = FactoryGirl.create(:active_music_session)
      FactoryGirl.create(:music_session_user_history, :history => music_session.music_session, :user => user1)


      feeds, next_page = Feed.index(user1, user: user1.id)
      puts "feeds #{feeds.inspect}"
      feeds.length.should == 1
      feeds[0].music_session.should == music_session.music_session

      feeds, next_page = Feed.index(user2, user: user1.id)
      feeds.length.should == 1
      feeds[0].music_session.should == music_session.music_session
    end


    it "shows private sessions to you and to others" do
      music_session = FactoryGirl.create(:active_music_session, fan_access: false)
      music_session.music_session.fan_access.should be_false
      FactoryGirl.create(:music_session_user_history, :history => music_session.music_session, :user => user1)

      feeds, next_page = Feed.index(user1, user: user1.id)
      feeds.length.should == 1
      feeds[0].music_session.should == music_session.music_session
      feeds[0].music_session.fan_access.should be_false


      feeds, next_page = Feed.index(user2, user: user1.id)
      feeds.length.should == 1
    end

    it "shows public recordings to you and to others" do
      claimed_recording1 = FactoryGirl.create(:claimed_recording)
      claimed_recording1.is_public = true
      claimed_recording1.save!

      feeds, next_page = Feed.index(claimed_recording1.user, user: claimed_recording1.user.id)
      feeds.length.should == 1
      feeds[0].recording.should == claimed_recording1.recording

      feeds, next_page = Feed.index(user1, user: claimed_recording1.user.id)
      feeds.length.should == 1
      feeds[0].recording.should == claimed_recording1.recording
    end

    it "shows private recordings to you and to others" do
      claimed_recording1 = FactoryGirl.create(:claimed_recording)
      claimed_recording1.is_public = false
      claimed_recording1.save!

      feeds, next_page = Feed.index(claimed_recording1.user, user: claimed_recording1.user.id)
      feeds.length.should == 1
      feeds[0].recording.should == claimed_recording1.recording

      feeds, next_page = Feed.index(user1, user: claimed_recording1.user.id)
      feeds.length.should == 1
    end

    it "shows band recordings to you even though you did not claim a recording" do
      user1.bands << band
      user1.save!
      user2.bands << band
      user2.save!

      claimed_recording1 = FactoryGirl.create(:claimed_recording, user: user2)
      claimed_recording1.is_public = true
      claimed_recording1.recording.band = band
      claimed_recording1.recording.save!
      claimed_recording1.save!

      feeds, next_page = Feed.index(user1, user: user1.id)
      feeds.length.should == 1
      feeds[0].recording.should == claimed_recording1 .recording

      # make it private; should still be available
      claimed_recording1.is_public = false
      claimed_recording1.save!

      feeds, next_page = Feed.index(user1, user: user1.id)
      feeds.length.should == 1
      feeds[0].recording.should == claimed_recording1 .recording

      # take user1 out of the band; shouldn't be able to see it
      user1.bands.delete_all

      feeds, next_page = Feed.index(user1, user: user1.id)
      feeds.length.should == 0
    end
  end

  describe "deleted recording" do
    it "should not show" do
      claimed_recording = FactoryGirl.create(:claimed_recording)
      MusicSessionUserHistory.delete_all # the factory makes a music_session while making the recording/claimed_recording
      MusicSession.delete_all # the factory makes a music_session while making the recording/claimed_recording
      recording = claimed_recording.recording
      recording.mark_delete
      recording.reload
      recording.deleted.should == true
      feeds, next_page = Feed.index(user1)
      feeds.length.should == 0
    end
  end


end
