aboutsummaryrefslogtreecommitdiffstats
path: root/activemodel/test/cases/validations/conditional_validation_test.rb
blob: c86124c8ea7445a16b5c08a7864bf0ad4ebb02cd (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# frozen_string_literal: true
require "cases/helper"

require "models/topic"

class ConditionalValidationTest < ActiveModel::TestCase
  def teardown
    Topic.clear_validators!
  end

  def test_if_validation_using_method_true
    # When the method returns true
    Topic.validates_length_of(:title, maximum: 5, too_long: "hoo %{count}", if: :condition_is_true)
    t = Topic.new("title" => "uhohuhoh", "content" => "whatever")
    assert t.invalid?
    assert t.errors[:title].any?
    assert_equal ["hoo 5"], t.errors["title"]
  end

  def test_unless_validation_using_method_true
    # When the method returns true
    Topic.validates_length_of(:title, maximum: 5, too_long: "hoo %{count}", unless: :condition_is_true)
    t = Topic.new("title" => "uhohuhoh", "content" => "whatever")
    assert t.valid?
    assert_empty t.errors[:title]
  end

  def test_if_validation_using_method_false
    # When the method returns false
    Topic.validates_length_of(:title, maximum: 5, too_long: "hoo %{count}", if: :condition_is_true_but_its_not)
    t = Topic.new("title" => "uhohuhoh", "content" => "whatever")
    assert t.valid?
    assert_empty t.errors[:title]
  end

  def test_unless_validation_using_method_false
    # When the method returns false
    Topic.validates_length_of(:title, maximum: 5, too_long: "hoo %{count}", unless: :condition_is_true_but_its_not)
    t = Topic.new("title" => "uhohuhoh", "content" => "whatever")
    assert t.invalid?
    assert t.errors[:title].any?
    assert_equal ["hoo 5"], t.errors["title"]
  end

  def test_if_validation_using_string_true
    # When the evaluated string returns true
    ActiveSupport::Deprecation.silence do
      Topic.validates_length_of(:title, maximum: 5, too_long: "hoo %{count}", if: "a = 1; a == 1")
    end
    t = Topic.new("title" => "uhohuhoh", "content" => "whatever")
    assert t.invalid?
    assert t.errors[:title].any?
    assert_equal ["hoo 5"], t.errors["title"]
  end

  def test_unless_validation_using_string_true
    # When the evaluated string returns true
    ActiveSupport::Deprecation.silence do
      Topic.validates_length_of(:title, maximum: 5, too_long: "hoo %{count}", unless: "a = 1; a == 1")
    end
    t = Topic.new("title" => "uhohuhoh", "content" => "whatever")
    assert t.valid?
    assert_empty t.errors[:title]
  end

  def test_if_validation_using_string_false
    # When the evaluated string returns false
    ActiveSupport::Deprecation.silence do
      Topic.validates_length_of(:title, maximum: 5, too_long: "hoo %{count}", if: "false")
    end
    t = Topic.new("title" => "uhohuhoh", "content" => "whatever")
    assert t.valid?
    assert_empty t.errors[:title]
  end

  def test_unless_validation_using_string_false
    # When the evaluated string returns false
    ActiveSupport::Deprecation.silence do
      Topic.validates_length_of(:title, maximum: 5, too_long: "hoo %{count}", unless: "false")
    end
    t = Topic.new("title" => "uhohuhoh", "content" => "whatever")
    assert t.invalid?
    assert t.errors[:title].any?
    assert_equal ["hoo 5"], t.errors["title"]
  end

  def test_if_validation_using_block_true
    # When the block returns true
    Topic.validates_length_of(:title, maximum: 5, too_long: "hoo %{count}",
      if: Proc.new { |r| r.content.size > 4 })
    t = Topic.new("title" => "uhohuhoh", "content" => "whatever")
    assert t.invalid?
    assert t.errors[:title].any?
    assert_equal ["hoo 5"], t.errors["title"]
  end

  def test_unless_validation_using_block_true
    # When the block returns true
    Topic.validates_length_of(:title, maximum: 5, too_long: "hoo %{count}",
      unless: Proc.new { |r| r.content.size > 4 })
    t = Topic.new("title" => "uhohuhoh", "content" => "whatever")
    assert t.valid?
    assert_empty t.errors[:title]
  end

  def test_if_validation_using_block_false
    # When the block returns false
    Topic.validates_length_of(:title, maximum: 5, too_long: "hoo %{count}",
      if: Proc.new { |r| r.title != "uhohuhoh" })
    t = Topic.new("title" => "uhohuhoh", "content" => "whatever")
    assert t.valid?
    assert_empty t.errors[:title]
  end

  def test_unless_validation_using_block_false
    # When the block returns false
    Topic.validates_length_of(:title, maximum: 5, too_long: "hoo %{count}",
      unless: Proc.new { |r| r.title != "uhohuhoh" })
    t = Topic.new("title" => "uhohuhoh", "content" => "whatever")
    assert t.invalid?
    assert t.errors[:title].any?
    assert_equal ["hoo 5"], t.errors["title"]
  end

  # previous implementation of validates_presence_of eval'd the
  # string with the wrong binding, this regression test is to
  # ensure that it works correctly
  def test_validation_with_if_as_string
    Topic.validates_presence_of(:title)
    ActiveSupport::Deprecation.silence do
      Topic.validates_presence_of(:author_name, if: "title.to_s.match('important')")
    end

    t = Topic.new
    assert t.invalid?, "A topic without a title should not be valid"
    assert_empty t.errors[:author_name], "A topic without an 'important' title should not require an author"

    t.title = "Just a title"
    assert t.valid?, "A topic with a basic title should be valid"

    t.title = "A very important title"
    assert t.invalid?, "A topic with an important title, but without an author, should not be valid"
    assert t.errors[:author_name].any?, "A topic with an 'important' title should require an author"

    t.author_name = "Hubert J. Farnsworth"
    assert t.valid?, "A topic with an important title and author should be valid"
  end
end