require 'test_helper'

require 'resque_unit'

class ThreeScale::Analytics::UserTrackingTest < ActiveSupport::TestCase
  include ResqueUnit::Assertions
  include ThreeScale::Analytics

  def setup
    account = FactoryGirl.build_stubbed(:simple_account, provider: true)
    @user = FactoryGirl.build_stubbed(:user, account: account, email: 'emilio@gmail.com')
  end

  def test_track_uses_segment
    UserTracking::Segment.expects(:track).once
    UserTracking.new(@user).track('foo')
  end

  def test_identify_uses_segment
    UserTracking::Segment.expects(:identify).once
    UserTracking.new(@user).identify(trait: 'value')
  end

  def test_flush_uses_segment
    UserTracking::Segment.expects(:flush).with().once
    UserTracking.new(@user).flush
  end

  def test_group_uses_segment
    UserTracking::Segment.expects(:group).once
    UserTracking.new(@user).group
  end

  def test_experiment
    tracking = UserTracking.new(@user)

    UserTracking::Segment.expects(:identify)
        .with(has_entry(traits: has_entry('Experiment: Some Name' => 'variant')))
    UserTracking::Segment.expects(:track)
        .with(has_entry(properties: { variation: 'variant'}))

    tracking.experiment('Some Name', 'variant')
  end

  def test_with_options
    tracking = UserTracking.new(@user)

    timestamp = 1.hour.from_now

    seq = sequence('segment')

    UserTracking::Segment.expects(:identify).in_sequence(seq).with(has_entry(timestamp: timestamp))

    UserTracking::Segment.expects(:identify).in_sequence(seq).with(Not(has_key(:timestamp)))

    tracking.with_segment_options(timestamp: timestamp) do
      tracking.identify
    end

    tracking.identify
  end

  def test_basic_traits
    traits = UserTracking.new(nil).basic_traits
    assert_equal Hash.new, traits

    traits = UserTracking.new(@user).basic_traits

    assert_equal traits.slice(:email), email: @user.email
  end

  def test_identify
    tracking = UserTracking.new(nil)
    refute tracking.identify

    tracking = UserTracking.new(@user)
    assert tracking.identify

    @user.account.provider = false
    refute tracking.identify
  end


  def test_track
    tracking = UserTracking.new(nil)
    refute tracking.track('Event')

    tracking = UserTracking.new(@user)
    assert tracking.track('Event')

    @user.account.provider = false
    refute tracking.track('Event')
  end

  def test_group
    tracking = UserTracking.new(nil)
    refute tracking.group

    tracking = UserTracking.new(@user)
    assert tracking.group

    @user.account.provider = false
    refute tracking.group
  end

  def test_group_traits
    tracking = UserTracking.new(nil)
    assert_equal Hash.new, tracking.group_traits

    tracking = UserTracking.new(@user)
    @user.account.stubs(bought_plan: Plan.new(name: 'fooplan', cost_per_month: 42), state: 'suspended')

    assert_equal({name: @user.account.name,
                  plan: 'fooplan',
                  monthly_spend: 42.0,
                  license_mrr: 42.0,
                  state: 'suspended',
                 }, tracking.group_traits)
  end

  def test_track_context
    @user.account.extra_fields[:marketo_cookie] = 'account-cookie'
    tracking = UserTracking.new(@user)

    UserTracking::Segment.expects(:track).with(has_entries(event: 'Marketo Event 1', context: has_entry(Marketo: has_entry(marketoCookie: 'account-cookie'))))
    tracking.track('Marketo Event 1')

    @user.extra_fields[:marketo_cookie] = 'user-cookie'
    tracking = UserTracking.new(@user)

    UserTracking::Segment.expects(:track).with(has_entries(event: 'Marketo Event 2', context: has_entry(Marketo: has_entry(marketoCookie: 'user-cookie'))))
    tracking.track('Marketo Event 2')
  end

  def test_can_send?
    refute UserTracking.new(nil).can_send?
    assert UserTracking.new(@user).can_send?

    @user.account.provider = false
    refute UserTracking.new(@user).can_send?
  end
end
