dry-rb/dry-validation

Validation passes when array type is invalid

Open

#713 opened on Sep 9, 2022

View on GitHub
 (1 comment) (0 reactions) (0 assignees)Ruby (193 forks)github user discovery
bughelp wanted

Repository metrics

Stars
 (1,421 stars)
PR merge metrics
 (PR metrics pending)

Description

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)

Contributor guide