require 'spec_helper'

describe "Signup", :js => true, :type => :feature, :capybara_feature => true do

  subject { page }

  before(:all) do
    @old_recaptcha=Rails.application.config.recaptcha_enable
    Rails.application.config.recaptcha_enable=false
  end

  after(:all) do
    Rails.application.config.recaptcha_enable=@old_recaptcha
  end

  before(:each) do
    @mac_client = FactoryGirl.create(:artifact_update)
    UserMailer.deliveries.clear
    MaxMindManager.create_phony_database
  end

  #----------------------------------------
  # shared examples
  #----------------------------------------
  shared_examples :default_signup_page do
    it "has default signup page content" do
      expect(page).to have_title "JamKazam | Register"
      should have_content(/Live music platform/)
    end
  end

  shared_examples :landing_signup_page do
    it "has landing signup page content" do
      expect(page).to have_title "JamKazam | Register"
      should have_content(/JamKazam has spent the last 6 years/)
    end
  end

  shared_examples :with_origin_signup_submit do
    describe 'form submit' do
      before do
        form_fill_and_submit({
          first_name: "Mike", last_name: "Jones", email: "withorigin1@jamkazam.com", password: "jam123", password_confirmation: "jam123"
        })
      end

      it{
        user = User.find_by_email('withorigin1@jamkazam.com')
        user.musician_instruments.length.should == 1
        location = GeoIpLocations.lookup('127.0.0.1')
        user.country.should == location[:country]
        user.state.should == location[:state]
        user.city.should == location[:city]
        # an email is sent on no-invite signup
        user.origin_utm_source.should eql 'abc'
        user.origin_utm_campaign.should eql 'campaign1'
        user.origin_utm_medium.should eql 'ads'
        user.origin_referrer.should be_nil
      }

      it "redirects" do
        if _page == 'default'
          should have_title("JamKazam | Congratulations")
          should have_content("Your account is ready.")
        else
          should have_title("JamKazam | Downloads")
          should have_content("Your account is ready.")
          should have_content("Signup successful!")
        end
      end


    end
  end

  shared_examples :without_origin_signup_submit do
    describe 'form submit' do
      before do
        form_fill_and_submit({
          first_name: "Mike", last_name: "Jones", email: "newuser1@jamkazam.com", password: "jam123", password_confirmation: "jam123"
        })
      end
      
      it {
        user = User.find_by_email('newuser1@jamkazam.com')
        user.musician?.should == true
        user.musician_instruments.length.should == 1
        location = GeoIpLocations.lookup('127.0.0.1')
        user.country.should == location[:country]
        user.state.should == location[:state]
        user.city.should == location[:city]
        # an email is sent on no-invite signup
        UserMailer.deliveries.length.should == 2
        UserMailer.deliveries[0].html_part.body.include?("To confirm this email address")== 1
      }

      it "redirects" do
        if _page == 'default'
          should have_title("JamKazam | Congratulations")
          should have_content("Your account is ready.")
        else
          should have_title("JamKazam | Downloads")
          should have_content("Signup successful!")
        end
      end

      describe "user can confirm email and receive welcome email" do

        before(:each) do
          UserMailer.deliveries.clear
          visit signup_confirm_path(User.find_by_email('newuser1@jamkazam.com').signup_token)
        end

        it {
          should have_title("Signup Confirmation")
          should have_selector('h1', text: "Email Confirmed")
        }
      end
    end
  end

  shared_examples :signup_with_invite do
    
    let(:invited_user) { FactoryGirl.create(:invited_user, :email => "noone@jamkazam.com", :sender => FactoryGirl.create(:user)) }
    
    before do
      visit "#{path}?invitation_code=#{invited_user.invitation_code}"
      find('#jam_ruby_user_first_name')
      sleep 1 # if I don't do this, first_name and/or last name intermittently fail to fill out

      UserMailer.deliveries.clear
     
      form_fill_and_submit({
        first_name: "Mike", last_name: "Jones", email: "newuser2@jamkazam.com", password: "jam123", password_confirmation: "jam123"
      })
    end

    # Successful sign-in goes to the client
    it {
      should have_title("JamKazam")
      should have_selector('.flash-content', text: "Soon you can play with #{invited_user.sender.name}")
      UserMailer.deliveries.length.should == 2
      uri = URI.parse(current_url)
      if path =~ /landing/
        "#{uri.path}?#{uri.query}".should == landing_client_downloads_path(:friend => invited_user.sender.name)
      else
        "#{uri.path}?#{uri.query}".should == congratulations_musician_path(:friend => invited_user.sender.name)
      end
      
    }
  end

  shared_examples :signup_with_invite_and_autofriend do
    
    before(:each) do
      InvitedUser.destroy_all
      User.destroy_all
      @user = FactoryGirl.create(:user)
      @invited_user = FactoryGirl.create(:invited_user, :sender => @user, :autofriend => true, :email => "noone@jamkazam.com")
      
      visit "#{path}?invitation_code=#{@invited_user.invitation_code}"
      find('#jam_ruby_user_first_name')
      sleep 1 # if I don't do this, first_name and/or last name intermittently fail to fill out

      form_fill_and_submit({
        first_name: "Mike", last_name: "Jones", email: "newuser3@jamkazam.com", password: "jam123", password_confirmation: "jam123"
      })
    end

    # Successful sign-in goes to the client
    it {
      should have_title("JamKazam")
      should have_selector('.flash-content', text: "Soon you can play with #{@invited_user.sender.name}")
      @user.friends?(User.find_by_email("newuser3@jamkazam.com"))
      User.find_by_email("newuser3@jamkazam.com").friends?(@user)
      uri = URI.parse(current_url)
      if path =~ /landing/
        "#{uri.path}?#{uri.query}".should == landing_client_downloads_path(:friend => @invited_user.sender.name)
      else
        "#{uri.path}?#{uri.query}".should == congratulations_musician_path(:friend => @invited_user.sender.name)
      end

    }
  end

  shared_examples :signup_with_different_email do
    let(:invited_user) { FactoryGirl.create(:invited_user, :email => "what@jamkazam.com", :sender => FactoryGirl.create(:user)) }
    before do
      
      visit "#{path}?invitation_code=#{invited_user.invitation_code}"
      find('#jam_ruby_user_first_name')
      sleep 1 # if I don't do this, first_name and/or last name intermittently fail to fill out

      UserMailer.deliveries.clear

      form_fill_and_submit({
        first_name: "Mike", last_name: "Jones", email: "newuser5@jamkazam.com", password: "jam123", password_confirmation: "jam123"
      })
    end

    it {
      
      should have_selector('.flash-content', text: "Soon you can play with #{invited_user.sender.name}")
      User.find_by_email('newuser5@jamkazam.com').musician_instruments.length.should == 1
      User.find_by_email('what@jamkazam.com').should be_nil
      # an email is sent when you invite but use a different email than the one used to invite
      UserMailer.deliveries.length.should == 2
      uri = URI.parse(current_url)
      if path =~ /landing/
        should have_title("JamKazam | Downloads")
        "#{uri.path}?#{uri.query}".should == landing_client_downloads_path(:friend => invited_user.sender.name)
      else
        should have_title("JamKazam | Congratulations")
        "#{uri.path}?#{uri.query}".should == congratulations_musician_path(:friend => invited_user.sender.name)
      end
      
      sign_out
    }
  end

  shared_examples :signup_hints do
    it "redirects to custom location on matched signup_hint" do
      # causes anon cookie to show
      visit '/'
      find('h2', text: 'Play music live and in sync with others from different locations')

      # get a anonymous cookie set up
      anon_user_id = get_me_the_cookie("user_uuid")
      puts "#ANON_USER_ID #{anon_user_id.inspect}"
      anon_user = AnonymousUser.new(anon_user_id[:value], {})
      SignupHint.refresh_by_anoymous_user(anon_user, {redirect_location: '/affiliateProgram'})

      visit path

      form_fill_and_submit({
        first_name: "Mike", last_name: "Jones", email: "signup_hint_guy@jamkazam.com", password: "jam123", password_confirmation: "jam123"
      })

      find('h1', text:'JamKazam Affiliate Program')

      user = User.find_by_email('signup_hint_guy@jamkazam.com')
      user.should_not be_nil
    end

    it "ignores expired_at signup_hint" do

      # causes anon cookie to show
      visit '/'
      find('h2', text: 'Play music live and in sync with others from different locations')

      # get a anonymous cookie set up
      anon_user_id = get_me_the_cookie("user_uuid")
      anon_user = AnonymousUser.new(anon_user_id[:value], {})
      hint = SignupHint.refresh_by_anoymous_user(anon_user, {redirect_location: '/products/jamblaster', want_jamblaster: true})
      hint.expires_at = 1.day.ago
      hint.save!

      visit path

      form_fill_and_submit({
        first_name: "Mike", last_name: "Jones", email: "signup_hint_guy2@jamkazam.com", password: "jam123", password_confirmation: "jam123"
      })
       
      if path =~ /landing/
        should have_title("JamKazam | Downloads")
      else
        should have_title("JamKazam | Congratulations")
      end

      user = User.find_by_email('signup_hint_guy2@jamkazam.com')
      user.want_jamblaster.should be false
    end
  end

  #----------------------------------------
  # examples
  #----------------------------------------

  # Successful signup with no invitation tells you to go sign up
  describe "with origin" do
    describe :default_signup do 
      before do
        User.destroy_all
        visit "/signup?utm_source=abc&utm_medium=ads&utm_campaign=campaign1"
      end
      it_behaves_like :default_signup_page
      it_behaves_like :with_origin_signup_submit do
        let(:_page){ 'default' }
      end
      
    end

    describe :landing_signup do
      before do
        User.destroy_all
        visit "/landing/general/signup?utm_source=abc&utm_medium=ads&utm_campaign=campaign1"
      end
      it_behaves_like :landing_signup_page
      it_behaves_like :with_origin_signup_submit do
        let(:_page){ 'landing' }
      end
      
    end

  end

  describe "without origin" do
   
    describe :default_signup do 
      before do
        User.destroy_all 
        visit signup_path 
      end
      it_behaves_like :default_signup_page
      it_behaves_like :without_origin_signup_submit  do
        let(:_page){ 'default' }
      end
    end

    describe :landing_signup do
      before do 
        User.destroy_all 
        visit "/landing/general/signup" 
      end
      it_behaves_like :landing_signup_page
      it_behaves_like :without_origin_signup_submit  do
        let(:_page){ 'landing' }
      end
    end
  end
 
  describe "submit form with errors" do

    describe :default_signup do 
      before do 
        visit signup_path 
      end
      it {
        #submit without filling the form
        find("#create-account-submit").click
        expect(page).to have_title "JamKazam | Register"
        should_not have_title("JamKazam | Congratulations")
      }
    end

    describe :landing_signup do
      before do 
        visit "/landing/general/signup" 
      end
      it {
        #submit without filling the form
        find("#create-account-submit").click
        expect(page).to have_title "JamKazam | Register"
        should_not have_title("JamKazam | Downloads")
      }
    end
  end
  
  describe "with user invite" do
    
    before(:each) do
      InvitedUser.destroy_all 
      User.destroy_all
    end

    describe :default_signup do
      it_behaves_like :signup_with_invite do
        let(:path){ "/signup" }
      end
    end
    
    describe :landing_signup do
      it_behaves_like :signup_with_invite do
        let(:path){ "/landing/general/signup" }
      end
    end
  end
  
  describe "with user invite and autofriend" do
  
    describe :default_signup do
      it_behaves_like :signup_with_invite_and_autofriend do
        let(:path){ "/signup" }
      end
    end
    
    describe :landing_signup do
      it_behaves_like :signup_with_invite_and_autofriend do
        let(:path){ "/landing/general/signup" }
      end
    end
  end
  
  describe "can signup with an email different than the one used to invite" do
    before(:each) do 
      User.destroy_all
    end

    describe :default_signup do
      it_behaves_like :signup_with_different_email do
        let(:path){ "/signup" }
      end
      
    end
    
    describe :landing_signup do
      it_behaves_like :signup_with_different_email do
        let(:path){ "/landing/general/signup" }
      end
   
    end
  end

  describe "signup hints" do
    before(:each) do 
      User.destroy_all
    end

    describe :default_signup do
      it_behaves_like :signup_hints do
        let(:path){ "/signup" }
      end
      
    end
    
    describe :landing_signup do
      it_behaves_like :signup_hints do
        let(:path){ "/landing/general/signup" }
      end
      
    end
  end

  def form_fill_and_submit(vals) 
    fill_in "jam_ruby_user[first_name]",    with: vals[:first_name]
    fill_in "jam_ruby_user[last_name]", with: vals[:last_name]
    fill_in "jam_ruby_user[email]", with: vals[:email]
    fill_in "jam_ruby_user[password]", with: vals[:password]
    password_confirmation = find('#jam_ruby_user_password_confirmation', visible: :all)
    if password_confirmation.visible? #landing/general/signup form does not show password_confirmation field 
      fill_in "jam_ruby_user[password_confirmation]", with: vals[:password_confirmation]
    end 

    check("jam_ruby_user[terms_of_service]")
    #click_button "Sign Up for JamKazam"
    find("#create-account-submit").click
  end
  
#===

  # def signup_invited_user
  #   visit "#{signup_path}?invitation_code=#{@invited_user.invitation_code}"
  #   find('#jam_ruby_user_first_name')
  #   sleep 1 # if I don't do this, first_name and/or last name intermittently fail to fill out

  #   fill_in "jam_ruby_user[first_name]",    with: "Mike"
  #   fill_in "jam_ruby_user[last_name]", with: "Jones"
  #   @invited_user_email = "newuser#{rand(10000)}@jamkazam.com"
  #   fill_in "jam_ruby_user[email]", with: @invited_user_email
  #   fill_in "jam_ruby_user[password]", with: "jam123"
  #   fill_in "jam_ruby_user[password_confirmation]", with: "jam123"

  #   check("jam_ruby_user[terms_of_service]")
  #   #click_button "Sign Up for JamKazam"
  #   find("#create-account-submit").click
  # end

    
end
