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 +5 -5
- data/CHANGELOG.md +19 -0
- data/DEVELOPER_DOCUMENTATION.md +7 -1
- data/config/database.yml +1 -1
- data/db/migrations/20190909_add_test_results_to_all_verifications.rb +23 -0
- data/db/migrations/20190910_add_test_results_to_latest_verifications.rb +37 -0
- data/db/migrations/20190911_add_test_results_to_latest_verifications_for_pact_versions.rb +34 -0
- data/lib/pact_broker/api/decorators/dashboard_decorator.rb +3 -1
- data/lib/pact_broker/api/pact_broker_urls.rb +38 -6
- data/lib/pact_broker/api/resources/index.rb +0 -2
- data/lib/pact_broker/app.rb +5 -0
- data/lib/pact_broker/logging.rb +1 -0
- data/lib/pact_broker/pacts/content.rb +28 -8
- data/lib/pact_broker/test/test_data_builder.rb +1 -1
- data/lib/pact_broker/verifications/all_verifications.rb +1 -0
- data/lib/pact_broker/verifications/latest_verification_for_pact_version.rb +1 -0
- data/lib/pact_broker/version.rb +1 -1
- data/lib/pact_broker/webhooks/webhook.rb +1 -0
- data/spec/fixtures/dashboard.json +1 -1
- data/spec/lib/pact_broker/api/decorators/dashboard_decorator_spec.rb +1 -1
- data/spec/lib/pact_broker/api/pact_broker_urls_spec.rb +14 -0
- data/spec/lib/pact_broker/pacts/content_spec.rb +8 -0
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 2e92bf0689f639ae130896a19f422d0c257a26e287c432692fb3ac5743da5eda
|
4
|
+
data.tar.gz: dbefceec4b74884062b31e0b4c84257252a6fa24f1a1850f149ebb09e3437717
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 55ae521524e210a6e136c07af4a0046c51063173ba911db685dcb0779a37310f3c42d9a045dcf2807b4e515924b0487eb5b954e78173f83df8c660ce454ed1d7
|
7
|
+
data.tar.gz: 507652c8d9105a7b8aaad4b3e9241b05829f2067e928df7f901ff3a0cd7ece60941a177dc199144c2b40971bc0cd218f3d7410c6260ee62bf11a2461f823950b
|
data/CHANGELOG.md
CHANGED
@@ -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
|
|
data/DEVELOPER_DOCUMENTATION.md
CHANGED
@@ -3,11 +3,17 @@
|
|
3
3
|
## File structure
|
4
4
|
|
5
5
|
* Application code - [lib](lib)
|
6
|
-
*
|
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
|
data/config/database.yml
CHANGED
@@ -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:
|
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
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
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
|
data/lib/pact_broker/app.rb
CHANGED
@@ -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
|
data/lib/pact_broker/logging.rb
CHANGED
@@ -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
|
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'] =
|
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'] =
|
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
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
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
|
data/lib/pact_broker/version.rb
CHANGED
@@ -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(:
|
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.
|
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-
|
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
|
1532
|
+
rubygems_version: 2.7.6
|
1531
1533
|
signing_key:
|
1532
1534
|
specification_version: 4
|
1533
1535
|
summary: See description
|