pact_broker 2.0.0 → 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/lib/pact_broker/api/decorators/version_decorator.rb +1 -1
- data/lib/pact_broker/api/decorators/webhook_decorator.rb +3 -3
- data/lib/pact_broker/api/decorators/webhooks_decorator.rb +10 -2
- data/lib/pact_broker/api/resources/version.rb +6 -1
- data/lib/pact_broker/app.rb +6 -1
- data/lib/pact_broker/doc/views/webhooks-create.markdown +38 -0
- data/lib/pact_broker/doc/views/webhooks-webhooks.markdown +15 -0
- data/lib/pact_broker/domain/order_versions.rb +15 -1
- data/lib/pact_broker/pacticipants/service.rb +4 -2
- data/lib/pact_broker/pacts/repository.rb +4 -0
- data/lib/pact_broker/tags/repository.rb +4 -0
- data/lib/pact_broker/version.rb +1 -1
- data/lib/pact_broker/versions/repository.rb +4 -0
- data/lib/pact_broker/versions/service.rb +7 -1
- data/lib/rack/pact_broker/database_transaction.rb +42 -0
- data/lib/rack/pact_broker/invalid_uri_protection.rb +36 -0
- data/pact_broker.gemspec +1 -0
- data/script/publish-new.sh +3 -1
- data/script/recreate-pg-db.sh +1 -0
- data/spec/features/delete_version_spec.rb +23 -0
- data/spec/lib/pact_broker/api/decorators/version_decorator_spec.rb +1 -1
- data/spec/lib/pact_broker/api/decorators/webhook_decorator_spec.rb +3 -3
- data/spec/lib/pact_broker/api/decorators/webhooks_decorator_spec.rb +3 -3
- data/spec/lib/pact_broker/app_spec.rb +35 -1
- data/spec/lib/pact_broker/domain/order_versions_spec.rb +22 -0
- data/spec/lib/pact_broker/pacts/repository_spec.rb +23 -0
- data/spec/lib/pact_broker/tags/repository_spec.rb +22 -1
- data/spec/lib/pact_broker/versions/repository_spec.rb +16 -0
- data/spec/lib/pact_broker/versions/service_spec.rb +35 -0
- data/spec/lib/rack/pact_broker/database_transaction_spec.rb +45 -0
- data/spec/lib/rack/pact_broker/invalid_uri_protection_spec.rb +30 -0
- data/spec/spec_helper.rb +2 -1
- metadata +28 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 880db0a792e03e1d623978995043fd1658e9674e
|
4
|
+
data.tar.gz: 0dca6bd356860e3392292b10bc3c23d18f51cd65
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2eab4b5d78400d982467ccd00f9e1e382a99cc145ee02d6721147a91de925f67f97c4a9cf3d998cef126ab73b1f41a85e308d64f5743aa8eef76b846052adf92
|
7
|
+
data.tar.gz: 9cd39079ca7a9ff6a595aee30933fd74dbc3c899a3fb65daf9522c040fa8a5979ccb3c5f2c295a3f7398c85d7010987812c24b43bd53aafe967690fbfe0dc238
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,13 @@ Do this to generate your change history
|
|
2
2
|
|
3
3
|
$ git log --pretty=format:' * %h - %s (%an, %ad)' vX.Y.Z..HEAD
|
4
4
|
|
5
|
+
#### 2.0.1 (2017-05-17)
|
6
|
+
* 8d105aa - Allow an application version to be deleted via the API. (Beth Skurrie, Fri May 19 10:39:16 2017 +1000)
|
7
|
+
* 025b0f7 - Ensure version numbers that don't conform to the semver2 spec don't cause errors when sorting versions. #103 (Beth Skurrie, Fri May 19 09:58:50 2017 +1000)
|
8
|
+
* ca6d88e - Corrected hal link rels that had missing curies (prepended "pb:") (Beth Skurrie, Thu May 18 10:20:06 2017 +1000)
|
9
|
+
* 1cabd5e - Use Rack::Protection. (Beth Skurrie, Tue May 16 10:13:40 2017 +1000)
|
10
|
+
* 2a3bbd1 - Return 404 instead of 500 when Ruby standard URI lib can't parse the URI. https://github.com/pact-foundation/pact_broker/issues/101 (Beth Skurrie, Tue May 16 09:45:37 2017 +1000)
|
11
|
+
|
5
12
|
#### 2.0.0 (2017-05-16)
|
6
13
|
|
7
14
|
#### 2.0.0.beta.8 (2017-05-15)
|
@@ -24,21 +24,21 @@ module PactBroker
|
|
24
24
|
|
25
25
|
end
|
26
26
|
|
27
|
-
link :'pact-webhooks' do | options |
|
27
|
+
link :'pb:pact-webhooks' do | options |
|
28
28
|
{
|
29
29
|
title: "All webhooks for the pact between #{represented.consumer.name} and #{represented.provider.name}",
|
30
30
|
href: webhooks_for_pact_url(represented.consumer, represented.provider, options[:base_url])
|
31
31
|
}
|
32
32
|
end
|
33
33
|
|
34
|
-
link :'webhooks' do | options |
|
34
|
+
link :'pb:webhooks' do | options |
|
35
35
|
{
|
36
36
|
title: "All webhooks",
|
37
37
|
href: webhooks_url(options[:base_url])
|
38
38
|
}
|
39
39
|
end
|
40
40
|
|
41
|
-
link :execute do | options |
|
41
|
+
link :'pb:execute' do | options |
|
42
42
|
{
|
43
43
|
title: "Test the execution of the webhook by sending a POST request to this URL",
|
44
44
|
href: webhook_execution_url(represented, options[:base_url])
|
@@ -14,7 +14,14 @@ module PactBroker
|
|
14
14
|
}
|
15
15
|
end
|
16
16
|
|
17
|
-
|
17
|
+
link :'pb:create' do | context |
|
18
|
+
{
|
19
|
+
title: "POST to create a webhook",
|
20
|
+
href: context[:resource_url]
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
links :'pb:webhooks' do | context |
|
18
25
|
represented.entries.collect do | webhook |
|
19
26
|
{
|
20
27
|
title: webhook.description,
|
@@ -27,7 +34,8 @@ module PactBroker
|
|
27
34
|
curies do | context |
|
28
35
|
[{
|
29
36
|
name: :pb,
|
30
|
-
href: context[:base_url] + '/doc/webhooks',
|
37
|
+
href: context[:base_url] + '/doc/webhooks-{rel}',
|
38
|
+
templated: true
|
31
39
|
}]
|
32
40
|
end
|
33
41
|
|
@@ -12,7 +12,7 @@ module PactBroker
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def allowed_methods
|
15
|
-
["GET"]
|
15
|
+
["GET", "DELETE"]
|
16
16
|
end
|
17
17
|
|
18
18
|
def resource_exists?
|
@@ -23,6 +23,11 @@ module PactBroker
|
|
23
23
|
Decorators::VersionDecorator.new(version).to_json(user_options: {base_url: base_url})
|
24
24
|
end
|
25
25
|
|
26
|
+
def delete_resource
|
27
|
+
version_service.delete version
|
28
|
+
true
|
29
|
+
end
|
30
|
+
|
26
31
|
private
|
27
32
|
|
28
33
|
def version
|
data/lib/pact_broker/app.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
require 'pact_broker/configuration'
|
2
2
|
require 'pact_broker/db'
|
3
3
|
require 'pact_broker/project_root'
|
4
|
+
require 'rack-protection'
|
4
5
|
require 'rack/hal_browser'
|
5
6
|
require 'rack/pact_broker/add_pact_broker_version_header'
|
6
7
|
require 'rack/pact_broker/convert_file_extension_to_accept_header'
|
8
|
+
require 'rack/pact_broker/database_transaction'
|
9
|
+
require 'rack/pact_broker/invalid_uri_protection'
|
7
10
|
require 'sucker_punch'
|
8
11
|
|
9
12
|
module PactBroker
|
@@ -54,6 +57,8 @@ module PactBroker
|
|
54
57
|
def build_app
|
55
58
|
@app = Rack::Builder.new
|
56
59
|
|
60
|
+
@app.use Rack::Protection, except: [:remote_token, :session_hijacking]
|
61
|
+
@app.use Rack::PactBroker::InvalidUriProtection
|
57
62
|
@app.use Rack::PactBroker::AddPactBrokerVersionHeader
|
58
63
|
@app.use Rack::Static, :urls => ["/stylesheets", "/css", "/fonts", "/js", "/javascripts", "/images"], :root => PactBroker.project_root.join("public")
|
59
64
|
@app.use Rack::PactBroker::ConvertFileExtensionToAcceptHeader
|
@@ -79,7 +84,7 @@ module PactBroker
|
|
79
84
|
end
|
80
85
|
|
81
86
|
apps << PactBroker::UI::App.new
|
82
|
-
apps << PactBroker::API
|
87
|
+
apps << Rack::PactBroker::DatabaseTransaction.new(PactBroker::API, configuration.database_connection)
|
83
88
|
|
84
89
|
@app.map "/" do
|
85
90
|
run Rack::Cascade.new(apps)
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# Create a webhook
|
2
|
+
|
3
|
+
Allowed methods: POST
|
4
|
+
|
5
|
+
1. Click the "NON-GET" button for the "pb:create" relation.
|
6
|
+
3. Paste in the webhook JSON (example shown below) in the body section and click "Make Request".
|
7
|
+
|
8
|
+
An example webhook to trigger a Bamboo job.
|
9
|
+
|
10
|
+
{
|
11
|
+
"request": {
|
12
|
+
"method": "POST",
|
13
|
+
"url": "http://master.ci.my.domain:8085/rest/api/latest/queue/SOME-PROJECT?os_authType=basic",
|
14
|
+
"username": "username",
|
15
|
+
"password": "password",
|
16
|
+
"headers": {
|
17
|
+
"Accept": "application/json"
|
18
|
+
}
|
19
|
+
}
|
20
|
+
}
|
21
|
+
|
22
|
+
A request body can be specified as well.
|
23
|
+
|
24
|
+
{
|
25
|
+
"request": {
|
26
|
+
"method": "POST",
|
27
|
+
"url": "http://example.org/something",
|
28
|
+
"body": {
|
29
|
+
"some" : "json"
|
30
|
+
}
|
31
|
+
}
|
32
|
+
}
|
33
|
+
|
34
|
+
**BEWARE** The password can be reverse engineered from the database, so make a separate account for the Pact Broker to use, don't use your personal account!
|
35
|
+
|
36
|
+
### Testing
|
37
|
+
|
38
|
+
To test a webhook, navigate to the webhook in the HAL browser, then make a POST request to the "execute" relation. The response or error will be shown in the window.
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# Webhooks
|
2
|
+
|
3
|
+
Allowed methods: GET, DELETE
|
4
|
+
|
5
|
+
### Testing
|
6
|
+
|
7
|
+
To test a webhook, navigate to the webhook in the HAL browser, then make a POST request to the "execute" relation. The response or error will be shown in the window.
|
8
|
+
|
9
|
+
### Deleting
|
10
|
+
|
11
|
+
Send a DELETE request to the webhook URL.
|
12
|
+
|
13
|
+
### Updating
|
14
|
+
|
15
|
+
Currently not implemented. You will need to delete and re-create the webhook.
|
@@ -26,8 +26,22 @@ module PactBroker
|
|
26
26
|
@sortable_number = PactBroker.configuration.version_parser.call version_model.number
|
27
27
|
end
|
28
28
|
|
29
|
+
# Incoming version numbers are rejected if they can't be parsed by the version parser,
|
30
|
+
# however, the change from Versionomy to SemVer for version parsing means that some
|
31
|
+
# existing version numbers cannot be parsed and are returning nil.
|
32
|
+
# The main reason to sort the versions is to that we can get the "latest" pact.
|
33
|
+
# Any existing version with a number that cannot be parsed will almost definitely not
|
34
|
+
# be the "latest", so sort them first.
|
29
35
|
def <=> other
|
30
|
-
|
36
|
+
if sortable_number.nil? && other.sortable_number.nil?
|
37
|
+
0
|
38
|
+
elsif sortable_number.nil?
|
39
|
+
-1
|
40
|
+
elsif other.sortable_number.nil?
|
41
|
+
1
|
42
|
+
else
|
43
|
+
self.sortable_number <=> other.sortable_number
|
44
|
+
end
|
31
45
|
end
|
32
46
|
|
33
47
|
def update_model new_order
|
@@ -75,15 +75,17 @@ module PactBroker
|
|
75
75
|
def self.delete name
|
76
76
|
pacticipant = find_pacticipant_by_name name
|
77
77
|
connection = PactBroker::Domain::Pacticipant.new.db
|
78
|
+
version_ids = PactBroker::Domain::Version.where(pacticipant_id: pacticipant.id).select(:id)
|
78
79
|
select_pacticipant = "select id from pacticipants where name = '#{name}'"
|
79
|
-
|
80
|
-
|
80
|
+
tag_repository.delete_by_version_id version_ids
|
81
|
+
pact_repository.delete_by_version_id version_ids
|
81
82
|
connection.run("delete from pact_publications where provider_id = #{pacticipant.id}")
|
82
83
|
connection.run("delete from verifications where pact_version_id IN (select id from pact_versions where provider_id = #{pacticipant.id})")
|
83
84
|
connection.run("delete from verifications where pact_version_id IN (select id from pact_versions where consumer_id = #{pacticipant.id})")
|
84
85
|
connection.run("delete from pact_versions where provider_id = #{pacticipant.id}")
|
85
86
|
connection.run("delete from pact_versions where consumer_id = #{pacticipant.id}")
|
86
87
|
connection.run("delete from versions where pacticipant_id = #{pacticipant.id}")
|
88
|
+
version_repository.delete_by_id version_ids
|
87
89
|
webhook_service.delete_by_pacticipant pacticipant
|
88
90
|
connection.run("delete from pacticipants where id = #{pacticipant.id}")
|
89
91
|
end
|
@@ -48,6 +48,10 @@ module PactBroker
|
|
48
48
|
PactPublication.where(id: id).delete
|
49
49
|
end
|
50
50
|
|
51
|
+
def delete_by_version_id version_id
|
52
|
+
Sequel::Model.db[:pact_publications].where(consumer_version_id: version_id).delete
|
53
|
+
end
|
54
|
+
|
51
55
|
def find_all_pact_versions_between consumer_name, options
|
52
56
|
provider_name = options.fetch(:and)
|
53
57
|
LatestPactPublicationsByConsumerVersion
|
@@ -22,6 +22,10 @@ module PactBroker
|
|
22
22
|
.where(name_like(Sequel.qualify("pacticipants", "name"), args.fetch(:pacticipant_name)))
|
23
23
|
.single_record
|
24
24
|
end
|
25
|
+
|
26
|
+
def delete_by_version_id version_id
|
27
|
+
Sequel::Model.db[:tags].where(version_id: version_id).delete
|
28
|
+
end
|
25
29
|
end
|
26
30
|
end
|
27
31
|
end
|
data/lib/pact_broker/version.rb
CHANGED
@@ -10,6 +10,12 @@ module PactBroker
|
|
10
10
|
def self.find_by_pacticipant_name_and_number params
|
11
11
|
version_repository.find_by_pacticipant_name_and_number params.fetch(:pacticipant_name), params.fetch(:pacticipant_version_number)
|
12
12
|
end
|
13
|
+
|
14
|
+
def self.delete version
|
15
|
+
tag_repository.delete_by_version_id version.id
|
16
|
+
pact_repository.delete_by_version_id version.id
|
17
|
+
version_repository.delete_by_id version.id
|
18
|
+
end
|
13
19
|
end
|
14
20
|
end
|
15
|
-
end
|
21
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'pact_broker/version'
|
2
|
+
require 'sequel'
|
3
|
+
|
4
|
+
module Rack
|
5
|
+
module PactBroker
|
6
|
+
class DatabaseTransaction
|
7
|
+
|
8
|
+
REQUEST_METHOD = "REQUEST_METHOD".freeze
|
9
|
+
TRANS_METHODS = %{POST PUT PATCH DELETE}.freeze
|
10
|
+
|
11
|
+
def initialize app, database_connection
|
12
|
+
@app = app
|
13
|
+
@database_connection = database_connection
|
14
|
+
end
|
15
|
+
|
16
|
+
def call env
|
17
|
+
if use_transaction? env
|
18
|
+
call_with_transaction env
|
19
|
+
else
|
20
|
+
call_without_transaction env
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def use_transaction? env
|
25
|
+
TRANS_METHODS.include? env[REQUEST_METHOD]
|
26
|
+
end
|
27
|
+
|
28
|
+
def call_without_transaction env
|
29
|
+
@app.call(env)
|
30
|
+
end
|
31
|
+
|
32
|
+
def call_with_transaction env
|
33
|
+
response = nil
|
34
|
+
@database_connection.transaction do
|
35
|
+
response = @app.call(env)
|
36
|
+
raise Sequel::Rollback if response.first == 500
|
37
|
+
end
|
38
|
+
response
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
3
|
+
# This class is for https://github.com/pact-foundation/pact_broker/issues/101
|
4
|
+
# curl -i "http://127.0.0.1:9292/<script>"
|
5
|
+
|
6
|
+
module Rack
|
7
|
+
module PactBroker
|
8
|
+
class InvalidUriProtection
|
9
|
+
|
10
|
+
def initialize app
|
11
|
+
@app = app
|
12
|
+
end
|
13
|
+
|
14
|
+
def call env
|
15
|
+
if valid_uri? env
|
16
|
+
@app.call(env)
|
17
|
+
else
|
18
|
+
[404, {}, []]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def valid_uri? env
|
23
|
+
begin
|
24
|
+
parse(::Rack::Request.new(env).url)
|
25
|
+
true
|
26
|
+
rescue URI::InvalidURIError
|
27
|
+
false
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def parse uri
|
32
|
+
URI.parse(uri)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/pact_broker.gemspec
CHANGED
@@ -36,6 +36,7 @@ Gem::Specification.new do |gem|
|
|
36
36
|
gem.add_runtime_dependency 'padrino-core', '~>0.12.4'
|
37
37
|
gem.add_runtime_dependency 'haml', '~>4.0'
|
38
38
|
gem.add_runtime_dependency 'sucker_punch', '~>2.0'
|
39
|
+
gem.add_runtime_dependency 'rack-protection', '~>1.5'
|
39
40
|
|
40
41
|
gem.add_development_dependency 'sqlite3'
|
41
42
|
gem.add_development_dependency 'pry-byebug'
|
data/script/publish-new.sh
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
# set -x
|
2
2
|
BODY=$(ruby -e "require 'json'; j = JSON.parse(File.read('script/foo-bar.json')); j['interactions'][0]['providerState'] = 'it is ' + Time.now.to_s; puts j.to_json")
|
3
|
+
latest_url=$(curl http://localhost:9292/pacts/provider/Bar/consumer/Foo/latest | jq -r ._links.self.href)
|
4
|
+
next_version=$(echo ${latest_url} | ruby -e "require 'semver'; puts SemVer.parse(ARGF.read[/\d+\.\d\.\d+/]).tap{ | v| v.minor = v.minor + 1}.format('%M.%m.%p')")
|
3
5
|
echo ${BODY} >> tmp.json
|
4
6
|
curl -v -XPUT \-H "Content-Type: application/json" \
|
5
7
|
-d@tmp.json \
|
6
|
-
http://127.0.0.1:9292/pacts/provider/Bar/consumer/Foo/version
|
8
|
+
http://127.0.0.1:9292/pacts/provider/Bar/consumer/Foo/version/${next_version}
|
7
9
|
rm tmp.json
|
data/script/recreate-pg-db.sh
CHANGED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec/support/provider_state_builder'
|
2
|
+
|
3
|
+
describe "Delete version" do
|
4
|
+
|
5
|
+
let(:path) { "/pacticipants/Consumer/versions/1.2.3" }
|
6
|
+
let(:last_response_body) { JSON.parse(subject.body, symbolize_names: true) }
|
7
|
+
|
8
|
+
subject { delete path; last_response }
|
9
|
+
|
10
|
+
before do
|
11
|
+
ProviderStateBuilder.new
|
12
|
+
.create_consumer("Another Consumer")
|
13
|
+
.create_consumer("Consumer")
|
14
|
+
.create_consumer_version("1.2.3")
|
15
|
+
.create_consumer_version_tag("prod")
|
16
|
+
.create_consumer_version("1.2.4")
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
it "returns a 200 HAL JSON response" do
|
21
|
+
expect(subject.status).to eq 204
|
22
|
+
end
|
23
|
+
end
|
@@ -35,7 +35,7 @@ module PactBroker
|
|
35
35
|
end
|
36
36
|
|
37
37
|
it "includes a link to the pacticipant" do
|
38
|
-
expect(subject[:_links][:pacticipant]).to eq title: "Pacticipant", name: "Consumer", href: "http://example.org/pacticipants/Consumer"
|
38
|
+
expect(subject[:_links][:'pb:pacticipant']).to eq title: "Pacticipant", name: "Consumer", href: "http://example.org/pacticipants/Consumer"
|
39
39
|
end
|
40
40
|
|
41
41
|
it "includes a list of the tags" do
|
@@ -72,15 +72,15 @@ module PactBroker
|
|
72
72
|
end
|
73
73
|
|
74
74
|
it 'includes a link to its parent collection' do
|
75
|
-
expect(parsed_json[:_links][:'pact-webhooks'][:href]).to_not be_nil
|
75
|
+
expect(parsed_json[:_links][:'pb:pact-webhooks'][:href]).to_not be_nil
|
76
76
|
end
|
77
77
|
|
78
78
|
it 'includes a link to the webhooks resource' do
|
79
|
-
expect(parsed_json[:_links][:webhooks][:href]).to_not be_nil
|
79
|
+
expect(parsed_json[:_links][:'pb:webhooks'][:href]).to_not be_nil
|
80
80
|
end
|
81
81
|
|
82
82
|
it 'includes a link to execute the webhook directly' do
|
83
|
-
expect(parsed_json[:_links][:execute][:href]).to eq 'http://example.org/webhooks/some-uuid/execute'
|
83
|
+
expect(parsed_json[:_links][:'pb:execute'][:href]).to eq 'http://example.org/webhooks/some-uuid/execute'
|
84
84
|
end
|
85
85
|
|
86
86
|
it 'includes timestamps' do
|
@@ -30,12 +30,12 @@ module PactBroker
|
|
30
30
|
end
|
31
31
|
|
32
32
|
it "includes a list of links to the webhooks" do
|
33
|
-
expect(subject[:_links][:webhooks]).to be_instance_of(Array)
|
34
|
-
expect(subject[:_links][:webhooks].first).to eq title: 'description', name: 'request description', href: 'http://example.org/webhooks/some-uuid'
|
33
|
+
expect(subject[:_links][:'pb:webhooks']).to be_instance_of(Array)
|
34
|
+
expect(subject[:_links][:'pb:webhooks'].first).to eq title: 'description', name: 'request description', href: 'http://example.org/webhooks/some-uuid'
|
35
35
|
end
|
36
36
|
|
37
37
|
it "includes curies" do
|
38
|
-
expect(subject[:_links][:curies]).to eq [{:name=>"pb", :href=>"http://example.org/doc/webhooks"}]
|
38
|
+
expect(subject[:_links][:curies]).to eq [{:name=>"pb", :href=>"http://example.org/doc/webhooks-{rel}", templated: true}]
|
39
39
|
end
|
40
40
|
|
41
41
|
end
|
@@ -3,9 +3,22 @@ require 'pact_broker/app'
|
|
3
3
|
module PactBroker
|
4
4
|
describe App do
|
5
5
|
|
6
|
+
class TestApp < PactBroker::App
|
7
|
+
|
8
|
+
def configure_database_connection
|
9
|
+
# do nothing
|
10
|
+
end
|
11
|
+
|
12
|
+
def post_configure
|
13
|
+
# do nothing
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
6
18
|
let(:app) do
|
7
|
-
|
19
|
+
TestApp.new do | configuration |
|
8
20
|
configuration.database_connection = PactBroker::DB.connection
|
21
|
+
configuration.auto_migrate_db = false
|
9
22
|
end
|
10
23
|
end
|
11
24
|
|
@@ -14,5 +27,26 @@ module PactBroker
|
|
14
27
|
expect(last_response.headers['X-Pact-Broker-Version']).to match /\d/
|
15
28
|
end
|
16
29
|
|
30
|
+
describe "transactions", no_db_clean: true do
|
31
|
+
let(:pact_content) { load_fixture('a_consumer-a_provider.json') }
|
32
|
+
let(:path) { "/pacts/provider/A%20Provider/consumer/A%20Consumer/versions/1.2.3" }
|
33
|
+
let(:response_body_json) { JSON.parse(subject.body) }
|
34
|
+
|
35
|
+
before do
|
36
|
+
PactBroker::Database.truncate
|
37
|
+
allow_any_instance_of(PactBroker::Pacts::Repository).to receive(:create).and_raise("an error")
|
38
|
+
end
|
39
|
+
|
40
|
+
after do
|
41
|
+
PactBroker::Database.truncate
|
42
|
+
end
|
43
|
+
|
44
|
+
subject { put path, pact_content, {'CONTENT_TYPE' => 'application/json' }; last_response }
|
45
|
+
|
46
|
+
it "wraps the API with a database transaction" do
|
47
|
+
expect { subject }.to_not change { PactBroker::Domain::Pacticipant.count }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
17
51
|
end
|
18
52
|
end
|
@@ -40,4 +40,26 @@ describe PactBroker::Domain::OrderVersions do
|
|
40
40
|
|
41
41
|
end
|
42
42
|
|
43
|
+
context "when an existing version number in the database that Versionomy could parse cannot be parsed by SemVer" do
|
44
|
+
let!(:consumer) do
|
45
|
+
ProviderStateBuilder.new
|
46
|
+
.create_consumer
|
47
|
+
.create_consumer_version('1')
|
48
|
+
.create_consumer_version('2')
|
49
|
+
.create_consumer_version('3')
|
50
|
+
.create_consumer_version('4')
|
51
|
+
.and_return(:consumer)
|
52
|
+
end
|
53
|
+
|
54
|
+
let(:ordered_versions) { PactBroker::Domain::Version.order(:order).all.collect(&:number) }
|
55
|
+
|
56
|
+
it "sorts the unparseable version as being first and maintains their relative order" do
|
57
|
+
Sequel::Model.db[:versions].where(number: '1').update(number: 'z')
|
58
|
+
Sequel::Model.db[:versions].where(number: '2').update(number: 'a')
|
59
|
+
Sequel::Model.db[:versions].where(number: '4').update(number: 'h')
|
60
|
+
PactBroker::Domain::Version.create(number: '5', pacticipant_id: consumer.id)
|
61
|
+
expect(ordered_versions).to eq(['z', 'a', 'h', '3', '5'])
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
43
65
|
end
|
@@ -191,6 +191,29 @@ module PactBroker
|
|
191
191
|
|
192
192
|
end
|
193
193
|
|
194
|
+
describe "delete_by_version_id" do
|
195
|
+
let!(:version) do
|
196
|
+
ProviderStateBuilder.new
|
197
|
+
.create_consumer
|
198
|
+
.create_provider
|
199
|
+
.create_consumer_version("4.5.6")
|
200
|
+
.create_pact
|
201
|
+
.create_consumer_version("1.2.3")
|
202
|
+
.create_pact
|
203
|
+
.and_return(:consumer_version)
|
204
|
+
end
|
205
|
+
|
206
|
+
subject { Repository.new.delete_by_version_id(version.id) }
|
207
|
+
|
208
|
+
it "deletes the pact publication" do
|
209
|
+
expect{ subject }.to change { PactPublication.count }.by(-1)
|
210
|
+
end
|
211
|
+
|
212
|
+
it "does not delete the content because it may be used by another pact" do
|
213
|
+
expect { subject }.to change { PactVersion.count }.by(0)
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
194
217
|
describe "#find_all_pact_versions_between" do
|
195
218
|
|
196
219
|
before do
|
@@ -62,6 +62,27 @@ module PactBroker
|
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
|
+
describe "delete_by_version_id" do
|
66
|
+
let!(:version) do
|
67
|
+
ProviderStateBuilder.new
|
68
|
+
.create_consumer
|
69
|
+
.create_provider
|
70
|
+
.create_consumer_version("4.5.6")
|
71
|
+
.create_consumer_version_tag("prod")
|
72
|
+
.create_consumer_version("1.2.3")
|
73
|
+
.create_consumer_version_tag("prod")
|
74
|
+
.create_consumer_version_tag("foo")
|
75
|
+
.and_return(:consumer_version)
|
76
|
+
end
|
77
|
+
|
78
|
+
subject { Repository.new.delete_by_version_id(version.id) }
|
79
|
+
|
80
|
+
it "deletes the tag" do
|
81
|
+
expect{ subject }.to change { PactBroker::Domain::Tag.count }.by(-2)
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
65
86
|
end
|
66
87
|
end
|
67
|
-
end
|
88
|
+
end
|
@@ -24,6 +24,22 @@ module PactBroker
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
+
describe "#delete_by_id" do
|
28
|
+
let!(:version) do
|
29
|
+
ProviderStateBuilder.new
|
30
|
+
.create_consumer
|
31
|
+
.create_consumer_version("1.2.3")
|
32
|
+
.create_consumer_version("4.5.6")
|
33
|
+
.and_return(:consumer_version)
|
34
|
+
end
|
35
|
+
|
36
|
+
subject { Repository.new.delete_by_id version.id }
|
37
|
+
|
38
|
+
it "deletes the version" do
|
39
|
+
expect { subject }.to change{ PactBroker::Domain::Version.count }.by(-1)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
27
43
|
describe "#find_by_pacticipant_name_and_number" do
|
28
44
|
|
29
45
|
subject { described_class.new.find_by_pacticipant_name_and_number pacticipant_name, version_number }
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'pact_broker/versions/service'
|
2
|
+
|
3
|
+
module PactBroker
|
4
|
+
|
5
|
+
module Versions
|
6
|
+
describe Service do
|
7
|
+
|
8
|
+
describe ".delete" do
|
9
|
+
let!(:version) do
|
10
|
+
ProviderStateBuilder.new
|
11
|
+
.create_consumer
|
12
|
+
.create_provider
|
13
|
+
.create_consumer_version("1.2.3")
|
14
|
+
.create_consumer_version_tag("prod")
|
15
|
+
.create_pact
|
16
|
+
.and_return(:consumer_version)
|
17
|
+
end
|
18
|
+
|
19
|
+
subject { Service.delete(version) }
|
20
|
+
|
21
|
+
it "deletes the pact publication" do
|
22
|
+
expect{ subject }.to change { PactBroker::Pacts::PactPublication.count }.by(-1)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "deletes the tags" do
|
26
|
+
expect{ subject }.to change { PactBroker::Domain::Tag.count }.by(-1)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "deletes the version" do
|
30
|
+
expect{ subject }.to change { PactBroker::Domain::Version.count }.by(-1)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'tasks/database'
|
2
|
+
require 'rack/pact_broker/database_transaction'
|
3
|
+
|
4
|
+
module Rack
|
5
|
+
module PactBroker
|
6
|
+
describe DatabaseTransaction, no_db_clean: true do
|
7
|
+
|
8
|
+
before do
|
9
|
+
::PactBroker::Database.truncate
|
10
|
+
end
|
11
|
+
|
12
|
+
after do
|
13
|
+
::PactBroker::Database.truncate
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:api) do
|
17
|
+
->(env) { ::PactBroker::Domain::Pacticipant.create(name: 'Foo'); [500, {}, []] }
|
18
|
+
end
|
19
|
+
|
20
|
+
let(:api_with_transaction) do
|
21
|
+
::Rack::PactBroker::DatabaseTransaction.new(api, ::PactBroker::DB.connection)
|
22
|
+
end
|
23
|
+
|
24
|
+
subject { self.send(http_method, "/") }
|
25
|
+
|
26
|
+
context "for get requests" do
|
27
|
+
let(:app) { api_with_transaction }
|
28
|
+
|
29
|
+
let(:http_method) { :get }
|
30
|
+
it "does not use a transaction" do
|
31
|
+
expect { subject }.to change { ::PactBroker::Domain::Pacticipant.count }.by(1)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
[:post, :put, :patch, :delete].each do | http_meth |
|
36
|
+
let(:http_method) { http_meth }
|
37
|
+
context "for #{http_meth} requests" do
|
38
|
+
it "uses a transaction and rollsback if there is a 500 error" do
|
39
|
+
expect { subject }.to change { ::PactBroker::Domain::Pacticipant.count }.by(0)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'rack/pact_broker/invalid_uri_protection'
|
2
|
+
|
3
|
+
module Rack
|
4
|
+
module PactBroker
|
5
|
+
describe InvalidUriProtection do
|
6
|
+
|
7
|
+
let(:app) { InvalidUriProtection.new(->(env){ [200,{},[]] }) }
|
8
|
+
|
9
|
+
subject { get "/badpath"; last_response }
|
10
|
+
|
11
|
+
context "with a URI that the Ruby default URI library cannot parse" do
|
12
|
+
|
13
|
+
before do
|
14
|
+
# Can't use or stub URI.parse because rack test uses it to execute the actual test
|
15
|
+
allow_any_instance_of(InvalidUriProtection).to receive(:parse).and_raise(URI::InvalidURIError)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "returns a 404" do
|
19
|
+
expect(subject.status).to eq 404
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "when the URI can be parsed" do
|
24
|
+
it "passes the request to the underlying app" do
|
25
|
+
expect(subject.status).to eq 200
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -5,6 +5,7 @@ $: << File.expand_path("../../", __FILE__)
|
|
5
5
|
require 'rack/test'
|
6
6
|
require 'db'
|
7
7
|
require 'pact_broker/api'
|
8
|
+
require 'tasks/database'
|
8
9
|
require 'rspec/its'
|
9
10
|
|
10
11
|
Dir.glob("./spec/support/**/*.rb") { |file| require file }
|
@@ -14,7 +15,7 @@ I18n.config.enforce_available_locales = false
|
|
14
15
|
RSpec.configure do | config |
|
15
16
|
config.before :suite do
|
16
17
|
raise "Wrong environment!!! Don't run this script!! ENV['RACK_ENV'] is #{ENV['RACK_ENV']} and RACK_ENV is #{RACK_ENV}" if ENV['RACK_ENV'] != 'test' || RACK_ENV != 'test'
|
17
|
-
PactBroker::DB.connection = DB::PACT_BROKER_DB
|
18
|
+
PactBroker::DB.connection = PactBroker::Database.database = DB::PACT_BROKER_DB
|
18
19
|
end
|
19
20
|
|
20
21
|
config.include Rack::Test::Methods
|
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.0.
|
4
|
+
version: 2.0.1
|
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: 2017-05-
|
13
|
+
date: 2017-05-19 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: httparty
|
@@ -234,6 +234,20 @@ dependencies:
|
|
234
234
|
- - "~>"
|
235
235
|
- !ruby/object:Gem::Version
|
236
236
|
version: '2.0'
|
237
|
+
- !ruby/object:Gem::Dependency
|
238
|
+
name: rack-protection
|
239
|
+
requirement: !ruby/object:Gem::Requirement
|
240
|
+
requirements:
|
241
|
+
- - "~>"
|
242
|
+
- !ruby/object:Gem::Version
|
243
|
+
version: '1.5'
|
244
|
+
type: :runtime
|
245
|
+
prerelease: false
|
246
|
+
version_requirements: !ruby/object:Gem::Requirement
|
247
|
+
requirements:
|
248
|
+
- - "~>"
|
249
|
+
- !ruby/object:Gem::Version
|
250
|
+
version: '1.5'
|
237
251
|
- !ruby/object:Gem::Dependency
|
238
252
|
name: sqlite3
|
239
253
|
requirement: !ruby/object:Gem::Requirement
|
@@ -534,6 +548,8 @@ files:
|
|
534
548
|
- lib/pact_broker/doc/views/self.markdown
|
535
549
|
- lib/pact_broker/doc/views/tag-prod-version.markdown
|
536
550
|
- lib/pact_broker/doc/views/tag-version.markdown
|
551
|
+
- lib/pact_broker/doc/views/webhooks-create.markdown
|
552
|
+
- lib/pact_broker/doc/views/webhooks-webhooks.markdown
|
537
553
|
- lib/pact_broker/doc/views/webhooks.markdown
|
538
554
|
- lib/pact_broker/domain.rb
|
539
555
|
- lib/pact_broker/domain/group.rb
|
@@ -607,6 +623,8 @@ files:
|
|
607
623
|
- lib/rack/hal_browser/redirect.rb
|
608
624
|
- lib/rack/pact_broker/add_pact_broker_version_header.rb
|
609
625
|
- lib/rack/pact_broker/convert_file_extension_to_accept_header.rb
|
626
|
+
- lib/rack/pact_broker/database_transaction.rb
|
627
|
+
- lib/rack/pact_broker/invalid_uri_protection.rb
|
610
628
|
- pact_broker.gemspec
|
611
629
|
- pact_broker_client-pact_broker.json
|
612
630
|
- public/Network Graph_files/d3.v3.js
|
@@ -643,6 +661,7 @@ files:
|
|
643
661
|
- script/update-hal-browser
|
644
662
|
- spec/features/create_webhook_spec.rb
|
645
663
|
- spec/features/delete_pact_spec.rb
|
664
|
+
- spec/features/delete_version_spec.rb
|
646
665
|
- spec/features/get_diff_spec.rb
|
647
666
|
- spec/features/get_pact_spec.rb
|
648
667
|
- spec/features/get_pact_versions_spec.rb
|
@@ -744,11 +763,14 @@ files:
|
|
744
763
|
- spec/lib/pact_broker/verifications/summary_for_consumer_version_spec.rb
|
745
764
|
- spec/lib/pact_broker/versions/parse_semantic_version_spec.rb
|
746
765
|
- spec/lib/pact_broker/versions/repository_spec.rb
|
766
|
+
- spec/lib/pact_broker/versions/service_spec.rb
|
747
767
|
- spec/lib/pact_broker/webhooks/job_spec.rb
|
748
768
|
- spec/lib/pact_broker/webhooks/repository_spec.rb
|
749
769
|
- spec/lib/pact_broker/webhooks/service_spec.rb
|
750
770
|
- spec/lib/rack/hal_browser/redirect_spec.rb
|
751
771
|
- spec/lib/rack/pact_broker/add_pact_broker_version_header_spec.rb
|
772
|
+
- spec/lib/rack/pact_broker/database_transaction_spec.rb
|
773
|
+
- spec/lib/rack/pact_broker/invalid_uri_protection_spec.rb
|
752
774
|
- spec/migrations/23_pact_versions_spec.rb
|
753
775
|
- spec/migrations/24_populate_pact_contents_spec.rb
|
754
776
|
- spec/migrations/34_latest_tagged_pacts_spec.rb
|
@@ -830,6 +852,7 @@ summary: See description
|
|
830
852
|
test_files:
|
831
853
|
- spec/features/create_webhook_spec.rb
|
832
854
|
- spec/features/delete_pact_spec.rb
|
855
|
+
- spec/features/delete_version_spec.rb
|
833
856
|
- spec/features/get_diff_spec.rb
|
834
857
|
- spec/features/get_pact_spec.rb
|
835
858
|
- spec/features/get_pact_versions_spec.rb
|
@@ -931,11 +954,14 @@ test_files:
|
|
931
954
|
- spec/lib/pact_broker/verifications/summary_for_consumer_version_spec.rb
|
932
955
|
- spec/lib/pact_broker/versions/parse_semantic_version_spec.rb
|
933
956
|
- spec/lib/pact_broker/versions/repository_spec.rb
|
957
|
+
- spec/lib/pact_broker/versions/service_spec.rb
|
934
958
|
- spec/lib/pact_broker/webhooks/job_spec.rb
|
935
959
|
- spec/lib/pact_broker/webhooks/repository_spec.rb
|
936
960
|
- spec/lib/pact_broker/webhooks/service_spec.rb
|
937
961
|
- spec/lib/rack/hal_browser/redirect_spec.rb
|
938
962
|
- spec/lib/rack/pact_broker/add_pact_broker_version_header_spec.rb
|
963
|
+
- spec/lib/rack/pact_broker/database_transaction_spec.rb
|
964
|
+
- spec/lib/rack/pact_broker/invalid_uri_protection_spec.rb
|
939
965
|
- spec/migrations/23_pact_versions_spec.rb
|
940
966
|
- spec/migrations/24_populate_pact_contents_spec.rb
|
941
967
|
- spec/migrations/34_latest_tagged_pacts_spec.rb
|