pact_broker 2.107.1 → 2.109.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 (201) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +68 -0
  3. data/Gemfile +5 -6
  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/publish_contract_decorator.rb +6 -1
  42. data/lib/pact_broker/api/decorators/released_versions_decorator.rb +2 -2
  43. data/lib/pact_broker/api/decorators/runtime_error_problem_json_decorator.rb +2 -2
  44. data/lib/pact_broker/api/decorators/validation_errors_decorator.rb +30 -0
  45. data/lib/pact_broker/api/decorators/validation_errors_problem_json_decorator.rb +4 -6
  46. data/lib/pact_broker/api/decorators/version_decorator.rb +5 -3
  47. data/lib/pact_broker/api/decorators/versions_decorator.rb +24 -14
  48. data/lib/pact_broker/api/decorators/webhook_decorator.rb +1 -1
  49. data/lib/pact_broker/api/decorators/webhook_execution_result_decorator.rb +2 -0
  50. data/lib/pact_broker/api/middleware/configuration.rb +2 -0
  51. data/lib/pact_broker/api/pact_broker_urls.rb +18 -2
  52. data/lib/pact_broker/api/resources/after_reply.rb +15 -0
  53. data/lib/pact_broker/api/resources/all_webhooks.rb +3 -3
  54. data/lib/pact_broker/api/resources/badge_methods.rb +2 -1
  55. data/lib/pact_broker/api/resources/base_resource.rb +6 -4
  56. data/lib/pact_broker/api/resources/branch.rb +40 -0
  57. data/lib/pact_broker/api/resources/branch_versions.rb +59 -0
  58. data/lib/pact_broker/api/resources/can_i_deploy_pacticipant_version_by_branch_to_environment_badge.rb +1 -1
  59. data/lib/pact_broker/api/resources/currently_deployed_versions_for_environment.rb +1 -1
  60. data/lib/pact_broker/api/resources/currently_supported_versions_for_environment.rb +1 -1
  61. data/lib/pact_broker/api/resources/dashboard.rb +10 -0
  62. data/lib/pact_broker/api/resources/deployed_versions_for_version_and_environment.rb +1 -1
  63. data/lib/pact_broker/api/resources/environment.rb +4 -0
  64. data/lib/pact_broker/api/resources/environments.rb +1 -1
  65. data/lib/pact_broker/api/resources/error_handler.rb +18 -52
  66. data/lib/pact_broker/api/resources/error_handling_methods.rb +40 -14
  67. data/lib/pact_broker/api/resources/error_response_generator.rb +23 -6
  68. data/lib/pact_broker/api/resources/event_methods.rb +15 -0
  69. data/lib/pact_broker/api/resources/filter_methods.rb +15 -0
  70. data/lib/pact_broker/api/resources/group.rb +11 -2
  71. data/lib/pact_broker/api/resources/index.rb +6 -0
  72. data/lib/pact_broker/api/resources/integrations.rb +18 -4
  73. data/lib/pact_broker/api/resources/latest_version.rb +2 -0
  74. data/lib/pact_broker/api/resources/pact.rb +16 -7
  75. data/lib/pact_broker/api/resources/pacticipant_branches.rb +67 -0
  76. data/lib/pact_broker/api/resources/pacticipants.rb +26 -7
  77. data/lib/pact_broker/api/resources/pacticipants_for_label.rb +2 -2
  78. data/lib/pact_broker/api/resources/pagination_methods.rb +11 -1
  79. data/lib/pact_broker/api/resources/publish_contracts.rb +1 -1
  80. data/lib/pact_broker/api/resources/verifications.rb +9 -4
  81. data/lib/pact_broker/api/resources/versions.rb +12 -0
  82. data/lib/pact_broker/api.rb +5 -0
  83. data/lib/pact_broker/app.rb +10 -9
  84. data/lib/pact_broker/application_context.rb +29 -25
  85. data/lib/pact_broker/async/after_reply.rb +30 -0
  86. data/lib/pact_broker/config/runtime_configuration.rb +9 -21
  87. data/lib/pact_broker/config/runtime_configuration_coercion_methods.rb +32 -2
  88. data/lib/pact_broker/config/runtime_configuration_database_methods.rb +1 -1
  89. data/lib/pact_broker/config/runtime_configuration_logging_methods.rb +15 -5
  90. data/lib/pact_broker/configuration.rb +29 -12
  91. data/lib/pact_broker/contracts/contract_to_publish.rb +4 -5
  92. data/lib/pact_broker/contracts/contracts_to_publish.rb +8 -0
  93. data/lib/pact_broker/contracts/service.rb +9 -3
  94. data/lib/pact_broker/dataset/page.rb +22 -0
  95. data/lib/pact_broker/dataset.rb +122 -0
  96. data/lib/pact_broker/db/data_migrations/set_contract_data_updated_at_for_integrations.rb +47 -0
  97. data/lib/pact_broker/db/migrate_data.rb +1 -0
  98. data/lib/pact_broker/db/models.rb +1 -1
  99. data/lib/pact_broker/deployments/currently_deployed_version_id.rb +2 -5
  100. data/lib/pact_broker/deployments/deployed_version.rb +3 -3
  101. data/lib/pact_broker/deployments/environment.rb +0 -2
  102. data/lib/pact_broker/deployments/released_version.rb +4 -5
  103. data/lib/pact_broker/doc/views/index/pacticipant-branch.markdown +25 -0
  104. data/lib/pact_broker/domain/label.rb +6 -3
  105. data/lib/pact_broker/domain/pact.rb +10 -5
  106. data/lib/pact_broker/domain/pacticipant.rb +4 -34
  107. data/lib/pact_broker/domain/tag.rb +4 -5
  108. data/lib/pact_broker/domain/verification.rb +2 -4
  109. data/lib/pact_broker/domain/version.rb +12 -19
  110. data/lib/pact_broker/errors/error_reporter.rb +30 -0
  111. data/lib/pact_broker/errors.rb +2 -15
  112. data/lib/pact_broker/events/subscriber.rb +12 -4
  113. data/lib/pact_broker/feature_toggle.rb +1 -1
  114. data/lib/pact_broker/groups/service.rb +38 -5
  115. data/lib/pact_broker/index/service.rb +1 -2
  116. data/lib/pact_broker/integrations/event_listener.rb +23 -0
  117. data/lib/pact_broker/integrations/integration.rb +24 -2
  118. data/lib/pact_broker/integrations/repository.rb +34 -1
  119. data/lib/pact_broker/integrations/service.rb +17 -18
  120. data/lib/pact_broker/labels/repository.rb +4 -8
  121. data/lib/pact_broker/locale/en.yml +5 -0
  122. data/lib/pact_broker/logging.rb +10 -0
  123. data/lib/pact_broker/matrix/every_row.rb +58 -40
  124. data/lib/pact_broker/matrix/integration_row.rb +95 -0
  125. data/lib/pact_broker/matrix/integrations_repository.rb +133 -0
  126. data/lib/pact_broker/matrix/matrix_row.rb +88 -0
  127. data/lib/pact_broker/matrix/matrix_row_dataset_module.rb +185 -0
  128. data/lib/pact_broker/matrix/matrix_row_instance_methods.rb +150 -0
  129. data/lib/pact_broker/matrix/matrix_row_verification_dataset_module.rb +83 -0
  130. data/lib/pact_broker/matrix/parse_query.rb +1 -0
  131. data/lib/pact_broker/matrix/repository.rb +62 -285
  132. data/lib/pact_broker/matrix/resolved_selector.rb +13 -4
  133. data/lib/pact_broker/matrix/resolved_selector_builder.rb +84 -0
  134. data/lib/pact_broker/matrix/resolved_selectors_builder.rb +39 -0
  135. data/lib/pact_broker/matrix/row_ignorer.rb +36 -0
  136. data/lib/pact_broker/matrix/selector_ignorer.rb +59 -0
  137. data/lib/pact_broker/matrix/selector_resolver.rb +130 -0
  138. data/lib/pact_broker/metrics/service.rb +4 -9
  139. data/lib/pact_broker/pacticipants/latest_version_for_pacticipant_eager_loader.rb +33 -0
  140. data/lib/pact_broker/pacticipants/repository.rb +7 -9
  141. data/lib/pact_broker/pacticipants/service.rb +2 -2
  142. data/lib/pact_broker/pacts/generate_sha.rb +9 -4
  143. data/lib/pact_broker/pacts/latest_pact_publication_id_for_consumer_version.rb +2 -4
  144. data/lib/pact_broker/pacts/metadata.rb +3 -1
  145. data/lib/pact_broker/pacts/pact_params.rb +1 -1
  146. data/lib/pact_broker/pacts/pact_publication.rb +23 -5
  147. data/lib/pact_broker/pacts/pact_publication_dataset_module.rb +5 -1
  148. data/lib/pact_broker/pacts/pact_version.rb +2 -3
  149. data/lib/pact_broker/pacts/pacts_for_verification_repository.rb +2 -5
  150. data/lib/pact_broker/pacts/placeholder_pact.rb +3 -1
  151. data/lib/pact_broker/pacts/repository.rb +12 -12
  152. data/lib/pact_broker/pacts/service.rb +12 -13
  153. data/lib/pact_broker/repositories.rb +9 -1
  154. data/lib/pact_broker/string_refinements.rb +4 -0
  155. data/lib/pact_broker/tags/head_pact_tags.rb +2 -5
  156. data/lib/pact_broker/tags/repository.rb +3 -7
  157. data/lib/pact_broker/test/test_data_builder.rb +57 -2
  158. data/lib/pact_broker/ui/controllers/base_controller.rb +4 -2
  159. data/lib/pact_broker/ui/controllers/groups.rb +2 -1
  160. data/lib/pact_broker/ui/view_models/matrix_line.rb +4 -4
  161. data/lib/pact_broker/ui/views/groups/show.html.erb +2 -1
  162. data/lib/pact_broker/ui.rb +20 -9
  163. data/lib/pact_broker/verifications/latest_verification_for_consumer_and_provider.rb +0 -3
  164. data/lib/pact_broker/verifications/latest_verification_id_for_pact_version_and_provider_version.rb +2 -4
  165. data/lib/pact_broker/verifications/repository.rb +2 -5
  166. data/lib/pact_broker/verifications/sequence.rb +1 -4
  167. data/lib/pact_broker/verifications/service.rb +4 -0
  168. data/lib/pact_broker/version.rb +1 -1
  169. data/lib/pact_broker/versions/branch.rb +2 -5
  170. data/lib/pact_broker/versions/branch_head.rb +0 -3
  171. data/lib/pact_broker/versions/branch_repository.rb +76 -0
  172. data/lib/pact_broker/versions/branch_service.rb +13 -25
  173. data/lib/pact_broker/versions/branch_version.rb +0 -3
  174. data/lib/pact_broker/versions/branch_version_repository.rb +17 -0
  175. data/lib/pact_broker/versions/repository.rb +19 -2
  176. data/lib/pact_broker/versions/sequence.rb +1 -3
  177. data/lib/pact_broker/versions/service.rb +4 -0
  178. data/lib/pact_broker/webhooks/execution.rb +3 -7
  179. data/lib/pact_broker/webhooks/job.rb +16 -7
  180. data/lib/pact_broker/webhooks/pact_and_verification_parameters.rb +2 -2
  181. data/lib/pact_broker/webhooks/repository.rb +0 -1
  182. data/lib/pact_broker/webhooks/trigger_service.rb +11 -12
  183. data/lib/pact_broker/webhooks/triggered_webhook.rb +3 -4
  184. data/lib/pact_broker/webhooks/webhook.rb +2 -2
  185. data/lib/pact_broker/webhooks/webhook_event.rb +2 -5
  186. data/lib/rack/pact_broker/add_cache_header.rb +14 -0
  187. data/lib/rack/pact_broker/application_context.rb +16 -0
  188. data/lib/rack/pact_broker/configurable_make_it_later.rb +1 -1
  189. data/lib/rack/pact_broker/invalid_uri_protection.rb +19 -3
  190. data/lib/webmachine/describe_routes.rb +55 -39
  191. data/lib/webmachine/render_error_monkey_patch.rb +13 -4
  192. data/pact_broker.gemspec +5 -5
  193. metadata +54 -31
  194. data/lib/pact_broker/api/decorators/decorator_context.rb +0 -22
  195. data/lib/pact_broker/matrix/query_builder.rb +0 -90
  196. data/lib/pact_broker/matrix/query_ids.rb +0 -40
  197. data/lib/pact_broker/matrix/quick_row.rb +0 -458
  198. data/lib/pact_broker/relationships/groupify.rb +0 -45
  199. data/lib/pact_broker/repositories/helpers.rb +0 -96
  200. data/lib/pact_broker/repositories/page.rb +0 -24
  201. 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
@@ -11,8 +11,13 @@ module PactBroker
11
11
  property :provider_name
12
12
  property :specification
13
13
  property :content_type
14
- property :decoded_content
14
+ property :decoded_content, setter: -> (fragment:, represented:, user_options:, **) {
15
+ represented.decoded_content = fragment
16
+ # Set the pact version sha when we set the content
17
+ represented.pact_version_sha = user_options.fetch(:sha_generator).call(fragment)
18
+ }
15
19
  property :on_conflict, default: "overwrite"
20
+
16
21
  end
17
22
  end
18
23
  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
@@ -16,7 +16,7 @@ module PactBroker
16
16
  property :name
17
17
  end
18
18
 
19
- property :uuid
19
+ property :uuid, writeable: false
20
20
 
21
21
  property :description, getter: lambda { |represented:, **| represented.display_description }
22
22
 
@@ -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",