2e81ca2d30
Updated to Rails 2.2.2. Added a couple more Ruby 1.9 fixes, but that's pretty much at a standstill, until one gets Maruku and HTML5lib working right under Ruby 1.9.
442 lines
13 KiB
Ruby
442 lines
13 KiB
Ruby
require "cases/helper"
|
|
require 'models/developer'
|
|
require 'models/project'
|
|
require 'models/company'
|
|
require 'models/topic'
|
|
require 'models/reply'
|
|
require 'models/computer'
|
|
require 'models/customer'
|
|
require 'models/order'
|
|
require 'models/post'
|
|
require 'models/author'
|
|
require 'models/tag'
|
|
require 'models/tagging'
|
|
require 'models/comment'
|
|
require 'models/sponsor'
|
|
require 'models/member'
|
|
|
|
class BelongsToAssociationsTest < ActiveRecord::TestCase
|
|
fixtures :accounts, :companies, :developers, :projects, :topics,
|
|
:developers_projects, :computers, :authors, :posts, :tags, :taggings, :comments
|
|
|
|
def test_belongs_to
|
|
Client.find(3).firm.name
|
|
assert_equal companies(:first_firm).name, Client.find(3).firm.name
|
|
assert !Client.find(3).firm.nil?, "Microsoft should have a firm"
|
|
end
|
|
|
|
def test_proxy_assignment
|
|
account = Account.find(1)
|
|
assert_nothing_raised { account.firm = account.firm }
|
|
end
|
|
|
|
def test_triple_equality
|
|
assert Client.find(3).firm === Firm
|
|
assert Firm === Client.find(3).firm
|
|
end
|
|
|
|
def test_type_mismatch
|
|
assert_raise(ActiveRecord::AssociationTypeMismatch) { Account.find(1).firm = 1 }
|
|
assert_raise(ActiveRecord::AssociationTypeMismatch) { Account.find(1).firm = Project.find(1) }
|
|
end
|
|
|
|
def test_natural_assignment
|
|
apple = Firm.create("name" => "Apple")
|
|
citibank = Account.create("credit_limit" => 10)
|
|
citibank.firm = apple
|
|
assert_equal apple.id, citibank.firm_id
|
|
end
|
|
|
|
def test_no_unexpected_aliasing
|
|
first_firm = companies(:first_firm)
|
|
another_firm = companies(:another_firm)
|
|
|
|
citibank = Account.create("credit_limit" => 10)
|
|
citibank.firm = first_firm
|
|
original_proxy = citibank.firm
|
|
citibank.firm = another_firm
|
|
|
|
assert_equal first_firm.object_id, original_proxy.target.object_id
|
|
assert_equal another_firm.object_id, citibank.firm.target.object_id
|
|
end
|
|
|
|
def test_creating_the_belonging_object
|
|
citibank = Account.create("credit_limit" => 10)
|
|
apple = citibank.create_firm("name" => "Apple")
|
|
assert_equal apple, citibank.firm
|
|
citibank.save
|
|
citibank.reload
|
|
assert_equal apple, citibank.firm
|
|
end
|
|
|
|
def test_building_the_belonging_object
|
|
citibank = Account.create("credit_limit" => 10)
|
|
apple = citibank.build_firm("name" => "Apple")
|
|
citibank.save
|
|
assert_equal apple.id, citibank.firm_id
|
|
end
|
|
|
|
def test_natural_assignment_to_nil
|
|
client = Client.find(3)
|
|
client.firm = nil
|
|
client.save
|
|
assert_nil client.firm(true)
|
|
assert_nil client.client_of
|
|
end
|
|
|
|
def test_with_different_class_name
|
|
assert_equal Company.find(1).name, Company.find(3).firm_with_other_name.name
|
|
assert_not_nil Company.find(3).firm_with_other_name, "Microsoft should have a firm"
|
|
end
|
|
|
|
def test_with_condition
|
|
assert_equal Company.find(1).name, Company.find(3).firm_with_condition.name
|
|
assert_not_nil Company.find(3).firm_with_condition, "Microsoft should have a firm"
|
|
end
|
|
|
|
def test_with_select
|
|
assert_equal Company.find(2).firm_with_select.attributes.size, 1
|
|
assert_equal Company.find(2, :include => :firm_with_select ).firm_with_select.attributes.size, 1
|
|
end
|
|
|
|
def test_belongs_to_counter
|
|
debate = Topic.create("title" => "debate")
|
|
assert_equal 0, debate.send(:read_attribute, "replies_count"), "No replies yet"
|
|
|
|
trash = debate.replies.create("title" => "blah!", "content" => "world around!")
|
|
assert_equal 1, Topic.find(debate.id).send(:read_attribute, "replies_count"), "First reply created"
|
|
|
|
trash.destroy
|
|
assert_equal 0, Topic.find(debate.id).send(:read_attribute, "replies_count"), "First reply deleted"
|
|
end
|
|
|
|
def test_belongs_to_counter_with_assigning_nil
|
|
p = Post.find(1)
|
|
c = Comment.find(1)
|
|
|
|
assert_equal p.id, c.post_id
|
|
assert_equal 2, Post.find(p.id).comments.size
|
|
|
|
c.post = nil
|
|
|
|
assert_equal 1, Post.find(p.id).comments.size
|
|
end
|
|
|
|
def test_belongs_to_counter_with_reassigning
|
|
t1 = Topic.create("title" => "t1")
|
|
t2 = Topic.create("title" => "t2")
|
|
r1 = Reply.new("title" => "r1", "content" => "r1")
|
|
r1.topic = t1
|
|
|
|
assert r1.save
|
|
assert_equal 1, Topic.find(t1.id).replies.size
|
|
assert_equal 0, Topic.find(t2.id).replies.size
|
|
|
|
r1.topic = Topic.find(t2.id)
|
|
|
|
assert r1.save
|
|
assert_equal 0, Topic.find(t1.id).replies.size
|
|
assert_equal 1, Topic.find(t2.id).replies.size
|
|
|
|
r1.topic = nil
|
|
|
|
assert_equal 0, Topic.find(t1.id).replies.size
|
|
assert_equal 0, Topic.find(t2.id).replies.size
|
|
|
|
r1.topic = t1
|
|
|
|
assert_equal 1, Topic.find(t1.id).replies.size
|
|
assert_equal 0, Topic.find(t2.id).replies.size
|
|
|
|
r1.destroy
|
|
|
|
assert_equal 0, Topic.find(t1.id).replies.size
|
|
assert_equal 0, Topic.find(t2.id).replies.size
|
|
end
|
|
|
|
def test_belongs_to_counter_after_save
|
|
topic = Topic.create!(:title => "monday night")
|
|
topic.replies.create!(:title => "re: monday night", :content => "football")
|
|
assert_equal 1, Topic.find(topic.id)[:replies_count]
|
|
|
|
topic.save!
|
|
assert_equal 1, Topic.find(topic.id)[:replies_count]
|
|
end
|
|
|
|
def test_belongs_to_counter_after_update_attributes
|
|
topic = Topic.create!(:title => "37s")
|
|
topic.replies.create!(:title => "re: 37s", :content => "rails")
|
|
assert_equal 1, Topic.find(topic.id)[:replies_count]
|
|
|
|
topic.update_attributes(:title => "37signals")
|
|
assert_equal 1, Topic.find(topic.id)[:replies_count]
|
|
end
|
|
|
|
def test_belongs_to_counter_after_save
|
|
topic = Topic.create("title" => "monday night")
|
|
topic.replies.create("title" => "re: monday night", "content" => "football")
|
|
assert_equal 1, Topic.find(topic.id).send(:read_attribute, "replies_count")
|
|
|
|
topic.save
|
|
assert_equal 1, Topic.find(topic.id).send(:read_attribute, "replies_count")
|
|
end
|
|
|
|
def test_belongs_to_counter_after_update_attributes
|
|
topic = Topic.create("title" => "37s")
|
|
topic.replies.create("title" => "re: 37s", "content" => "rails")
|
|
assert_equal 1, Topic.find(topic.id).send(:read_attribute, "replies_count")
|
|
|
|
topic.update_attributes("title" => "37signals")
|
|
assert_equal 1, Topic.find(topic.id).send(:read_attribute, "replies_count")
|
|
end
|
|
|
|
def test_assignment_before_parent_saved
|
|
client = Client.find(:first)
|
|
apple = Firm.new("name" => "Apple")
|
|
client.firm = apple
|
|
assert_equal apple, client.firm
|
|
assert apple.new_record?
|
|
assert client.save
|
|
assert apple.save
|
|
assert !apple.new_record?
|
|
assert_equal apple, client.firm
|
|
assert_equal apple, client.firm(true)
|
|
end
|
|
|
|
def test_assignment_before_child_saved
|
|
final_cut = Client.new("name" => "Final Cut")
|
|
firm = Firm.find(1)
|
|
final_cut.firm = firm
|
|
assert final_cut.new_record?
|
|
assert final_cut.save
|
|
assert !final_cut.new_record?
|
|
assert !firm.new_record?
|
|
assert_equal firm, final_cut.firm
|
|
assert_equal firm, final_cut.firm(true)
|
|
end
|
|
|
|
def test_assignment_before_either_saved
|
|
final_cut = Client.new("name" => "Final Cut")
|
|
apple = Firm.new("name" => "Apple")
|
|
final_cut.firm = apple
|
|
assert final_cut.new_record?
|
|
assert apple.new_record?
|
|
assert final_cut.save
|
|
assert !final_cut.new_record?
|
|
assert !apple.new_record?
|
|
assert_equal apple, final_cut.firm
|
|
assert_equal apple, final_cut.firm(true)
|
|
end
|
|
|
|
def test_new_record_with_foreign_key_but_no_object
|
|
c = Client.new("firm_id" => 1)
|
|
assert_equal Firm.find(:first), c.firm_with_basic_id
|
|
end
|
|
|
|
def test_forgetting_the_load_when_foreign_key_enters_late
|
|
c = Client.new
|
|
assert_nil c.firm_with_basic_id
|
|
|
|
c.firm_id = 1
|
|
assert_equal Firm.find(:first), c.firm_with_basic_id
|
|
end
|
|
|
|
def test_field_name_same_as_foreign_key
|
|
computer = Computer.find(1)
|
|
assert_not_nil computer.developer, ":foreign key == attribute didn't lock up" # '
|
|
end
|
|
|
|
def test_counter_cache
|
|
topic = Topic.create :title => "Zoom-zoom-zoom"
|
|
assert_equal 0, topic[:replies_count]
|
|
|
|
reply = Reply.create(:title => "re: zoom", :content => "speedy quick!")
|
|
reply.topic = topic
|
|
|
|
assert_equal 1, topic.reload[:replies_count]
|
|
assert_equal 1, topic.replies.size
|
|
|
|
topic[:replies_count] = 15
|
|
assert_equal 15, topic.replies.size
|
|
end
|
|
|
|
def test_custom_counter_cache
|
|
reply = Reply.create(:title => "re: zoom", :content => "speedy quick!")
|
|
assert_equal 0, reply[:replies_count]
|
|
|
|
silly = SillyReply.create(:title => "gaga", :content => "boo-boo")
|
|
silly.reply = reply
|
|
|
|
assert_equal 1, reply.reload[:replies_count]
|
|
assert_equal 1, reply.replies.size
|
|
|
|
reply[:replies_count] = 17
|
|
assert_equal 17, reply.replies.size
|
|
end
|
|
|
|
def test_store_two_association_with_one_save
|
|
num_orders = Order.count
|
|
num_customers = Customer.count
|
|
order = Order.new
|
|
|
|
customer1 = order.billing = Customer.new
|
|
customer2 = order.shipping = Customer.new
|
|
assert order.save
|
|
assert_equal customer1, order.billing
|
|
assert_equal customer2, order.shipping
|
|
|
|
order.reload
|
|
|
|
assert_equal customer1, order.billing
|
|
assert_equal customer2, order.shipping
|
|
|
|
assert_equal num_orders +1, Order.count
|
|
assert_equal num_customers +2, Customer.count
|
|
end
|
|
|
|
|
|
def test_store_association_in_two_relations_with_one_save
|
|
num_orders = Order.count
|
|
num_customers = Customer.count
|
|
order = Order.new
|
|
|
|
customer = order.billing = order.shipping = Customer.new
|
|
assert order.save
|
|
assert_equal customer, order.billing
|
|
assert_equal customer, order.shipping
|
|
|
|
order.reload
|
|
|
|
assert_equal customer, order.billing
|
|
assert_equal customer, order.shipping
|
|
|
|
assert_equal num_orders +1, Order.count
|
|
assert_equal num_customers +1, Customer.count
|
|
end
|
|
|
|
def test_store_association_in_two_relations_with_one_save_in_existing_object
|
|
num_orders = Order.count
|
|
num_customers = Customer.count
|
|
order = Order.create
|
|
|
|
customer = order.billing = order.shipping = Customer.new
|
|
assert order.save
|
|
assert_equal customer, order.billing
|
|
assert_equal customer, order.shipping
|
|
|
|
order.reload
|
|
|
|
assert_equal customer, order.billing
|
|
assert_equal customer, order.shipping
|
|
|
|
assert_equal num_orders +1, Order.count
|
|
assert_equal num_customers +1, Customer.count
|
|
end
|
|
|
|
def test_store_association_in_two_relations_with_one_save_in_existing_object_with_values
|
|
num_orders = Order.count
|
|
num_customers = Customer.count
|
|
order = Order.create
|
|
|
|
customer = order.billing = order.shipping = Customer.new
|
|
assert order.save
|
|
assert_equal customer, order.billing
|
|
assert_equal customer, order.shipping
|
|
|
|
order.reload
|
|
|
|
customer = order.billing = order.shipping = Customer.new
|
|
|
|
assert order.save
|
|
order.reload
|
|
|
|
assert_equal customer, order.billing
|
|
assert_equal customer, order.shipping
|
|
|
|
assert_equal num_orders +1, Order.count
|
|
assert_equal num_customers +2, Customer.count
|
|
end
|
|
|
|
|
|
def test_association_assignment_sticks
|
|
post = Post.find(:first)
|
|
|
|
author1, author2 = Author.find(:all, :limit => 2)
|
|
assert_not_nil author1
|
|
assert_not_nil author2
|
|
|
|
# make sure the association is loaded
|
|
post.author
|
|
|
|
# set the association by id, directly
|
|
post.author_id = author2.id
|
|
|
|
# save and reload
|
|
post.save!
|
|
post.reload
|
|
|
|
# the author id of the post should be the id we set
|
|
assert_equal post.author_id, author2.id
|
|
end
|
|
|
|
def test_cant_save_readonly_association
|
|
assert_raise(ActiveRecord::ReadOnlyRecord) { companies(:first_client).readonly_firm.save! }
|
|
assert companies(:first_client).readonly_firm.readonly?
|
|
end
|
|
|
|
def test_polymorphic_assignment_foreign_type_field_updating
|
|
# should update when assigning a saved record
|
|
sponsor = Sponsor.new
|
|
member = Member.create
|
|
sponsor.sponsorable = member
|
|
assert_equal "Member", sponsor.sponsorable_type
|
|
|
|
# should update when assigning a new record
|
|
sponsor = Sponsor.new
|
|
member = Member.new
|
|
sponsor.sponsorable = member
|
|
assert_equal "Member", sponsor.sponsorable_type
|
|
end
|
|
|
|
def test_polymorphic_assignment_updates_foreign_id_field_for_new_and_saved_records
|
|
sponsor = Sponsor.new
|
|
saved_member = Member.create
|
|
new_member = Member.new
|
|
|
|
sponsor.sponsorable = saved_member
|
|
assert_equal saved_member.id, sponsor.sponsorable_id
|
|
|
|
sponsor.sponsorable = new_member
|
|
assert_equal nil, sponsor.sponsorable_id
|
|
end
|
|
|
|
def test_save_fails_for_invalid_belongs_to
|
|
assert log = AuditLog.create(:developer_id=>0,:message=>"")
|
|
|
|
log.developer = Developer.new
|
|
assert !log.developer.valid?
|
|
assert !log.valid?
|
|
assert !log.save
|
|
assert_equal "is invalid", log.errors.on("developer")
|
|
end
|
|
|
|
def test_save_succeeds_for_invalid_belongs_to_with_validate_false
|
|
assert log = AuditLog.create(:developer_id=>0,:message=>"")
|
|
|
|
log.unvalidated_developer = Developer.new
|
|
assert !log.unvalidated_developer.valid?
|
|
assert log.valid?
|
|
assert log.save
|
|
end
|
|
|
|
def test_belongs_to_proxy_should_not_respond_to_private_methods
|
|
assert_raises(NoMethodError) { companies(:first_firm).private_method }
|
|
assert_raises(NoMethodError) { companies(:second_client).firm.private_method }
|
|
end
|
|
|
|
def test_belongs_to_proxy_should_respond_to_private_methods_via_send
|
|
companies(:first_firm).send(:private_method)
|
|
companies(:second_client).firm.send(:private_method)
|
|
end
|
|
end
|