Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Validation passes when array type is invalid #713

Open
guilherme-andrade opened this issue Sep 9, 2022 · 1 comment
Open

Validation passes when array type is invalid #713

guilherme-andrade opened this issue Sep 9, 2022 · 1 comment

Comments

@guilherme-andrade
Copy link

Describe the bug

When creating a custom type and using with the array rule, it appears that the validations applied by the type are not applied always by the rule. See the example below, and note that the last test is failing when it shouldn't:

To Reproduce

require 'dry/validation'
require 'dry/types'

module Types
  include Dry.Types(default: :nominal)

  StringOrHash = Types::Strict::String.enum('foo') | Types::Strict::Hash.schema(bar: Types::Strict::String.enum('baz'))
end


class TestContract < Dry::Validation::Contract
  params do
    required(:test).array(Types::StringOrHash)
  end
end

These tests all pass as expected:

RSpec.describe Types::StringOrHash do
  it 'works with a valid hash input' do
    expect { described_class[{ bar: 'baz' }] }.not_to raise_error
  end

  it 'works with a valid string input' do
    expect { described_class['foo'] }.not_to raise_error
  end

  it 'fails with an invalid string input' do
    expect { described_class['bar'] }.to raise_error
  end

  it 'fails with a hash with invalid values' do
    expect { described_class[{ bar: 'quz' }] }.to raise_error
  end

  it 'fails with a hash with invalid keys' do
    expect { described_class[{ quz: 'baz' }] }.to raise_error
  end
end

The first test passes, the second fails:

RSpec.describe TestContract do
  subject { described_class.new.call(params) }

  context 'when passing a valid array' do
    let(:params) { { test: ['foo', { bar: 'baz' }] } }

    it { is_expected.to be_success }
  end

  # THIS TEST FAILS
  context 'when passing an invalid array' do
    let(:params) { { test: ['foo', { bar: 'qux' }] } }

    it { is_expected.to be_failure }
  end
end

Expected behavior

It is expected that the validation fails when the input value is not of the described value.

My environment

  • Affects my production application: YES
  • Ruby version: 2.7.5
  • OS: MacOS Monterrey 12.0.1 (Apple chip)
@solnic
Copy link
Member

solnic commented Sep 12, 2022

Thanks for reporting this. Looks like the right-side hash type is not expanded fully to a schema rule:

dry-validation> TestContract.schema
=> #<Dry::Schema::Params keys=["test"] rules={:test=>"key?(:test) AND key[test](array? AND each(str? AND included_in?([\"foo\"]) OR hash?))"}>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants