pact_broker 2.37.0 → 2.38.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
- SHA1:
3
- metadata.gz: f2f3154a77ea59e200285d2ce7771d02f8333c47
4
- data.tar.gz: 5e9096d23e486f5cd2b370b61b7be1733cfa7876
2
+ SHA256:
3
+ metadata.gz: 2e92bf0689f639ae130896a19f422d0c257a26e287c432692fb3ac5743da5eda
4
+ data.tar.gz: dbefceec4b74884062b31e0b4c84257252a6fa24f1a1850f149ebb09e3437717
5
5
  SHA512:
6
- metadata.gz: f1fefb75e3e0e1a7ffe4008c6a35b580569069d4ac3d48b3848d02f730e7723a22a4b425f2306dabc3697d3cdd4d1ae78f728d84b70615d1805736e3dfb48d2c
7
- data.tar.gz: 4faa99affeef607ac56cb4feaffd9142fc1351ee101d5eb798f48f8b9d6675814c058d5d00e4af2169ab28b43e511fbda02e717461ae2af6f6e6ef3dc12b48d8
6
+ metadata.gz: 55ae521524e210a6e136c07af4a0046c51063173ba911db685dcb0779a37310f3c42d9a045dcf2807b4e515924b0487eb5b954e78173f83df8c660ce454ed1d7
7
+ data.tar.gz: 507652c8d9105a7b8aaad4b3e9241b05829f2067e928df7f901ff3a0cd7ece60941a177dc199144c2b40971bc0cd218f3d7410c6260ee62bf11a2461f823950b
@@ -1,3 +1,22 @@
1
+ <a name="v2.38.0"></a>
2
+ ### v2.38.0 (2019-09-20)
3
+
4
+
5
+ #### Features
6
+
7
+ * add pactflow message to start up and error logs ([530dbfe9](/../../commit/530dbfe9))
8
+ * allow interaction ids to be manually set for test data ([4e256102](/../../commit/4e256102))
9
+
10
+ * **dashboard**
11
+ * use 'refreshable' link for latest verification result so pact can be refreshed and display the latest result ([1ab8a5d9](/../../commit/1ab8a5d9))
12
+
13
+
14
+ #### Bug Fixes
15
+
16
+ * don't drop column from view in down step, because you can't remove a column from a view in posgres ([045f3f38](/../../commit/045f3f38))
17
+ * add test results to all verifications views ([9bc1eab1](/../../commit/9bc1eab1))
18
+
19
+
1
20
  <a name="v2.37.0"></a>
2
21
  ### v2.37.0 (2019-09-02)
3
22
 
@@ -3,11 +3,17 @@
3
3
  ## File structure
4
4
 
5
5
  * Application code - [lib](lib)
6
- * List of API endpoints - [lib/pact_broker/api.rb](lib/pact_broker/api.rb)
6
+ * The aggregated application (API, UI, middleware, HAL Browser, diagnostic endpoints etc) - [lib/pact_broker/app.rb](lib/pact_broker/app.rb)
7
7
  * API - [lib/pact_broker/api](lib/pact_broker/api)
8
+ * Routes - [lib/pact_broker/api.rb](lib/pact_broker/api.rb)
8
9
  * HTTP Resources - [lib/pact_broker/api/resources](lib/pact_broker/api/resources) These handle the HTTP requests.
9
10
  * Decorators - [lib/pact_broker/api/decorators](lib/pact_broker/api/decorators) These render the response bodies.
10
11
  * Contracts - [lib/pact_broker/api/contracts](lib/pact_broker/api/contracts) These validate incoming API requests.
12
+ * UI - [lib/pact_broker/ui](lib/pact_broker/ui)
13
+ * Routes - [lib/pact_broker/ui/app.rb](lib/pact_broker/ui/app.rb)
14
+ * Controllers - [lib/pact_broker/ui/controllers](lib/pact_broker/ui/controllers) These handle the HTTP requests.
15
+ * Views - [lib/pact_broker/ui/views](lib/pact_broker/ui/views) These render the view using HAML
16
+ * View models - [lib/pact_broker/ui/view_models](lib/pact_broker/ui/view_models) These expose the domain model data in a way that is suited to rendering in a view.
11
17
  * Domain - Domain classes were intially created in [lib/pact_broker/domain](lib/pact_broker/domain) but are now put in their own modules. The ones left here just haven't been migrated yet. The module name is the plural of the domain class name. eg `lib/pact_broker/widgets/widget.rb`.
12
18
  * Services and Repositories - in the module with the name of their domain concept. eg `lib/pact_broker/widgets/service.rb` and `lib/pact_broker/widgets/repository.rb`
13
19
  * Standalone "function as class" classes go into the module they relate to. This pattern is used when there is some significant stateless logic that we want to
@@ -17,7 +17,7 @@ test:
17
17
  username: postgres
18
18
  password: postgres
19
19
  host: "localhost"
20
- port: "5432"
20
+ port: "5433"
21
21
  mysql:
22
22
  <<: *default
23
23
  adapter: mysql2
@@ -0,0 +1,23 @@
1
+ Sequel.migration do
2
+ up do
3
+ create_or_replace_view(:all_verifications,
4
+ from(:verifications).select(
5
+ Sequel[:verifications][:id],
6
+ Sequel[:verifications][:number],
7
+ :success,
8
+ :provider_version_id,
9
+ Sequel[:v][:number].as(:provider_version_number),
10
+ Sequel[:v][:order].as(:provider_version_order),
11
+ :build_url,
12
+ :pact_version_id,
13
+ :execution_date,
14
+ Sequel[:verifications][:created_at],
15
+ :test_results
16
+ ).join(:versions, {id: :provider_version_id}, {:table_alias => :v})
17
+ )
18
+ end
19
+
20
+ down do
21
+ # do nothing - you can't drop columns from a postgres view
22
+ end
23
+ end
@@ -0,0 +1,37 @@
1
+ Sequel.migration do
2
+ up do
3
+ # The most recent verification for each pact_version
4
+ # provider_version column is DEPRECATED, use provider_version_number
5
+ # Think this can be replaced by latest_verification_id_for_pact_version_and_provider_version?
6
+ v = :verifications
7
+ create_or_replace_view(:latest_verifications,
8
+ from(v)
9
+ .select(
10
+ Sequel[v][:id],
11
+ Sequel[v][:number],
12
+ Sequel[v][:success],
13
+ Sequel[:s][:number].as(:provider_version),
14
+ Sequel[v][:build_url],
15
+ Sequel[v][:pact_version_id],
16
+ Sequel[v][:execution_date],
17
+ Sequel[v][:created_at],
18
+ Sequel[v][:provider_version_id],
19
+ Sequel[:s][:number].as(:provider_version_number),
20
+ Sequel[:s][:order].as(:provider_version_order),
21
+ Sequel[v][:test_results])
22
+ .join(:latest_verification_numbers,
23
+ {
24
+ Sequel[v][:pact_version_id] => Sequel[:lv][:pact_version_id],
25
+ Sequel[v][:number] => Sequel[:lv][:latest_number]
26
+ }, { table_alias: :lv })
27
+ .join(:versions,
28
+ {
29
+ Sequel[v][:provider_version_id] => Sequel[:s][:id]
30
+ }, { table_alias: :s })
31
+ )
32
+ end
33
+
34
+ down do
35
+ # do nothing - you can't drop columns from a postgres view
36
+ end
37
+ end
@@ -0,0 +1,34 @@
1
+ Sequel.migration do
2
+ up do
3
+ # The most recent verification for each pact_version
4
+ v = :verifications
5
+ create_or_replace_view(:latest_verifications_for_pact_versions,
6
+ from(v)
7
+ .select(
8
+ Sequel[v][:id],
9
+ Sequel[v][:number],
10
+ Sequel[v][:success],
11
+ Sequel[v][:build_url],
12
+ Sequel[v][:pact_version_id],
13
+ Sequel[v][:execution_date],
14
+ Sequel[v][:created_at],
15
+ Sequel[v][:provider_version_id],
16
+ Sequel[:s][:number].as(:provider_version_number),
17
+ Sequel[:s][:order].as(:provider_version_order),
18
+ Sequel[v][:test_results])
19
+ .join(:latest_verification_ids_for_pact_versions,
20
+ {
21
+ Sequel[v][:pact_version_id] => Sequel[:lv][:pact_version_id],
22
+ Sequel[v][:id] => Sequel[:lv][:latest_verification_id]
23
+ }, { table_alias: :lv })
24
+ .join(:versions,
25
+ {
26
+ Sequel[v][:provider_version_id] => Sequel[:s][:id]
27
+ }, { table_alias: :s })
28
+ )
29
+ end
30
+
31
+ down do
32
+ # do nothing - you can't drop columns from a postgres view
33
+ end
34
+ end
@@ -102,13 +102,15 @@ module PactBroker
102
102
  end
103
103
 
104
104
  def verification_hash(index_item, base_url)
105
+ # Use the 'latest pact' URL instead of the permalink URL so that the page can be
106
+ # refreshed, and the latest verification result will be updated to the most recent
105
107
  if index_item.latest_verification
106
108
  {
107
109
  success: index_item.latest_verification.success,
108
110
  verifiedAt: format_date_time(index_item.latest_verification.created_at),
109
111
  _links: {
110
112
  self: {
111
- href: verification_url(index_item.latest_verification, base_url)
113
+ href: latest_verification_for_pact_url(index_item.latest_pact, base_url, false)
112
114
  }
113
115
  }
114
116
  }
@@ -157,12 +157,20 @@ module PactBroker
157
157
  "#{base_url}/verification-results/consumer/#{url_encode(version.pacticipant.name)}/version/#{version.number}/latest"
158
158
  end
159
159
 
160
- def latest_verification_for_pact_url pact, base_url
161
- verification_url_from_params(
162
- provider_name: pact.provider_name,
163
- consumer_name: pact.consumer_name,
164
- pact_version_sha: pact.pact_version_sha,
165
- verification_number: 'latest')
160
+ def latest_verification_for_pact_url pact, base_url, permalink = true
161
+ if permalink
162
+ verification_url_from_params(
163
+ {
164
+ provider_name: provider_name(pact),
165
+ consumer_name: consumer_name(pact),
166
+ pact_version_sha: pact.pact_version_sha,
167
+ verification_number: 'latest'
168
+ },
169
+ base_url
170
+ )
171
+ else
172
+ pact_url(base_url, pact) + "/verification-results/latest"
173
+ end
166
174
  end
167
175
 
168
176
  def verification_triggered_webhooks_url verification, base_url = ''
@@ -276,6 +284,30 @@ module PactBroker
276
284
  'consumer', url_encode(params[:consumer_name])
277
285
  ].join('/')
278
286
  end
287
+
288
+ def consumer_name(thing)
289
+ if thing.respond_to?(:consumer_name)
290
+ thing.consumer_name
291
+ elsif thing.respond_to?(:consumer)
292
+ thing.consumer.name
293
+ elsif thing.respond_to?(:[])
294
+ thing[:consumer_name]
295
+ else
296
+ nil
297
+ end
298
+ end
299
+
300
+ def provider_name(thing)
301
+ if thing.respond_to?(:provider_name)
302
+ thing.provider_name
303
+ elsif thing.respond_to?(:provider)
304
+ thing.provider.name
305
+ elsif thing.respond_to?(:[])
306
+ thing[:provider_name]
307
+ else
308
+ nil
309
+ end
310
+ end
279
311
  end
280
312
  end
281
313
  end
@@ -4,9 +4,7 @@ require 'json'
4
4
  module PactBroker
5
5
  module Api
6
6
  module Resources
7
-
8
7
  class Index < BaseResource
9
-
10
8
  def content_types_provided
11
9
  [["application/hal+json", :to_json]]
12
10
  end
@@ -36,6 +36,7 @@ module PactBroker
36
36
  prepare_database
37
37
  load_configuration_from_database
38
38
  seed_example_data
39
+ print_startup_message
39
40
  end
40
41
 
41
42
  # Allows middleware to be inserted at the bottom of the shared middlware stack
@@ -223,5 +224,9 @@ module PactBroker
223
224
  @app_builder
224
225
  end
225
226
  end
227
+
228
+ def print_startup_message
229
+ logger.info "\n\n#{'*' * 80}\n\nWant someone to manage your Pact Broker for you? Check out https://pactflow.io/oss for a hardened, fully supported SaaS version of the Pact Broker with an improved UI + more.\n\n#{'*' * 80}\n"
230
+ end
226
231
  end
227
232
  end
@@ -35,6 +35,7 @@ module PactBroker
35
35
  message = "#{e.class} #{e.message}\n#{e.backtrace.join("\n")}"
36
36
  message = "#{description} - #{message}" if description
37
37
  logger.error message
38
+ logger.info "\n\n#{'*' * 80}\n\nPrefer it was someone else's job to deal with this error? Check out https://pactflow.io/oss for a hardened, fully supported SaaS version of the Pact Broker with an improved UI + more.\n\n#{'*' * 80}\n"
38
39
  end
39
40
  end
40
41
 
@@ -31,14 +31,26 @@ module PactBroker
31
31
  Content.from_hash(SortContent.call(pact_hash))
32
32
  end
33
33
 
34
- def with_ids
34
+ def with_test_results(test_results)
35
35
  new_pact_hash = pact_hash.dup
36
36
  if interactions && interactions.is_a?(Array)
37
- new_pact_hash['interactions'] = add_ids(interactions)
37
+ new_pact_hash['interactions'] = merge_verification_results(interactions, test_results)
38
38
  end
39
39
 
40
40
  if messages && messages.is_a?(Array)
41
- new_pact_hash['messages'] = add_ids(messages)
41
+ new_pact_hash['messages'] = merge_verification_results(messages, test_results)
42
+ end
43
+ Content.from_hash(new_pact_hash)
44
+ end
45
+
46
+ def with_ids(overwrite_existing_id = true)
47
+ new_pact_hash = pact_hash.dup
48
+ if interactions && interactions.is_a?(Array)
49
+ new_pact_hash['interactions'] = add_ids(interactions, overwrite_existing_id)
50
+ end
51
+
52
+ if messages && messages.is_a?(Array)
53
+ new_pact_hash['messages'] = add_ids(messages, overwrite_existing_id)
42
54
  end
43
55
  Content.from_hash(new_pact_hash)
44
56
  end
@@ -64,6 +76,10 @@ module PactBroker
64
76
  pact_hash.is_a?(Hash) ? pact_hash['interactions'] : nil
65
77
  end
66
78
 
79
+ def messages_or_interactions
80
+ messages || interactions
81
+ end
82
+
67
83
  def pact_specification_version
68
84
  maybe_pact_specification_version_1 = pact_hash['metadata']['pactSpecification']['version'] rescue nil
69
85
  maybe_pact_specification_version_2 = pact_hash['metadata']['pact-specification']['version'] rescue nil
@@ -75,13 +91,17 @@ module PactBroker
75
91
 
76
92
  attr_reader :pact_hash
77
93
 
78
- def add_ids(interactions)
94
+ def add_ids(interactions, overwrite_existing_id)
79
95
  interactions.map do | interaction |
80
96
  if interaction.is_a?(Hash)
81
- # just in case there is a previous ID in there
82
- interaction_without_id = interaction.reject { |k, _| k == "_id" }
83
- # make the _id the first key in the hash when rendered to JSON
84
- { "_id" => generate_interaction_sha(interaction_without_id) }.merge(interaction)
97
+ if !interaction.key?("_id") || overwrite_existing_id
98
+ # just in case there is a previous ID in there
99
+ interaction_without_id = interaction.reject { |k, _| k == "_id" }
100
+ # make the _id the first key in the hash when rendered to JSON
101
+ { "_id" => generate_interaction_sha(interaction_without_id) }.merge(interaction)
102
+ else
103
+ interaction
104
+ end
85
105
  else
86
106
  interaction
87
107
  end
@@ -331,7 +331,7 @@ module PactBroker
331
331
  end
332
332
 
333
333
  def prepare_json_content(json_content)
334
- PactBroker::Pacts::Content.from_json(json_content).with_ids.to_json
334
+ PactBroker::Pacts::Content.from_json(json_content).with_ids(false).to_json
335
335
  end
336
336
 
337
337
  def set_created_at_if_set created_at, table_name, selector
@@ -38,3 +38,4 @@ end
38
38
  # pact_version_id | integer |
39
39
  # execution_date | timestamp without time zone |
40
40
  # created_at | timestamp without time zone |
41
+ # test_results | text |
@@ -36,3 +36,4 @@ end
36
36
  # provider_version_id | integer |
37
37
  # provider_version_number | text |
38
38
  # provider_version_order | integer |
39
+ # test_results | text |
@@ -1,3 +1,3 @@
1
1
  module PactBroker
2
- VERSION = '2.37.0'
2
+ VERSION = '2.38.0'
3
3
  end
@@ -108,6 +108,7 @@ end
108
108
  # password | text |
109
109
  # enabled | boolean | DEFAULT true
110
110
  # description | text |
111
+ # headers | text |
111
112
  # Indexes:
112
113
  # webhooks_pkey | PRIMARY KEY btree (id)
113
114
  # uq_webhook_uuid | UNIQUE btree (uuid)
@@ -26,7 +26,7 @@
26
26
  "latestVerificationResult": {
27
27
  "_links": {
28
28
  "self": {
29
- "href": "verification_url"
29
+ "href": "latest_verification_url"
30
30
  }
31
31
  },
32
32
  "success": true,
@@ -49,7 +49,7 @@ module PactBroker
49
49
 
50
50
  before do
51
51
  allow_any_instance_of(DashboardDecorator).to receive(:pact_url).with(base_url, pact).and_return('pact_url')
52
- allow_any_instance_of(DashboardDecorator).to receive(:verification_url).with(verification, base_url).and_return('verification_url')
52
+ allow_any_instance_of(DashboardDecorator).to receive(:latest_verification_for_pact_url).with(pact, base_url, false).and_return('latest_verification_url')
53
53
  allow_any_instance_of(DashboardDecorator).to receive(:pacticipant_url).with(base_url, consumer).and_return('consumer_url')
54
54
  allow_any_instance_of(DashboardDecorator).to receive(:pacticipant_url).with(base_url, provider).and_return('provider_url')
55
55
  allow_any_instance_of(DashboardDecorator).to receive(:version_url).with(base_url, consumer_version).and_return('consumer_version_url')
@@ -113,6 +113,20 @@ module PactBroker
113
113
  end
114
114
  end
115
115
  end
116
+
117
+ describe "latest_verification_for_pact_url" do
118
+ context "when permalink = true" do
119
+ subject { PactBrokerUrls.latest_verification_for_pact_url(pact, base_url, true) }
120
+
121
+ it { is_expected.to eq "http://example.org/pacts/provider/Bar%2FBar/consumer/Foo%2FFoo/pact-version/5hbfu/verification-results/latest" }
122
+ end
123
+
124
+ context "when permalink = false" do
125
+ subject { PactBrokerUrls.latest_verification_for_pact_url(pact, base_url, false) }
126
+
127
+ it { is_expected.to eq "http://example.org/pacts/provider/Bar%2FBar/consumer/Foo%2FFoo/version/123%2F456/verification-results/latest" }
128
+ end
129
+ end
116
130
  end
117
131
  end
118
132
  end
@@ -59,6 +59,14 @@ module PactBroker
59
59
  expect(subject.messages.first["_id"]).to eq "some-id"
60
60
  end
61
61
  end
62
+
63
+ context "when override_existing_ids = false (for setting up test data)" do
64
+ let(:interaction) { { "_id" => "1", "foo" => "bar" } }
65
+
66
+ it "does not override the existing ids" do
67
+ expect(subject.interactions.first["_id"]).to eq "1"
68
+ end
69
+ end
62
70
  end
63
71
 
64
72
  describe "content_that_affects_verification_results" do
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.37.0
4
+ version: 2.38.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-09-02 00:00:00.000000000 Z
13
+ date: 2019-09-20 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: httparty
@@ -714,6 +714,9 @@ files:
714
714
  - db/migrations/20190525_add_description_column_to_webhooks.rb
715
715
  - db/migrations/20190602_add_headers_column_to_webhooks.rb
716
716
  - db/migrations/20190603_migrate_webhook_headers.rb
717
+ - db/migrations/20190909_add_test_results_to_all_verifications.rb
718
+ - db/migrations/20190910_add_test_results_to_latest_verifications.rb
719
+ - db/migrations/20190911_add_test_results_to_latest_verifications_for_pact_versions.rb
717
720
  - db/migrations/migration_helper.rb
718
721
  - db/test/backwards_compatibility/.rspec
719
722
  - db/test/backwards_compatibility/Appraisals
@@ -753,7 +756,6 @@ files:
753
756
  - example/basic_auth/config.ru
754
757
  - example/config.ru
755
758
  - example/example_data.sql
756
- - example/pact_broker_database.sqlite3
757
759
  - lib/db.rb
758
760
  - lib/pact/doc/README.md
759
761
  - lib/pact/doc/doc_file.rb
@@ -1527,7 +1529,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1527
1529
  version: '0'
1528
1530
  requirements: []
1529
1531
  rubyforge_project:
1530
- rubygems_version: 2.6.14.3
1532
+ rubygems_version: 2.7.6
1531
1533
  signing_key:
1532
1534
  specification_version: 4
1533
1535
  summary: See description