# frozen_string_literal: true

require "test_helper"

class DsnAuthServiceTest < ActiveSupport::TestCase
  self.use_transactional_tests = true

  def setup
    @dsn = Dsn.create!(name: "Test DSN", key: "test-auth-key-1234567890abcdef")
  end

  def teardown
    Dsn.delete_all
  end

  test "should authenticate via query parameter baffle_key" do
    request = ActionDispatch::TestRequest.create
    request.query_parameters = { "baffle_key" => @dsn.key }

    authenticated_dsn = DsnAuthenticationService.authenticate(request)
    assert_equal @dsn, authenticated_dsn
  end

  test "should authenticate via Authorization Bearer header" do
    request = ActionDispatch::TestRequest.create
    request.headers["Authorization"] = "Bearer #{@dsn.key}"

    authenticated_dsn = DsnAuthenticationService.authenticate(request)
    assert_equal @dsn, authenticated_dsn
  end

  test "should authenticate via Basic auth with username as key" do
    request = ActionDispatch::TestRequest.create
    credentials = Base64.strict_encode64("#{@dsn.key}:ignored-password")
    request.headers["Authorization"] = "Basic #{credentials}"

    authenticated_dsn = DsnAuthenticationService.authenticate(request)
    assert_equal @dsn, authenticated_dsn
  end

  test "should fail authentication with disabled DSN" do
    @dsn.update!(enabled: false)

    request = ActionDispatch::TestRequest.create
    request.query_parameters = { "baffle_key" => @dsn.key }

    assert_raises(DsnAuthenticationService::AuthenticationError) do
      DsnAuthenticationService.authenticate(request)
    end
  end

  test "should fail authentication with non-existent key" do
    request = ActionDispatch::TestRequest.create
    request.query_parameters = { "baffle_key" => "non-existent-key" }

    assert_raises(DsnAuthenticationService::AuthenticationError) do
      DsnAuthenticationService.authenticate(request)
    end
  end

  test "should fail authentication with no authentication method" do
    request = ActionDispatch::TestRequest.create

    assert_raises(DsnAuthenticationService::AuthenticationError) do
      DsnAuthenticationService.authenticate(request)
    end
  end
end