Как проверить соглашения с API, для которого требуется токен авторизации?

Я использую гем Pact (и мне это нравится!) Для моего контракта. Служба API, которую я тестирую, требует токен авторизации для всех запросов.

Я знаю, как создать токен API для моего пользователя, но я не знаю, где разместить токен в рабочем процессе Pact. Я искал в документации и репозитории Pact примеры, но безуспешно.

Я попытался отправить POST в спецификации потребителя, чтобы сгенерировать токен, но фиктивный сервер Pact не знает, что делать с запросом и ошибками (как я и ожидал).

Я нашел этот пример, и он кажется многообещающим, особенно возможность назначать предопределенные заголовки для всех запросов с requestFilter и addHeader метод.

Как я могу использовать такой фильтр запросов с гемом Pact?

Если это не актуальная функция, какие у меня есть альтернативы?

ОБНОВИТЬ:

Ответ J_A_X отлично подходит для создания пактов с фиктивным сервером, но он не удовлетворяет ожидания поставщика API-сервиса в отношении действительного токена аутентификации. Более конкретно, мне нужно динамически вставлять действительные токены аутентификации в пакты при запуске pact:verify. Итак, на шаг ближе, но все же нужно разобраться с последней частью.

Ответ Мэтью содержит подсказки для двух возможных решений последней части (пакт: проверить). Я не решаюсь представить еще одну зависимость, поэтому я хотел бы, чтобы пример класса ProxyApp работал. Я не понимаю, что именно я бы передать в ProxyApp.new(), хотя. Предложения?

2 ответа

Реализация Ruby в Pact не поддерживает это напрямую в соответствии с реализацией JVM.

Если вы используете гем Pact Provider Proxy, вы можете взглянуть на некоторые из вариантов, обсуждаемых по адресу https://github.com/realestate-com-au/pact/issues/49 и https://groups.google.com/forum/.

Пример может выглядеть примерно так:

class ProxyApp

  def initialize real_app
    @real_app = real_app
  end

  def call env
    @real_app.call(env.merge('HTTP_AUTHORIZATION' => '12345'))
  end
end

Pact.service_provider "Some Provider" do
  app do
    ProxyApp.new(RealApp)
  end

  honours_pact_with "Some Consumer" do
    #...
  end
end

На самом деле вам не нужно использовать настоящий токен для каждого взаимодействия с пактом, если вы действительно этого не хотите / не хотите.

Обычно для такого рода вещей я просто создаю регулярное выражение, которое будет использоваться в заголовке для проверки определенных правил, оставляя его "открытым". В моем проекте узла (который использует двоичный файл Ruby сзади) я создал эти две служебные функции для создания объектов с шаблоном, а другую - для минимума объекта, равного:

function term(matcher, generate) {
    if ((typeof matcher === 'undefined') || (typeof generate === 'undefined')) {
      throw 'Matcher and Generate arguments must be specified to use Term';
    }
    return {
      "json_class": "Pact::Term",
      "data": {
        "generate": generate,
        "matcher": {
          "json_class": "Regexp",
          "o": 0,
          "s": matcher
        }
      }
    };
  }

  function somethingLike(value) {
    return {
      "json_class": "Pact::SomethingLike",
      "contents": value
    };
  }

Затем вы можете использовать его в своем определении DSL следующим образом:

mockService
      .given('a form')
      .uponReceiving('a GET request with a valid auth')
      .withRequest('get', '/', term('^Bearer (?!null$).+$', 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ'))
      .willRespondWith({
        status: 200,
        headers: {'Content-Type': 'application/json;charset=utf-8'},
        body: {worked:true}
      });

Утилита 'term' имеет регулярное выражение в качестве первого параметра, а затем пример (который должен соответствовать первому) того, что использовать во время теста.

Я знаю, что это должно быть расширено в самом Pact, чтобы его было проще использовать. Надеюсь, это поможет.

Другие вопросы по тегам