Skip to content

Commit

Permalink
feat(verifications): allow provider version tags to be specified
Browse files Browse the repository at this point in the history
  • Loading branch information
bethesque committed Oct 30, 2017
1 parent 4f8688d commit bff4611
Show file tree
Hide file tree
Showing 9 changed files with 94 additions and 17 deletions.
7 changes: 6 additions & 1 deletion lib/pact/provider/configuration/service_provider_config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ class ServiceProviderConfig

attr_accessor :application_version

def initialize application_version, publish_verification_results, &app_block
def initialize application_version, tags, publish_verification_results, &app_block
@application_version = application_version
@tags = [*tags]
@publish_verification_results = publish_verification_results
@app_block = app_block
end
Expand All @@ -18,6 +19,10 @@ def app
def publish_verification_results?
@publish_verification_results
end

def tags
@tags
end
end
end
end
Expand Down
9 changes: 7 additions & 2 deletions lib/pact/provider/configuration/service_provider_dsl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class ServiceProviderDSL

extend Pact::DSL

attr_accessor :name, :app_block, :application_version, :publish_verification_results
attr_accessor :name, :app_block, :application_version, :tags, :publish_verification_results

CONFIG_RU_APP = lambda {
unless File.exist? Pact.configuration.config_ru_path
Expand All @@ -25,6 +25,7 @@ class ServiceProviderDSL
def initialize name
@name = name
@publish_verification_results = false
@tags = []
@app_block = CONFIG_RU_APP
end

Expand All @@ -37,6 +38,10 @@ def app_version application_version
self.application_version = application_version
end

def app_version_tags tags
self.tags = tags
end

def publish_verification_results publish_verification_results
self.publish_verification_results = publish_verification_results
Pact::RSpec.with_rspec_2 do
Expand Down Expand Up @@ -70,7 +75,7 @@ def application_version_blank?
end

def create_service_provider
Pact.configuration.provider = ServiceProviderConfig.new(application_version, publish_verification_results, &@app_block)
Pact.configuration.provider = ServiceProviderConfig.new(application_version, tags, publish_verification_results, &@app_block)
end
end
end
Expand Down
46 changes: 39 additions & 7 deletions lib/pact/provider/verification_results/publish.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
require 'json'
require 'pact/errors'

# TODO move this to the pact broker client
# TODO retries

module Pact
module Provider
module VerificationResults
Expand All @@ -20,6 +23,11 @@ def initialize pact_source, verification_result

def call
if Pact.configuration.provider.publish_verification_results?
if tag_url('')
tag
else
Pact.configuration.error_stream.puts "WARN: Cannot tag provider version as there is no link named pb:tag-version in the pact JSON."
end
if publication_url
publish
else
Expand All @@ -34,11 +42,35 @@ def publication_url
@publication_url ||= pact_source.pact_hash.fetch('_links', {}).fetch('pb:publish-verification-results', {})['href']
end

def tag_url tag
href = pact_source.pact_hash.dig('_links', 'pb:tag-version', 'href')
href ? href.gsub('{tag}', tag) : nil
end

def tag
Pact.configuration.provider.tags.each do | tag |
uri = URI(tag_url(tag))
request = build_request('Put', uri, nil, "Tagging provider version at")
response = nil
begin
options = {:use_ssl => uri.scheme == 'https'}
response = Net::HTTP.start(uri.host, uri.port, options) do |http|
http.request request
end
rescue StandardError => e
error_message = "Failed to tag provider version due to: #{e.class} #{e.message}"
raise PublicationError.new(error_message)
end

unless response.code.start_with?("2")
raise PublicationError.new("Error returned from tagging request #{response.code} #{response.body}")
end
end
end

def publish
#TODO https
#TODO username/password
uri = URI(publication_url)
request = build_request(uri)
request = build_request('Post', uri, verification_result.to_json, "Publishing verification result #{verification_result.to_json} to")
response = nil
begin
options = {:use_ssl => uri.scheme == 'https'}
Expand All @@ -55,16 +87,16 @@ def publish
end
end

def build_request uri
request = Net::HTTP::Post.new(uri.path)
def build_request meth, uri, body, action
request = Net::HTTP.const_get(meth).new(uri.path)
request['Content-Type'] = "application/json"
request.body = verification_result.to_json
request.body = body if body
debug_uri = uri
if pact_source.uri.basic_auth?
request.basic_auth pact_source.uri.username, pact_source.uri.password
debug_uri = URI(uri.to_s).tap { |x| x.userinfo="#{pact_source.uri.username}:*****"}
end
Pact.configuration.output_stream.puts "INFO: Publishing verification result #{verification_result.to_json} to #{debug_uri}"
Pact.configuration.output_stream.puts "INFO: #{action} #{debug_uri}"
request
end

Expand Down
1 change: 1 addition & 0 deletions lib/pact/provider/verification_results/publish_all.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ def initialize pact_sources, rspec_summary
@rspec_summary = rspec_summary
end

# TODO do not publish unless all interactions have been run
def call
verification_results.collect do | pair |
Publish.call(pair.first, pair.last)
Expand Down
1 change: 0 additions & 1 deletion lib/tasks/pact.rake
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,4 @@ namespace :pact do
require 'pact/provider/help/console_text'
puts Pact::Provider::Help::ConsoleText.(args[:reports_dir])
end

end
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ module Configuration

let(:app_block) { ->{ Object.new } }

subject { ServiceProviderConfig.new("1.2.3'", true, &app_block) }
subject { ServiceProviderConfig.new("1.2.3'", [], true, &app_block) }

it "should execute the app_block each time" do
expect(subject.app.object_id).to_not equal(subject.app.object_id)
Expand All @@ -20,4 +20,4 @@ module Configuration
end
end
end
end
end
39 changes: 37 additions & 2 deletions spec/lib/pact/provider/verification_results/publish_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,27 @@ module VerificationResults
describe Publish do
describe "call" do
let(:publish_verification_url) { nil }
let(:tag_version_url) { 'http://tag-me/{tag}' }
let(:pact_source) { instance_double("Pact::Provider::PactSource", pact_hash: pact_hash, uri: pact_url)}
let(:pact_url) { instance_double("Pact::Provider::PactURI", basic_auth?: basic_auth, username: 'username', password: 'password')}
let(:basic_auth) { false }
let(:pact_hash) { {'consumer' => {'name' => 'Foo'}, '_links' => {'pb:publish-verification-results'=> {'href' => publish_verification_url}}} }
let(:pact_hash) do
{
'consumer' => {
'name' => 'Foo'
},
'_links' => {
'pb:publish-verification-results'=> {
'href' => publish_verification_url
},
'pb:tag-version'=> {'href' => tag_version_url}
}
}
end
let(:app_version_set) { false }
let(:verification_json) { '{"foo": "bar"}' }
let(:publish_verification_results) { false }
let(:tags) { [] }
let(:verification) do
instance_double("Pact::Verifications::Verification",
to_json: verification_json,
Expand All @@ -21,13 +35,14 @@ module VerificationResults
end

let(:provider_configuration) do
double('provider config', publish_verification_results?: publish_verification_results)
double('provider config', publish_verification_results?: publish_verification_results, tags: tags)
end

before do
allow($stdout).to receive(:puts)
allow(Pact.configuration).to receive(:provider).and_return(provider_configuration)
stub_request(:post, 'http://broker/verifications')
stub_request(:put, /tag-me/)
end

subject { Publish.call(pact_source, verification)}
Expand All @@ -50,6 +65,26 @@ module VerificationResults
expect(WebMock).to have_requested(:post, publish_verification_url).with(body: verification_json, headers: {'Content-Type' => 'application/json'})
end

context "with tags" do
let(:tags) { ['foo'] }

it "tags the provider version" do
subject
expect(WebMock).to have_requested(:put, 'http://tag-me/foo').with(headers: {'Content-Type' => 'application/json'})
end

context "when there is no pb:tag-version link" do
before do
pact_hash['_links'].delete('pb:tag-version')
end

it "prints a warning" do
expect($stderr).to receive(:puts).with /WARN: Cannot tag provider version/
subject
end
end
end

context "when basic auth is configured on the pact URL" do
let(:basic_auth) { true }
it "sets the username and password for the pubication URL" do
Expand Down
1 change: 1 addition & 0 deletions spec/support/bar_pact_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ def call env
Pact.service_provider "Bar" do
app { BarApp.new }
app_version '1.2.3'
app_version_tags ['master']
publish_verification_results true

honours_pact_with 'Foo' do
Expand Down
3 changes: 1 addition & 2 deletions tasks/foo-bar.rake
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
require 'pact/tasks/verification_task'
# Use for end to end manual debugging of issues.

BROKER_BASE_URL = 'http://127.0.0.1:9292'
BROKER_BASE_URL = 'http://localhost:9292'

RSpec::Core::RakeTask.new('pact:foobar:create') do | task |
task.pattern = "spec/features/foo_bar_spec.rb"

end

task 'pact:foobar:publish' do
Expand Down

0 comments on commit bff4611

Please sign in to comment.