Skip to content

Commit

Permalink
Merge pull request #706 from MatElGran/bugfix/invalid_substring_rule_…
Browse files Browse the repository at this point in the history
…keys

[changelog]

version: unreleased
fixed: "Raise an InvalidKeyErrors on substring of valid keys (issue #705 fixed via #706) (@MatElGran)"
  • Loading branch information
solnic authored Mar 15, 2022
2 parents 301e1fd + 5ede7ce commit 0f0791a
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 3 deletions.
8 changes: 5 additions & 3 deletions lib/dry/validation/contract/class_interface.rb
Original file line number Diff line number Diff line change
Expand Up @@ -158,11 +158,13 @@ def ensure_valid_keys(*keys)
valid_paths = key_map.to_dot_notation
key_paths = key_paths(keys)

invalid_keys = key_paths.map { |(key, path)|
unless valid_paths.any? { |vp| vp.include?(path) || vp.include?("#{path}[]") }
invalid_keys = key_paths.filter_map { |(key, path)|
if valid_paths.none? { |vp|
vp == path || vp.start_with?("#{path}.", "#{path}[]")
}
key
end
}.compact.uniq
}.uniq

return if invalid_keys.empty?

Expand Down
68 changes: 68 additions & 0 deletions spec/integration/contract/class_interface/rule_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,74 @@ def self.name
end
end

context "when keys are prefixes of valid keys" do
it "raises error with a list of symbol keys" do
expect { contract_class.rule(:details, :addres) }
.to raise_error(
Dry::Validation::InvalidKeysError,
"TestContract.rule specifies keys that are not defined by the schema: [:addres]"
)
end

it "raises error with a hash path" do
expect { contract_class.rule(details: :addres) }
.to raise_error(
Dry::Validation::InvalidKeysError,
"TestContract.rule specifies keys that are not defined by the schema: [{:details=>:addres}]"
)
end

it "raises error with a dot notation" do
expect { contract_class.rule("details.addres") }
.to raise_error(
Dry::Validation::InvalidKeysError,
'TestContract.rule specifies keys that are not defined by the schema: ["details.addres"]'
)
end

it "raises error with a hash path with multiple nested keys" do
expect { contract_class.rule(details: %i[addres]) }
.to raise_error(
Dry::Validation::InvalidKeysError,
"TestContract.rule specifies keys that are not defined by the schema: [{:details=>[:addres]}]"
)
end
end

context "when keys are suffixes of valid keys" do
it "raises error with a list of symbol keys" do
expect { contract_class.rule(:etails, :address) }
.to raise_error(
Dry::Validation::InvalidKeysError,
"TestContract.rule specifies keys that are not defined by the schema: [:etails, :address]"
)
end

it "raises error with a hash path" do
expect { contract_class.rule(etails: :address) }
.to raise_error(
Dry::Validation::InvalidKeysError,
"TestContract.rule specifies keys that are not defined by the schema: [{:etails=>:address}]"
)
end

it "raises error with a dot notation" do
expect { contract_class.rule("etails.address") }
.to raise_error(
Dry::Validation::InvalidKeysError,
'TestContract.rule specifies keys that are not defined by the schema: ["etails.address"]'
)
end

it "raises error with a hash path with multiple nested keys" do
expect { contract_class.rule(etails: %i[address]) }
.to raise_error(
Dry::Validation::InvalidKeysError,
"TestContract.rule specifies keys that are not defined by the schema: [{:etails=>[:address]}]"
)
end
end

describe "abstract contract" do
let(:abstract_contract) do
Class.new(Dry::Validation::Contract) do
Expand Down

0 comments on commit 0f0791a

Please sign in to comment.