require 'test_helper'

class AuthenticateUserFromOmniauthTest < ActiveSupport::TestCase
  test "logs in with existing details" do
    provider = "foobar"
    uid = "bizzzz"
    user = create :user, provider: provider, uid: uid

    auth = mock(provider: provider, uid: uid)
    actual = AuthenticateUserFromOmniauth.(auth)
    assert_equal user, actual
  end

  test "creates with correct details" do
    provider = "foobar"
    uid = "bizzzz"
    email = "asdas@asdasda.com"
    name = "asda adsdsa"
    handle = "asdqweqwewqe"
    avatar_url = "http://asdadhasa.com/jasds.jpg"

    info = mock
    info.stubs(email: email, name: name, nickname: handle, image: avatar_url)
    auth = mock
    auth.stubs(provider: provider, uid: uid, info: info)

    DeviseMailer.expects(:confirmation_instructions).never
    user = AuthenticateUserFromOmniauth.(auth)
    assert user.persisted?
    assert_equal provider, user.provider
    assert_equal uid, user.uid
    assert_equal email, user.email
    assert_equal name, user.name
    assert_equal handle, user.handle
    assert_equal avatar_url, user.avatar_url
  end

  test "logs in with same email" do
    user = create :user

    info = mock
    info.stubs(email: user.email)
    auth = mock
    auth.stubs(provider: 'asda', uid: '12312', info: info)
    actual = AuthenticateUserFromOmniauth.(auth)
    assert_equal user, actual
  end

  test "chooses free handle if it's not unique" do
    handle = "asdqweqwewqe"
    num1 = 8833
    num2 = 2134

    info = mock
    info.stubs(nickname: handle, email: "asd@erwerew.com", name: "qwe asd", image: "http://a.com/j.jpg")
    auth = mock
    auth.stubs(provider: "qwe", uid: "asdasa", info: info)

    create :user, handle: handle
    create :user, handle: "#{handle}-#{num1}"

    SecureRandom.stubs(:random_number).with(10000).returns(num1, num2)
    user = AuthenticateUserFromOmniauth.(auth)
    assert user.persisted?
    assert_equal "#{handle}-#{num2}", user.handle
  end

  test "does not updates email if it's not @users.noreply.github.com" do
    provider = "foobar"
    uid = "bizzzz"
    old_email = "foo@users1.noreply.github.com"
    user = create :user, provider: provider, uid: uid, email: old_email

    auth = mock(provider: provider, uid: uid)
    actual = AuthenticateUserFromOmniauth.(auth)
    assert_equal user, actual

    user.reload
    assert_equal old_email, user.email
  end

  test "updates email if it's @users.noreply.github.com" do
    provider = "foobar"
    uid = SecureRandom.uuid
    new_email = "dog@cat.com"
    user = create :user, provider: provider, uid: uid, email: "foo@users.noreply.github.com"

    auth = mock(provider: provider, uid: uid, info: mock(email: new_email))
    actual = AuthenticateUserFromOmniauth.(auth)
    assert_equal user, actual

    user.reload
    assert_equal new_email, user.email
  end

  test "updates provider, uid with email match" do
    user = create :user

    provider = "asda"
    uid = SecureRandom.uuid
    info = mock
    info.stubs(email: user.email)
    auth = mock
    auth.stubs(provider: provider, uid: uid, info: info)
    actual = AuthenticateUserFromOmniauth.(auth)
    assert_equal user, actual

    user.reload
    assert_equal provider, user.provider
    assert_equal uid, user.uid
  end

  test "confirms user and resets password on email match" do
    Timecop.freeze do
      user = create :user

      new_password = "foobarqwe"
      uid = SecureRandom.uuid
      info = mock
      info.stubs(email: user.email)
      auth = mock
      auth.stubs(provider: 'asd', uid: 'qwe', info: info)

      SecureRandom.stubs(uuid: new_password)
      actual = AuthenticateUserFromOmniauth.(auth)
      assert_equal user, actual

      user.reload
      assert_equal DateTime.now.to_i, user.confirmed_at.to_i
      assert user.valid_password?(new_password)
    end
  end
end
