require 'spec_helper'

describe MusicSession do

  before(:each) do
    MusicSession.delete_all
  end
  it 'can grant access to valid user' do

    user1 = FactoryGirl.create(:user) # in the jam session
    user2 = FactoryGirl.create(:user) # in the jam session
    user3 = FactoryGirl.create(:user) # not in the jam session

    music_session = FactoryGirl.create(:music_session, :creator => user1, :musician_access => false)
    FactoryGirl.create(:connection, :user => user1, :music_session => music_session)
    FactoryGirl.create(:connection, :user => user2, :music_session => music_session)


    music_session.access?(user1).should == true
    music_session.access?(user2).should == true
    music_session.access?(user3).should == false
  end

  it 'anyone can join a open music session' do

    user1 = FactoryGirl.create(:user) # in the jam session
    user2 = FactoryGirl.create(:user) # in the jam session
    user3 = FactoryGirl.create(:user) # not in the jam session

    music_session = FactoryGirl.create(:music_session, :creator => user1, :musician_access => true)

    music_session.can_join?(user1, true).should == true
    music_session.can_join?(user2, true).should == true
    music_session.can_join?(user3, true).should == true
  end

  it 'no one but invited people can join closed music session' do
    user1 = FactoryGirl.create(:user) # in the jam session
    user2 = FactoryGirl.create(:user) # in the jam session
    user3 = FactoryGirl.create(:user) # not in the jam session

    music_session = FactoryGirl.create(:music_session, :creator => user1, :musician_access => false)
    FactoryGirl.create(:connection, :user => user1, :music_session => music_session)

    music_session.can_join?(user1, true).should == true
    music_session.can_join?(user2, true).should == false
    music_session.can_join?(user3, true).should == false

    # invite user 2
    FactoryGirl.create(:friendship, :user => user1, :friend => user2)
    FactoryGirl.create(:friendship, :user => user2, :friend => user1)
    FactoryGirl.create(:invitation, :sender => user1, :receiver => user2, :music_session => music_session)

    music_session.can_join?(user1, true).should == true
    music_session.can_join?(user2, true).should == true
    music_session.can_join?(user3, true).should == false
  end

  it 'no one but invited people can see closed music session' do
    user1 = FactoryGirl.create(:user) # in the jam session
    user2 = FactoryGirl.create(:user) # in the jam session
    user3 = FactoryGirl.create(:user) # not in the jam session

    music_session = FactoryGirl.create(:music_session, :creator => user1, :musician_access => false)
    FactoryGirl.create(:connection, :user => user1, :music_session => music_session)

    music_session.can_see?(user1).should == true
    music_session.can_see?(user2).should == false
    music_session.can_see?(user3).should == false

    # invite user 2
    FactoryGirl.create(:friendship, :user => user1, :friend => user2)
    FactoryGirl.create(:friendship, :user => user2, :friend => user1)
    FactoryGirl.create(:invitation, :sender => user1, :receiver => user2, :music_session => music_session)

    music_session.can_see?(user1).should == true
    music_session.can_see?(user2).should == true
    music_session.can_see?(user3).should == false
  end


  it "orders two sessions by created_at starting with most recent" do
    creator = FactoryGirl.create(:user)
    creator2 = FactoryGirl.create(:user)

    earlier_session = FactoryGirl.create(:music_session, :creator => creator, :description => "Earlier Session")
    FactoryGirl.create(:connection, :user => creator, :music_session => earlier_session)

    later_session = FactoryGirl.create(:music_session, :creator => creator2, :description => "Later Session")
    FactoryGirl.create(:connection, :user => creator2, :music_session => later_session)

    user = FactoryGirl.create(:user)

    #ActiveRecord::Base.logger = Logger.new(STDOUT)
    music_sessions = MusicSession.index(user)
    music_sessions.length.should == 2
    music_sessions.first.id.should == later_session.id
  end

  it "orders sessions with inviteds first, even if created first" do
    creator1 = FactoryGirl.create(:user)
    creator2 = FactoryGirl.create(:user)

    earlier_session = FactoryGirl.create(:music_session, :creator => creator1, :description => "Earlier Session")
    FactoryGirl.create(:connection, :user => creator1, :music_session => earlier_session)
    later_session = FactoryGirl.create(:music_session, :creator => creator2, :description => "Later Session")
    FactoryGirl.create(:connection, :user => creator2, :music_session => later_session)
    user = FactoryGirl.create(:user)
    FactoryGirl.create(:connection, :user => creator1, :music_session => earlier_session)
    FactoryGirl.create(:friendship, :user => creator1, :friend => user)
    FactoryGirl.create(:friendship, :user => user, :friend => creator1)
    FactoryGirl.create(:invitation, :sender => creator1, :receiver => user, :music_session => earlier_session)

    music_sessions = MusicSession.index(user)
    music_sessions.length.should == 2
    music_sessions.first.id.should == earlier_session.id
  end


  it "orders sessions with friends in the session first, even if created first" do
    
    creator1 = FactoryGirl.create(:user)
    creator2 = FactoryGirl.create(:user)
    earlier_session = FactoryGirl.create(:music_session, :creator => creator1, :description => "Earlier Session")
    FactoryGirl.create(:connection, :user => creator1, :music_session => earlier_session)
    later_session = FactoryGirl.create(:music_session, :creator => creator2, :description => "Later Session")
    FactoryGirl.create(:connection, :user => creator2, :music_session => later_session)

    user = FactoryGirl.create(:user)
    FactoryGirl.create(:friendship, :user => creator1, :friend => user)
    FactoryGirl.create(:friendship, :user => user, :friend => creator1)
    FactoryGirl.create(:connection, :user => creator1, :music_session => earlier_session)
    FactoryGirl.create(:connection, :user => creator2, :music_session => earlier_session)

    music_sessions = MusicSession.index(user)
    music_sessions.length.should == 2
    music_sessions.first.id.should == earlier_session.id
  end  

  it "doesn't list a session if musician_access is set to false" do
    creator = FactoryGirl.create(:user)
    session = FactoryGirl.create(:music_session, :creator => creator, :description => "Session", :musician_access => false)
    user = FactoryGirl.create(:user)

    music_sessions = MusicSession.index(user)
    music_sessions.length.should == 0
  end

  it "does list a session if musician_access is set to false but user was invited" do
    creator = FactoryGirl.create(:user)
    session = FactoryGirl.create(:music_session, :creator => creator, :description => "Session", :musician_access => false)
    user = FactoryGirl.create(:user)
    FactoryGirl.create(:connection, :user => creator, :music_session => session)  
    FactoryGirl.create(:friendship, :user => creator, :friend => user)
    FactoryGirl.create(:friendship, :user => user, :friend => creator)    
    FactoryGirl.create(:invitation, :sender => creator, :receiver => user, :music_session => session)

    music_sessions = MusicSession.index(user)
    music_sessions.length.should == 1
  end

  it "lists a session if the genre matches" do
    creator = FactoryGirl.create(:user)
    genre = FactoryGirl.create(:genre)
    session = FactoryGirl.create(:music_session, :creator => creator, :description => "Session", :genres => [genre])
    FactoryGirl.create(:connection, :user => creator, :music_session => session)
    user = FactoryGirl.create(:user)

    music_sessions = MusicSession.index(user, nil, [genre.id])
    music_sessions.length.should == 1
  end

  it "does not list a session if the genre fails to match" do
    creator = FactoryGirl.create(:user)
    genre1 = FactoryGirl.create(:genre)
    genre2 = FactoryGirl.create(:genre)
    session = FactoryGirl.create(:music_session, :creator => creator, :description => "Session", :genres => [genre1])
    user = FactoryGirl.create(:user)

    music_sessions = MusicSession.index(user, nil, [genre2.id])
    music_sessions.length.should == 0
  end

  it "does not list a session if friends_only is set and no friends are in it" do
    creator = FactoryGirl.create(:user)
    session = FactoryGirl.create(:music_session, :creator => creator, :description => "Session")
    user = FactoryGirl.create(:user)

    music_sessions = MusicSession.index(user, nil, nil, true)
    music_sessions.length.should == 0
  end

  it "lists a session properly if a friend is in it" do
    creator = FactoryGirl.create(:user)
    session = FactoryGirl.create(:music_session, :creator => creator, :description => "Session")
    user = FactoryGirl.create(:user)
    FactoryGirl.create(:friendship, :user => creator, :friend => user)
    FactoryGirl.create(:friendship, :user => user, :friend => creator)
    FactoryGirl.create(:connection, :user => creator, :music_session => session)

    music_sessions = MusicSession.index(user, nil, nil)
    music_sessions.length.should == 1
    music_sessions = MusicSession.index(user, nil, nil, true)
    music_sessions.length.should == 1
    music_sessions = MusicSession.index(user, nil, nil, false, true)
    music_sessions.length.should == 0
    music_sessions = MusicSession.index(user, nil, nil, true, true)
    music_sessions.length.should == 1
  end

  it "does not list a session if it has no participants" do
    # it's a design goal that there should be no sessions with 0 connections;
    # however, this bug continually crops up so the .index method will protect against this common bug

    creator = FactoryGirl.create(:user)
    session = FactoryGirl.create(:music_session, :creator => creator, :description => "Session")
    session.connections.delete_all # should leave a bogus, 0 participant session around

    music_sessions = MusicSession.index(creator, nil, nil)
    music_sessions.length.should == 0

  end

  it "does not list a session if my_bands_only is set and it's not my band" do
    creator = FactoryGirl.create(:user)
    session = FactoryGirl.create(:music_session, :creator => creator, :description => "Session")
    user = FactoryGirl.create(:user)

    music_sessions = MusicSession.index(user, nil, nil, false, true)
    music_sessions.length.should == 0
  end

  it "lists a session properly if it's my band's session" do
    band = FactoryGirl.create(:band)
    creator = FactoryGirl.create(:user)
    session = FactoryGirl.create(:music_session, :creator => creator, :description => "Session", :band => band)
    FactoryGirl.create(:connection, :user => creator, :music_session => session)
    user = FactoryGirl.create(:user)
    FactoryGirl.create(:band_musician, :band => band, :user => creator)
    FactoryGirl.create(:band_musician, :band => band, :user => user)

    music_sessions = MusicSession.index(user, nil, nil)
    music_sessions.length.should == 1
    music_sessions = MusicSession.index(user, nil, nil, true)
    music_sessions.length.should == 0
    music_sessions = MusicSession.index(user, nil, nil, false, true)
    music_sessions.length.should == 1
    music_sessions = MusicSession.index(user, nil, nil, true, true)
    music_sessions.length.should == 1
  end

  it "updates the fields of a music session properly" do
    genre1 = FactoryGirl.create(:genre)
    genre2 = FactoryGirl.create(:genre)
    genre3 = FactoryGirl.create(:genre)
    genre4 = FactoryGirl.create(:genre)
    creator = FactoryGirl.create(:user)
    session = FactoryGirl.create(:music_session, :creator => creator, :description => "Session", :genres => [genre3,genre4])
    session.update_attributes({:description => "Session2", :genre => [genre1, genre2]})
    session.genres = [genre1, genre2]
    session.reload
    session.description.should == "Session2"
    session.genres.length.should == 2
    session.genres[0].id.should == genre1.id
  end

=begin
  # mslemmer:
  # I'm going to clean this up into smaller tasks.
  it 'can list sessions with appropriate sort order' do

    user1 = FactoryGirl.create(:user)
    user2 = FactoryGirl.create(:user)
    user3 = FactoryGirl.create(:user)
    user4 = FactoryGirl.create(:user)
    user5 = FactoryGirl.create(:user)

    music_session = FactoryGirl.create(:music_session, :creator => user1, :musician_access => false)
    FactoryGirl.create(:connection, :user => user1, :music_session => music_session)

    music_sessions = MusicSession.index(user2)
    music_sessions.length.should == 0
    music_session2 = FactoryGirl.create(:music_session, :creator => user3, :musician_access => true)
    FactoryGirl.create(:connection, :user => user3, :music_session => music_session2)

    music_sessions = MusicSession.index(user2)
    music_sessions.length.should == 1
    music_sessions[0].connections[0].user.friends.length == 0

    # users 1 and 5 are friends
    FactoryGirl.create(:friendship, :user => user1, :friend => user5)
    FactoryGirl.create(:friendship, :user => user5, :friend => user1)

    # users 1 and 2 are friends
    FactoryGirl.create(:friendship, :user => user1, :friend => user2)
    FactoryGirl.create(:friendship, :user => user2, :friend => user1)

    # users 2 and 4 are friends
    FactoryGirl.create(:friendship, :user => user2, :friend => user4)
    FactoryGirl.create(:friendship, :user => user4, :friend => user2)

    # user 2 should now be able to see this session, because his friend is in the session
    music_sessions = MusicSession.index(user2)
    music_sessions.length.should == 2
    music_sessions[0].id.should == music_session.id
    music_sessions[0].connections[0].user.id.should == user1.id
    music_sessions[0].connections[0].user.friends.length == 1
    music_sessions[1].id.should == music_session2.id

    FactoryGirl.create(:invitation, :sender => user1, :receiver => user2, :music_session => music_session)

    music_sessions = MusicSession.index(user2)
    music_sessions.length.should == 2
    music_sessions[0].id.should == music_session.id
    music_sessions[1].id.should == music_session2.id

    # create another, but friendy usic session with user 4
    music_session3 = FactoryGirl.create(:music_session, :creator => user4, :musician_access => false, :created_at => 1.week.ago)
    FactoryGirl.create(:connection, :user => user4, :music_session => music_session3)

    music_sessions = MusicSession.index(user2)
    music_sessions.length.should == 3
    music_sessions[0].id.should == music_session.id
    music_sessions[1].id.should == music_session3.id
    music_sessions[2].id.should == music_session2.id

    # verify we can inspect the data
    music_session.invitations.length.should == 1


    music_session4 = FactoryGirl.create(:music_session, :creator => user5, :musician_access => false, :created_at => 2.week.ago)
    FactoryGirl.create(:connection, :user => user5, :music_session => music_session4)

    music_sessions = MusicSession.index(user2)
    music_sessions.length.should == 3
    # make this session public now
    music_session4.musician_access = true
    music_session4.save

    music_sessions = MusicSession.index(user2)
    music_sessions.length.should == 4
    music_sessions[0].id.should == music_session.id
    music_sessions[1].id.should == music_session3.id
    music_sessions[2].id.should == music_session2.id
    music_sessions[3].id.should == music_session4.id

    # ok let's make the public session that we just made, become a 'friendy' one
    # make user2/5 friends
    FactoryGirl.create(:friendship, :user => user2, :friend => user5)
    FactoryGirl.create(:friendship, :user => user5, :friend => user2)

    music_sessions = MusicSession.index(user2)
    music_sessions.length.should == 4
    music_sessions[0].id.should == music_session.id
    music_sessions[1].id.should == music_session3.id
    music_sessions[2].id.should == music_session4.id
    music_sessions[3].id.should == music_session2.id

    # and finally make it an invite
    FactoryGirl.create(:invitation, :sender => user5, :receiver => user2, :music_session => music_session4  )
    music_sessions = MusicSession.index(user2)
    music_sessions.length.should == 4

    music_sessions[0].id.should == music_session.id
    music_sessions[1].id.should == music_session4.id
    music_sessions[2].id.should == music_session3.id
    music_sessions[3].id.should == music_session2.id
  end
=end

  it 'uninvited users cant join approval-required sessions without invitation' do
    user1 = FactoryGirl.create(:user) # in the jam session
    user2 = FactoryGirl.create(:user) # in the jam session

    music_session = FactoryGirl.create(:music_session, :creator => user1, :musician_access => true, :approval_required => true)

    connection1 = FactoryGirl.create(:connection, :user => user1, :music_session => music_session)
    expect { FactoryGirl.create(:connection, :user => user2, :music_session => music_session, :joining_session => true) }.to raise_error(ActiveRecord::RecordInvalid)

  end

  it "must have legal_terms accepted" do
    user1 = FactoryGirl.create(:user)
    music_session = FactoryGirl.build(:music_session, :creator => user1, :legal_terms=> false)
    music_session.save
    music_session.valid?.should be_false
    music_session.errors["legal_terms"].should == ["is not included in the list"]
  end

  it "cannot have profanity in the description" do
    user1 = FactoryGirl.create(:user)
    music_session = FactoryGirl.build(:music_session, :creator => user1, :legal_terms=> false, :description => "fuck you")
    music_session.save
    music_session.valid?.should be_false
  end

end

