pact_broker 2.29.0 → 2.30.0

Sign up to get free protection for your applications and to get access to all the features.
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