pact_broker 1.14.0 → 1.15.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 +4 -4
- data/.travis.yml +1 -0
- data/CHANGELOG.md +11 -0
- data/LICENSE.txt +2 -0
- data/README.md +6 -2
- data/example/Gemfile +3 -3
- data/lib/pact_broker.rb +6 -1
- data/lib/pact_broker/api.rb +8 -1
- data/lib/pact_broker/api/contracts/pacticipant_name_contract.rb +2 -4
- data/lib/pact_broker/api/contracts/put_pact_params_contract.rb +25 -32
- data/lib/pact_broker/api/contracts/request_validations.rb +5 -11
- data/lib/pact_broker/api/contracts/webhook_contract.rb +28 -15
- data/lib/pact_broker/api/decorators/versions_decorator.rb +41 -0
- data/lib/pact_broker/api/resources/base_resource.rb +7 -3
- data/lib/pact_broker/api/resources/latest_pact.rb +1 -1
- data/lib/pact_broker/api/resources/latest_pacts.rb +2 -2
- data/lib/pact_broker/api/resources/latest_provider_pacts.rb +1 -1
- data/lib/pact_broker/api/resources/pact.rb +2 -2
- data/lib/pact_broker/api/resources/pact_content_diff.rb +2 -5
- data/lib/pact_broker/api/resources/pact_versions.rb +1 -1
- data/lib/pact_broker/api/resources/pact_webhooks.rb +8 -5
- data/lib/pact_broker/api/resources/pacticipant.rb +1 -1
- data/lib/pact_broker/api/resources/pacticipants.rb +2 -2
- data/lib/pact_broker/api/resources/tag.rb +2 -2
- data/lib/pact_broker/api/resources/version.rb +1 -1
- data/lib/pact_broker/api/resources/versions.rb +34 -0
- data/lib/pact_broker/api/resources/webhook.rb +2 -2
- data/lib/pact_broker/api/resources/webhook_execution.rb +1 -1
- data/lib/pact_broker/domain/version.rb +4 -0
- data/lib/pact_broker/domain/webhook.rb +2 -0
- data/lib/pact_broker/locale/en.yml +9 -1
- data/lib/pact_broker/pacts/diff.rb +26 -27
- data/lib/pact_broker/repositories/pacticipant_repository.rb +7 -0
- data/lib/pact_broker/services/pacticipant_service.rb +4 -0
- data/lib/pact_broker/services/webhook_service.rb +2 -2
- data/lib/pact_broker/version.rb +1 -1
- data/pact_broker.gemspec +4 -6
- data/spec/features/get_versions_spec.rb +36 -0
- data/spec/lib/pact_broker/api/contracts/put_pact_params_contract_spec.rb +12 -19
- data/spec/lib/pact_broker/api/contracts/webhook_contract_spec.rb +7 -9
- data/spec/lib/pact_broker/api/decorators/embedded_tag_decorator_spec.rb +2 -2
- data/spec/lib/pact_broker/api/decorators/embedded_version_decorator_spec.rb +1 -1
- data/spec/lib/pact_broker/api/decorators/latest_pact_decorator_spec.rb +1 -1
- data/spec/lib/pact_broker/api/decorators/pact_decorator_spec.rb +2 -2
- data/spec/lib/pact_broker/api/decorators/pact_version_decorator_spec.rb +1 -1
- data/spec/lib/pact_broker/api/decorators/tag_decorator_spec.rb +1 -1
- data/spec/lib/pact_broker/api/decorators/version_decorator_spec.rb +1 -1
- data/spec/lib/pact_broker/api/decorators/versions_decorator_spec.rb +44 -0
- data/spec/lib/pact_broker/api/decorators/webhook_decorator_spec.rb +35 -39
- data/spec/lib/pact_broker/api/decorators/webhook_execution_result_decorator_spec.rb +2 -2
- data/spec/lib/pact_broker/api/decorators/webhooks_decorator_spec.rb +2 -2
- data/spec/lib/pact_broker/api/resources/pact_spec.rb +2 -3
- data/spec/lib/pact_broker/api/resources/pact_webhooks_spec.rb +3 -3
- data/spec/lib/pact_broker/api/resources/tag_spec.rb +2 -2
- data/spec/lib/pact_broker/api/resources/webhook_execution_spec.rb +1 -1
- data/spec/lib/pact_broker/api/resources/webhook_spec.rb +1 -1
- data/spec/lib/pact_broker/pacts/diff_spec.rb +1 -1
- metadata +28 -22
@@ -4,9 +4,7 @@ require 'pact_broker/api/contracts/put_pact_params_contract'
|
|
4
4
|
module PactBroker
|
5
5
|
module Api
|
6
6
|
module Contracts
|
7
|
-
|
8
7
|
describe PutPactParamsContract do
|
9
|
-
|
10
8
|
let(:json_content) { {'some' => 'json' }.to_json }
|
11
9
|
let(:pact_params) { Pacts::PactParams.new(attributes) }
|
12
10
|
|
@@ -24,17 +22,16 @@ module PactBroker
|
|
24
22
|
subject { PutPactParamsContract.new(pact_params) }
|
25
23
|
|
26
24
|
describe "errors" do
|
27
|
-
|
28
25
|
let(:attributes) { valid_attributes }
|
29
26
|
|
30
27
|
before do
|
31
|
-
subject.validate
|
28
|
+
subject.validate(attributes)
|
32
29
|
end
|
33
30
|
|
34
31
|
context "with valid params" do
|
35
32
|
|
36
33
|
it "is empty" do
|
37
|
-
expect(subject.errors
|
34
|
+
expect(subject.errors).to be_empty
|
38
35
|
end
|
39
36
|
end
|
40
37
|
|
@@ -44,7 +41,7 @@ module PactBroker
|
|
44
41
|
end
|
45
42
|
|
46
43
|
it "returns an error" do
|
47
|
-
expect(subject.errors
|
44
|
+
expect(subject.errors[:consumer_version_number]).to include("can't be blank")
|
48
45
|
end
|
49
46
|
end
|
50
47
|
|
@@ -54,42 +51,41 @@ module PactBroker
|
|
54
51
|
end
|
55
52
|
|
56
53
|
it "returns an error" do
|
57
|
-
expect(subject.errors
|
54
|
+
expect(subject.errors[:consumer_version_number]).to include("can't be blank")
|
58
55
|
end
|
59
56
|
end
|
60
57
|
|
61
58
|
context "with an invalid version number" do
|
62
|
-
let(:attributes)
|
59
|
+
let(:attributes) do
|
60
|
+
valid_attributes.merge(consumer_version_number: 'blah')
|
61
|
+
end
|
63
62
|
|
64
63
|
it "returns an error" do
|
65
|
-
expect(subject.errors[:
|
64
|
+
expect(subject.errors[:consumer_version_number]).to include(/Consumer version number 'blah' cannot be parsed to a version number/)
|
66
65
|
end
|
67
66
|
end
|
68
67
|
|
69
68
|
context "with a consumer name in the pact that does not match the consumer name in the path" do
|
70
|
-
|
71
69
|
let(:attributes) do
|
72
70
|
valid_attributes.merge(consumer_name: "another consumer")
|
73
71
|
end
|
74
72
|
|
75
73
|
it "returns an error" do
|
76
|
-
expect(subject.errors.
|
74
|
+
expect(subject.errors[:'consumer.name']).to include("does not match consumer name in path ('another consumer').")
|
77
75
|
end
|
78
76
|
end
|
79
77
|
|
80
78
|
context "with a provider name in the pact that does not match the provider name in the path" do
|
81
|
-
|
82
79
|
let(:attributes) do
|
83
80
|
valid_attributes.merge(provider_name: "another provider")
|
84
81
|
end
|
85
82
|
|
86
83
|
it "returns an error" do
|
87
|
-
expect(subject.errors.
|
84
|
+
expect(subject.errors[:'provider.name']).to include("does not match provider name in path ('another provider').")
|
88
85
|
end
|
89
86
|
end
|
90
87
|
|
91
88
|
context "when the consumer name in the pact is not present" do
|
92
|
-
|
93
89
|
let(:attributes) do
|
94
90
|
valid_attributes.tap do | atts |
|
95
91
|
atts.delete(:consumer_name_in_pact)
|
@@ -97,12 +93,11 @@ module PactBroker
|
|
97
93
|
end
|
98
94
|
|
99
95
|
it "returns no error because I don't want to stop a different CDC from being published" do
|
100
|
-
expect(subject.errors
|
96
|
+
expect(subject.errors).to be_empty
|
101
97
|
end
|
102
98
|
end
|
103
99
|
|
104
100
|
context "when the provider name in the pact is not present" do
|
105
|
-
|
106
101
|
let(:attributes) do
|
107
102
|
valid_attributes.tap do | atts |
|
108
103
|
atts.delete(:provider_name_in_pact)
|
@@ -110,12 +105,10 @@ module PactBroker
|
|
110
105
|
end
|
111
106
|
|
112
107
|
it "returns no error because I don't want to stop a different CDC from being published" do
|
113
|
-
expect(subject.errors
|
108
|
+
expect(subject.errors).to be_empty
|
114
109
|
end
|
115
110
|
end
|
116
|
-
|
117
111
|
end
|
118
|
-
|
119
112
|
end
|
120
113
|
end
|
121
114
|
end
|
@@ -6,8 +6,8 @@ module PactBroker
|
|
6
6
|
module Api
|
7
7
|
module Contracts
|
8
8
|
describe WebhookContract do
|
9
|
-
|
10
9
|
let(:json) { load_fixture 'webhook_valid.json' }
|
10
|
+
let(:hash) { JSON.parse(json) }
|
11
11
|
let(:webhook) { PactBroker::Api::Decorators::WebhookDecorator.new(Domain::Webhook.new).from_json(json) }
|
12
12
|
let(:subject) { WebhookContract.new(webhook) }
|
13
13
|
|
@@ -20,21 +20,19 @@ module PactBroker
|
|
20
20
|
describe "errors" do
|
21
21
|
|
22
22
|
before do
|
23
|
-
subject.validate
|
23
|
+
subject.validate(hash)
|
24
24
|
end
|
25
25
|
|
26
26
|
context "with valid fields" do
|
27
27
|
it "is empty" do
|
28
|
-
expect(subject.errors
|
28
|
+
expect(subject.errors).to be_empty
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
32
|
context "with no request defined" do
|
33
|
-
|
34
33
|
let(:json) { {}.to_json }
|
35
34
|
|
36
35
|
it "contains an error for missing request" do
|
37
|
-
subject.validate
|
38
36
|
expect(subject.errors[:request]).to eq ["can't be blank"]
|
39
37
|
end
|
40
38
|
end
|
@@ -47,7 +45,7 @@ module PactBroker
|
|
47
45
|
end
|
48
46
|
|
49
47
|
it "contains an error for missing method" do
|
50
|
-
expect(subject.errors[:"request.http_method"]).to
|
48
|
+
expect(subject.errors[:"request.http_method"]).to include "can't be blank"
|
51
49
|
end
|
52
50
|
end
|
53
51
|
|
@@ -59,7 +57,7 @@ module PactBroker
|
|
59
57
|
end
|
60
58
|
|
61
59
|
it "contains an error for invalid method" do
|
62
|
-
expect(subject.errors[:"request.
|
60
|
+
expect(subject.errors[:"request.http_method"]).to include "is not a recognised HTTP method"
|
63
61
|
end
|
64
62
|
end
|
65
63
|
|
@@ -71,7 +69,7 @@ module PactBroker
|
|
71
69
|
end
|
72
70
|
|
73
71
|
it "contains an error for missing URL" do
|
74
|
-
expect(subject.errors[:"request.url"]).to
|
72
|
+
expect(subject.errors[:"request.url"]).to include "can't be blank"
|
75
73
|
end
|
76
74
|
end
|
77
75
|
|
@@ -103,4 +101,4 @@ module PactBroker
|
|
103
101
|
end
|
104
102
|
end
|
105
103
|
end
|
106
|
-
end
|
104
|
+
end
|
@@ -15,10 +15,10 @@ module PactBroker
|
|
15
15
|
.create_consumer("Consumer")
|
16
16
|
.create_version("1.2.3")
|
17
17
|
.create_tag("prod")
|
18
|
-
PactBroker::Repositories::TagRepository.new.find
|
18
|
+
PactBroker::Repositories::TagRepository.new.find(tag_name: 'prod', pacticipant_version_number: '1.2.3', pacticipant_name: 'Consumer')
|
19
19
|
end
|
20
20
|
|
21
|
-
let(:options) { {base_url: 'http://example.org' }}
|
21
|
+
let(:options) { { user_options: { base_url: 'http://example.org' } } }
|
22
22
|
|
23
23
|
subject { JSON.parse TagDecorator.new(tag).to_json(options), symbolize_names: true }
|
24
24
|
|
@@ -13,7 +13,7 @@ module PactBroker
|
|
13
13
|
PactBroker::Repositories::VersionRepository.new.find_by_pacticipant_name_and_number "Consumer", "1.2.3"
|
14
14
|
end
|
15
15
|
|
16
|
-
let(:options) { {base_url: 'http://example.org' }}
|
16
|
+
let(:options) { { user_options: { base_url: 'http://example.org' } } }
|
17
17
|
|
18
18
|
subject { JSON.parse EmbeddedVersionDecorator.new(version).to_json(options), symbolize_names: true }
|
19
19
|
|
@@ -12,7 +12,7 @@ module PactBroker
|
|
12
12
|
let(:pact) { RepresentablePact.new(ProviderStateBuilder.new.create_pact_with_hierarchy 'Consumer', '1.2.3', 'Provider') }
|
13
13
|
let(:base_url) { 'http://example.org' }
|
14
14
|
|
15
|
-
subject { JSON.parse LatestPactDecorator.new(pact).to_json(base_url: base_url), symbolize_names: true}
|
15
|
+
subject { JSON.parse LatestPactDecorator.new(pact).to_json(user_options: { base_url: base_url }), symbolize_names: true}
|
16
16
|
|
17
17
|
it "includes the createdAt date" do
|
18
18
|
expect(subject[:createdAt]).to_not be_nil
|
@@ -35,7 +35,7 @@ module PactBroker
|
|
35
35
|
let(:provider) { instance_double(PactBroker::Domain::Pacticipant, name: 'A Provider')}
|
36
36
|
let(:consumer_version) { instance_double(PactBroker::Domain::Version, number: '1234', pacticipant: consumer)}
|
37
37
|
|
38
|
-
subject { JSON.parse PactDecorator.new(pact).to_json(base_url: base_url), symbolize_names: true}
|
38
|
+
subject { JSON.parse PactDecorator.new(pact).to_json(user_options: { base_url: base_url }), symbolize_names: true}
|
39
39
|
|
40
40
|
describe "#to_json" do
|
41
41
|
|
@@ -105,4 +105,4 @@ module PactBroker
|
|
105
105
|
end
|
106
106
|
end
|
107
107
|
end
|
108
|
-
end
|
108
|
+
end
|
@@ -35,7 +35,7 @@ module PactBroker
|
|
35
35
|
let(:consumer_version) { instance_double(PactBroker::Domain::Version, number: '1234', pacticipant: consumer)}
|
36
36
|
let(:decorator_context) { DecoratorContext.new(base_url, '') }
|
37
37
|
|
38
|
-
let(:json) { PactVersionDecorator.new(pact).to_json(decorator_context) }
|
38
|
+
let(:json) { PactVersionDecorator.new(pact).to_json(user_options: decorator_context) }
|
39
39
|
|
40
40
|
subject { JSON.parse(json, symbolize_names: true) }
|
41
41
|
|
@@ -19,7 +19,7 @@ module PactBroker
|
|
19
19
|
PactBroker::Repositories::TagRepository.new.find tag_name: 'prod', pacticipant_version_number: '1.2.3', pacticipant_name: 'Consumer'
|
20
20
|
end
|
21
21
|
|
22
|
-
let(:options) { {base_url: 'http://example.org' }}
|
22
|
+
let(:options) { { user_options: { base_url: 'http://example.org' } } }
|
23
23
|
|
24
24
|
subject { JSON.parse TagDecorator.new(tag).to_json(options), symbolize_names: true }
|
25
25
|
|
@@ -14,7 +14,7 @@ module PactBroker
|
|
14
14
|
PactBroker::Repositories::VersionRepository.new.find_by_pacticipant_name_and_number "Consumer", "1.2.3"
|
15
15
|
end
|
16
16
|
|
17
|
-
let(:options) { {base_url: 'http://example.org' }}
|
17
|
+
let(:options) { { user_options: { base_url: 'http://example.org' } } }
|
18
18
|
|
19
19
|
subject { JSON.parse VersionDecorator.new(version).to_json(options), symbolize_names: true }
|
20
20
|
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'pact_broker/api/decorators/versions_decorator'
|
3
|
+
require 'pact_broker/domain/version'
|
4
|
+
|
5
|
+
module PactBroker
|
6
|
+
|
7
|
+
module Api
|
8
|
+
|
9
|
+
module Decorators
|
10
|
+
|
11
|
+
describe VersionsDecorator do
|
12
|
+
|
13
|
+
let(:options) { {base_url: 'http://example.org', pacticipant_name: "Consumer" }}
|
14
|
+
|
15
|
+
subject { JSON.parse VersionsDecorator.new(versions).to_json(user_options: options), symbolize_names: true }
|
16
|
+
|
17
|
+
context "with no versions" do
|
18
|
+
let(:versions) { [] }
|
19
|
+
|
20
|
+
it "doesn't blow up" do
|
21
|
+
subject
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context "with versions" do
|
26
|
+
let(:version) do
|
27
|
+
ProviderStateBuilder.new
|
28
|
+
.create_consumer("Consumer")
|
29
|
+
.create_consumer_version("1.2.3")
|
30
|
+
.create_consumer_version_tag("prod")
|
31
|
+
PactBroker::Repositories::VersionRepository.new.find_by_pacticipant_name_and_number "Consumer", "1.2.3"
|
32
|
+
end
|
33
|
+
let(:versions) { [version] }
|
34
|
+
|
35
|
+
it "displays a list of versions" do
|
36
|
+
expect(subject[:_embedded][:versions]).to be_instance_of(Array)
|
37
|
+
expect(subject[:_embedded][:versions].size).to eq 1
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -5,8 +5,7 @@ module PactBroker
|
|
5
5
|
module Api
|
6
6
|
module Decorators
|
7
7
|
describe WebhookDecorator do
|
8
|
-
|
9
|
-
let(:headers) { {:'Content-Type' => 'application/json'} }
|
8
|
+
let(:headers) { { :'Content-Type' => 'application/json' } }
|
10
9
|
let(:request) do
|
11
10
|
{
|
12
11
|
method: 'POST',
|
@@ -32,97 +31,94 @@ module PactBroker
|
|
32
31
|
consumer: consumer,
|
33
32
|
provider: provider,
|
34
33
|
created_at: created_at,
|
35
|
-
updated_at: updated_at
|
34
|
+
updated_at: updated_at
|
35
|
+
)
|
36
36
|
end
|
37
37
|
|
38
38
|
subject { WebhookDecorator.new(webhook) }
|
39
39
|
|
40
|
-
describe
|
41
|
-
|
42
|
-
let(:parsed_json) { JSON.parse(subject.to_json(base_url: 'http://example.org'), symbolize_names: true)}
|
40
|
+
describe 'to_json' do
|
41
|
+
let(:parsed_json) { JSON.parse(subject.to_json(user_options: { base_url: 'http://example.org' }), symbolize_names: true) }
|
43
42
|
|
44
|
-
it
|
43
|
+
it 'includes the request' do
|
45
44
|
expect(parsed_json[:request]).to eq request
|
46
45
|
end
|
47
46
|
|
48
|
-
it
|
47
|
+
it 'includes an embedded consumer' do
|
49
48
|
expect(parsed_json[:_embedded][:consumer]).to eq ({
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
49
|
+
name: 'Consumer',
|
50
|
+
_links: {
|
51
|
+
self: {
|
52
|
+
href: 'http://example.org/pacticipants/Consumer'
|
53
|
+
}
|
54
|
+
}
|
55
|
+
})
|
57
56
|
end
|
58
57
|
|
59
|
-
it
|
58
|
+
it 'includes an embedded provider' do
|
60
59
|
expect(parsed_json[:_embedded][:provider]).to eq ({
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
60
|
+
name: 'Provider',
|
61
|
+
_links: {
|
62
|
+
self: {
|
63
|
+
href: 'http://example.org/pacticipants/Provider'
|
64
|
+
}
|
65
|
+
}
|
66
|
+
})
|
68
67
|
end
|
69
68
|
|
70
|
-
it
|
69
|
+
it 'includes a link to itself' do
|
71
70
|
expect(parsed_json[:_links][:self][:href]).to eq 'http://example.org/webhooks/some-uuid'
|
72
71
|
expect(parsed_json[:_links][:self][:title]).to_not be_nil
|
73
72
|
end
|
74
73
|
|
75
|
-
it
|
74
|
+
it 'includes a link to its parent collection' do
|
76
75
|
expect(parsed_json[:_links][:'pact-webhooks'][:href]).to_not be_nil
|
77
76
|
end
|
78
77
|
|
79
|
-
|
80
|
-
it "includes a link to the webhooks resource" do
|
78
|
+
it 'includes a link to the webhooks resource' do
|
81
79
|
expect(parsed_json[:_links][:webhooks][:href]).to_not be_nil
|
82
80
|
end
|
83
81
|
|
84
|
-
it
|
82
|
+
it 'includes a link to execute the webhook directly' do
|
85
83
|
expect(parsed_json[:_links][:execute][:href]).to eq 'http://example.org/webhooks/some-uuid/execute'
|
86
84
|
end
|
87
85
|
|
88
|
-
it
|
86
|
+
it 'includes timestamps' do
|
89
87
|
expect(parsed_json[:createdAt]).to eq created_at.xmlschema
|
90
88
|
expect(parsed_json[:updatedAt]).to eq updated_at.xmlschema
|
91
89
|
end
|
92
90
|
|
93
|
-
context
|
91
|
+
context 'when the headers are empty' do
|
94
92
|
let(:headers) { nil }
|
95
|
-
it
|
93
|
+
it 'does not include the headers' do
|
96
94
|
expect(parsed_json[:request]).to_not have_key :headers
|
97
95
|
end
|
98
96
|
end
|
99
|
-
|
100
97
|
end
|
101
98
|
|
102
|
-
describe
|
99
|
+
describe 'from_json' do
|
103
100
|
let(:hash) { { request: request } }
|
104
101
|
let(:json) { hash.to_json }
|
105
102
|
let(:webhook) { Domain::Webhook.new }
|
106
103
|
let(:parsed_object) { subject.from_json(json) }
|
107
104
|
|
108
|
-
it
|
105
|
+
it 'parses the request method' do
|
109
106
|
expect(parsed_object.request.method).to eq 'POST'
|
110
107
|
end
|
111
108
|
|
112
|
-
it
|
109
|
+
it 'parses the request URL' do
|
113
110
|
expect(parsed_object.request.url).to eq 'http://example.org/hook'
|
114
111
|
end
|
115
112
|
|
116
|
-
it
|
113
|
+
it 'parses the request headers' do
|
117
114
|
expect(parsed_object.request.headers).to eq 'Content-Type' => 'application/json'
|
118
115
|
end
|
119
116
|
|
120
|
-
it
|
117
|
+
it 'parses the request body' do
|
121
118
|
expect(parsed_object.request.body).to eq 'some' => 'body'
|
122
119
|
end
|
123
120
|
end
|
124
|
-
|
125
121
|
end
|
126
122
|
end
|
127
123
|
end
|
128
|
-
end
|
124
|
+
end
|