pact_broker 2.29.0 → 2.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d618dcd0c7582bad7822bac6bf8b32db26a25cea
4
- data.tar.gz: 2a0d1f85dbdb9d2291308e483d60422431fe4013
3
+ metadata.gz: '081cc254335adf8cdabb9bfbc1819c8bf23bb292'
4
+ data.tar.gz: c02b5d34019e3f645df1a47bdc271f0cb0f32919
5
5
  SHA512:
6
- metadata.gz: f7ee32711c4be853ccfb0d0eefd62c87ec9aad7407c2344a0d12c9537aeaa88483e0fce93c33e1ed51389c98f41dae1125f11ce47869e5b73a11e866473c03aa
7
- data.tar.gz: 3b8217e5d02bff7be409a8dbfa51a4caf8ca1f6dfb2132b470926100efa7aa5c2dd9c85525ae4bd54c8997091c2c2495ebce785342dc4341c41b7562b093edf8
6
+ metadata.gz: a58feed7d9ff5c59f84387cd8e5293fbdd480d11ce6ca6f7ee0a12bc86fba8c2d127f1a7135efb4cabb8bbdabae2a44bc9ed5ebf31125def2a810806a3a822ec
7
+ data.tar.gz: 613811b6f2f348e0a18ea825e995b6a33fcf72ca50f66065c84a8de88eb9e20d308a776d4d4eef9c641c0b98870dca36df3391990272fd00b86b6a0ba2831ff0
@@ -1,3 +1,26 @@
1
+ <a name="v2.30.0"></a>
2
+ ### v2.30.0 (2019-03-29)
3
+
4
+
5
+ #### Features
6
+
7
+ * add helper text on index page for getting started ([cdeb2cd9](/../../commit/cdeb2cd9))
8
+ * allow rack protection to be turned off so that the headers can be managed in nginx ([941371ec](/../../commit/941371ec))
9
+ * allow all pacts between a given consumer and provider to be deleted at once ([9f1ce9c3](/../../commit/9f1ce9c3))
10
+ * correctly identify javascript and css content types ([6470d199](/../../commit/6470d199))
11
+ * add .css and .js file extensions to middleware that sets the accept header ([eb1cd323](/../../commit/eb1cd323))
12
+ * add helper text on index page for getting started ([222d8965](/../../commit/222d8965))
13
+ * allow rack protection to be turned off so that the headers can be managed in nginx ([b43e60ee](/../../commit/b43e60ee))
14
+ * allow all pacts between a given consumer and provider to be deleted at once ([0c8106b6](/../../commit/0c8106b6))
15
+ * correctly identify javascript and css content types ([03e156cb](/../../commit/03e156cb))
16
+ * add .css and .js file extensions to middleware that sets the accept header ([2aa533dc](/../../commit/2aa533dc))
17
+ * add a new webhook event for contract_published ([2e2a2034](/../../commit/2e2a2034))
18
+
19
+ * **matrix**
20
+ * improve reasons in response when pacticipant cannot be deployed ([85e11616](/../../commit/85e11616))
21
+ * allow provider to be deployed to an environment without the consumer having to be deployed there already ([125c2722](/../../commit/125c2722))
22
+
23
+
1
24
  <a name="v2.29.0"></a>
2
25
  ### v2.29.0 (2019-03-15)
3
26
 
@@ -13,7 +13,7 @@ module PactBroker
13
13
  end
14
14
 
15
15
  def allowed_methods
16
- ["GET", "OPTIONS"]
16
+ ["GET", "DELETE", "OPTIONS"]
17
17
  end
18
18
 
19
19
  def resource_exists?
@@ -29,6 +29,10 @@ module PactBroker
29
29
  pact_service.find_all_pact_versions_between consumer_name, :and => provider_name
30
30
  end
31
31
 
32
+ def delete_resource
33
+ pact_service.delete_all_pact_versions_between(consumer_name, and: provider_name)
34
+ true
35
+ end
32
36
  end
33
37
  end
34
38
  end
@@ -118,7 +118,9 @@ module PactBroker
118
118
 
119
119
  def configure_middleware
120
120
  # NOTE THAT NONE OF THIS IS PROTECTED BY AUTH - is that ok?
121
- @app_builder.use Rack::Protection, except: [:path_traversal, :remote_token, :session_hijacking, :http_origin]
121
+ if configuration.use_rack_protection
122
+ @app_builder.use Rack::Protection, except: [:path_traversal, :remote_token, :session_hijacking, :http_origin]
123
+ end
122
124
  @app_builder.use Rack::PactBroker::InvalidUriProtection
123
125
  @app_builder.use Rack::PactBroker::StoreBaseURL
124
126
  @app_builder.use Rack::PactBroker::AddPactBrokerVersionHeader
@@ -32,7 +32,7 @@ module PactBroker
32
32
  :base_equality_only_on_content_that_affects_verification_results
33
33
  ]
34
34
 
35
- attr_accessor :log_dir, :database_connection, :auto_migrate_db, :auto_migrate_db_data, :use_hal_browser, :html_pact_renderer
35
+ attr_accessor :log_dir, :database_connection, :auto_migrate_db, :auto_migrate_db_data, :use_hal_browser, :html_pact_renderer, :use_rack_protection
36
36
  attr_accessor :validate_database_connection_config, :enable_diagnostic_endpoints, :version_parser, :sha_generator
37
37
  attr_accessor :use_case_sensitive_resource_names, :order_versions_by_date
38
38
  attr_accessor :check_for_potential_duplicate_pacticipant_names
@@ -62,6 +62,7 @@ module PactBroker
62
62
  config.log_dir = File.expand_path("./log")
63
63
  config.auto_migrate_db = true
64
64
  config.auto_migrate_db_data = true
65
+ config.use_rack_protection = true
65
66
  config.use_hal_browser = true
66
67
  config.validate_database_connection_config = true
67
68
  config.enable_diagnostic_endpoints = true
@@ -1,6 +1,6 @@
1
1
  # Consumer
2
2
 
3
- Allowed methods: GET, PATCH, DELETE
3
+ Allowed methods: `GET`, `PATCH`, `DELETE`
4
4
 
5
5
  The application that initiates the HTTP request.
6
6
 
@@ -0,0 +1,10 @@
1
+ # All versions of a pact between a given consumer and provider
2
+
3
+ Allowed methods: `GET`, `DELETE`
4
+ Path: `/pacts/provider/{provider}/consumer/{consumer}/versions`
5
+
6
+ This resource returns a history of all the versions of the given pact between a consumer and provider.
7
+
8
+ ## Deleting pacts
9
+
10
+ Sending a `DELETE` to this resource will delete all the pacts between the specified applications.
@@ -234,6 +234,14 @@ module PactBroker
234
234
  end
235
235
  end
236
236
 
237
+ def find_previous_pacts pact
238
+ if pact.consumer_version_tag_names.any?
239
+ pact.consumer_version_tag_names.map { |tag| find_previous_pact(pact, tag) }
240
+ else
241
+ [find_previous_pact(pact, :untagged)]
242
+ end
243
+ end
244
+
237
245
  private
238
246
 
239
247
  def find_previous_distinct_pact_by_sha pact
@@ -108,7 +108,7 @@ module PactBroker
108
108
 
109
109
  # TODO also take into account overridden revisions
110
110
  def pact_is_new_or_pact_has_changed_since_previous_version? pact
111
- find_previous_pacts(pact).any? { |previous_pact| previous_pact.nil? || pact.json_content != previous_pact.json_content}
111
+ pact_repository.find_previous_pacts(pact).any? { |previous_pact| previous_pact.nil? || pact.json_content != previous_pact.json_content}
112
112
  end
113
113
 
114
114
  private
@@ -118,10 +118,11 @@ module PactBroker
118
118
  logger.debug "Content #{params[:json_content]}"
119
119
  updated_pact = pact_repository.update existing_pact.id, params
120
120
 
121
+ webhook_service.trigger_webhooks updated_pact, nil, PactBroker::Webhooks::WebhookEvent::CONTRACT_PUBLISHED
121
122
  if existing_pact.json_content != updated_pact.json_content
122
123
  webhook_service.trigger_webhooks updated_pact, nil, PactBroker::Webhooks::WebhookEvent::CONTRACT_CONTENT_CHANGED
123
124
  else
124
- logger.debug "Pact has not changed since previous revision, not triggering webhooks"
125
+ logger.debug "Pact has not changed since previous version, not triggering webhooks for changed content"
125
126
  end
126
127
 
127
128
  updated_pact
@@ -137,18 +138,11 @@ module PactBroker
137
138
 
138
139
  def trigger_webhooks pact
139
140
  # TODO add tests for this
141
+ webhook_service.trigger_webhooks pact, nil, PactBroker::Webhooks::WebhookEvent::CONTRACT_PUBLISHED
140
142
  if pact_is_new_or_pact_has_changed_since_previous_version?(pact)
141
143
  webhook_service.trigger_webhooks pact, nil, PactBroker::Webhooks::WebhookEvent::CONTRACT_CONTENT_CHANGED
142
144
  else
143
- logger.debug "Pact has not changed since previous version, not triggering webhooks"
144
- end
145
- end
146
-
147
- def find_previous_pacts pact
148
- if pact.consumer_version_tag_names.any?
149
- pact.consumer_version_tag_names.map { |tag| pact_repository.find_previous_pact(pact, tag) }
150
- else
151
- [pact_repository.find_previous_pact(pact, :untagged)]
145
+ logger.debug "Pact has not changed since previous version, not triggering webhooks for changed content"
152
146
  end
153
147
  end
154
148
  end
@@ -21,6 +21,10 @@ module PactBroker
21
21
  end
22
22
  end
23
23
 
24
+ def empty?
25
+ index_items.empty?
26
+ end
27
+
24
28
  private
25
29
 
26
30
  attr_reader :index_items
@@ -0,0 +1,6 @@
1
+ %div.getting-started
2
+ %h3 Welcome!
3
+ %p
4
+ Just getting started? Confused as to why there's nothing "clicky clicky" to see here? The Pact workflow is a "code first" approach. Your pacts will be generated by your consumer tests and then published here, ready to be retrieved by your provider tests for verification.
5
+ %p
6
+ For step by step instructions on getting started, check out the <a href="https://docs.pact.io/best_practices/pact_nirvana">Effective Pact Setup Guide</a>.
@@ -3,6 +3,8 @@
3
3
  %script{type: 'text/javascript', src:'/javascripts/jquery.tablesorter.min.js'}
4
4
  .container
5
5
  = render :haml, :'index/_navbar', :layout => false, locals: {tag_toggle: false}
6
+ - if index_items.empty?
7
+ = render :haml, :'index/_getting-started', :layout => false
6
8
  %h1.page-header
7
9
  Pacts
8
10
  %table.table.table-bordered.table-striped{ id: 'relationships' }
@@ -3,6 +3,8 @@
3
3
  %script{type: 'text/javascript', src:'/javascripts/jquery.tablesorter.min.js'}
4
4
  .container
5
5
  = render :haml, :'index/_navbar', :layout => false, locals: {tag_toggle: true}
6
+ - if index_items.empty?
7
+ = render :haml, :'index/_getting-started', :layout => false
6
8
  %h1.page-header
7
9
  Pacts
8
10
  %table.table.table-bordered.table-striped{ id: 'relationships' }
@@ -1,3 +1,3 @@
1
1
  module PactBroker
2
- VERSION = '2.29.0'
2
+ VERSION = '2.30.0'
3
3
  end
@@ -5,18 +5,23 @@ module PactBroker
5
5
  module Webhooks
6
6
  class WebhookEvent < Sequel::Model
7
7
 
8
+ CONTRACT_PUBLISHED = 'contract_published'
8
9
  CONTRACT_CONTENT_CHANGED = 'contract_content_changed'
9
10
  VERIFICATION_PUBLISHED = 'provider_verification_published'
10
11
  DEFAULT_EVENT_NAME = CONTRACT_CONTENT_CHANGED
11
12
  #CONTRACT_VERIFIABLE_CONTENT_CHANGED = 'contract_verifiable_content_changed'
12
13
  #VERIFICATION_STATUS_CHANGED = 'verification_status_changed'
13
14
 
14
- EVENT_NAMES = [CONTRACT_CONTENT_CHANGED, VERIFICATION_PUBLISHED]
15
+ EVENT_NAMES = [CONTRACT_PUBLISHED, CONTRACT_CONTENT_CHANGED, VERIFICATION_PUBLISHED]
15
16
 
16
17
  dataset_module do
17
18
  include PactBroker::Repositories::Helpers
18
19
  end
19
20
 
21
+ def contract_published?
22
+ name == CONTRACT_PUBLISHED
23
+ end
24
+
20
25
  def contract_content_changed?
21
26
  name == CONTRACT_CONTENT_CHANGED
22
27
  end
@@ -1,29 +1,29 @@
1
+ # Decides whether this is a browser request or a request for the API
1
2
  module Rack
2
3
  module PactBroker
3
4
  class AcceptsHtmlFilter
4
-
5
5
  def initialize app
6
6
  @app = app
7
7
  end
8
8
 
9
9
  def call env
10
- if accepts_html_and_not_json_or_csv env
10
+ if accepts_web_content_types_and_not_api_media env
11
11
  @app.call(env)
12
12
  else
13
13
  [404, {},[]]
14
14
  end
15
15
  end
16
16
 
17
- def accepts_html_and_not_json_or_csv env
17
+ def accepts_web_content_types_and_not_api_media env
18
18
  accept = env['HTTP_ACCEPT'] || ''
19
- accepts_html(accept) && !accepts_json_or_csv(accept)
19
+ accepts_web_content_types(accept) && !accepts_api_content_types(accept)
20
20
  end
21
21
 
22
- def accepts_html(accept)
23
- accept.include?("html")
22
+ def accepts_web_content_types(accept)
23
+ accept.include?("*/*") || accept.include?("html") || accept.include?("text/css") || accept.include?("text/javascript")
24
24
  end
25
25
 
26
- def accepts_json_or_csv accept
26
+ def accepts_api_content_types accept
27
27
  accept.include?("json") || accept.include?("csv")
28
28
  end
29
29
  end
@@ -9,7 +9,7 @@ module Rack
9
9
  def call env
10
10
  response = @app.call(env)
11
11
 
12
- if response.first == 404 && response[1]['Content-Type'] == 'text/html' && !(env['HTTP_ACCEPT'] =~ /html/)
12
+ if response.first == 404 && response[1]['Content-Type'] == 'text/html' && !(env['HTTP_ACCEPT'] =~ /html|javascript|css/)
13
13
  [404, { 'Content-Type' => 'application/hal+json'},[]]
14
14
  else
15
15
  response
@@ -113,4 +113,9 @@ table#relationships .label {
113
113
 
114
114
  div.tag {
115
115
  display: inline-block;
116
+ }
117
+
118
+ div.getting-started {
119
+ max-width: 600px;
120
+ margin-bottom: 50px;
116
121
  }
@@ -0,0 +1,29 @@
1
+ describe "Deleting pact versions" do
2
+
3
+ let(:path) { "/pacts/provider/Bar/consumer/Foo/versions" }
4
+
5
+ subject { delete(path) }
6
+
7
+ context "when the pact exists" do
8
+ before do
9
+ TestDataBuilder.new
10
+ .create_pact_with_hierarchy("Foo", "1.2.3", "Bar")
11
+ .create_provider("Baz")
12
+ .create_pact
13
+ end
14
+
15
+ it "deletes the pacts" do
16
+ expect{ subject }.to change{ PactBroker::Pacts::PactPublication.count }.by(-1)
17
+ end
18
+
19
+ it "returns a 204" do
20
+ expect(subject.status).to be 204
21
+ end
22
+ end
23
+
24
+ context "when the pact does not exist" do
25
+ it "returns a 404 Not Found" do
26
+ expect(subject.status).to be 404
27
+ end
28
+ end
29
+ end
@@ -7,9 +7,59 @@ module PactBroker
7
7
 
8
8
  module Pacts
9
9
  describe Service do
10
-
11
10
  let(:td) { TestDataBuilder.new }
12
11
 
12
+ describe "create_or_update_pact" do
13
+ include_context "stubbed repositories"
14
+
15
+ before do
16
+ allow(described_class).to receive(:webhook_service).and_return(webhook_service)
17
+ allow(pacticipant_repository).to receive(:find_by_name_or_create).with(params[:consumer_name]).and_return(consumer)
18
+ allow(pacticipant_repository).to receive(:find_by_name_or_create).with(params[:provider_name]).and_return(provider)
19
+ allow(version_repository).to receive(:find_by_pacticipant_id_and_number_or_create).and_return(version)
20
+ allow(pact_repository).to receive(:find_by_version_and_provider).and_return(existing_pact)
21
+ allow(pact_repository).to receive(:create).and_return(new_pact)
22
+ allow(pact_repository).to receive(:update).and_return(new_pact)
23
+ allow(pact_repository).to receive(:find_previous_pacts).and_return(previous_pacts)
24
+ allow(webhook_service).to receive(:trigger_webhooks)
25
+ end
26
+
27
+ let(:webhook_service) { class_double("PactBroker::Webhooks::Service").as_stubbed_const }
28
+ let(:consumer) { double('consumer', id: 1) }
29
+ let(:provider) { double('provider', id: 2) }
30
+ let(:version) { double('version', id: 3, pacticipant_id: 1) }
31
+ let(:existing_pact) { nil }
32
+ let(:new_pact) { double('new_pact', json_content: json_content) }
33
+ let(:json_content) { { the: "contract" }.to_json }
34
+ let(:previous_pacts) { [] }
35
+ let(:params) do
36
+ {
37
+ consumer_name: "Foo",
38
+ provider_name: "Bar",
39
+ consumer_version_number: "1",
40
+ json_content: json_content
41
+ }
42
+ end
43
+
44
+ subject { Service.create_or_update_pact(params) }
45
+
46
+ context "when no pact exists with the same params" do
47
+ it "triggers webhooks for contract publications" do
48
+ expect(webhook_service).to receive(:trigger_webhooks).with(new_pact, nil, PactBroker::Webhooks::WebhookEvent::CONTRACT_PUBLISHED)
49
+ subject
50
+ end
51
+ end
52
+
53
+ context "when a pact exists with the same params" do
54
+ let(:existing_pact) { double('existing_pact', id: 4, json_content: { the: "contract" }.to_json) }
55
+
56
+ it "triggers webhooks for contract publications" do
57
+ expect(webhook_service).to receive(:trigger_webhooks).with(new_pact, nil, PactBroker::Webhooks::WebhookEvent::CONTRACT_PUBLISHED)
58
+ subject
59
+ end
60
+ end
61
+ end
62
+
13
63
  describe "find_distinct_pacts_between" do
14
64
  let(:pact_1) { double('pact 1', json_content: 'content 1')}
15
65
  let(:pact_2) { double('pact 2', json_content: 'content 2')}
@@ -27,7 +77,6 @@ module PactBroker
27
77
  it "returns the distinct pacts" do
28
78
  expect(subject).to eq [pact_4, pact_2, pact_1]
29
79
  end
30
-
31
80
  end
32
81
 
33
82
  describe "#pact_is_new_or_pact_has_changed_since_previous_version?" do
@@ -2,4 +2,5 @@ require 'semantic_logger'
2
2
  require 'pact_broker/logging/default_formatter'
3
3
 
4
4
  FileUtils.mkdir_p("log")
5
+ SemanticLogger.default_level = :error
5
6
  SemanticLogger.add_appender(file_name: "log/test.log", formatter: PactBroker::Logging::DefaultFormatter.new)
@@ -2,9 +2,26 @@ RSpec.shared_context "stubbed services" do
2
2
 
3
3
  let(:pact_service) { class_double("PactBroker::Pacts::Service").as_stubbed_const }
4
4
  let(:pacticipant_service) { class_double("PactBroker::Pacticipants::Service").as_stubbed_const }
5
+ let(:version_service) { class_double("PactBroker::Versions::Service").as_stubbed_const }
6
+ let(:webhook_service) { class_double("PactBroker::Webhooks::Service").as_stubbed_const }
5
7
 
6
8
  before do
7
9
  allow_any_instance_of(described_class).to receive(:pact_service).and_return(pact_service)
8
10
  allow_any_instance_of(described_class).to receive(:pacticipant_service).and_return(pacticipant_service)
11
+ allow_any_instance_of(described_class).to receive(:version_service).and_return(version_service)
12
+ allow_any_instance_of(described_class).to receive(:webhook_service).and_return(webhook_service)
13
+ end
14
+ end
15
+
16
+ RSpec.shared_context "stubbed repositories" do
17
+
18
+ let(:pact_repository) { instance_double("PactBroker::Pacts::Repository") }
19
+ let(:pacticipant_repository) { instance_double("PactBroker::Pacticipants::Repository") }
20
+ let(:version_repository) { instance_double("PactBroker::Version::Repository") }
21
+
22
+ before do
23
+ allow(described_class).to receive(:pact_repository).and_return(pact_repository)
24
+ allow(described_class).to receive(:pacticipant_repository).and_return(pacticipant_repository)
25
+ allow(described_class).to receive(:version_repository).and_return(version_repository)
9
26
  end
10
27
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pact_broker
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.29.0
4
+ version: 2.30.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bethany Skurrie
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2019-03-24 00:00:00.000000000 Z
13
+ date: 2019-04-01 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: httparty
@@ -881,6 +881,7 @@ files:
881
881
  - lib/pact_broker/doc/views/layouts/main.haml
882
882
  - lib/pact_broker/doc/views/not_found.markdown
883
883
  - lib/pact_broker/doc/views/pact-versions.markdown
884
+ - lib/pact_broker/doc/views/pact/all-pact-versions.markdown
884
885
  - lib/pact_broker/doc/views/pact/diff-previous-distinct.markdown
885
886
  - lib/pact_broker/doc/views/pact/diff.markdown
886
887
  - lib/pact_broker/doc/views/pact/latest-pact-version.markdown
@@ -979,6 +980,7 @@ files:
979
980
  - lib/pact_broker/ui/view_models/matrix_tag.rb
980
981
  - lib/pact_broker/ui/views/clusters/show.haml
981
982
  - lib/pact_broker/ui/views/groups/show.html.erb
983
+ - lib/pact_broker/ui/views/index/_getting-started.haml
982
984
  - lib/pact_broker/ui/views/index/_navbar.haml
983
985
  - lib/pact_broker/ui/views/index/show-with-tags.haml
984
986
  - lib/pact_broker/ui/views/index/show.haml
@@ -1094,6 +1096,7 @@ files:
1094
1096
  - spec/features/create_webhook_spec.rb
1095
1097
  - spec/features/delete_label_spec.rb
1096
1098
  - spec/features/delete_pact_spec.rb
1099
+ - spec/features/delete_pact_versions_spec.rb
1097
1100
  - spec/features/delete_tagged_pact_versions_spec.rb
1098
1101
  - spec/features/delete_version_spec.rb
1099
1102
  - spec/features/delete_webhook_spec.rb
@@ -1422,6 +1425,7 @@ test_files:
1422
1425
  - spec/features/create_webhook_spec.rb
1423
1426
  - spec/features/delete_label_spec.rb
1424
1427
  - spec/features/delete_pact_spec.rb
1428
+ - spec/features/delete_pact_versions_spec.rb
1425
1429
  - spec/features/delete_tagged_pact_versions_spec.rb
1426
1430
  - spec/features/delete_version_spec.rb
1427
1431
  - spec/features/delete_webhook_spec.rb