require 'test_helper'

class DeveloperPortal::LoginTest < ActionDispatch::IntegrationTest
  include DeveloperPortal::Engine.routes.url_helpers

  def setup
    @provider = FactoryGirl.create(:simple_provider)
    @buyer    = FactoryGirl.create(:simple_buyer, provider_account: @provider)
    @user     = FactoryGirl.create(:user, account: @buyer, authentication_id: 'wild')
    @auth     = FactoryGirl.create(:authentication_provider, account: @provider, kind: 'base')

    @user.activate!
    host! @provider.domain
  end

  def test_create
    # user is using the old method of authentication
    assert_equal 0, @user.sso_authorizations.count
    assert_not_empty @user.authentication_id

    # user should be identified by old authentication method
    stub_user_data(authentication_id: @user.authentication_id, uid: 'new-uid')
    stub_oauth2_request
    post session_path(system_name: @auth.system_name, code: 'alaska')
    assert_equal 'Signed in successfully', flash[:notice]

    get logout_path
    assert_response :redirect

    # user should be migrated to new sso
    @user.reload
    assert_nil @user.authentication_id
    assert_equal 1, @user.sso_authorizations.count

    # user should be identified by new sso authorization method
    @user.reload
    stub_user_data(uid: @user.sso_authorizations.last.uid)
    stub_oauth2_request
    post session_path(system_name: @auth.system_name, code: 'alaska')
    assert_equal 'Signed in successfully', flash[:notice]

    @user.sso_authorizations.destroy_all

    # user should not be identified by not confirmed email address
    stub_user_data(uid: 'new-uid', email: @user.email, email_confirmed: false)
    stub_oauth2_request
    post session_path(system_name: @auth.system_name, code: 'alaska')
    assert_equal 'Succesfully authenticated, please complete the signup form', flash[:notice]
    @user.reload
    assert_equal 0, @user.sso_authorizations.count

    # user should be identified by confirmed email address
    stub_user_data(uid: 'new-uid', email: @user.email, email_confirmed: true)
    stub_oauth2_request
    post session_path(system_name: @auth.system_name, code: 'alaska')
    assert_equal 'Signed in successfully', flash[:notice]
    @user.reload
    assert_equal 1, @user.sso_authorizations.count

    get logout_path
    assert_response :redirect

    # user should be identified by new sso authorization method
    @user.reload
    stub_user_data(uid: @user.sso_authorizations.first.uid)
    stub_oauth2_request
    post session_path(system_name: @auth.system_name, code: 'alaska')
    assert_equal 'Signed in successfully', flash[:notice]
    @user.reload
    assert_equal 1, @user.sso_authorizations.count
  end

  private

  def stub_user_data(user_data)
    ThreeScale::OAuth2::ClientBase.any_instance.expects(:user_data).returns(user_data)
  end

  def stub_oauth2_request
    mock_oauth2(@user.authentication_id, 'alaska', @auth.user_info_url)
  end
end
