require 'spec_helper'

describe JamRuby::Connection do
  let(:user) { FactoryGirl.create(:user) }
  let (:music_session) { FactoryGirl.create(:active_music_session, :creator => user) }
  let (:conn) { FactoryGirl.create(:connection,
                                  :user => user,
                                  :music_session => music_session,
                                  :ip_address => "1.1.1.1",
                                  :client_id => "1") }

  let(:tracks) { [{'sound' => 'mono', 'client_track_id' => 'abc', 'instrument_id' => 'piano'}] }

  it 'starts in the correct state' do
    connection = FactoryGirl.create(:connection, 
                                    :user => user, 
                                    :music_session => music_session, 
                                    :ip_address => "1.1.1.1", 
                                    :client_id => "1")

    connection.idle?.should be_true
  end

  it 'transitions properly' do
    connection = FactoryGirl.create(:connection, 
                                    :user => user, 
                                    :music_session => music_session, 
                                    :ip_address => "1.1.1.1", 
                                    :client_id => "1")

    connection.connect!
    connection.connected?.should be_true
    connection.state_message.should == 'Connected'

    connection.stale!
    connection.stale?.should be_true
    connection.state_message.should == 'Stale'

    connection.expire!
    connection.destroyed?.should be_true
  end

  it 'updates user lat/lng' do
    pending 'distance search changes'
    uu = FactoryGirl.create(:user)
    uu.lat.should == nil
    msess = FactoryGirl.create(:active_music_session, :creator => uu)
    geocode = FactoryGirl.create(:geocoder)
    connection = FactoryGirl.create(:connection, 
                                    :user => uu, 
                                    :music_session => msess, 
                                    :ip_address => "1.1.1.1", 
                                    :client_id => "1")
    user.lat.should == geocode.lat
    user.lng.should == geocode.lng
  end

  describe "audio latency" do
    it "allow update" do
      conn.last_jam_audio_latency = 1
      conn.save!
    end

    it "prevent negative or 0" do
      conn.last_jam_audio_latency = 0
      conn.save.should be_false
      conn.errors[:last_jam_audio_latency].should == ['must be greater than 0']
    end

    it "prevent non numerical" do
      conn.last_jam_audio_latency = 'a'
      conn.save.should be_false
      conn.errors[:last_jam_audio_latency].should == ['is not a number']
    end
  end

  describe "triggers" do
    describe "manage_user_online" do
      it "offline for new user" do
        user.online.should be_false
      end

      it "online/offline based on connection up/down" do
        conn.touch # make a connection
        user.reload
        user.online.should be_true

        conn.delete
        user.reload
        user.online.should be_false
      end

      it "verify that online up/down is only for affected user (no spillover)" do
        user2 = FactoryGirl.create(:user)
        user2.online.should be_false

        conn.touch
        user.reload
        user2.reload

        user.online.should be_true
        user2.online.should be_false # make sure there is no spillover to unrelated users

        conn2 = FactoryGirl.create(:connection,
                           :user => user2,
                           :music_session => music_session,
                           :ip_address => "1.1.1.1",
                           :client_id => "2")

        user.reload
        user2.reload

        user.online.should be_true
        user2.online.should be_true

        # whack one of the connections
        conn.delete
        user.reload
        user2.reload
        user.online.should be_false
        user2.online.should be_true

        conn2.delete
        user.reload
        user2.reload
        user.online.should be_false
        user2.online.should be_false
      end

      it "n connections" do
        conn.touch
        conn2 = FactoryGirl.create(:connection,
                                   :user => user,
                                   :music_session => music_session,
                                   :ip_address => "1.1.1.1",
                                   :client_id => "2")

        user.reload
        user.online.should be_true

        conn.delete
        user.reload
        user.online.should be_true

        conn2.delete
        user.reload
        user.online.should be_false
      end

    end
  end

  describe "stats" do

    it "no connections" do
      stats = Connection.stats
      stats[Connection::TYPE_CLIENT].should eq(0)
      stats[Connection::TYPE_BROWSER].should eq(0)
      stats[Connection::TYPE_LATENCY_TESTER].should eq(0)
      stats['count'].should eq(0)
      stats['scoring_timeout'].should eq(0)
      stats['in_session'].should eq(0)
      stats['musicians'].should eq(0)
      stats['udp_reachable'].should eq(0)
      stats['networking_testing'].should eq(0)
    end

    it "1 connection" do
      conn.touch

      stats = Connection.stats
      stats[Connection::TYPE_CLIENT].should eq(1)
      stats[Connection::TYPE_BROWSER].should eq(0)
      stats[Connection::TYPE_LATENCY_TESTER].should eq(0)
      stats['count'].should eq(1)
      stats['scoring_timeout'].should eq(0)
      stats['in_session'].should eq(1)
      stats['musicians'].should eq(1)
      stats['udp_reachable'].should eq(1)
      stats['networking_testing'].should eq(0)
    end
  end
end
