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.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +18 -0
  3. data/README.md +8 -11
  4. data/lib/pact_broker/api.rb +2 -0
  5. data/lib/pact_broker/api/decorators/decorator_context.rb +8 -1
  6. data/lib/pact_broker/api/decorators/pact_decorator.rb +18 -3
  7. data/lib/pact_broker/api/decorators/pact_version_decorator.rb +39 -0
  8. data/lib/pact_broker/api/decorators/pact_versions_decorator.rb +48 -0
  9. data/lib/pact_broker/api/decorators/pacticipant_decorator.rb +3 -3
  10. data/lib/pact_broker/api/decorators/webhook_decorator.rb +1 -1
  11. data/lib/pact_broker/api/decorators/webhook_execution_result_decorator.rb +1 -1
  12. data/lib/pact_broker/api/decorators/webhooks_decorator.rb +1 -1
  13. data/lib/pact_broker/api/pact_broker_urls.rb +16 -6
  14. data/lib/pact_broker/api/renderers/html_pact_renderer.rb +35 -6
  15. data/lib/pact_broker/api/resources/base_resource.rb +80 -33
  16. data/lib/pact_broker/api/resources/group.rb +26 -24
  17. data/lib/pact_broker/api/resources/index.rb +52 -51
  18. data/lib/pact_broker/api/resources/latest_pact.rb +22 -22
  19. data/lib/pact_broker/api/resources/latest_pacts.rb +18 -17
  20. data/lib/pact_broker/api/resources/pact.rb +34 -39
  21. data/lib/pact_broker/api/resources/pact_versions.rb +35 -0
  22. data/lib/pact_broker/api/resources/pact_webhooks.rb +54 -61
  23. data/lib/pact_broker/api/resources/pacticipant.rb +40 -39
  24. data/lib/pact_broker/api/resources/pacticipant_resource_methods.rb +19 -0
  25. data/lib/pact_broker/api/resources/pacticipants.rb +52 -17
  26. data/lib/pact_broker/api/resources/relationships.rb +18 -17
  27. data/lib/pact_broker/api/resources/tag.rb +30 -29
  28. data/lib/pact_broker/api/resources/webhook.rb +29 -28
  29. data/lib/pact_broker/api/resources/webhook_execution.rb +0 -1
  30. data/lib/pact_broker/api/resources/webhook_resource_methods.rb +24 -0
  31. data/lib/pact_broker/api/resources/webhooks.rb +18 -17
  32. data/lib/pact_broker/app.rb +1 -0
  33. data/lib/pact_broker/configuration.rb +2 -2
  34. data/lib/pact_broker/doc/views/webhooks.markdown +1 -1
  35. data/lib/pact_broker/functions/find_potential_duplicate_pacticipant_names.rb +43 -0
  36. data/lib/pact_broker/locale/en.yml +7 -0
  37. data/lib/pact_broker/messages.rb +20 -1
  38. data/lib/pact_broker/models/pact.rb +8 -0
  39. data/lib/pact_broker/models/pacticipant.rb +9 -0
  40. data/lib/pact_broker/models/version.rb +1 -0
  41. data/lib/pact_broker/repositories/pact_repository.rb +6 -0
  42. data/lib/pact_broker/repositories/pacticipant_repository.rb +4 -0
  43. data/lib/pact_broker/repositories/webhook_repository.rb +2 -3
  44. data/lib/pact_broker/services/pact_service.rb +20 -0
  45. data/lib/pact_broker/services/pacticipant_service.rb +28 -0
  46. data/lib/pact_broker/services/webhook_service.rb +7 -2
  47. data/lib/pact_broker/version.rb +1 -1
  48. data/pact_broker.gemspec +1 -1
  49. data/public/stylesheets/github.css +1 -1
  50. data/public/stylesheets/pact.css +12 -0
  51. data/spec/lib/pact_broker/api/decorators/pact_decorator_spec.rb +10 -0
  52. data/spec/lib/pact_broker/api/decorators/pact_version_decorator_spec.rb +49 -0
  53. data/spec/lib/pact_broker/api/renderers/html_pact_renderer_spec.rb +9 -1
  54. data/spec/lib/pact_broker/api/resources/group_spec.rb +1 -1
  55. data/spec/lib/pact_broker/api/resources/latest_pact_spec.rb +1 -1
  56. data/spec/lib/pact_broker/api/resources/pact_spec.rb +35 -6
  57. data/spec/lib/pact_broker/api/resources/pact_webhooks_spec.rb +6 -4
  58. data/spec/lib/pact_broker/api/resources/pacticipants_spec.rb +91 -0
  59. data/spec/lib/pact_broker/configuration_spec.rb +3 -3
  60. data/spec/lib/pact_broker/functions/find_potential_duplicate_pacticipant_names_spec.rb +82 -0
  61. data/spec/lib/pact_broker/messages_spec.rb +31 -0
  62. data/spec/lib/pact_broker/models/pacticipant_spec.rb +32 -0
  63. data/spec/lib/pact_broker/repositories/pact_repository_spec.rb +29 -0
  64. data/spec/lib/pact_broker/repositories/pacticipant_repository_spec.rb +29 -0
  65. data/spec/lib/pact_broker/repositories/webhook_repository_spec.rb +7 -18
  66. data/spec/lib/pact_broker/services/pact_service_spec.rb +20 -0
  67. data/spec/lib/pact_broker/services/pacticipant_service_spec.rb +87 -2
  68. data/spec/support/provider_state_builder.rb +7 -7
  69. data/tasks/rspec.rake +1 -1
  70. metadata +27 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cedb84e67d02ce7d28e31fdc09aca4c39fa19e98
4
- data.tar.gz: 4fa9e9b2022aa04df878b8cd6769a9d9ad36e1a6
3
+ metadata.gz: eab6ba50f1698c583aa2c5ea2499134dccdf26fe
4
+ data.tar.gz: 90c46d03810fdaba756c7d10528193636913a159
5
5
  SHA512:
6
- metadata.gz: 7f756c1fc77440d7805ceeda97220d64dd1ad1f8f0fd940eb9f2be76f683bc5b7bb3c5ea8e4f6a8fd3a65f9b39951f58faba1537722ac5e6c3ff40b84d6310e5
7
- data.tar.gz: a4ed85b29750424cc833bfe1bec6b43805304f2c006bd61fe0612eabd703a38110317a7a5d74a6900e429337db60def0a344d829ff5436ae05688504ae4ed355
6
+ metadata.gz: 71d627be7fcefa1d267b9e6347bd473aea3fe9b204a2d3235b9a0df7f03701f45ff764a9e235300b3b813ba19027f9bb5b3cca18261e5a2461d8cdf134a142af
7
+ data.tar.gz: 45bebda0fb63072a4fc33c082b1990b1a0ae941e04858624a733aa94a7aab9c51ab6b8bd8a965b350c1128987590ddb4f5fc489ed1bc6e4dfcac68346c5799c8
data/CHANGELOG.md CHANGED
@@ -2,6 +2,24 @@ Do this to generate your change history
2
2
 
3
3
  $ git log --pretty=format:' * %h - %s (%an, %ad)'
4
4
 
5
+ #### 1.2.0 (2014-09-22)
6
+
7
+ * 0ccde50 - Made webhook creation code more Webmachiney. (Beth, Tue Sep 16 10:07:56 2014 +1000)
8
+ * 4c628e5 - Using localtime to display dates. (Beth, Fri Aug 29 13:32:20 2014 +1000)
9
+ * 7d99c51 - Fixed HAL Browser link - page title was stopping it being clickable (Beth, Fri Sep 5 16:41:03 2014 +1000)
10
+ * 8ba3be0 - Updating spec task for latest rspec (Beth, Fri Sep 5 16:40:10 2014 +1000)
11
+ * fcc25eb - Updated pact gem (Beth, Tue Aug 26 18:45:31 2014 +1000)
12
+ * 5d0d3dc - Added pact versions link to the pact response (Beth, Tue Aug 26 07:54:26 2014 +1000)
13
+ * 16971ff - Added method to find distinct pacts between a consumer and provider (Beth, Tue Aug 26 07:41:54 2014 +1000)
14
+ * 4798c09 - Added pact versions endpoint. (Beth, Mon Aug 25 22:23:48 2014 +1000)
15
+ * e1f8c97 - Changed 'Date published' to display pact.updated_at date instead of created_at date (Beth, Mon Aug 25 07:37:58 20
16
+ * 39eac31 - Fixed pact-webhooks rel title (Beth, Sun Aug 24 17:54:05 2014 +1000)
17
+ * f6fc9f7 - Added latest-pact rel to pact representation (Beth, Sun Aug 24 17:51:08 2014 +1000)
18
+ * 08b088c - Added method to pacticipant_service to find potentially duplicated pacticipants (Beth, Sat Aug 23 08:32:34 2014 +
19
+ * 24e8d5d - Adding support for creating a pacticipant through the API (as distinct from it being auto created by publishing a
20
+ * dc4d4aa - Set DB timezone to UTC. (Beth, Thu Aug 21 17:30:41 2014 +1000)
21
+ * 19693fa - Added pact metadata to HTML view (Beth, Thu Aug 21 17:30:23 2014 +1000)
22
+
5
23
  #### 1.1.0 (2014-08-21)
6
24
 
7
25
  * d25395b - Fixed pacts failing to publish because of too deeply nested JSON (Beth, Tue Aug 19 11:13:02 2014 +1000)
data/README.md CHANGED
@@ -2,22 +2,19 @@
2
2
 
3
3
  The Pact Broker provides a repository for pacts created using the pact gem. It solves the problem of how to share pacts between consumer and provider projects.
4
4
 
5
- When a consumer CI build is configured to publish its pacts to a Pact Broker, it allows the provider to always be verified against the latest version of the pact. Once the required development work has been done, it will also allow providers to be verified against the "production" version of a pact, giving confidence when deploying that a new version of a provider will work against the production version of a consumer.
5
+ The Pact Broker:
6
6
 
7
- It provides endpoints for the following:
8
-
9
- * Publish a pact between a provider and a given version of a consumer.
10
- * Retrieve the latest pact between a consumer and a provider.
11
- * View a list of published pacts.
12
- * View a list of "pacticipants" (consumers and providers).
7
+ * Enables pacts to be shared between consumer and provider projects.
8
+ * Displays autogenerated documentation for each pact.
9
+ * Enables a pact to be tagged (ie. "prod") so a provider can verify itself against a fixed version of a pact to ensure backwards compatibility.
10
+ * Provides webhooks to trigger a provider build when a consumer publishes a change to a pact.
11
+ * Displays dynamically generated network diagrams.
13
12
 
14
13
  See the [Pact Broker Client](https://github.com/bethesque/pact_broker-client) for documentation on how to publish a pact to the Pact Broker, and configure the URLs in the provider project.
15
14
 
16
- ### Upcoming development
15
+ ## Documentation
17
16
 
18
- * Create a UI to show a network diagram based on the published pacts.
19
- * Display pacts in HTML format.
20
- * Allow "tagging" of pacts so that the provider can be verified against the production version of a pact.
17
+ See the [wiki](https://github.com/bethesque/pact_broker/wiki) for documentation.
21
18
 
22
19
  ## Usage
23
20
 
@@ -8,6 +8,7 @@ require 'pact_broker/api/resources/index'
8
8
  require 'pact_broker/api/resources/relationships'
9
9
  require 'pact_broker/api/resources/group'
10
10
  require 'pact_broker/api/resources/pact_webhooks'
11
+ require 'pact_broker/api/resources/pact_versions'
11
12
  require 'pact_broker/api/resources/webhooks'
12
13
  require 'pact_broker/api/resources/webhook'
13
14
  require 'pact_broker/api/resources/webhook_execution'
@@ -25,6 +26,7 @@ module PactBroker
25
26
  add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'latest'], Api::Resources::LatestPact
26
27
  add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'latest', :tag], Api::Resources::LatestPact
27
28
  add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'version', :consumer_version_number], Api::Resources::Pact
29
+ add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'versions'], Api::Resources::PactVersions
28
30
  add ['pact', 'provider', :provider_name, 'consumer', :consumer_name, 'version', :consumer_version_number], Api::Resources::Pact
29
31
  add ['pact', 'provider', :provider_name, 'consumer', :consumer_name, 'latest'], Api::Resources::LatestPact
30
32
  add ['pacts', 'latest'], Api::Resources::LatestPacts
@@ -6,13 +6,20 @@ module PactBroker
6
6
 
7
7
  attr_reader :base_url, :resource_url, :resource_title
8
8
 
9
- def initialize base_url, resource_url, options
9
+ def initialize base_url, resource_url, options = {}
10
10
  @base_url = base_url
11
+ self[:base_url] = base_url
11
12
  @resource_url = resource_url
13
+ self[:resource_url] = resource_url
12
14
  @resource_title = options[:resource_title]
15
+ self[:resource_title] = resource_title
13
16
  merge!(options)
14
17
  end
15
18
 
19
+ def to_s
20
+ "DecoratorContext #{super}"
21
+ end
22
+
16
23
  end
17
24
 
18
25
  end
@@ -9,16 +9,31 @@ module PactBroker
9
9
 
10
10
  class PactDecorator < BaseDecorator
11
11
 
12
- property :createdAt, getter: lambda { |_| created_at.xmlschema }
13
- property :updatedAt, getter: lambda { |_| updated_at.xmlschema }
12
+ property :createdAt, getter: lambda { |_| created_at.xmlschema }, writeable: false
13
+ property :updatedAt, getter: lambda { |_| updated_at.xmlschema }, writeable: false
14
14
 
15
15
  def to_hash(options = {})
16
16
  ::JSON.parse(represented.json_content, PACT_PARSING_OPTIONS).merge super
17
17
  end
18
18
 
19
+ link :'latest-pact' do | options |
20
+ {
21
+ title: "Latest version of the pact between #{represented.consumer.name} and #{represented.provider.name}",
22
+ href: latest_pact_url(options.fetch(:base_url), represented)
23
+
24
+ }
25
+ end
26
+
27
+ link :'pact-versions' do | options |
28
+ {
29
+ title: "All versions of the pact between #{represented.consumer.name} and #{represented.provider.name}",
30
+ href: pact_versions_url(represented.consumer.name, represented.provider.name, options.fetch(:base_url))
31
+ }
32
+ end
33
+
19
34
  link :'pact-webhooks' do | options |
20
35
  {
21
- title: 'Webhooks for this pact',
36
+ title: "Webhooks for the pact between #{represented.consumer.name} and #{represented.provider.name}",
22
37
  href: webhooks_for_pact_url(represented.consumer, represented.provider, options.fetch(:base_url))
23
38
  }
24
39
  end
@@ -0,0 +1,39 @@
1
+ require_relative 'base_decorator'
2
+ require_relative 'pact_pacticipant_decorator'
3
+
4
+ module PactBroker
5
+
6
+ module Api
7
+
8
+ module Decorators
9
+
10
+ class EmbeddedVersionDecorator < BaseDecorator
11
+
12
+ property :number
13
+
14
+ link :self do | options |
15
+ version_url(options[:base_url], represented)
16
+ end
17
+ end
18
+
19
+ class PactVersionDecorator < BaseDecorator
20
+
21
+
22
+ property :createdAt, getter: lambda { |_| created_at.to_time.localtime.xmlschema }, writeable: false
23
+ property :updatedAt, getter: lambda { |_| updated_at.to_time.localtime.xmlschema }, writeable: false
24
+
25
+ property :consumer_version, as: :consumerVersion, embedded: true, decorator: EmbeddedVersionDecorator
26
+
27
+
28
+ link :self do | options |
29
+ {
30
+ href: pact_url(options.base_url, represented),
31
+ title: represented.name
32
+ }
33
+
34
+ end
35
+
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,48 @@
1
+ require_relative 'base_decorator'
2
+ require_relative 'pact_version_decorator'
3
+
4
+ module PactBroker
5
+
6
+ module Api
7
+
8
+ module Decorators
9
+
10
+
11
+ class PactVersionsDecorator < BaseDecorator
12
+
13
+ collection :entries, as: :pacts, embedded: true, :extend => PactBroker::Api::Decorators::PactVersionDecorator
14
+
15
+ link :self do | context |
16
+ {
17
+ href: context.resource_url,
18
+ title: "All versions of the pact between #{context[:consumer_name]} and #{context[:provider_name]}"
19
+ }
20
+ end
21
+
22
+ link :consumer do | context |
23
+ {
24
+ href: pacticipant_url(context.base_url, OpenStruct.new(name: context[:consumer_name])),
25
+ title: context[:consumer_name]
26
+ }
27
+ end
28
+
29
+ link :provider do | context |
30
+ {
31
+ href: pacticipant_url(context.base_url, OpenStruct.new(name: context[:provider_name])),
32
+ title: context[:provider_name]
33
+ }
34
+ end
35
+
36
+ links :'pact-versions' do | context |
37
+ represented.collect do | pact |
38
+ {
39
+ :href => pact_url(context.base_url, pact),
40
+ :title => pact.version_and_updated_date
41
+ }
42
+ end
43
+ end
44
+
45
+ end
46
+ end
47
+ end
48
+ end
@@ -11,10 +11,10 @@ module PactBroker
11
11
 
12
12
  property :name
13
13
  property :repository_url, as: :repositoryUrl
14
- property :latest_version, as: :'latest-version', :class => PactBroker::Models::Version, :extend => PactBroker::Api::Decorators::VersionRepresenter, :embedded => true
15
- property :createdAt, getter: lambda { |_| created_at.xmlschema }
16
- property :updatedAt, getter: lambda { |_| updated_at.xmlschema }
17
14
 
15
+ property :latest_version, as: :'latest-version', :class => PactBroker::Models::Version, :extend => PactBroker::Api::Decorators::VersionRepresenter, :embedded => true, writeable: false
16
+ property :createdAt, getter: lambda { |_| created_at.xmlschema }, writeable: false
17
+ property :updatedAt, getter: lambda { |_| updated_at.xmlschema }, writeable: false
18
18
 
19
19
  link :self do | options |
20
20
  pacticipant_url(options[:base_url], represented)
@@ -19,7 +19,7 @@ module PactBroker
19
19
  link :self do | options |
20
20
  {
21
21
  title: represented.description,
22
- href: webhook_url(represented, options[:base_url])
22
+ href: webhook_url(represented.uuid, options[:base_url])
23
23
  }
24
24
 
25
25
  end
@@ -42,7 +42,7 @@ module PactBroker
42
42
 
43
43
  link :webhook do | options |
44
44
  {
45
- href: webhook_url(options.fetch(:webhook), options.fetch(:base_url))
45
+ href: webhook_url(options.fetch(:webhook).uuid, options.fetch(:base_url))
46
46
  }
47
47
  end
48
48
 
@@ -19,7 +19,7 @@ module PactBroker
19
19
  {
20
20
  title: webhook.description,
21
21
  name: webhook.request_description,
22
- href: webhook_url(webhook, context.base_url)
22
+ href: webhook_url(webhook.uuid, context.base_url)
23
23
  }
24
24
  end
25
25
  end
@@ -2,6 +2,8 @@ module PactBroker
2
2
  module Api
3
3
  module PactBrokerUrls
4
4
 
5
+ extend self
6
+
5
7
  def pacticipants_url base_url
6
8
  "#{base_url}/pacticipants"
7
9
  end
@@ -35,6 +37,10 @@ module PactBroker
35
37
  "#{base_url}/pacts/latest"
36
38
  end
37
39
 
40
+ def pact_versions_url consumer_name, provider_name, base_url
41
+ "#{base_url}/pacts/provider/#{url_encode(provider_name)}/consumer/#{url_encode(consumer_name)}/versions"
42
+ end
43
+
38
44
  def tags_url base_url, version
39
45
  "#{version_url(base_url, version)}/tags"
40
46
  end
@@ -47,8 +53,8 @@ module PactBroker
47
53
  "#{base_url}/webhooks"
48
54
  end
49
55
 
50
- def webhook_url webhook, base_url
51
- "#{base_url}/webhooks/#{webhook.uuid}"
56
+ def webhook_url uuid, base_url
57
+ "#{base_url}/webhooks/#{uuid}"
52
58
  end
53
59
 
54
60
  def webhook_execution_url webhook, base_url
@@ -59,6 +65,14 @@ module PactBroker
59
65
  "#{base_url}/webhooks/provider/#{provider.name}/consumer/#{consumer.name}"
60
66
  end
61
67
 
68
+ def hal_browser_url target_url
69
+ "/hal-browser/browser.html#" + target_url
70
+ end
71
+
72
+ def url_encode param
73
+ ERB::Util.url_encode param
74
+ end
75
+
62
76
  private
63
77
 
64
78
  def representable_pact pact
@@ -68,10 +82,6 @@ module PactBroker
68
82
  def pactigration_base_url base_url, pact
69
83
  "#{base_url}/pacts/provider/#{url_encode(pact.provider.name)}/consumer/#{url_encode(pact.consumer.name)}"
70
84
  end
71
-
72
- def url_encode param
73
- ERB::Util.url_encode param
74
- end
75
85
  end
76
86
  end
77
87
  end
@@ -2,28 +2,57 @@ require 'pact/consumer_contract'
2
2
  require 'pact/reification'
3
3
  require 'redcarpet'
4
4
  require 'pact/doc/markdown/consumer_contract_renderer'
5
+ require 'pact_broker/api/pact_broker_urls'
5
6
 
6
7
  module PactBroker
7
8
  module Api
8
9
  module Renderers
9
10
  class HtmlPactRenderer
10
11
 
11
- def self.call json_content
12
- new(json_content).call
12
+ def self.call pact
13
+ new(pact).call
13
14
  end
14
15
 
15
- def initialize json_content
16
- @json_content = json_content
16
+ def initialize pact
17
+ @json_content = pact.json_content
18
+ @pact = pact
17
19
  end
18
20
 
19
21
  def call
20
- "<html><head>#{head}</head><body>#{html}</body></html>"
22
+ "<html><head>#{head}</head><body>#{pact_metadata}#{html}</body></html>"
21
23
  end
22
24
 
23
25
  private
24
26
 
25
27
  def head
26
- '<link rel="stylesheet" type="text/css" href="/stylesheets/github.css">'
28
+ '<link rel="stylesheet" type="text/css" href="/stylesheets/github.css">' + "\n" +
29
+ '<link rel="stylesheet" type="text/css" href="/stylesheets/pact.css">'
30
+ end
31
+
32
+ def pact_metadata
33
+ "<div class='pact-metadata'>
34
+ <ul>
35
+ <li>
36
+ <span class='name'>#{@pact.consumer.name} version:</span>
37
+ <span class='value'>#{@pact.consumer_version_number}</span>
38
+ </li>
39
+ <li>
40
+ <span class='name'>Date published:</span>
41
+ <span class='value'>#{@pact.updated_at.to_time.localtime.to_datetime.strftime("%d/%m/%Y %l:%M%p %:z")}</span>
42
+ </li>
43
+ <li>
44
+ <a href=\"#{json_url}\">View in HAL Browser</a>
45
+ </li>
46
+ </ul>
47
+ </div>"
48
+ end
49
+
50
+ def json_url
51
+ PactBroker::Api::PactBrokerUrls.hal_browser_url pact_url
52
+ end
53
+
54
+ def pact_url
55
+ PactBroker::Api::PactBrokerUrls.pact_url '', @pact
27
56
  end
28
57
 
29
58
  def markdown
@@ -4,55 +4,102 @@ require 'pact_broker/api/decorators'
4
4
  require 'pact_broker/logging'
5
5
  require 'pact_broker/api/pact_broker_urls'
6
6
  require 'pact_broker/api/decorators/decorator_context'
7
+ require 'pact_broker/json'
7
8
 
8
- module PactBroker::Api
9
+ module PactBroker
9
10
 
10
- module Resources
11
+ module Api
12
+ module Resources
11
13
 
14
+ class InvalidJsonError < StandardError ; end
12
15
 
13
- class ErrorHandler
16
+ class ErrorHandler
14
17
 
15
- include PactBroker::Logging
18
+ include PactBroker::Logging
16
19
 
17
- def self.handle_exception e, response
18
- logger.error e
19
- logger.error e.backtrace
20
- response.body = {:message => e.message, :backtrace => e.backtrace }.to_json
21
- response.code = 500
20
+ def self.handle_exception e, response
21
+ logger.error e
22
+ logger.error e.backtrace
23
+ response.body = {:message => e.message, :backtrace => e.backtrace }.to_json
24
+ end
22
25
  end
23
- end
24
26
 
25
- class BaseResource < Webmachine::Resource
27
+ class BaseResource < Webmachine::Resource
26
28
 
27
- include PactBroker::Services
28
- include PactBroker::Api::PactBrokerUrls
29
- include PactBroker::Logging
29
+ include PactBroker::Services
30
+ include PactBroker::Api::PactBrokerUrls
31
+ include PactBroker::Logging
30
32
 
31
- def identifier_from_path
32
- request.path_info.each_with_object({}) do | pair, hash|
33
- hash[pair.first] = CGI::unescape(pair.last)
33
+ def identifier_from_path
34
+ request.path_info.each_with_object({}) do | pair, hash|
35
+ hash[pair.first] = URI.decode(pair.last)
36
+ end
34
37
  end
35
- end
36
38
 
37
- # This should be called base_url
38
- def base_url
39
- request.uri.to_s.gsub(/#{request.uri.path}$/,'')
40
- end
39
+ # This should be called base_url
40
+ def base_url
41
+ request.uri.to_s.gsub(/#{request.uri.path}$/,'')
42
+ end
41
43
 
42
- def resource_url
43
- request.uri.to_s
44
- end
44
+ def resource_url
45
+ request.uri.to_s
46
+ end
45
47
 
46
- def decorator_context options = {}
47
- Decorators::DecoratorContext.new(base_url, resource_url, options)
48
- end
48
+ def decorator_context options = {}
49
+ Decorators::DecoratorContext.new(base_url, resource_url, options)
50
+ end
49
51
 
50
- def handle_exception e
51
- PactBroker::Api::Resources::ErrorHandler.handle_exception(e, response)
52
- end
52
+ def handle_exception e
53
+ PactBroker::Api::Resources::ErrorHandler.handle_exception(e, response)
54
+ end
55
+
56
+ def params
57
+ @params ||= JSON.parse(request.body.to_s, {symbolize_names: true}.merge(PACT_PARSING_OPTIONS))
58
+ end
59
+
60
+ def set_json_error_message message
61
+ response.headers['Content-Type'] = 'application/json'
62
+ response.body = {error: message}.to_json
63
+ end
64
+
65
+ def set_json_validation_error_messages errors
66
+ response.headers['Content-Type'] = 'application/json'
67
+ response.body = {errors: errors}.to_json
68
+ end
69
+
70
+ def request_body
71
+ @request_body ||= request.body.to_s
72
+ end
73
+
74
+ def consumer_name
75
+ identifier_from_path[:consumer_name]
76
+ end
77
+
78
+ def provider_name
79
+ identifier_from_path[:provider_name]
80
+ end
81
+
82
+ def invalid_json?
83
+ begin
84
+ JSON.parse(request_body, PACT_PARSING_OPTIONS) #Not load! Otherwise it will try to load Ruby classes.
85
+ false
86
+ rescue StandardError => e
87
+ logger.error "Error parsing JSON #{e} - #{request_body}"
88
+ set_json_error_message "Error parsing JSON - #{e.message}"
89
+ response.headers['Content-Type'] = 'application/json'
90
+ true
91
+ end
92
+ end
93
+
94
+ def validation_errors? model
95
+ if (errors = model.validate).any?
96
+ set_json_validation_error_messages errors
97
+ true
98
+ else
99
+ false
100
+ end
101
+ end
53
102
 
54
- def params
55
- JSON.parse(request.body.to_s, symbolize_names: true)
56
103
  end
57
104
  end
58
105
  end