pact_broker 2.3.0 → 2.4.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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -0
  3. data/README.md +3 -4
  4. data/db/migrations/37_create_labels_table.rb +11 -0
  5. data/lib/pact_broker/api.rb +4 -0
  6. data/lib/pact_broker/api/decorators/embedded_label_decorator.rb +20 -0
  7. data/lib/pact_broker/api/decorators/label_decorator.rb +32 -0
  8. data/lib/pact_broker/api/decorators/pact_collection_decorator.rb +1 -5
  9. data/lib/pact_broker/api/decorators/pact_versions_decorator.rb +0 -5
  10. data/lib/pact_broker/api/decorators/pacticipant_collection_decorator.rb +31 -2
  11. data/lib/pact_broker/api/decorators/pacticipant_decorator.rb +37 -8
  12. data/lib/pact_broker/api/pact_broker_urls.rb +12 -4
  13. data/lib/pact_broker/api/resources/label.rb +52 -0
  14. data/lib/pact_broker/api/resources/pacticipants.rb +1 -1
  15. data/lib/pact_broker/api/resources/pacticipants_for_label.rb +27 -0
  16. data/lib/pact_broker/api/resources/verifications.rb +1 -1
  17. data/lib/pact_broker/badges/service.rb +13 -3
  18. data/lib/pact_broker/configuration.rb +1 -1
  19. data/lib/pact_broker/domain.rb +1 -0
  20. data/lib/pact_broker/domain/label.rb +19 -0
  21. data/lib/pact_broker/domain/pacticipant.rb +12 -1
  22. data/lib/pact_broker/labels/repository.rb +32 -0
  23. data/lib/pact_broker/labels/service.rb +26 -0
  24. data/lib/pact_broker/pacticipants/repository.rb +8 -7
  25. data/lib/pact_broker/pacticipants/service.rb +4 -0
  26. data/lib/pact_broker/repositories.rb +5 -0
  27. data/lib/pact_broker/services.rb +5 -0
  28. data/lib/pact_broker/version.rb +1 -1
  29. data/spec/features/delete_label_spec.rb +28 -0
  30. data/spec/features/get_label_spec.rb +28 -0
  31. data/spec/features/get_pacticipants_by_label_spec.rb +27 -0
  32. data/spec/features/label_pacticipant_spec.rb +22 -0
  33. data/spec/lib/pact_broker/api/decorators/embedded_label_decorator_spec.rb +34 -0
  34. data/spec/lib/pact_broker/api/decorators/label_decorator_spec.rb +42 -0
  35. data/spec/lib/pact_broker/api/decorators/pacticipant_collection_decorator_spec.rb +34 -8
  36. data/spec/lib/pact_broker/api/decorators/pacticipant_decorator_spec.rb +41 -2
  37. data/spec/lib/pact_broker/api/decorators/tag_decorator_spec.rb +1 -1
  38. data/spec/lib/pact_broker/api/resources/verifications_spec.rb +2 -2
  39. data/spec/lib/pact_broker/badges/service_spec.rb +1 -1
  40. data/spec/lib/pact_broker/labels/repository_spec.rb +124 -0
  41. data/spec/lib/pact_broker/labels/service_spec.rb +28 -0
  42. data/spec/lib/pact_broker/pacticipants/repository_spec.rb +19 -0
  43. data/spec/support/test_data_builder.rb +6 -0
  44. data/tasks/database.rb +1 -1
  45. data/vendor/hal-browser/browser.html +1 -1
  46. data/vendor/hal-browser/js/hal/resource.js +1 -0
  47. metadata +26 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 03e1cb232f71117f88a50df3b9b46001bf5fcc4d
4
- data.tar.gz: 72758f12fc4fb67c94bb3f21190ccf7e56e36b80
3
+ metadata.gz: ccb2b3e09704513328cc45bb520d07bec978a711
4
+ data.tar.gz: a98ed177a3db187c531c6f7a606a38c0382278b5
5
5
  SHA512:
6
- metadata.gz: a455b7e1e44018827ac663ffe87eeb4c118c082865f9cbb926f0cc2fc3ed7d30ba28686c6b58548b7f36550f30ff8a634f0dc4ec26af8238aaae5d27b96cf2f0
7
- data.tar.gz: 805d6d8e3d035ae6543d342459f22e21dc05eb0cda99bf96c64b568c937c383678c5ce20582d0a44ffa41f626e9e40bed0fe15f5dcdcf5155fa053e47cad9cc9
6
+ metadata.gz: 029ca439a15afebbcca133103d59a67ce4a359df4f57dfb4d9da5e0cf02b820d6eccbb93304d64f400216d455f7c3beac9b27fcd04318a5beb4960e66cf569a7
7
+ data.tar.gz: 462f2d6f9a04dbe36916b94e0f2a52965c8f23234d901ea80280859e2f71c8695a2c1f7b484f763a633b1de873c9d9cec6b9ac93b08dab900f07d93f809c52db
data/CHANGELOG.md CHANGED
@@ -2,6 +2,14 @@ Do this to generate your change history
2
2
 
3
3
  $ git log --pretty=format:' * %h - %s (%an, %ad)'
4
4
 
5
+ * 3a03f41 - fix(publish verification result): Fix Location header for newly created resource (Beth Skurrie, Mon Jul 31 10:49:37 2017 +1000)
6
+ * 3b0f390 - feat(pacticipant labels): Add HAL link to pacticipants resource to find pacticipants by label. (Beth Skurrie, Mon Jul 24 08:17:36 2017 +1000)
7
+ * 588d2ad - fix(pacticipant and pacticipants resources): Add correctly capitalised and namespaced properties and relations. Added deprecation warnings to existing incorrect properties and relations. (Beth Skurrie, Mon Jul 24 08:14:52 2017 +1000)
8
+ * ab11f56 - feat(pacticipant labels): Adds embedded label resources to pacticipant resource. (Beth Skurrie, Fri Jul 21 18:03:15 2017 +1000)
9
+ * 57086cf - feat(pacticipant labels): Adds /pacticipants/label/LABEL_NAME resource to retrieve pacticipants by label. (Beth Skurrie, Fri Jul 21 14:07:08 2017 +1000)
10
+ * 4b44331 - feat(pacticipant labels): Adds pacticipant label resource with GET, PUT and DELETE (Beth Skurrie, Fri Jul 21 13:18:18 2017 +1000)
11
+ * c5af7e1 - feat(badges): Allow badge config settings to be saved to/loaded from database (Beth Skurrie, Fri Jul 14 20:50:02 2017 +1000)
12
+
5
13
  #### 2.3.0 (2017-07-14)
6
14
  * 3ac4351 - fix(potential duplicate pacticipant names): Make duplicate logic smarter. Fixes https://github.com/pact-foundation/pact_broker/issues/35 (Beth Skurrie, Tue Jul 11 10:30:11 2017 +1000)
7
15
  * 81979b1 - add basic auth example to duplicate pacticipant error/help message (Fitzgerald, Andrew, Mon Jul 10 00:11:25 2017 -0400)
data/README.md CHANGED
@@ -21,15 +21,14 @@ Features:
21
21
  * A RESTful API for publishing and retrieving pacts.
22
22
  * An embedded HAL browser for navigating the API.
23
23
  * Autogenerated documentation for each pact.
24
- * Dynamically generated network diagrams.
25
- * Displays provider verificaton results.
24
+ * Dynamically generated network diagrams so you can visualise your microservice network.
25
+ * Displays provider verificaton results so you know if you can deploy safely.
26
+ * Provides badges to display pact verification statuses in your READMEs.
26
27
  * Enables a pact version to be tagged (ie. "prod") so a provider can verify itself against a fixed version of a pact to ensure backwards compatibility.
27
28
  * Provides webhooks to trigger a provider build when a consumer publishes a change to a pact.
28
29
  * Tracks changes between Pact versions so you can tell when a consumer has changed its expectations.
29
30
  * [Docker Pact Broker][docker]
30
31
 
31
- Travis CI Status: [![Build Status](https://travis-ci.org/pact-foundation/pact_broker.svg?branch=master)](https://travis-ci.org/pact-foundation/pact_broker)
32
-
33
32
  ### How would I use the Pact Broker?
34
33
 
35
34
  #### Step 1. Consumer CI build
@@ -0,0 +1,11 @@
1
+ Sequel.migration do
2
+ change do
3
+ create_table(:labels, charset: 'utf8') do
4
+ String :name
5
+ foreign_key :pacticipant_id, :pacticipants
6
+ primary_key [:pacticipant_id, :name], name: :labels_pk
7
+ DateTime :created_at, null: false
8
+ DateTime :updated_at, null: false
9
+ end
10
+ end
11
+ end
@@ -9,7 +9,9 @@ require 'pact_broker/api/resources/latest_pact'
9
9
  require 'pact_broker/api/resources/latest_pacts'
10
10
  require 'pact_broker/api/resources/pacticipant'
11
11
  require 'pact_broker/api/resources/pacticipants'
12
+ require 'pact_broker/api/resources/pacticipants_for_label'
12
13
  require 'pact_broker/api/resources/tag'
14
+ require 'pact_broker/api/resources/label'
13
15
  require 'pact_broker/api/resources/index'
14
16
  require 'pact_broker/api/resources/relationships'
15
17
  require 'pact_broker/api/resources/group'
@@ -69,10 +71,12 @@ module PactBroker
69
71
 
70
72
  # Pacticipants
71
73
  add ['pacticipants'], Api::Resources::Pacticipants, {resource_name: "pacticipants"}
74
+ add ['pacticipants', 'label', :label_name], PactBroker::Api::Resources::PacticipantsForLabel, {resource_name: "pacticipants_for_label"}
72
75
  add ['pacticipants', :name], Api::Resources::Pacticipant, {resource_name: "pacticipant"}
73
76
  add ['pacticipants', :pacticipant_name, 'versions'], Api::Resources::Versions, {resource_name: "pacticipant_versions"}
74
77
  add ['pacticipants', :pacticipant_name, 'versions', :pacticipant_version_number], Api::Resources::Version, {resource_name: "pacticipant_version"}
75
78
  add ['pacticipants', :pacticipant_name, 'versions', :pacticipant_version_number, 'tags', :tag_name], Api::Resources::Tag, {resource_name: "pacticipant_version_tag"}
79
+ add ['pacticipants', :pacticipant_name, 'labels', :label_name], Api::Resources::Label, {resource_name: "pacticipant_label"}
76
80
 
77
81
  # Webhooks
78
82
  add ['webhooks', 'provider', :provider_name, 'consumer', :consumer_name ], Api::Resources::PactWebhooks, {resource_name: "pact_webhooks"}
@@ -0,0 +1,20 @@
1
+ require_relative 'base_decorator'
2
+
3
+ module PactBroker
4
+ module Api
5
+ module Decorators
6
+ class EmbeddedLabelDecorator < BaseDecorator
7
+
8
+ property :name
9
+
10
+ link :self do | options |
11
+ {
12
+ title: 'Label',
13
+ name: represented.name,
14
+ href: label_url(represented, options[:base_url])
15
+ }
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,32 @@
1
+ require_relative 'base_decorator'
2
+ require_relative 'pact_pacticipant_decorator'
3
+ require_relative 'timestamps'
4
+
5
+ module PactBroker
6
+ module Api
7
+ module Decorators
8
+ class LabelDecorator < BaseDecorator
9
+
10
+ property :name
11
+
12
+ include Timestamps
13
+
14
+ link :self do | options |
15
+ {
16
+ title: 'Label',
17
+ name: represented.name,
18
+ href: label_url(represented, options[:base_url])
19
+ }
20
+ end
21
+
22
+ link :pacticipant do | options |
23
+ {
24
+ title: 'Pacticipant',
25
+ name: represented.pacticipant.name,
26
+ href: pacticipant_url(options.fetch(:base_url), represented.pacticipant)
27
+ }
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -4,11 +4,8 @@ require_relative 'latest_pact_decorator'
4
4
  require_relative 'representable_pact'
5
5
 
6
6
  module PactBroker
7
-
8
7
  module Api
9
-
10
8
  module Decorators
11
-
12
9
  class PactCollectionDecorator < BaseDecorator
13
10
  include Roar::JSON::HAL
14
11
  include PactBroker::Api::PactBrokerUrls
@@ -37,8 +34,7 @@ module PactBroker
37
34
  }
38
35
  end
39
36
  end
40
-
41
37
  end
42
38
  end
43
39
  end
44
- end
40
+ end
@@ -2,12 +2,8 @@ require_relative 'base_decorator'
2
2
  require_relative 'pact_version_decorator'
3
3
 
4
4
  module PactBroker
5
-
6
5
  module Api
7
-
8
6
  module Decorators
9
-
10
-
11
7
  class PactVersionsDecorator < BaseDecorator
12
8
 
13
9
  collection :entries, as: :pacts, embedded: true, :extend => PactBroker::Api::Decorators::PactVersionDecorator
@@ -45,7 +41,6 @@ module PactBroker
45
41
  }
46
42
  end
47
43
  end
48
-
49
44
  end
50
45
  end
51
46
  end
@@ -10,16 +10,45 @@ module PactBroker
10
10
 
11
11
  class PacticipantCollectionDecorator < BaseDecorator
12
12
 
13
- collection :entries, :as => :pacticipants, :class => PactBroker::Domain::Pacticipant, :extend => PactBroker::Api::Decorators::PacticipantDecorator
13
+ collection :entries, :as => :pacticipants, :class => PactBroker::Domain::Pacticipant, :extend => PactBroker::Api::Decorators::PacticipantDecorator, embedded: true
14
14
 
15
15
  link :self do | options |
16
16
  pacticipants_url options[:base_url]
17
17
  end
18
18
 
19
+ link :'pb:pacticipants-with-label' do | options |
20
+ {
21
+ title: "Find pacticipants by label",
22
+ href: "#{pacticipants_url(options[:base_url])}/label/{label}",
23
+ templated: true
24
+ }
25
+ end
26
+
27
+ links :'pb:pacticipants' do | options |
28
+ represented.collect{ | pacticipant | {:href => pacticipant_url(options[:base_url], pacticipant), title: 'Pacticipant', name: pacticipant.name } }
29
+ end
30
+
31
+ # TODO deprecate in v3
19
32
  links :pacticipants do | options |
20
- represented.collect{ | pacticipant | {:href => pacticipant_url(options[:base_url], pacticipant), :title => pacticipant.name } }
33
+ represented.collect{ | pacticipant | {:href => pacticipant_url(options[:base_url], pacticipant), :title => pacticipant.name, name: 'DEPRECATED - please use pb:pacticipants' } }
21
34
  end
35
+ end
22
36
 
37
+ class DeprecatedPacticipantDecorator < PactBroker::Api::Decorators::PacticipantDecorator
38
+ property :title, getter: ->(something) { "DEPRECATED - Please use the embedded pacticipants collection" }
39
+ end
40
+
41
+ class NonEmbeddedPacticipantCollectionDecorator < BaseDecorator
42
+ collection :entries, :as => :pacticipants, :class => PactBroker::Domain::Pacticipant, :extend => DeprecatedPacticipantDecorator, embedded: false
43
+ end
44
+
45
+ # TODO deprecate this - breaking change for v 3.0
46
+ class DeprecatedPacticipantCollectionDecorator < PacticipantCollectionDecorator
47
+ def to_hash(options = {})
48
+ embedded_pacticipant_hash = super
49
+ non_embedded_pacticipant_hash = NonEmbeddedPacticipantCollectionDecorator.new(represented).to_hash(options)
50
+ embedded_pacticipant_hash.merge(non_embedded_pacticipant_hash)
51
+ end
23
52
  end
24
53
  end
25
54
  end
@@ -1,20 +1,19 @@
1
1
  require_relative 'base_decorator'
2
2
  require_relative 'embedded_version_decorator'
3
- require 'pact_broker/api/decorators/timestamps'
3
+ require_relative 'embedded_label_decorator'
4
+ require_relative 'timestamps'
4
5
  require 'pact_broker/domain'
5
6
 
6
7
  module PactBroker
7
-
8
8
  module Api
9
-
10
9
  module Decorators
11
-
12
10
  class PacticipantDecorator < BaseDecorator
13
11
 
14
12
  property :name
15
13
  property :repository_url, as: :repositoryUrl
16
14
 
17
- property :latest_version, as: :'latest-version', :class => PactBroker::Domain::Version, :extend => PactBroker::Api::Decorators::EmbeddedVersionDecorator, :embedded => true, writeable: false
15
+ property :latest_version, as: :latestVersion, :class => PactBroker::Domain::Version, extend: PactBroker::Api::Decorators::EmbeddedVersionDecorator, embedded: true, writeable: false
16
+ collection :labels, :class => PactBroker::Domain::Label, extend: PactBroker::Api::Decorators::EmbeddedLabelDecorator, embedded: true
18
17
 
19
18
  include Timestamps
20
19
 
@@ -22,14 +21,44 @@ module PactBroker
22
21
  pacticipant_url(options[:base_url], represented)
23
22
  end
24
23
 
25
- link 'latest-version' do | options |
26
- latest_version_url(options[:base_url], represented)
24
+ link :'pb:versions' do | options |
25
+ versions_url(options[:base_url], represented)
27
26
  end
28
27
 
28
+ # TODO deprecate in v3
29
+ # URL isn't implemented
30
+ # link 'latest-version' do | options |
31
+ # {
32
+ # title: "Deprecated - use pb:latest-version",
33
+ # href: latest_version_url(options[:base_url], represented)
34
+ # }
35
+ # end
36
+
37
+ # TODO deprecate in v3
29
38
  link :versions do | options |
30
- versions_url(options[:base_url], represented)
39
+ {
40
+ title: "Deprecated - use pb:versions",
41
+ href: versions_url(options[:base_url], represented)
42
+ }
43
+ end
44
+
45
+ def to_hash options
46
+ h = super
47
+ dasherized = DasherizedVersionDecorator.new(represented).to_hash(options)
48
+ if dasherized['_embedded']
49
+ if dasherized['_embedded']['latest-version']
50
+ dasherized['_embedded']['latest-version']['title'] = 'DEPRECATED - please use latestVersion'
51
+ end
52
+ h['_embedded'] ||= {}
53
+ h['_embedded'].merge!(dasherized['_embedded'])
54
+ end
55
+ h
31
56
  end
57
+ end
32
58
 
59
+ class DasherizedVersionDecorator < BaseDecorator
60
+ # TODO deprecate in v3
61
+ property :latest_version, as: :'latest-version', :class => PactBroker::Domain::Version, extend: PactBroker::Api::Decorators::EmbeddedVersionDecorator, embedded: true, writeable: false
33
62
  end
34
63
  end
35
64
  end
@@ -67,11 +67,11 @@ module PactBroker
67
67
  "#{version_url(base_url, version)}/tags"
68
68
  end
69
69
 
70
- def new_verification_url params, number, base_url
70
+ def new_verification_url pact, number, base_url
71
71
  [ base_url, 'pacts',
72
- 'provider', url_encode(params[:provider_name]),
73
- 'consumer', url_encode(params[:consumer_name]),
74
- 'pact-version', params[:sha],
72
+ 'provider', url_encode(pact.provider_name),
73
+ 'consumer', url_encode(pact.consumer_name),
74
+ 'pact-version', pact.pact_version_sha,
75
75
  'verification-results', number
76
76
  ].join('/')
77
77
  end
@@ -97,6 +97,14 @@ module PactBroker
97
97
  "#{tags_url(base_url, tag.version)}/#{tag.name}"
98
98
  end
99
99
 
100
+ def label_url label, base_url
101
+ "#{labels_url(label.pacticipant, base_url)}/#{label.name}"
102
+ end
103
+
104
+ def labels_url pacticipant, base_url
105
+ "#{pacticipant_url(base_url, pacticipant)}/labels"
106
+ end
107
+
100
108
  def webhooks_url base_url
101
109
  "#{base_url}/webhooks"
102
110
  end
@@ -0,0 +1,52 @@
1
+ require 'pact_broker/api/resources/base_resource'
2
+ require 'pact_broker/api/decorators/label_decorator'
3
+
4
+ module PactBroker
5
+ module Api
6
+ module Resources
7
+
8
+ class Label < BaseResource
9
+
10
+ def content_types_provided
11
+ [["application/hal+json", :to_json]]
12
+ end
13
+
14
+ def content_types_accepted
15
+ [["application/json", :from_json]]
16
+ end
17
+
18
+ def allowed_methods
19
+ ["GET","PUT","DELETE"]
20
+ end
21
+
22
+ def from_json
23
+ unless label
24
+ @label = label_service.create identifier_from_path
25
+ # Make it return a 201 by setting the Location header
26
+ response.headers["Location"] = label_url(label, base_url)
27
+ end
28
+ response.body = to_json
29
+ end
30
+
31
+ def resource_exists?
32
+ label
33
+ end
34
+
35
+ def to_json
36
+ PactBroker::Api::Decorators::LabelDecorator.new(label).to_json(user_options: { base_url: base_url })
37
+ end
38
+
39
+ def label
40
+ @label ||= label_service.find identifier_from_path
41
+ end
42
+
43
+ def delete_resource
44
+ label_service.delete identifier_from_path
45
+ true
46
+ end
47
+
48
+ end
49
+ end
50
+
51
+ end
52
+ end
@@ -45,7 +45,7 @@ module PactBroker
45
45
  end
46
46
 
47
47
  def generate_json pacticipants
48
- PactBroker::Api::Decorators::PacticipantCollectionDecorator.new(pacticipants).to_json(user_options: { base_url: base_url })
48
+ PactBroker::Api::Decorators::DeprecatedPacticipantCollectionDecorator.new(pacticipants).to_json(user_options: { base_url: base_url })
49
49
  end
50
50
 
51
51
  def decorator_for model
@@ -0,0 +1,27 @@
1
+ require 'pact_broker/api/resources/base_resource'
2
+ require 'pact_broker/api/decorators/pacticipant_collection_decorator'
3
+
4
+ module PactBroker
5
+ module Api
6
+ module Resources
7
+ class PacticipantsForLabel < BaseResource
8
+
9
+ def content_types_provided
10
+ [["application/hal+json", :to_json]]
11
+ end
12
+
13
+ def allowed_methods
14
+ ["GET"]
15
+ end
16
+
17
+ def to_json
18
+ generate_json(pacticipant_service.find identifier_from_path )
19
+ end
20
+
21
+ def generate_json pacticipants
22
+ PactBroker::Api::Decorators::PacticipantCollectionDecorator.new(pacticipants).to_json(user_options: { base_url: base_url })
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -39,7 +39,7 @@ module PactBroker
39
39
  end
40
40
 
41
41
  def create_path
42
- new_verification_url(pact_params, next_verification_number, base_url)
42
+ new_verification_url(pact, next_verification_number, base_url)
43
43
  end
44
44
 
45
45
  def from_json
@@ -12,7 +12,6 @@ module PactBroker
12
12
  include PactBroker::Logging
13
13
 
14
14
  SPACE_DASH_UNDERSCORE = /[\s_\-]/
15
- LOWER_TO_UPPERCASE = /[a-zA-Z](?=[A-Z])/
16
15
 
17
16
  def pact_verification_badge pact, label, initials, verification_status
18
17
  return static_svg(pact, verification_status) unless pact
@@ -37,13 +36,24 @@ module PactBroker
37
36
 
38
37
  def prepare_name name, initials
39
38
  if initials
40
- parts = name.split(SPACE_DASH_UNDERSCORE)
41
- parts = name.split(LOWER_TO_UPPERCASE) if parts.size == 1
39
+ parts = split_space_dash_underscore(name)
40
+ parts = split_camel_case(name) if parts.size == 1
42
41
  return parts.collect{ |p| p[0] }.join.downcase if parts.size > 1
43
42
  end
44
43
  name.downcase
45
44
  end
46
45
 
46
+ def split_space_dash_underscore name
47
+ name.split(SPACE_DASH_UNDERSCORE)
48
+ end
49
+
50
+ def split_camel_case name
51
+ name.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
52
+ .gsub(/([a-z\d])([A-Z])/, '\1_\2')
53
+ .tr('-', '_')
54
+ .split('_')
55
+ end
56
+
47
57
  def badge_status verification_status
48
58
  case verification_status
49
59
  when :success then "verified"