Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add integration description to replayed request ENV #62

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions lib/pact/provider_verifier/add_interaction_attributes_header.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
require 'delegate'

module Pact
module ProviderVerifier
class RequestDelegate < SimpleDelegator
def initialize request, extra_rack_headers
super(request)
@extra_rack_headers = extra_rack_headers
end

def headers
__getobj__().headers.merge(@extra_rack_headers)
end

def method
__getobj__().method
end
end

class AddInteractionAttributesHeader
def self.call(request, interaction)
extra_rack_headers = {
"X_PACT_DESCRIPTION" => interaction.description
}

if interaction.provider_states
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

provider_states is always set, even if parsing a v2 spec. which means this block of code always runs, and the block beneath doesn't

with a v2 spec, we get a change in behaviour

{"rack.version"=>[1, 3], "rack.input"=>#<StringIO:0x0000000139657a90>, "rack.errors"=>#<StringIO:0x0000000139658710>, "rack.multithread"=>true, "rack.multiprocess"=>true, "rack.run_once"=>false, "REQUEST_METHOD"=>"GET", "SERVER_NAME"=>"example.org", "SERVER_PORT"=>"80", "QUERY_STRING"=>"", "PATH_INFO"=>"/somestate", "rack.url_scheme"=>"http", "HTTPS"=>"off", "SCRIPT_NAME"=>"", "CONTENT_LENGTH"=>"0", "rack.test"=>true, "REMOTE_ADDR"=>"127.0.0.1", "SERVER_PROTOCOL"=>"HTTP/1.0", "HTTP_VERSION"=>"HTTP/1.0", "X_PACT_DESCRIPTION"=>"Provider state success", "X_PACT_PROVIDER_STATES"=>[{"name"=>"There is a greeting", "params"=>{}}], "HTTP_HOST"=>"example.org", "HTTP_COOKIE"=>""}

"X_PACT_DESCRIPTION"=>"Provider state success"
"X_PACT_PROVIDER_STATES"=>[{"name"=>"There is a greeting", "params"=>{}}]

before change

{"rack.version"=>[1, 3], "rack.input"=>#<StringIO:0x0000000122dd5248>, "rack.errors"=>#<StringIO:0x0000000122dd5838>, "rack.multithread"=>true, "rack.multiprocess"=>true, "rack.run_once"=>false, "REQUEST_METHOD"=>"GET", "SERVER_NAME"=>"example.org", "SERVER_PORT"=>"80", "QUERY_STRING"=>"", "PATH_INFO"=>"/somestate", "rack.url_scheme"=>"http", "HTTPS"=>"off", "SCRIPT_NAME"=>"", "CONTENT_LENGTH"=>"0", "rack.test"=>true, "REMOTE_ADDR"=>"127.0.0.1", "SERVER_PROTOCOL"=>"HTTP/1.0", "HTTP_VERSION"=>"HTTP/1.0", "X_PACT_PROVIDER_STATES"=>[{"name"=>"There is a greeting"}], "HTTP_HOST"=>"example.org", "HTTP_COOKIE"=>""}

"X_PACT_PROVIDER_STATES"=>[{"name"=>"There is a greeting"}]

extra_rack_headers["X_PACT_PROVIDER_STATES"] = interaction
.provider_states.collect(&:to_hash)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fails when parsing a v3 spec

header X-Gateway-Pact-States has field value "{\"name\"=>\"There is a greeting1\", \"params\"=>{\"id\"=>\"foo1\"}}\n{\"name\"=>\"There is a greeting2\", \"params\"=>{\"id\"=>2}}", this cannot include CR/LF

we would need to parse it into json, to pass it along the wire, I think

given this pact

{
  "consumer": {
    "name": "me"
  },
  "provider": {
    "name": "they"
  },
  "interactions": [
    {
      "description": "Provider state success",
      "providerState": "There is a greeting",
      "providerStates": [
        {
          "name": "There is a greeting1",
          "params": {
            "id": "foo1"
          }
        },
        {
          "name": "There is a greeting2",
          "params": {
            "id": 2
          }
        }
      ],
      "request": {
        "method": "GET",
        "path": "/somestate"
      },
      "response": {
        "status": 200,
        "headers": {},
        "body": {
          "greeting": "State data!"
        }
      }
    }
  ],
  "metadata": {
    "pactSpecificationVersion": "3.0.0"
  }
}

elsif interaction.provider_state
extra_rack_headers["X_PACT_PROVIDER_STATES"] = [
{ "name" => interaction.provider_state }
]
end

RequestDelegate.new(request, extra_rack_headers)
end
end
end
end
12 changes: 6 additions & 6 deletions lib/pact/provider_verifier/app.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require 'pact/wait_until_server_available'
require 'pact/provider_verifier/add_header_middlware'
require 'pact/provider_verifier/provider_states/add_provider_states_header'
require 'pact/provider_verifier/provider_states/remove_provider_states_header_middleware'
require 'pact/provider_verifier/add_interaction_attributes_header'
require 'pact/provider_verifier/remove_interaction_attributes_header_middleware'
require 'pact/provider_verifier/custom_middleware'
require 'pact/provider/rspec'
require 'pact/message'
Expand Down Expand Up @@ -68,7 +68,7 @@ def set_environment_variables
def configure_service_provider
# Have to declare these locally as the class scope gets lost within the block
application = configure_reverse_proxy
application = configure_provider_states_header_removal_middleware(application)
application = configure_interaction_attributes_header_removal_middleware(application)
application = configure_custom_middleware(application)
application = configure_custom_header_middleware(application)

Expand Down Expand Up @@ -130,8 +130,8 @@ def configure_custom_middleware app
end
end

def configure_provider_states_header_removal_middleware app
ProviderStates::RemoveProviderStatesHeaderMiddleware.new(app)
def configure_interaction_attributes_header_removal_middleware app
ProviderVerifier::RemoveInteractionAttributesHeaderMiddleware.new(app)
end

def require_custom_middlware
Expand Down Expand Up @@ -161,7 +161,7 @@ def verify_pact(pact_uri)
backtrace: ENV['BACKTRACE'] == 'true',
format: options.format,
out: options.out,
request_customizer: ProviderStates::AddProviderStatesHeader
request_customizer: ProviderVerifier::AddInteractionAttributesHeader
}
verify_options[:description] = ENV['PACT_DESCRIPTION'] if ENV['PACT_DESCRIPTION']
verify_options[:provider_state] = ENV['PACT_PROVIDER_STATE'] if ENV['PACT_PROVIDER_STATE']
Expand Down
6 changes: 3 additions & 3 deletions lib/pact/provider_verifier/custom_middleware.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
require 'ostruct'

module Pact
module ProviderVerifier
class CustomMiddleware
Expand All @@ -23,7 +21,9 @@ def call env

def provider_states_from(env)
if env["X_PACT_PROVIDER_STATES"]
env["X_PACT_PROVIDER_STATES"].collect{ | provider_state| OpenStruct.new(provider_state) }
env["X_PACT_PROVIDER_STATES"].collect do | provider_state|
Pact::ProviderState.from_hash(provider_state)
end
else
[]
end
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module Pact
module ProviderVerifier
class RemoveInteractionAttributesHeaderMiddleware
HEADERS_TO_REMOVE = %w[
X_PACT_DESCRIPTION
X_PACT_PROVIDER_STATES
]

def initialize app
@app = app
end

def call env
@app.call(remove_header(env))
end

def remove_header env
env.reject { | key, _ | HEADERS_TO_REMOVE.include?(key) }
end
end
end
end