pact_broker 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -0
- data/README.md +8 -11
- data/lib/pact_broker/api.rb +2 -0
- data/lib/pact_broker/api/decorators/decorator_context.rb +8 -1
- data/lib/pact_broker/api/decorators/pact_decorator.rb +18 -3
- data/lib/pact_broker/api/decorators/pact_version_decorator.rb +39 -0
- data/lib/pact_broker/api/decorators/pact_versions_decorator.rb +48 -0
- data/lib/pact_broker/api/decorators/pacticipant_decorator.rb +3 -3
- data/lib/pact_broker/api/decorators/webhook_decorator.rb +1 -1
- data/lib/pact_broker/api/decorators/webhook_execution_result_decorator.rb +1 -1
- data/lib/pact_broker/api/decorators/webhooks_decorator.rb +1 -1
- data/lib/pact_broker/api/pact_broker_urls.rb +16 -6
- data/lib/pact_broker/api/renderers/html_pact_renderer.rb +35 -6
- data/lib/pact_broker/api/resources/base_resource.rb +80 -33
- data/lib/pact_broker/api/resources/group.rb +26 -24
- data/lib/pact_broker/api/resources/index.rb +52 -51
- data/lib/pact_broker/api/resources/latest_pact.rb +22 -22
- data/lib/pact_broker/api/resources/latest_pacts.rb +18 -17
- data/lib/pact_broker/api/resources/pact.rb +34 -39
- data/lib/pact_broker/api/resources/pact_versions.rb +35 -0
- data/lib/pact_broker/api/resources/pact_webhooks.rb +54 -61
- data/lib/pact_broker/api/resources/pacticipant.rb +40 -39
- data/lib/pact_broker/api/resources/pacticipant_resource_methods.rb +19 -0
- data/lib/pact_broker/api/resources/pacticipants.rb +52 -17
- data/lib/pact_broker/api/resources/relationships.rb +18 -17
- data/lib/pact_broker/api/resources/tag.rb +30 -29
- data/lib/pact_broker/api/resources/webhook.rb +29 -28
- data/lib/pact_broker/api/resources/webhook_execution.rb +0 -1
- data/lib/pact_broker/api/resources/webhook_resource_methods.rb +24 -0
- data/lib/pact_broker/api/resources/webhooks.rb +18 -17
- data/lib/pact_broker/app.rb +1 -0
- data/lib/pact_broker/configuration.rb +2 -2
- data/lib/pact_broker/doc/views/webhooks.markdown +1 -1
- data/lib/pact_broker/functions/find_potential_duplicate_pacticipant_names.rb +43 -0
- data/lib/pact_broker/locale/en.yml +7 -0
- data/lib/pact_broker/messages.rb +20 -1
- data/lib/pact_broker/models/pact.rb +8 -0
- data/lib/pact_broker/models/pacticipant.rb +9 -0
- data/lib/pact_broker/models/version.rb +1 -0
- data/lib/pact_broker/repositories/pact_repository.rb +6 -0
- data/lib/pact_broker/repositories/pacticipant_repository.rb +4 -0
- data/lib/pact_broker/repositories/webhook_repository.rb +2 -3
- data/lib/pact_broker/services/pact_service.rb +20 -0
- data/lib/pact_broker/services/pacticipant_service.rb +28 -0
- data/lib/pact_broker/services/webhook_service.rb +7 -2
- data/lib/pact_broker/version.rb +1 -1
- data/pact_broker.gemspec +1 -1
- data/public/stylesheets/github.css +1 -1
- data/public/stylesheets/pact.css +12 -0
- data/spec/lib/pact_broker/api/decorators/pact_decorator_spec.rb +10 -0
- data/spec/lib/pact_broker/api/decorators/pact_version_decorator_spec.rb +49 -0
- data/spec/lib/pact_broker/api/renderers/html_pact_renderer_spec.rb +9 -1
- data/spec/lib/pact_broker/api/resources/group_spec.rb +1 -1
- data/spec/lib/pact_broker/api/resources/latest_pact_spec.rb +1 -1
- data/spec/lib/pact_broker/api/resources/pact_spec.rb +35 -6
- data/spec/lib/pact_broker/api/resources/pact_webhooks_spec.rb +6 -4
- data/spec/lib/pact_broker/api/resources/pacticipants_spec.rb +91 -0
- data/spec/lib/pact_broker/configuration_spec.rb +3 -3
- data/spec/lib/pact_broker/functions/find_potential_duplicate_pacticipant_names_spec.rb +82 -0
- data/spec/lib/pact_broker/messages_spec.rb +31 -0
- data/spec/lib/pact_broker/models/pacticipant_spec.rb +32 -0
- data/spec/lib/pact_broker/repositories/pact_repository_spec.rb +29 -0
- data/spec/lib/pact_broker/repositories/pacticipant_repository_spec.rb +29 -0
- data/spec/lib/pact_broker/repositories/webhook_repository_spec.rb +7 -18
- data/spec/lib/pact_broker/services/pact_service_spec.rb +20 -0
- data/spec/lib/pact_broker/services/pacticipant_service_spec.rb +87 -2
- data/spec/support/provider_state_builder.rb +7 -7
- data/tasks/rspec.rake +1 -1
- metadata +27 -2
@@ -1,38 +1,40 @@
|
|
1
1
|
require 'pact_broker/api/resources/base_resource'
|
2
2
|
require 'pact_broker/api/decorators/relationships_csv_decorator'
|
3
3
|
|
4
|
-
module PactBroker
|
4
|
+
module PactBroker
|
5
5
|
|
6
|
-
module
|
6
|
+
module Api
|
7
|
+
module Resources
|
7
8
|
|
8
|
-
|
9
|
+
class Group < BaseResource
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
11
|
+
def content_types_provided
|
12
|
+
[["text/csv", :to_csv]]
|
13
|
+
end
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
15
|
+
def allowed_methods
|
16
|
+
["GET"]
|
17
|
+
end
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
19
|
+
def to_csv
|
20
|
+
generate_csv(group_service.find_group_containing @pacticipant)
|
21
|
+
end
|
21
22
|
|
22
|
-
|
23
|
-
|
24
|
-
|
23
|
+
def generate_csv group
|
24
|
+
PactBroker::Api::Decorators::RelationshipsCsvDecorator.new(group).to_csv
|
25
|
+
end
|
25
26
|
|
26
|
-
|
27
|
-
|
28
|
-
|
27
|
+
def pacticipant_name
|
28
|
+
identifier_from_path[:pacticipant_name]
|
29
|
+
end
|
29
30
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
31
|
+
def resource_exists?
|
32
|
+
@pacticipant = pacticipant_service.find_pacticipant_by_name(pacticipant_name)
|
33
|
+
@pacticipant != nil
|
34
|
+
end
|
34
35
|
|
36
|
+
end
|
35
37
|
end
|
36
|
-
end
|
37
38
|
|
38
|
-
end
|
39
|
+
end
|
40
|
+
end
|
@@ -1,59 +1,60 @@
|
|
1
1
|
require 'pact_broker/api/resources/base_resource'
|
2
2
|
require 'json'
|
3
3
|
|
4
|
-
module PactBroker
|
4
|
+
module PactBroker
|
5
|
+
module Api
|
6
|
+
module Resources
|
7
|
+
|
8
|
+
class Index < BaseResource
|
9
|
+
|
10
|
+
def content_types_provided
|
11
|
+
[["application/hal+json", :to_json]]
|
12
|
+
end
|
13
|
+
|
14
|
+
def allowed_methods
|
15
|
+
["GET"]
|
16
|
+
end
|
17
|
+
|
18
|
+
# TODO change to use request.base_url to avoid params getting included!!!
|
19
|
+
def to_json
|
20
|
+
{
|
21
|
+
_links: {
|
22
|
+
'pb:self' =>
|
23
|
+
{
|
24
|
+
href: request.uri.to_s,
|
25
|
+
title: 'The Pact Broker index page',
|
26
|
+
templated: false
|
27
|
+
},
|
28
|
+
'pb:latest-pacts' =>
|
29
|
+
{
|
30
|
+
href: request.uri.to_s + 'pacts/latest',
|
31
|
+
title: 'Retrieve latest pacts',
|
32
|
+
templated: false
|
33
|
+
},
|
34
|
+
'pb:pacticipants' =>
|
35
|
+
{
|
36
|
+
href: request.uri.to_s + 'pacticipants',
|
37
|
+
title: 'Retrieve pacticipants',
|
38
|
+
templated: false
|
39
|
+
},
|
40
|
+
'pb:webhooks' =>
|
41
|
+
{
|
42
|
+
href: request.uri.to_s + 'webhooks',
|
43
|
+
title: 'Webhooks',
|
44
|
+
templated: false
|
45
|
+
},'curies' =>
|
46
|
+
[{
|
47
|
+
name: 'pb',
|
48
|
+
href: request.uri.to_s + 'doc/{rel}',
|
49
|
+
templated: true
|
50
|
+
}]
|
51
|
+
}
|
52
|
+
}.to_json
|
53
|
+
end
|
5
54
|
|
6
|
-
module Resources
|
7
55
|
|
8
|
-
class Index < BaseResource
|
9
|
-
|
10
|
-
def content_types_provided
|
11
|
-
[["application/hal+json", :to_json]]
|
12
|
-
end
|
13
|
-
|
14
|
-
def allowed_methods
|
15
|
-
["GET"]
|
16
|
-
end
|
17
|
-
|
18
|
-
# TODO change to use request.base_url to avoid params getting included!!!
|
19
|
-
def to_json
|
20
|
-
{
|
21
|
-
_links: {
|
22
|
-
'pb:self' =>
|
23
|
-
{
|
24
|
-
href: request.uri.to_s,
|
25
|
-
title: 'The Pact Broker index page',
|
26
|
-
templated: false
|
27
|
-
},
|
28
|
-
'pb:latest-pacts' =>
|
29
|
-
{
|
30
|
-
href: request.uri.to_s + 'pacts/latest',
|
31
|
-
title: 'Retrieve latest pacts',
|
32
|
-
templated: false
|
33
|
-
},
|
34
|
-
'pb:pacticipants' =>
|
35
|
-
{
|
36
|
-
href: request.uri.to_s + 'pacticipants',
|
37
|
-
title: 'Retrieve pacticipants',
|
38
|
-
templated: false
|
39
|
-
},
|
40
|
-
'pb:webhooks' =>
|
41
|
-
{
|
42
|
-
href: request.uri.to_s + 'webhooks',
|
43
|
-
title: 'Webhooks',
|
44
|
-
templated: false
|
45
|
-
},'curies' =>
|
46
|
-
[{
|
47
|
-
name: 'pb',
|
48
|
-
href: request.uri.to_s + 'doc/{rel}',
|
49
|
-
templated: true
|
50
|
-
}]
|
51
|
-
}
|
52
|
-
}.to_json
|
53
56
|
end
|
54
|
-
|
55
|
-
|
56
57
|
end
|
57
|
-
end
|
58
58
|
|
59
|
-
end
|
59
|
+
end
|
60
|
+
end
|
@@ -1,36 +1,36 @@
|
|
1
1
|
require 'pact_broker/api/resources/base_resource'
|
2
2
|
require 'pact_broker/configuration'
|
3
3
|
|
4
|
-
module PactBroker
|
4
|
+
module PactBroker
|
5
|
+
module Api
|
6
|
+
module Resources
|
5
7
|
|
6
|
-
|
8
|
+
class LatestPact < BaseResource
|
7
9
|
|
8
|
-
|
10
|
+
def content_types_provided
|
11
|
+
[["application/json", :to_json],
|
12
|
+
["text/html", :to_html]]
|
13
|
+
end
|
9
14
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
end
|
15
|
+
def allowed_methods
|
16
|
+
["GET"]
|
17
|
+
end
|
14
18
|
|
15
|
-
|
16
|
-
|
17
|
-
|
19
|
+
def resource_exists?
|
20
|
+
@pact = pact_service.find_latest_pact(identifier_from_path)
|
21
|
+
@pact != nil
|
22
|
+
end
|
18
23
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
24
|
+
def to_json
|
25
|
+
response.headers['X-Pact-Consumer-Version'] = @pact.consumer_version_number
|
26
|
+
PactBroker::Api::Decorators::PactDecorator.new(@pact).to_json(base_url: base_url)
|
27
|
+
end
|
23
28
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
end
|
29
|
+
def to_html
|
30
|
+
PactBroker.configuration.html_pact_renderer.call(@pact)
|
31
|
+
end
|
28
32
|
|
29
|
-
def to_html
|
30
|
-
PactBroker.configuration.html_pact_renderer.call(@pact.json_content)
|
31
33
|
end
|
32
|
-
|
33
34
|
end
|
34
35
|
end
|
35
|
-
|
36
36
|
end
|
@@ -1,28 +1,29 @@
|
|
1
1
|
require 'pact_broker/api/resources/base_resource'
|
2
2
|
|
3
|
-
module PactBroker
|
3
|
+
module PactBroker
|
4
|
+
module Api
|
5
|
+
module Resources
|
4
6
|
|
5
|
-
|
7
|
+
class LatestPacts < BaseResource
|
6
8
|
|
7
|
-
|
9
|
+
def content_types_provided
|
10
|
+
[["application/hal+json", :to_json]]
|
11
|
+
end
|
8
12
|
|
9
|
-
|
10
|
-
|
11
|
-
|
13
|
+
def allowed_methods
|
14
|
+
["GET"]
|
15
|
+
end
|
12
16
|
|
13
|
-
|
14
|
-
|
15
|
-
|
17
|
+
def to_json
|
18
|
+
generate_json(pact_service.find_latest_pacts)
|
19
|
+
end
|
16
20
|
|
17
|
-
|
18
|
-
|
19
|
-
|
21
|
+
def generate_json pacts
|
22
|
+
PactBroker::Api::Decorators::PactCollectionDecorator.new(pacts).to_json(base_url: base_url)
|
23
|
+
end
|
20
24
|
|
21
|
-
def generate_json pacts
|
22
|
-
PactBroker::Api::Decorators::PactCollectionDecorator.new(pacts).to_json(base_url: base_url)
|
23
25
|
end
|
24
|
-
|
25
26
|
end
|
26
|
-
end
|
27
27
|
|
28
|
-
end
|
28
|
+
end
|
29
|
+
end
|
@@ -1,60 +1,55 @@
|
|
1
1
|
require 'cgi'
|
2
2
|
require 'pact_broker/api/resources/base_resource'
|
3
|
+
require 'pact_broker/api/resources/pacticipant_resource_methods'
|
3
4
|
require 'pact_broker/api/decorators/pact_decorator'
|
4
5
|
require 'pact_broker/json'
|
5
6
|
|
6
|
-
module PactBroker
|
7
|
+
module PactBroker
|
7
8
|
|
8
|
-
module
|
9
|
+
module Api
|
10
|
+
module Resources
|
9
11
|
|
10
|
-
|
12
|
+
class Pact < BaseResource
|
11
13
|
|
12
|
-
|
13
|
-
[["application/json", :to_json]]
|
14
|
-
end
|
14
|
+
include PacticipantResourceMethods
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
def content_types_provided
|
17
|
+
[["application/json", :to_json]]
|
18
|
+
end
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
def content_types_accepted
|
21
|
+
[["application/json", :from_json]]
|
22
|
+
end
|
23
|
+
|
24
|
+
def allowed_methods
|
25
|
+
["GET", "PUT"]
|
26
|
+
end
|
23
27
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
+
def malformed_request?
|
29
|
+
if request.put?
|
30
|
+
return invalid_json? ||
|
31
|
+
potential_duplicate_pacticipants?([identifier_from_path[:consumer_name], identifier_from_path[:provider_name]])
|
32
|
+
else
|
28
33
|
false
|
29
|
-
rescue StandardError => e
|
30
|
-
logger.error "Error parsing JSON #{e} - #{pact_content}"
|
31
|
-
response.headers['Content-Type'] = 'application/json'
|
32
|
-
response.body = {error: "Invalid JSON - #{e.message}"}.to_json
|
33
|
-
true
|
34
34
|
end
|
35
35
|
end
|
36
|
-
end
|
37
36
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
37
|
+
def resource_exists?
|
38
|
+
@pact = pact_service.find_pact(identifier_from_path)
|
39
|
+
@pact != nil
|
40
|
+
end
|
42
41
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
42
|
+
def from_json
|
43
|
+
@pact, created = pact_service.create_or_update_pact(identifier_from_path.merge(:json_content => request_body))
|
44
|
+
response.headers["Location"] = pact_url(base_url, @pact) if created
|
45
|
+
response.body = to_json
|
46
|
+
end
|
48
47
|
|
49
|
-
|
50
|
-
|
51
|
-
|
48
|
+
def to_json
|
49
|
+
PactBroker::Api::Decorators::PactDecorator.new(@pact).to_json(base_url: base_url)
|
50
|
+
end
|
52
51
|
|
53
|
-
def pact_content
|
54
|
-
request.body.to_s
|
55
52
|
end
|
56
|
-
|
57
53
|
end
|
58
54
|
end
|
59
|
-
|
60
|
-
end
|
55
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'pact_broker/api/resources/base_resource'
|
2
|
+
require 'pact_broker/configuration'
|
3
|
+
require 'pact_broker/api/decorators/pact_versions_decorator'
|
4
|
+
|
5
|
+
module PactBroker
|
6
|
+
module Api
|
7
|
+
module Resources
|
8
|
+
|
9
|
+
class PactVersions < BaseResource
|
10
|
+
|
11
|
+
def content_types_provided
|
12
|
+
[["application/json", :to_json]]
|
13
|
+
end
|
14
|
+
|
15
|
+
def allowed_methods
|
16
|
+
["GET"]
|
17
|
+
end
|
18
|
+
|
19
|
+
def resource_exists?
|
20
|
+
pacticipant_service.find_pacticipant_by_name(consumer_name) &&
|
21
|
+
pacticipant_service.find_pacticipant_by_name(provider_name)
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_json
|
25
|
+
PactBroker::Api::Decorators::PactVersionsDecorator.new(pacts).to_json(decorator_context(identifier_from_path))
|
26
|
+
end
|
27
|
+
|
28
|
+
def pacts
|
29
|
+
pact_service.find_all_pacts_between consumer_name, :and => provider_name
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -3,85 +3,78 @@ require 'pact_broker/api/resources/base_resource'
|
|
3
3
|
require 'pact_broker/api/decorators/webhook_decorator'
|
4
4
|
require 'pact_broker/api/decorators/webhooks_decorator'
|
5
5
|
|
6
|
-
module PactBroker
|
6
|
+
module PactBroker
|
7
7
|
|
8
|
-
module
|
8
|
+
module Api
|
9
|
+
module Resources
|
9
10
|
|
10
|
-
|
11
|
+
class PactWebhooks < BaseResource
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
13
|
+
def allowed_methods
|
14
|
+
["POST", "GET"]
|
15
|
+
end
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
|
17
|
+
def content_types_provided
|
18
|
+
[["application/hal+json", :to_json]]
|
19
|
+
end
|
19
20
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
21
|
+
def content_types_accepted
|
22
|
+
[["application/json", :from_json]]
|
23
|
+
end
|
24
|
+
|
25
|
+
def resource_exists?
|
26
|
+
(@consumer = find_pacticipant(identifier_from_path[:consumer_name], "consumer")) &&
|
27
|
+
(@provider = find_pacticipant(identifier_from_path[:provider_name], "provider"))
|
28
|
+
end
|
24
29
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
if (errors = webhook.validate).any?
|
29
|
-
set_json_validation_error_messages errors
|
30
|
-
return true
|
31
|
-
end
|
32
|
-
rescue
|
33
|
-
set_json_error_message 'Invalid JSON'
|
34
|
-
return true
|
30
|
+
def malformed_request?
|
31
|
+
if request.post?
|
32
|
+
return invalid_json? || validation_errors?(webhook)
|
35
33
|
end
|
34
|
+
false
|
36
35
|
end
|
37
|
-
false
|
38
|
-
end
|
39
36
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
response.headers['Location'] = webhook_url saved_webhook, base_url
|
44
|
-
response.body = Decorators::WebhookDecorator.new(saved_webhook).to_json(base_url: base_url)
|
45
|
-
true
|
46
|
-
end
|
37
|
+
def create_path
|
38
|
+
webhook_url next_uuid, base_url
|
39
|
+
end
|
47
40
|
|
48
|
-
|
49
|
-
|
50
|
-
|
41
|
+
def post_is_create?
|
42
|
+
true
|
43
|
+
end
|
51
44
|
|
52
|
-
|
45
|
+
def from_json
|
46
|
+
saved_webhook = webhook_service.create next_uuid, webhook, consumer, provider
|
47
|
+
response.body = Decorators::WebhookDecorator.new(saved_webhook).to_json(base_url: base_url)
|
48
|
+
true
|
49
|
+
end
|
53
50
|
|
54
|
-
|
51
|
+
def to_json
|
52
|
+
Decorators::WebhooksDecorator.new(webhooks).to_json(decorator_context(resource_title: 'Pact webhooks'))
|
53
|
+
end
|
55
54
|
|
56
|
-
|
57
|
-
webhook_service.find_by_consumer_and_provider consumer, provider
|
58
|
-
end
|
55
|
+
private
|
59
56
|
|
60
|
-
|
61
|
-
@webhook ||= Decorators::WebhookDecorator.new(PactBroker::Models::Webhook.new).from_json(request.body.to_s)
|
62
|
-
end
|
57
|
+
attr_reader :consumer, :provider
|
63
58
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
end
|
59
|
+
def webhooks
|
60
|
+
webhook_service.find_by_consumer_and_provider consumer, provider
|
61
|
+
end
|
68
62
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
end
|
63
|
+
def webhook
|
64
|
+
@webhook ||= Decorators::WebhookDecorator.new(PactBroker::Models::Webhook.new).from_json(request_body)
|
65
|
+
end
|
73
66
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
67
|
+
def next_uuid
|
68
|
+
@next_uuid ||= webhook_service.next_uuid
|
69
|
+
end
|
70
|
+
|
71
|
+
def find_pacticipant name, role
|
72
|
+
pacticipant_service.find_pacticipant_by_name(name).tap do | pacticipant |
|
73
|
+
set_json_error_message("No #{role} with name '#{name}' found") if pacticipant.nil?
|
74
|
+
end
|
81
75
|
end
|
82
|
-
end
|
83
76
|
|
77
|
+
end
|
84
78
|
end
|
85
79
|
end
|
86
|
-
|
87
|
-
end
|
80
|
+
end
|