pact_broker 2.107.1 → 2.108.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (191) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +55 -0
  3. data/Gemfile +5 -4
  4. data/README.md +1 -0
  5. data/db/migrations/20230615_add_integrations_contract_data_updated_at.rb +13 -0
  6. data/db/migrations/20230616_set_integrations_contract_data_updated_at.rb +11 -0
  7. data/db/migrations/20231002_add_version_id_index_to_released_version.rb +21 -0
  8. data/db/migrations/20231003_add_version_id_index_to_deployed_version.rb +21 -0
  9. data/docs/CONFIGURATION.md +10 -0
  10. data/lib/pact_broker/api/contracts/base_contract.rb +2 -1
  11. data/lib/pact_broker/api/contracts/dry_validation_errors_formatter.rb +2 -0
  12. data/lib/pact_broker/api/contracts/pagination_query_params_schema.rb +19 -0
  13. data/lib/pact_broker/api/contracts/publish_contracts_contract_contract.rb +29 -18
  14. data/lib/pact_broker/api/decorators/base_decorator.rb +40 -1
  15. data/lib/pact_broker/api/decorators/branch_decorator.rb +35 -0
  16. data/lib/pact_broker/api/decorators/branch_version_decorator.rb +16 -0
  17. data/lib/pact_broker/api/decorators/configuration.rb +19 -0
  18. data/lib/pact_broker/api/decorators/custom_error_problem_json_decorator.rb +1 -1
  19. data/lib/pact_broker/api/decorators/decorator_context_creator.rb +47 -2
  20. data/lib/pact_broker/api/decorators/deployed_version_decorator.rb +2 -1
  21. data/lib/pact_broker/api/decorators/deployed_versions_decorator.rb +2 -2
  22. data/lib/pact_broker/api/decorators/dry_validation_errors_decorator.rb +32 -0
  23. data/lib/pact_broker/api/decorators/dry_validation_errors_problem_json_decorator.rb +24 -0
  24. data/lib/pact_broker/api/decorators/embedded_branch_version_decorator.rb +2 -2
  25. data/lib/pact_broker/api/decorators/embedded_deployed_version_decorator.rb +30 -0
  26. data/lib/pact_broker/api/decorators/embedded_error_problem_json_decorator.rb +84 -0
  27. data/lib/pact_broker/api/decorators/embedded_released_version_decorator.rb +27 -0
  28. data/lib/pact_broker/api/decorators/embedded_version_decorator.rb +0 -3
  29. data/lib/pact_broker/api/decorators/error_decorator.rb +30 -0
  30. data/lib/pact_broker/api/decorators/extended_pact_decorator.rb +6 -1
  31. data/lib/pact_broker/api/decorators/integration_decorator.rb +3 -2
  32. data/lib/pact_broker/api/decorators/integrations_decorator.rb +3 -0
  33. data/lib/pact_broker/api/decorators/notices_decorator.rb +11 -0
  34. data/lib/pact_broker/api/decorators/pact_pacticipant_decorator.rb +1 -5
  35. data/lib/pact_broker/api/decorators/pact_versions_decorator.rb +0 -1
  36. data/lib/pact_broker/api/decorators/pact_webhooks_status_decorator.rb +0 -1
  37. data/lib/pact_broker/api/decorators/pacticipant_branches_decorator.rb +32 -0
  38. data/lib/pact_broker/api/decorators/pacticipant_decorator.rb +11 -1
  39. data/lib/pact_broker/api/decorators/{pacticipant_collection_decorator.rb → pacticipants_decorator.rb} +8 -4
  40. data/lib/pact_broker/api/decorators/pagination_links.rb +2 -2
  41. data/lib/pact_broker/api/decorators/released_versions_decorator.rb +2 -2
  42. data/lib/pact_broker/api/decorators/runtime_error_problem_json_decorator.rb +2 -2
  43. data/lib/pact_broker/api/decorators/validation_errors_decorator.rb +30 -0
  44. data/lib/pact_broker/api/decorators/validation_errors_problem_json_decorator.rb +4 -6
  45. data/lib/pact_broker/api/decorators/version_decorator.rb +5 -3
  46. data/lib/pact_broker/api/decorators/versions_decorator.rb +24 -14
  47. data/lib/pact_broker/api/decorators/webhook_execution_result_decorator.rb +2 -0
  48. data/lib/pact_broker/api/middleware/configuration.rb +2 -0
  49. data/lib/pact_broker/api/pact_broker_urls.rb +18 -2
  50. data/lib/pact_broker/api/resources/after_reply.rb +15 -0
  51. data/lib/pact_broker/api/resources/all_webhooks.rb +3 -3
  52. data/lib/pact_broker/api/resources/badge_methods.rb +2 -1
  53. data/lib/pact_broker/api/resources/base_resource.rb +6 -4
  54. data/lib/pact_broker/api/resources/branch.rb +40 -0
  55. data/lib/pact_broker/api/resources/branch_versions.rb +59 -0
  56. data/lib/pact_broker/api/resources/can_i_deploy_pacticipant_version_by_branch_to_environment_badge.rb +1 -1
  57. data/lib/pact_broker/api/resources/currently_deployed_versions_for_environment.rb +1 -1
  58. data/lib/pact_broker/api/resources/currently_supported_versions_for_environment.rb +1 -1
  59. data/lib/pact_broker/api/resources/dashboard.rb +10 -0
  60. data/lib/pact_broker/api/resources/deployed_versions_for_version_and_environment.rb +1 -1
  61. data/lib/pact_broker/api/resources/environments.rb +1 -1
  62. data/lib/pact_broker/api/resources/error_handler.rb +18 -52
  63. data/lib/pact_broker/api/resources/error_handling_methods.rb +40 -14
  64. data/lib/pact_broker/api/resources/error_response_generator.rb +23 -6
  65. data/lib/pact_broker/api/resources/event_methods.rb +15 -0
  66. data/lib/pact_broker/api/resources/filter_methods.rb +15 -0
  67. data/lib/pact_broker/api/resources/group.rb +11 -2
  68. data/lib/pact_broker/api/resources/index.rb +6 -0
  69. data/lib/pact_broker/api/resources/integrations.rb +18 -4
  70. data/lib/pact_broker/api/resources/latest_version.rb +2 -0
  71. data/lib/pact_broker/api/resources/pact.rb +11 -6
  72. data/lib/pact_broker/api/resources/pacticipant_branches.rb +67 -0
  73. data/lib/pact_broker/api/resources/pacticipants.rb +26 -7
  74. data/lib/pact_broker/api/resources/pacticipants_for_label.rb +2 -2
  75. data/lib/pact_broker/api/resources/pagination_methods.rb +11 -1
  76. data/lib/pact_broker/api/resources/verifications.rb +9 -4
  77. data/lib/pact_broker/api/resources/versions.rb +12 -0
  78. data/lib/pact_broker/api.rb +5 -0
  79. data/lib/pact_broker/app.rb +10 -4
  80. data/lib/pact_broker/application_context.rb +29 -25
  81. data/lib/pact_broker/async/after_reply.rb +30 -0
  82. data/lib/pact_broker/config/runtime_configuration.rb +9 -21
  83. data/lib/pact_broker/config/runtime_configuration_coercion_methods.rb +32 -2
  84. data/lib/pact_broker/config/runtime_configuration_database_methods.rb +1 -1
  85. data/lib/pact_broker/config/runtime_configuration_logging_methods.rb +15 -5
  86. data/lib/pact_broker/configuration.rb +29 -12
  87. data/lib/pact_broker/contracts/contracts_to_publish.rb +8 -0
  88. data/lib/pact_broker/contracts/service.rb +7 -1
  89. data/lib/pact_broker/dataset/page.rb +22 -0
  90. data/lib/pact_broker/dataset.rb +122 -0
  91. data/lib/pact_broker/db/data_migrations/set_contract_data_updated_at_for_integrations.rb +47 -0
  92. data/lib/pact_broker/db/migrate_data.rb +1 -0
  93. data/lib/pact_broker/db/models.rb +1 -1
  94. data/lib/pact_broker/deployments/currently_deployed_version_id.rb +2 -5
  95. data/lib/pact_broker/deployments/deployed_version.rb +3 -3
  96. data/lib/pact_broker/deployments/environment.rb +0 -2
  97. data/lib/pact_broker/deployments/released_version.rb +4 -5
  98. data/lib/pact_broker/doc/views/index/pacticipant-branch.markdown +25 -0
  99. data/lib/pact_broker/domain/label.rb +6 -3
  100. data/lib/pact_broker/domain/pact.rb +10 -5
  101. data/lib/pact_broker/domain/pacticipant.rb +4 -34
  102. data/lib/pact_broker/domain/tag.rb +4 -5
  103. data/lib/pact_broker/domain/verification.rb +2 -4
  104. data/lib/pact_broker/domain/version.rb +12 -19
  105. data/lib/pact_broker/errors/error_reporter.rb +30 -0
  106. data/lib/pact_broker/errors.rb +2 -15
  107. data/lib/pact_broker/events/subscriber.rb +12 -4
  108. data/lib/pact_broker/feature_toggle.rb +1 -1
  109. data/lib/pact_broker/groups/service.rb +38 -5
  110. data/lib/pact_broker/index/service.rb +1 -2
  111. data/lib/pact_broker/integrations/event_listener.rb +23 -0
  112. data/lib/pact_broker/integrations/integration.rb +24 -2
  113. data/lib/pact_broker/integrations/repository.rb +34 -1
  114. data/lib/pact_broker/integrations/service.rb +17 -18
  115. data/lib/pact_broker/labels/repository.rb +4 -8
  116. data/lib/pact_broker/locale/en.yml +5 -0
  117. data/lib/pact_broker/matrix/every_row.rb +58 -40
  118. data/lib/pact_broker/matrix/integration_row.rb +95 -0
  119. data/lib/pact_broker/matrix/integrations_repository.rb +133 -0
  120. data/lib/pact_broker/matrix/matrix_row.rb +88 -0
  121. data/lib/pact_broker/matrix/matrix_row_dataset_module.rb +185 -0
  122. data/lib/pact_broker/matrix/matrix_row_instance_methods.rb +150 -0
  123. data/lib/pact_broker/matrix/matrix_row_verification_dataset_module.rb +83 -0
  124. data/lib/pact_broker/matrix/parse_query.rb +1 -0
  125. data/lib/pact_broker/matrix/repository.rb +62 -285
  126. data/lib/pact_broker/matrix/resolved_selector.rb +13 -4
  127. data/lib/pact_broker/matrix/resolved_selector_builder.rb +84 -0
  128. data/lib/pact_broker/matrix/resolved_selectors_builder.rb +39 -0
  129. data/lib/pact_broker/matrix/row_ignorer.rb +36 -0
  130. data/lib/pact_broker/matrix/selector_ignorer.rb +59 -0
  131. data/lib/pact_broker/matrix/selector_resolver.rb +130 -0
  132. data/lib/pact_broker/metrics/service.rb +4 -9
  133. data/lib/pact_broker/pacticipants/latest_version_for_pacticipant_eager_loader.rb +33 -0
  134. data/lib/pact_broker/pacticipants/repository.rb +7 -9
  135. data/lib/pact_broker/pacticipants/service.rb +2 -2
  136. data/lib/pact_broker/pacts/latest_pact_publication_id_for_consumer_version.rb +2 -4
  137. data/lib/pact_broker/pacts/metadata.rb +3 -1
  138. data/lib/pact_broker/pacts/pact_publication.rb +23 -5
  139. data/lib/pact_broker/pacts/pact_publication_dataset_module.rb +5 -1
  140. data/lib/pact_broker/pacts/pact_version.rb +2 -3
  141. data/lib/pact_broker/pacts/pacts_for_verification_repository.rb +2 -5
  142. data/lib/pact_broker/pacts/placeholder_pact.rb +3 -1
  143. data/lib/pact_broker/pacts/repository.rb +12 -12
  144. data/lib/pact_broker/pacts/service.rb +1 -1
  145. data/lib/pact_broker/repositories.rb +9 -1
  146. data/lib/pact_broker/string_refinements.rb +4 -0
  147. data/lib/pact_broker/tags/head_pact_tags.rb +2 -5
  148. data/lib/pact_broker/tags/repository.rb +3 -7
  149. data/lib/pact_broker/test/test_data_builder.rb +50 -1
  150. data/lib/pact_broker/ui/controllers/groups.rb +2 -1
  151. data/lib/pact_broker/ui/view_models/matrix_line.rb +4 -4
  152. data/lib/pact_broker/ui/views/groups/show.html.erb +2 -1
  153. data/lib/pact_broker/verifications/latest_verification_for_consumer_and_provider.rb +0 -3
  154. data/lib/pact_broker/verifications/latest_verification_id_for_pact_version_and_provider_version.rb +2 -4
  155. data/lib/pact_broker/verifications/repository.rb +2 -5
  156. data/lib/pact_broker/verifications/sequence.rb +1 -4
  157. data/lib/pact_broker/verifications/service.rb +4 -0
  158. data/lib/pact_broker/version.rb +1 -1
  159. data/lib/pact_broker/versions/branch.rb +2 -5
  160. data/lib/pact_broker/versions/branch_head.rb +0 -3
  161. data/lib/pact_broker/versions/branch_repository.rb +76 -0
  162. data/lib/pact_broker/versions/branch_service.rb +13 -25
  163. data/lib/pact_broker/versions/branch_version.rb +0 -3
  164. data/lib/pact_broker/versions/branch_version_repository.rb +17 -0
  165. data/lib/pact_broker/versions/repository.rb +19 -2
  166. data/lib/pact_broker/versions/sequence.rb +1 -3
  167. data/lib/pact_broker/versions/service.rb +4 -0
  168. data/lib/pact_broker/webhooks/execution.rb +3 -7
  169. data/lib/pact_broker/webhooks/job.rb +16 -7
  170. data/lib/pact_broker/webhooks/pact_and_verification_parameters.rb +2 -2
  171. data/lib/pact_broker/webhooks/repository.rb +0 -1
  172. data/lib/pact_broker/webhooks/trigger_service.rb +11 -12
  173. data/lib/pact_broker/webhooks/triggered_webhook.rb +3 -4
  174. data/lib/pact_broker/webhooks/webhook.rb +2 -2
  175. data/lib/pact_broker/webhooks/webhook_event.rb +2 -5
  176. data/lib/rack/pact_broker/add_cache_header.rb +14 -0
  177. data/lib/rack/pact_broker/application_context.rb +16 -0
  178. data/lib/rack/pact_broker/configurable_make_it_later.rb +1 -1
  179. data/lib/rack/pact_broker/invalid_uri_protection.rb +19 -3
  180. data/lib/webmachine/describe_routes.rb +55 -39
  181. data/lib/webmachine/render_error_monkey_patch.rb +13 -4
  182. data/pact_broker.gemspec +4 -4
  183. metadata +52 -29
  184. data/lib/pact_broker/api/decorators/decorator_context.rb +0 -22
  185. data/lib/pact_broker/matrix/query_builder.rb +0 -90
  186. data/lib/pact_broker/matrix/query_ids.rb +0 -40
  187. data/lib/pact_broker/matrix/quick_row.rb +0 -458
  188. data/lib/pact_broker/relationships/groupify.rb +0 -45
  189. data/lib/pact_broker/repositories/helpers.rb +0 -96
  190. data/lib/pact_broker/repositories/page.rb +0 -24
  191. data/lib/pact_broker/tags/tag_with_latest_flag.rb +0 -28
@@ -0,0 +1,30 @@
1
+ require "pact_broker/api/decorators/base_decorator"
2
+ require "pact_broker/api/decorators/embedded_pacticipant_decorator"
3
+ require "pact_broker/api/decorators/embedded_version_decorator"
4
+ require "pact_broker/api/decorators/environment_decorator"
5
+
6
+ module PactBroker
7
+ module Api
8
+ module Decorators
9
+ class EmbeddedDeployedVersionDecorator < BaseDecorator
10
+ property :uuid
11
+ property :currently_deployed, camelize: true
12
+ property :target, camelize: true # deprecated
13
+ property :applicationInstance, getter: lambda { |_| target }
14
+ property :undeployedAt, getter: lambda { |_| undeployed_at ? FormatDateTime.call(undeployed_at) : nil }, writeable: false
15
+
16
+ property :pacticipant, :extend => EmbeddedPacticipantDecorator, writeable: false, embedded: true, if: -> (user_options:, **_other) { user_options[:expand]&.include?(:pacticipant) }
17
+ property :version, :extend => EmbeddedVersionDecorator, writeable: false, embedded: true, if: -> (user_options:, **_other) { user_options[:expand]&.include?(:version) }
18
+ property :environment, :extend => EnvironmentDecorator, writeable: false, embedded: true, if: -> (user_options:, **_other) { user_options[:expand]&.include?(:environment) }
19
+
20
+ include Timestamps
21
+
22
+ link :self do | user_options |
23
+ {
24
+ href: deployed_version_url(represented, user_options.fetch(:base_url))
25
+ }
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,84 @@
1
+ require "pact_broker/api/decorators/base_decorator"
2
+
3
+ # Decorates the individual validation error message Dry::Validation::Message
4
+
5
+ module PactBroker
6
+ module Api
7
+ module Decorators
8
+ class EmbeddedErrorProblemJsonDecorator < BaseDecorator
9
+
10
+ property :type, getter: -> (decorator:, user_options:, **) { decorator.type(user_options[:base_url]) }
11
+ property :title, exec_context: :decorator
12
+ property :text, as: :detail
13
+ property :pointer, exec_context: :decorator
14
+ property :parameter, exec_context: :decorator
15
+
16
+ # dry-validation doesn't support validating a top level array, so we wrap
17
+ # the json patch operations array in a hash with the key :_ops to validate it.
18
+ # When we render the error, we have to remove the /_ops prefix from the pointer.
19
+ # For contracts where we validate the path and the body together using _path and _body
20
+ # we also need to remove the first key from the path.
21
+ # It's possible the pointer should have a # at the start of it as per https://www.rfc-editor.org/rfc/rfc6901 :shrug:
22
+ def pointer
23
+ if is_path_error?
24
+ nil
25
+ # _ops, _path or _body for use when we need to hack the way dry-validation schemas work
26
+ elsif represented.path.first.to_s.start_with?("_")
27
+ "/" + represented.path[1..-1].join("/")
28
+ else
29
+ "/" + represented.path.join("/")
30
+ end
31
+ end
32
+
33
+ def parameter
34
+ if is_path_error?
35
+ represented.path.last.to_s
36
+ else
37
+ nil
38
+ end
39
+ end
40
+
41
+ def title
42
+ if is_path_error?
43
+ "Invalid path segment"
44
+ else
45
+ "Invalid body parameter"
46
+ end
47
+ end
48
+
49
+ # @param [String] base_url
50
+ def type(base_url)
51
+ if is_path_error?
52
+ "#{base_url}/#{path_type}"
53
+ else
54
+ "#{base_url}/#{body_type}"
55
+ end
56
+ end
57
+
58
+ def path_type
59
+ if represented.text.include?("missing")
60
+ "problems/missing-request-parameter"
61
+ elsif represented.text.include?("format")
62
+ "problems/invalid-request-parameter-format"
63
+ else
64
+ "problems/invalid-request-parameter-value"
65
+ end
66
+ end
67
+
68
+ def body_type
69
+ if represented.text.include?("missing")
70
+ "problems/missing-body-property"
71
+ elsif represented.text.include?("format")
72
+ "problems/invalid-body-property-format"
73
+ else
74
+ "problems/invalid-body-property-value"
75
+ end
76
+ end
77
+
78
+ def is_path_error?
79
+ represented.path.first == :_path
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,27 @@
1
+ require "pact_broker/api/decorators/base_decorator"
2
+ require "pact_broker/api/decorators/embedded_pacticipant_decorator"
3
+ require "pact_broker/api/decorators/embedded_version_decorator"
4
+ require "pact_broker/api/decorators/environment_decorator"
5
+
6
+ module PactBroker
7
+ module Api
8
+ module Decorators
9
+ class EmbeddedReleasedVersionDecorator < BaseDecorator
10
+ property :uuid
11
+ property :currently_supported, camelize: true
12
+ include Timestamps
13
+ property :supportEndedAt, getter: lambda { |_| support_ended_at ? FormatDateTime.call(support_ended_at) : nil }, writeable: false
14
+
15
+ property :pacticipant, :extend => EmbeddedPacticipantDecorator, writeable: false, embedded: true, if: -> (user_options:, **_other) { user_options[:expand]&.include?(:pacticipant) }
16
+ property :version, :extend => EmbeddedVersionDecorator, writeable: false, embedded: true, if: -> (user_options:, **_other) { user_options[:expand]&.include?(:version) }
17
+ property :environment, :extend => EnvironmentDecorator, writeable: false, embedded: true, if: -> (user_options:, **_other) { user_options[:expand]&.include?(:environment) }
18
+
19
+ link :self do | user_options |
20
+ {
21
+ href: released_version_url(represented, user_options.fetch(:base_url))
22
+ }
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -7,9 +7,6 @@ module PactBroker
7
7
  camelize_property_names
8
8
 
9
9
  property :number
10
- if PactBroker.feature_enabled?(:branches)
11
- property :build_url
12
- end
13
10
 
14
11
  link :self do | options |
15
12
  {
@@ -0,0 +1,30 @@
1
+ # Formats a nested Hash of errors into the "old" Pact Broker errors format
2
+ # TODO: delete this in favour of problem+json in the next major version
3
+
4
+ module PactBroker
5
+ module Api
6
+ module Decorators
7
+ class ErrorDecorator
8
+
9
+ # @param error [String]
10
+ def initialize(error)
11
+ @error = error
12
+ end
13
+
14
+ # @return [Hash]
15
+ def to_hash(*_args, **_kwargs)
16
+ { error: error }
17
+ end
18
+
19
+ # @return [String] JSON
20
+ def to_json(*args, **kwargs)
21
+ to_hash(*args, **kwargs).to_json
22
+ end
23
+
24
+ private
25
+
26
+ attr_reader :error
27
+ end
28
+ end
29
+ end
30
+ end
@@ -1,5 +1,10 @@
1
1
  require "pact_broker/api/decorators/pact_decorator"
2
2
 
3
+ # Pactflow notes:
4
+ # This decorator was added for Pactflow, but we needed to change it so much that there
5
+ # is a separate class in pact_broker_fork/lib/pactflow/api/decorators/extended_pact_decorator.rb now
6
+ # and this one isn't used.
7
+
3
8
  module PactBroker
4
9
  module Api
5
10
  module Decorators
@@ -47,4 +52,4 @@ module PactBroker
47
52
  end
48
53
  end
49
54
  end
50
- end
55
+ end
@@ -7,16 +7,16 @@ module PactBroker
7
7
  class IntegrationDecorator < BaseDecorator
8
8
  include PactBroker::Api::PactBrokerUrls
9
9
 
10
+ # TODO should be embedded in v3
10
11
  property :consumer do
11
12
  property :name
12
13
  end
13
14
 
15
+ # TODO should be embedded in v3
14
16
  property :provider do
15
17
  property :name
16
18
  end
17
19
 
18
- property :verificationStatus, getter: ->(represented:, **) { represented.verification_status_for_latest_pact.to_s }
19
-
20
20
  link "pb:dashboard" do | options |
21
21
  {
22
22
  title: "BETA: Pacts to show on the dashboard",
@@ -40,3 +40,4 @@ module PactBroker
40
40
  end
41
41
  end
42
42
  end
43
+
@@ -1,5 +1,6 @@
1
1
  require_relative "base_decorator"
2
2
  require_relative "integration_decorator"
3
+ require "pact_broker/api/decorators/pagination_links"
3
4
 
4
5
  module PactBroker
5
6
  module Api
@@ -13,6 +14,8 @@ module PactBroker
13
14
  title: "All integrations"
14
15
  }
15
16
  end
17
+
18
+ include PactBroker::Api::Decorators::PaginationLinks
16
19
  end
17
20
  end
18
21
  end
@@ -0,0 +1,11 @@
1
+ require_relative "base_decorator"
2
+
3
+ module PactBroker
4
+ module Api
5
+ module Decorators
6
+ class NoticesDecorator < BaseDecorator
7
+ property :entries, as: :notices, getter: ->(represented:, **) { represented.collect(&:to_h) }
8
+ end
9
+ end
10
+ end
11
+ end
@@ -3,11 +3,8 @@ require_relative "embedded_version_decorator"
3
3
  require_relative "base_decorator"
4
4
 
5
5
  module PactBroker
6
-
7
6
  module Api
8
-
9
7
  module Decorators
10
-
11
8
  class PactPacticipantDecorator < BaseDecorator
12
9
 
13
10
  property :name
@@ -17,8 +14,7 @@ module PactBroker
17
14
  link :self do | options |
18
15
  pacticipant_url(options[:base_url], represented)
19
16
  end
20
-
21
17
  end
22
18
  end
23
19
  end
24
- end
20
+ end
@@ -5,7 +5,6 @@ module PactBroker
5
5
  module Api
6
6
  module Decorators
7
7
  class PactVersionsDecorator < BaseDecorator
8
-
9
8
  collection :entries, as: :pacts, embedded: true, :extend => PactBroker::Api::Decorators::PactVersionDecorator
10
9
 
11
10
  link :self do | context |
@@ -6,7 +6,6 @@ require_relative "triggered_webhook_decorator"
6
6
  module PactBroker
7
7
  module Api
8
8
  module Decorators
9
-
10
9
  class PactWebhooksStatusDecorator < BaseDecorator
11
10
 
12
11
  property :summary, exec_context: :decorator do
@@ -0,0 +1,32 @@
1
+ require "pact_broker/api/decorators/base_decorator"
2
+ require "pact_broker/api/decorators/timestamps"
3
+ require "pact_broker/api/decorators/pagination_links"
4
+ require "pact_broker/api/decorators/branch_decorator"
5
+
6
+ module PactBroker
7
+ module Api
8
+ module Decorators
9
+ class PacticipantBranchesDecorator < BaseDecorator
10
+ collection :entries, as: :branches, embedded: true, :extend => PactBroker::Api::Decorators::BranchDecorator
11
+
12
+ link :self do | user_options |
13
+ {
14
+ title: "#{user_options.fetch(:pacticipant).name} branches",
15
+ href: user_options.fetch(:request_url)
16
+ }
17
+ end
18
+
19
+ links "pb:branches" do | user_options |
20
+ represented.collect do | branch |
21
+ {
22
+ name: branch.name,
23
+ href: branch_url(branch, user_options.fetch(:base_url))
24
+ }
25
+ end
26
+ end
27
+
28
+ include PaginationLinks
29
+ end
30
+ end
31
+ end
32
+ end
@@ -19,12 +19,18 @@ module PactBroker
19
19
  property :repository_namespace
20
20
  property :main_branch
21
21
 
22
-
23
22
  property :latest_version, as: :latestVersion, :class => PactBroker::Domain::Version, extend: PactBroker::Api::Decorators::EmbeddedVersionDecorator, embedded: true, writeable: false
24
23
  collection :labels, :class => PactBroker::Domain::Label, extend: PactBroker::Api::Decorators::EmbeddedLabelDecorator, embedded: true
25
24
 
26
25
  include Timestamps
27
26
 
27
+ # The associations that should be eager loaded on the Pacticipant so that this
28
+ # decorator can be used without any extra calls to the database.
29
+ # @return Array<Symbol>
30
+ def self.eager_load_associations
31
+ [:labels, :latest_version]
32
+ end
33
+
28
34
  link :self do | options |
29
35
  pacticipant_url(options[:base_url], represented)
30
36
  end
@@ -33,6 +39,10 @@ module PactBroker
33
39
  versions_url(options[:base_url], represented)
34
40
  end
35
41
 
42
+ link :'pb:branches' do | options |
43
+ pacticipant_branches_url(represented, options[:base_url])
44
+ end
45
+
36
46
  link :'pb:version' do | options |
37
47
  {
38
48
  title: "Get, create or delete a pacticipant version",
@@ -8,12 +8,16 @@ require "pact_broker/api/decorators/pacticipant_decorator"
8
8
  module PactBroker
9
9
  module Api
10
10
  module Decorators
11
- class PacticipantCollectionDecorator < BaseDecorator
11
+ class PacticipantsDecorator < BaseDecorator
12
12
 
13
13
  collection :entries, :as => :pacticipants, :class => PactBroker::Domain::Pacticipant, :extend => PactBroker::Api::Decorators::PacticipantDecorator, embedded: true
14
14
 
15
15
  include PaginationLinks
16
16
 
17
+ def self.eager_load_associations
18
+ PactBroker::Api::Decorators::PacticipantDecorator.eager_load_associations
19
+ end
20
+
17
21
  link :self do | options |
18
22
  pacticipants_url options[:base_url]
19
23
  end
@@ -27,12 +31,12 @@ module PactBroker
27
31
  end
28
32
 
29
33
  links :'pb:pacticipants' do | options |
30
- represented.collect{ | pacticipant | {:href => pacticipant_url(options[:base_url], pacticipant), title: "Pacticipant", name: pacticipant.name } }
34
+ represented.collect{ | pacticipant | { href: pacticipant_url(options[:base_url], pacticipant), title: "Pacticipant", name: pacticipant.name } }
31
35
  end
32
36
 
33
37
  # TODO deprecate in v3
34
38
  links :pacticipants do | options |
35
- represented.collect{ | pacticipant | {:href => pacticipant_url(options[:base_url], pacticipant), :title => pacticipant.name, name: "DEPRECATED - please use pb:pacticipants" } }
39
+ represented.collect{ | pacticipant | { href: pacticipant_url(options[:base_url], pacticipant), :title => pacticipant.name, name: "DEPRECATED - please use pb:pacticipants" } }
36
40
  end
37
41
  end
38
42
 
@@ -45,7 +49,7 @@ module PactBroker
45
49
  end
46
50
 
47
51
  # TODO deprecate this - breaking change for v 3.0
48
- class DeprecatedPacticipantCollectionDecorator < PacticipantCollectionDecorator
52
+ class DeprecatedPacticipantsDecorator < PacticipantsDecorator
49
53
  def to_hash(options)
50
54
  embedded_pacticipant_hash = super
51
55
  non_embedded_pacticipant_hash = NonEmbeddedPacticipantCollectionDecorator.new(represented).to_hash(options)
@@ -24,7 +24,7 @@ module PactBroker
24
24
  represented.respond_to?(:page_count) &&
25
25
  represented.current_page < represented.page_count
26
26
  {
27
- href: context[:resource_url] + "?pageSize=#{represented.page_size}&pageNumber=#{represented.current_page + 1}",
27
+ href: context[:resource_url] + "?size=#{represented.page_size}&page=#{represented.current_page + 1}",
28
28
  title: "Next page"
29
29
  }
30
30
 
@@ -34,7 +34,7 @@ module PactBroker
34
34
  link :previous do | context |
35
35
  if represented.respond_to?(:first_page?) && !represented.first_page?
36
36
  {
37
- href: context[:resource_url] + "?pageSize=#{represented.page_size}&pageNumber=#{represented.current_page - 1}",
37
+ href: context[:resource_url] + "?size=#{represented.page_size}&page=#{represented.current_page - 1}",
38
38
  title: "Previous page"
39
39
  }
40
40
  end
@@ -1,11 +1,11 @@
1
1
  require "pact_broker/api/decorators/base_decorator"
2
- require "pact_broker/api/decorators/released_version_decorator"
2
+ require "pact_broker/api/decorators/embedded_released_version_decorator"
3
3
 
4
4
  module PactBroker
5
5
  module Api
6
6
  module Decorators
7
7
  class ReleasedVersionsDecorator < BaseDecorator
8
- collection :entries, as: :releasedVersions, embedded: true, :extend => PactBroker::Api::Decorators::ReleasedVersionDecorator
8
+ collection :entries, as: :releasedVersions, embedded: true, :extend => PactBroker::Api::Decorators::EmbeddedReleasedVersionDecorator
9
9
 
10
10
  link :self do | context |
11
11
  href = append_query_if_present(context[:resource_url], context[:query_string])
@@ -3,7 +3,7 @@
3
3
  module PactBroker
4
4
  module Api
5
5
  module Decorators
6
- class RuntimeErrorProblemJSONDecorator
6
+ class RuntimeErrorProblemJsonDecorator
7
7
 
8
8
  # @param message [String]
9
9
  def initialize(message)
@@ -14,7 +14,7 @@ module PactBroker
14
14
  def to_hash(user_options:, **)
15
15
  {
16
16
  "title" => "Server error",
17
- "type" => "#{user_options[:base_url]}/problems/server_error",
17
+ "type" => "#{user_options[:base_url]}/problems/server-error",
18
18
  "detail" => message,
19
19
  "status" => 500
20
20
  }
@@ -0,0 +1,30 @@
1
+ # Formats a nested Hash of errors, or an Array of Strings, into the "old" Pact Broker errors format
2
+ # TODO: delete this in favour of problem+json in the next major version
3
+
4
+ module PactBroker
5
+ module Api
6
+ module Decorators
7
+ class ValidationErrorsDecorator
8
+
9
+ # @param errors [Hash, Array<String>]
10
+ def initialize(errors)
11
+ @errors = errors
12
+ end
13
+
14
+ # @return [Hash]
15
+ def to_hash(*_args, **_kwargs)
16
+ { errors: errors }
17
+ end
18
+
19
+ # @return [String] JSON
20
+ def to_json(*args, **kwargs)
21
+ to_hash(*args, **kwargs).to_json
22
+ end
23
+
24
+ private
25
+
26
+ attr_reader :errors
27
+ end
28
+ end
29
+ end
30
+ end
@@ -1,11 +1,10 @@
1
- # Formats a nested Hash of errors as it comes out of the Dry Validation library
2
- # into application/problem+json format.
1
+ # Formats a nested Hash of errors into application/problem+json format.
3
2
  require "pact_broker/string_refinements"
4
3
 
5
4
  module PactBroker
6
5
  module Api
7
6
  module Decorators
8
- class ValidationErrorsProblemJSONDecorator
7
+ class ValidationErrorsProblemJsonDecorator
9
8
  using PactBroker::StringRefinements
10
9
 
11
10
 
@@ -53,9 +52,8 @@ module PactBroker
53
52
  def append_error(list, message, path, base_url)
54
53
  error = {
55
54
  "type" => "#{base_url}/problems/invalid-body-property-value",
56
- "title" => "Validation error",
57
- "detail" => message,
58
- "status" => 400
55
+ "title" => "Invalid body parameter",
56
+ "detail" => message
59
57
  }
60
58
  error["pointer"] = path.tr(".", "/") if path.present?
61
59
  list << error
@@ -1,5 +1,6 @@
1
1
  require_relative "base_decorator"
2
2
  require_relative "embedded_tag_decorator"
3
+ require_relative "embedded_branch_version_decorator"
3
4
 
4
5
  module PactBroker
5
6
  module Api
@@ -20,7 +21,8 @@ module PactBroker
20
21
  {
21
22
  title: "Version",
22
23
  name: represented.number,
23
- href: version_url(options.fetch(:base_url), represented)
24
+ # This decorator is used for multiple Version resources, so dynamically fetch the current resource URL
25
+ href: options.fetch(:resource_url)
24
26
  }
25
27
  end
26
28
 
@@ -58,7 +60,7 @@ module PactBroker
58
60
  end
59
61
 
60
62
  links :'pb:record-deployment' do | context |
61
- context.fetch(:environments, []).collect do | environment |
63
+ context[:environments]&.collect do | environment |
62
64
  {
63
65
  title: "Record deployment to #{environment.display_name}",
64
66
  name: environment.name,
@@ -68,7 +70,7 @@ module PactBroker
68
70
  end
69
71
 
70
72
  links :'pb:record-release' do | context |
71
- context.fetch(:environments, []).collect do | environment |
73
+ context[:environments]&.collect do | environment |
72
74
  {
73
75
  title: "Record release to #{environment.display_name}",
74
76
  name: environment.name,
@@ -6,46 +6,56 @@ module PactBroker
6
6
  module Api
7
7
  module Decorators
8
8
  class VersionsDecorator < BaseDecorator
9
+ class VersionInCollectionDecorator < PactBroker::Api::Decorators::VersionDecorator
10
+ # VersionDecorator has a dynamic self URL, depending which path the Version resource is mounted at.
11
+ # Hardcode the URL of the embedded Versions in this collection to use the canonical URL with the version number.
12
+ link :self do | user_options |
13
+ {
14
+ title: "Version",
15
+ name: represented.number,
16
+ href: version_url(user_options.fetch(:base_url), represented)
17
+ }
18
+ end
19
+ end
9
20
 
10
- collection :entries, as: :versions, embedded: true, :extend => PactBroker::Api::Decorators::VersionDecorator
21
+ collection :entries, as: :versions, embedded: true, :extend => VersionInCollectionDecorator
11
22
 
12
- link :self do | context |
13
- href = append_query_if_present(context[:resource_url], context[:query_string])
23
+ link :self do | user_options |
14
24
  {
15
- href: href,
16
- title: "All application versions of #{context[:pacticipant_name]}"
25
+ href: user_options.fetch(:request_url),
26
+ title: user_options[:resource_title] || "All application versions of #{user_options[:pacticipant_name]}"
17
27
  }
18
28
  end
19
29
 
20
30
  include PaginationLinks
21
31
 
22
- link :'pb:pacticipant' do | context |
32
+ link :'pb:pacticipant' do | user_options |
23
33
  {
24
- href: pacticipant_url(context[:base_url], OpenStruct.new(name: context[:pacticipant_name])),
25
- title: context[:pacticipant_name]
34
+ href: pacticipant_url(user_options[:base_url], OpenStruct.new(name: user_options[:pacticipant_name])),
35
+ title: user_options[:pacticipant_name]
26
36
  }
27
37
  end
28
38
 
29
- links :'pb:versions' do | context |
39
+ links :'pb:versions' do | user_options |
30
40
  represented.collect do | version |
31
41
  {
32
- :href => version_url(context[:base_url], version),
42
+ :href => version_url(user_options[:base_url], version),
33
43
  :title => version.version_and_updated_date
34
44
  }
35
45
  end
36
46
  end
37
47
 
38
- link :pacticipant do | context |
48
+ link :pacticipant do | user_options |
39
49
  {
40
- href: pacticipant_url(context[:base_url], OpenStruct.new(name: context[:pacticipant_name])),
50
+ href: pacticipant_url(user_options[:base_url], OpenStruct.new(name: user_options[:pacticipant_name])),
41
51
  title: "Deprecated - please use pb:pacticipant"
42
52
  }
43
53
  end
44
54
 
45
- links :'versions' do | context |
55
+ links :'versions' do | user_options |
46
56
  represented.collect do | version |
47
57
  {
48
- :href => version_url(context[:base_url], version),
58
+ :href => version_url(user_options[:base_url], version),
49
59
  :title => "Deprecated - please use pb:versions"
50
60
  }
51
61
  end
@@ -65,6 +65,7 @@ module PactBroker
65
65
  property :logs
66
66
  property :success?, as: :success
67
67
 
68
+ #TODO rename to pb:webhook in next major version
68
69
  link :webhook do | options |
69
70
  if options.fetch(:webhook).uuid
70
71
  {
@@ -73,6 +74,7 @@ module PactBroker
73
74
  end
74
75
  end
75
76
 
77
+ #TODO rename to pb:try-again in next major version
76
78
  link :'try-again' do | options |
77
79
  {
78
80
  title: "Execute the webhook again",
@@ -1,5 +1,7 @@
1
1
  require "pact_broker/logging"
2
2
 
3
+ # Allows the load-time configuration to be overridden on a per-request basis (for Pactflow)
4
+
3
5
  module PactBroker
4
6
  module Api
5
7
  module Middleware