pact_broker 2.3.0 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
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"