Skip to content

Commit

Permalink
fix: add extra validation to ensure parsed content is a hash when pub…
Browse files Browse the repository at this point in the history
…lishing pacts
  • Loading branch information
bethesque committed May 8, 2023
1 parent 5af8917 commit 913e0a5
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,7 @@ class PublishContractsContractContract < BaseContract
rule(:consumerName).validate(:not_blank_if_present)
rule(:providerName).validate(:not_blank_if_present)

# validate_consumer_name_in_content
rule(:decodedParsedContent, :consumerName, :specification) do
consumer_name_in_content = values.dig(:decodedParsedContent, :consumer, :name)
if consumer_name_in_content && consumer_name_in_content != values[:consumerName]
base.failure(validation_message("consumer_name_in_content_mismatch", { consumer_name_in_content: consumer_name_in_content, consumer_name: values[:consumerName] }))
end
end

# validate_provider_name_in_content
rule(:decodedParsedContent, :providerName) do
provider_name_in_content = values.dig(:decodedParsedContent, :provider, :name)
if provider_name_in_content && provider_name_in_content != values[:providerName]
base.failure(validation_message("provider_name_in_content_mismatch", { provider_name_in_content: provider_name_in_content, provider_name: values[:providerName] }))
end
end

# validate_encoding
# validate_encoding (ensure all UTF-8 chars)
rule(:decodedContent) do
if value.nil?
base.failure(validation_message("base64"))
Expand All @@ -50,12 +34,39 @@ class PublishContractsContractContract < BaseContract
end
end

# validate_content_matches_content_type
# validate content could be parsed according to its content type
rule(:decodedParsedContent, :contentType) do
if values[:decodedParsedContent].nil? && values[:contentType]
base.failure(validation_message("invalid_content_for_content_type", { content_type: values[:contentType] }))
end
end

# validate parsed contract is a hash
rule(:decodedParsedContent, :contentType) do
if !base_rule_error? && !values[:decodedParsedContent].is_a?(Hash)
base.failure(validation_message("invalid_parsed_contract_class", { actual_class: values[:decodedParsedContent].class }))
end
end

# validate consumer name in content matches the details higher in the JSON document
rule(:decodedParsedContent, :consumerName, :specification) do
if !base_rule_error?
consumer_name_in_content = values.dig(:decodedParsedContent, :consumer, :name)
if consumer_name_in_content && consumer_name_in_content != values[:consumerName]
base.failure(validation_message("consumer_name_in_content_mismatch", { consumer_name_in_content: consumer_name_in_content, consumer_name: values[:consumerName] }))
end
end
end

# validate provider name in content matches the details higher in the JSON document
rule(:decodedParsedContent, :providerName) do
if !base_rule_error?
provider_name_in_content = values.dig(:decodedParsedContent, :provider, :name)
if provider_name_in_content && provider_name_in_content != values[:providerName]
base.failure(validation_message("provider_name_in_content_mismatch", { provider_name_in_content: provider_name_in_content, provider_name: values[:providerName] }))
end
end
end
end
end
end
Expand Down
1 change: 1 addition & 0 deletions lib/pact_broker/locale/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ en:
environment_with_name_not_found: "Environment with name '%{name}' does not exist"
cannot_modify_version_branch: "The branch for a pacticipant version cannot be changed once set (currently '%{old_branch}', proposed value '%{new_branch}'). Your pact publication/verification publication configurations may be in conflict with each other if you are seeing this error. If the current branch value is incorrect, you must delete the pacticipant version resource at %{version_url} and publish the pacts/verification results again with a consistent branch name."
invalid_content_for_content_type: "content could not be parsed as %{content_type}"
invalid_parsed_contract_class: "parsed content was expected to be a Hash but was a %{actual_class}"
cannot_set_currently_deployed_true: The currentlyDeployed property cannot be set back to true. Please record a new deployment.
cannot_set_currently_supported_true: The currentlySupported property cannot be set back to true. Please record a new deployment.
invalid_limit: The limit must be 1 or greater.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,12 @@ module Contracts
its([:contracts, 0]) { is_expected.to include "blank" }
end

context "when the contract has been successfully JSON parsed to an object that is not a hash" do
let(:decoded_parsed_content) { "contract" }

its([:contracts, 0]) { is_expected.to eq "parsed content was expected to be a Hash but was a String (at index 0)" }
end

context "when the consumer name is missing and there is a validation error with the content" do
let(:params) do
JSON.parse(File.read("spec/fixtures/invalid-publish-contract-body.json"), symbolize_names: true)
Expand Down

0 comments on commit 913e0a5

Please sign in to comment.