require 'test_helper'

class ThreeScale::Analytics::GoogleExperimentTest < ActiveSupport::TestCase
  GoogleExperiments = ThreeScale::Analytics::GoogleExperiments

  attr_reader :config

  def setup
    # noinspection RubyArgCount
    GoogleExperiments.stubs(config: @config = mock('config'))
  end

  def test_class_many_from_utmx_cookie
    cookie = '66263346.NkmCEpptTJmuN88Es2N5-Q$0:1.LZh8g5E-TCiGSa118bhKfA$0:0.xzrLyKW8QW-fVsW-StRWmQ$0:1'

    experiments = GoogleExperiments.from_cookie(cookie)

    assert experiments

    assert_equal 3, experiments.size
  end

  def test_class_from_utmx_cookie
    assert experiments = GoogleExperiments.from_cookie('67508621.LZh8g5E-TCiGSa118bhKfA$0:1')

    assert_equal 1, experiments.size
    experiment = experiments.to_a.first
    assert_equal 'LZh8g5E-TCiGSa118bhKfA', experiment.id
    assert_equal 1, experiment.variation
  end


  def test_class_from_utmxx_cookie
    assert experiments = GoogleExperiments.from_cookie('67508621.LZh8g5E-TCiGSa118bhKfA$0:1427825318:8035200')
    assert_equal 1, experiments.size

    experiment = experiments.to_a.first
    assert_equal 'LZh8g5E-TCiGSa118bhKfA', experiment.id
    assert_equal 1, experiment.variation
  end

  def test_class_from_invalid_cookie
    experiments = GoogleExperiments.from_cookie('invalid')
    assert experiments
    assert experiments.empty?
  end

  def test_class_fetch_info
    json = { 'Content-Type' => 'application/json' }
    private_key = OpenSSL::PKey::RSA.generate(1024)

    config.expects(account_id: 'account-id',
                   profile_id: 'profile-id',
                   web_property_id: 'web-property-id',
                   private_key: private_key,
                   issuer: 'example@3scale.net',
                   person: 'someone@3scale.net'
                  )

    # Get authentication token (headers contain signed request by private key)
    stub_request(:post, 'https://accounts.google.com/o/oauth2/token')
        .to_return(status: 200, body: { access_token: 'access-token'}.to_json )

    # get the api by auto discovery (persisted in fixtures)
    stub_request(:get, 'https://www.googleapis.com/discovery/v1/apis/analytics/v3/rest')
        .to_return(status: 200, headers: json,
                  body: Rails.root.join('test/fixtures/www.googleapis.com/discovery/v1/apis/analytics/v3/rest.json').read)

    # finally use the api to get the experiments info
    stub_request(:get, 'https://www.googleapis.com/analytics/v3/management/accounts/account-id/webproperties/web-property-id/profiles/profile-id/experiments/some-id')
        .with(headers: {'Authorization' => 'Bearer access-token'})
        .to_return(status: 200, headers: json,
                  body: {name: 'name', variations: [{name: 'a'}, {name: 'b'}]}.to_json)

    assert experiment = GoogleExperiments.fetch_info('some-id')

    assert_equal({name: 'name', variations: %w(a b)}, experiment)
  end

  def test_to_hash
    experiments = GoogleExperiments.new([{abc: 'abc'}, {efg: 'efg'}])

    assert_equal({abc: 'abc', efg: 'efg'}, experiments.to_hash)
  end

  def test_experiment_name_and_variation_name
    experiments = GoogleExperiments.experiment('some-id', 1)

    GoogleExperiments.expects(:fetch_info)
        .with('some-id').returns(info = { name: 'some-name', variations: %w(a b)})

    assert_equal 'some-name', experiments.name
    assert_equal 'b', experiments.variation_name
  end


  def test_experiment_to_hash
    experiment = GoogleExperiments.experiment('some-id', 1)

    GoogleExperiments.expects(:fetch_info)
        .with('some-id').returns(info = { name: 'some-name', variations: %w(a b)})

    assert_equal({'Experiment: some-name' => 'b'}, experiment.to_hash)
  end
end
