aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test/cases/validations/association_validation_test.rb
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/test/cases/validations/association_validation_test.rb')
-rw-r--r--activerecord/test/cases/validations/association_validation_test.rb99
1 files changed, 99 insertions, 0 deletions
diff --git a/activerecord/test/cases/validations/association_validation_test.rb b/activerecord/test/cases/validations/association_validation_test.rb
new file mode 100644
index 0000000000..ce6d42b34b
--- /dev/null
+++ b/activerecord/test/cases/validations/association_validation_test.rb
@@ -0,0 +1,99 @@
+# frozen_string_literal: true
+
+require "cases/helper"
+require "models/topic"
+require "models/reply"
+require "models/man"
+require "models/interest"
+
+class AssociationValidationTest < ActiveRecord::TestCase
+ fixtures :topics
+
+ repair_validations(Topic, Reply)
+
+ def test_validates_associated_many
+ Topic.validates_associated(:replies)
+ Reply.validates_presence_of(:content)
+ t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
+ t.replies << [r = Reply.new("title" => "A reply"), r2 = Reply.new("title" => "Another reply", "content" => "non-empty"), r3 = Reply.new("title" => "Yet another reply"), r4 = Reply.new("title" => "The last reply", "content" => "non-empty")]
+ assert_not_predicate t, :valid?
+ assert_predicate t.errors[:replies], :any?
+ assert_equal 1, r.errors.count # make sure all associated objects have been validated
+ assert_equal 0, r2.errors.count
+ assert_equal 1, r3.errors.count
+ assert_equal 0, r4.errors.count
+ r.content = r3.content = "non-empty"
+ assert_predicate t, :valid?
+ end
+
+ def test_validates_associated_one
+ Reply.validates :topic, associated: true
+ Topic.validates_presence_of(:content)
+ r = Reply.new("title" => "A reply", "content" => "with content!")
+ r.topic = Topic.create("title" => "uhohuhoh")
+ assert_not_predicate r, :valid?
+ assert_predicate r.errors[:topic], :any?
+ r.topic.content = "non-empty"
+ assert_predicate r, :valid?
+ end
+
+ def test_validates_associated_marked_for_destruction
+ Topic.validates_associated(:replies)
+ Reply.validates_presence_of(:content)
+ t = Topic.new
+ t.replies << Reply.new
+ assert_predicate t, :invalid?
+ t.replies.first.mark_for_destruction
+ assert_predicate t, :valid?
+ end
+
+ def test_validates_associated_without_marked_for_destruction
+ reply = Class.new do
+ def valid?
+ true
+ end
+ end
+ Topic.validates_associated(:replies)
+ t = Topic.new
+ t.define_singleton_method(:replies) { [reply.new] }
+ assert_predicate t, :valid?
+ end
+
+ def test_validates_associated_with_custom_message_using_quotes
+ Reply.validates_associated :topic, message: "This string contains 'single' and \"double\" quotes"
+ Topic.validates_presence_of :content
+ r = Reply.create("title" => "A reply", "content" => "with content!")
+ r.topic = Topic.create("title" => "uhohuhoh")
+ assert_not_operator r, :valid?
+ assert_equal ["This string contains 'single' and \"double\" quotes"], r.errors[:topic]
+ end
+
+ def test_validates_associated_missing
+ Reply.validates_presence_of(:topic)
+ r = Reply.create("title" => "A reply", "content" => "with content!")
+ assert_not_predicate r, :valid?
+ assert_predicate r.errors[:topic], :any?
+
+ r.topic = Topic.first
+ assert_predicate r, :valid?
+ end
+
+ def test_validates_presence_of_belongs_to_association__parent_is_new_record
+ repair_validations(Interest) do
+ # Note that Interest and Man have the :inverse_of option set
+ Interest.validates_presence_of(:man)
+ man = Man.new(name: "John")
+ interest = man.interests.build(topic: "Airplanes")
+ assert interest.valid?, "Expected interest to be valid, but was not. Interest should have a man object associated"
+ end
+ end
+
+ def test_validates_presence_of_belongs_to_association__existing_parent
+ repair_validations(Interest) do
+ Interest.validates_presence_of(:man)
+ man = Man.create!(name: "John")
+ interest = man.interests.build(topic: "Airplanes")
+ assert interest.valid?, "Expected interest to be valid, but was not. Interest should have a man object associated"
+ end
+ end
+end