require 'spec_helper'

# these tests avoid the use of ActiveRecord and FactoryGirl to do blackbox, non test-instrumented tests
describe UserManager do


  before(:each) do
    @user_manager = UserManager.new(:conn => @conn)
    UserMailer.deliveries.clear
    @location = { :country => "US", :state => "Arkansas", :city => "Little Rock" }
    @instruments = [ { :instrument_id=>"electric guitar", :proficiency_level => '1', :priority=>0 }]
  end

  describe "signup" do
    it "signup successfully" do
      @user = @user_manager.signup("127.0.0.1", "bob", "smith", "bob@jamkazam.com", "foobar", "foobar", true, nil, @instruments, nil, nil, true, nil, nil, "http://localhost:3000/confirm" )

      @user.errors.any?.should be_false
      @user.first_name.should == "bob"
      @user.last_name.should == "smith"
      @user.email.should == "bob@jamkazam.com"
      @user.email_confirmed.should be_false
      @user.city.should be_nil
      @user.state.should be_nil
      @user.country.should be_nil
      @user.instruments.length.should == 1
      @user.signup_token.should_not be_nil

      UserMailer.deliveries.length.should == 1
    end

    it "signup successfully with instruments" do
      @user = @user_manager.signup("127.0.0.1", "bob", "smith", "bob@jamkazam.com", "foobar", "foobar", true, nil,
                                   @instruments, nil, nil, true, nil, nil, "http://localhost:3000/confirm")

      @user.errors.any?.should be_false
      @user.instruments.length.should == 1
      musician_instrument = @user.musician_instruments[0]
      musician_instrument.instrument.should == Instrument.find("electric guitar")
      musician_instrument.proficiency_level.should == 1
    end

    it "doesnt fail if ip address is nil" do
      @user = @user_manager.signup(nil, "bob", "smith", "bob@jamkazam.com", "foobar", "foobar", true, nil, @instruments, nil, nil, true, nil, nil, "http://localhost:3000/confirm" )

      @user.errors.any?.should be_false
      @user.city.should be_nil
      @user.state.should be_nil
      @user.country.should be_nil
    end

    it "sets the location properly from maxmind" do
      MaxMindManager.active_record_transaction do |manager|
        manager.create_phony_database()
      end
      @user = @user_manager.signup("127.0.0.1", "bob", "smith", "bob@jamkazam.com", "foobar", "foobar", true, nil, @instruments, nil, nil, true, nil, nil, "http://localhost:3000/confirm" )

      @user.errors.any?.should be_false
      @user.city.should == 'City 127'
      @user.state.should == 'Region 63'
      @user.country.should == 'US'
    end

    it "accepts location if specified" do
      MaxMindManager.active_record_transaction do |manager|
        manager.create_phony_database()
      end
      @user = @user_manager.signup("127.0.0.1", "bob", "smith", "bob@jamkazam.com", "foobar", "foobar", true, nil, @instruments, nil, @location, true, nil, nil, "http://localhost:3000/confirm" )

      @user.errors.any?.should be_false
      @user.city.should == 'Little Rock'
      @user.state.should == 'Arkansas'
      @user.country.should == 'US'
    end

    it "accepts a nil location, if specified" do
      MaxMindManager.active_record_transaction do |manager|
        manager.create_phony_database()
      end
      @user = @user_manager.signup("127.0.0.1", "bob", "smith", "bob@jamkazam.com", "foobar", "foobar", true, nil, @instruments, nil, {}, true, nil, nil, "http://localhost:3000/confirm" )

      @user.errors.any?.should be_false
      @user.city.should be_nil
      @user.state.should be_nil
      @user.country.should be_nil
    end


    it "accepts birth_date if specified" do
      MaxMindManager.active_record_transaction do |manager|
        manager.create_phony_database()
      end
      @user = @user_manager.signup("127.0.0.1", "bob", "smith", "bob@jamkazam.com", "foobar", "foobar", true, nil, @instruments, Date.new(2001, 1, 1), nil, true, nil, nil, "http://localhost:3000/confirm" )

      @user.errors.any?.should be_false
      @user.birth_date.should == Date.new(2001, 1, 1)
    end


    it "duplicate signup failure" do
      @user = @user_manager.signup("127.0.0.1", "bob", "smith", "bob@jamkazam.com", "foobar", "foobar", true, nil, @instruments, nil, nil, true, nil, nil, "http://localhost:3000/confirm")
      UserMailer.deliveries.length.should == 1
      @user.errors.any?.should be_false

      # exactly the same parameters; should dup on email, and send no email
      @user = @user_manager.signup("127.0.0.1", "bob", "smith", "bob@jamkazam.com", "foobar", "foobar", true, nil, @instruments, nil, nil, true, nil, nil, "http://localhost:3000/confirm")
      UserMailer.deliveries.length.should == 1
      @user.errors.any?.should be_true
      @user.errors[:email][0].should == "has already been taken"
    end

    it "fail on no username" do
      @user = @user_manager.signup("127.0.0.1", "", "", "bob@jamkazam.com", "foobar", "foobar", true, nil, @instruments, nil, nil, true, nil, nil, "http://localhost:3000/confirm")
      UserMailer.deliveries.length.should == 0
      @user.errors.any?.should be_true
      @user.errors[:first_name][0].should == "can't be blank"
    end

    it "fail on no email" do
      @user = @user_manager.signup("127.0.0.1", "murp", "blurp", "", "foobar", "foobar", true, nil, @instruments, nil, nil, true, nil, nil, "http://localhost:3000/confirm" )
      UserMailer.deliveries.length.should == 0
      @user.errors.any?.should be_true
      @user.errors[:email][0].should == "can't be blank"
    end

  end

  describe "signup_confirm" do
    it "fail on no username" do
       @user = @user_manager.signup("127.0.0.1", "bob", "smith", "bob@jamkazam.com", "foobar", "foobar", true, nil, @instruments, nil, nil, true, nil, nil, "http://localhost:3000/confirm" )
       @user = @user_manager.signup_confirm(@user.signup_token)
       @user.email_confirmed.should be_true
    end

    it "fail to confirm bogus signup_confirmnup token" do
       @user_manager.signup_confirm("murp").should be_nil
    end

    it "fail to confirm empty signup token" do
      @user_manager.signup_confirm("").should be_nil
    end

    it "fail to confirm nil signup token" do
      @user_manager.signup_confirm(nil).should be_nil
    end
  end

  it "signup successfully with due to service (not from any particular user) invitation" do

    @invitation = FactoryGirl.create(:invited_user)

    UserMailer.deliveries.clear

    @invitation.accepted.should be_false

    @user = @user_manager.signup("127.0.0.1", "bob", "smith", @invitation.email, "foobar", "foobar", true, nil,
                                 @instruments, nil, nil, true, nil, @invitation, "http://localhost:3000/confirm")

    @user.errors.any?.should be_false
    @user.email_confirmed.should be_true
    @user.signup_token.should be_nil
    @invitation.errors.any?.should be_false
    @invitation.accepted.should be_true

    UserMailer.deliveries.length.should == 1
  end

  it "signup successfully with due to user invitation with no autofriend" do

    @some_user = FactoryGirl.create(:user)
    @invitation = FactoryGirl.create(:invited_user, :sender => @some_user)
    @invitation.accepted.should be_false
    UserMailer.deliveries.clear


    @user = @user_manager.signup("127.0.0.1", "bob", "smith", @invitation.email, "foobar", "foobar", true, nil,
                                 @instruments, nil, nil, true, nil, @invitation, "http://localhost:3000/confirm")

    @user.errors.any?.should be_false
    @user.email_confirmed.should be_true
    @user.signup_token.should be_nil
    @invitation.errors.any?.should be_false
    @invitation.accepted.should be_true

    UserMailer.deliveries.length.should == 1
  end

  it "signup successfully with due to user invitation with autofriend" do

    @some_user = FactoryGirl.create(:user)
    @invitation = FactoryGirl.create(:invited_user, :sender => @some_user, :autofriend => true)
    @invitation.accepted.should be_false
    UserMailer.deliveries.clear


    @user = @user_manager.signup("127.0.0.1", "bob", "smith", @invitation.email, "foobar", "foobar", true, nil,
                                 @instruments, nil, nil, true, nil, @invitation, "http://localhost:3000/confirm")

    @user.errors.any?.should be_false
    @user.email_confirmed.should be_true
    @user.signup_token.should be_nil
    @invitation.errors.any?.should be_false
    @invitation.accepted.should be_true
    @user.friends?(@some_user).should be_true
    @user.friends?(@some_user).should be_true

    UserMailer.deliveries.length.should == 1
  end

  it "signup successfully with due to user invitation with autofriend, but uses another email" do

    @some_user = FactoryGirl.create(:user)
    @invitation = FactoryGirl.create(:invited_user, :sender => @some_user, :autofriend => true)
    @invitation.accepted.should be_false
    UserMailer.deliveries.clear


    @user = @user_manager.signup("127.0.0.1", "bob", "smith", "bob@jamkazam.com", "foobar", "foobar", true, nil,
                                 @instruments, nil, nil, true, nil, @invitation, "http://localhost:3000/confirm")

    @user.errors.any?.should be_false
    @user.email_confirmed.should be_false
    @user.signup_token.should_not be_nil
    @invitation.errors.any?.should be_false
    @invitation.accepted.should be_true
    @user.friends?(@some_user).should be_true
    @user.friends?(@some_user).should be_true

    UserMailer.deliveries.length.should == 1 # no emails should be sent, in this case
  end
end
