diff options
Diffstat (limited to 'activerecord/test/cases')
18 files changed, 766 insertions, 38 deletions
diff --git a/activerecord/test/cases/adapters/mysql/schema_test.rb b/activerecord/test/cases/adapters/mysql/schema_test.rb index c6c1d1dad5..a2155d1dd1 100644 --- a/activerecord/test/cases/adapters/mysql/schema_test.rb +++ b/activerecord/test/cases/adapters/mysql/schema_test.rb @@ -31,6 +31,6 @@ module ActiveRecord def test_table_exists_wrong_schema assert(!@connection.table_exists?("#{@db_name}.zomg"), "table should not exist") end - end if current_adapter?(:MysqlAdapter) + end end end diff --git a/activerecord/test/cases/adapters/mysql2/schema_test.rb b/activerecord/test/cases/adapters/mysql2/schema_test.rb new file mode 100644 index 0000000000..858d1da2dd --- /dev/null +++ b/activerecord/test/cases/adapters/mysql2/schema_test.rb @@ -0,0 +1,36 @@ +require "cases/helper" +require 'models/post' +require 'models/comment' + +module ActiveRecord + module ConnectionAdapters + class Mysql2SchemaTest < ActiveRecord::TestCase + fixtures :posts + + def setup + @connection = ActiveRecord::Base.connection + db = Post.connection_pool.spec.config[:database] + table = Post.table_name + @db_name = db + + @omgpost = Class.new(Post) do + set_table_name "#{db}.#{table}" + def self.name; 'Post'; end + end + end + + def test_schema + assert @omgpost.find(:first) + end + + def test_table_exists? + name = @omgpost.table_name + assert @connection.table_exists?(name), "#{name} table should exist" + end + + def test_table_exists_wrong_schema + assert(!@connection.table_exists?("#{@db_name}.zomg"), "table should not exist") + end + end + end +end diff --git a/activerecord/test/cases/adapters/postgresql/datatype_test.rb b/activerecord/test/cases/adapters/postgresql/datatype_test.rb index 5bb8fa2f93..ce08e4c6a7 100644 --- a/activerecord/test/cases/adapters/postgresql/datatype_test.rb +++ b/activerecord/test/cases/adapters/postgresql/datatype_test.rb @@ -3,6 +3,9 @@ require "cases/helper" class PostgresqlArray < ActiveRecord::Base end +class PostgresqlTsvector < ActiveRecord::Base +end + class PostgresqlMoney < ActiveRecord::Base end @@ -34,6 +37,9 @@ class PostgresqlDataTypeTest < ActiveRecord::TestCase @connection.execute("INSERT INTO postgresql_arrays (commission_by_quarter, nicknames) VALUES ( '{35000,21000,18000,17000}', '{foo,bar,baz}' )") @first_array = PostgresqlArray.find(1) + @connection.execute("INSERT INTO postgresql_tsvectors (text_vector) VALUES (' ''text'' ''vector'' ')") + @first_tsvector = PostgresqlTsvector.find(1) + @connection.execute("INSERT INTO postgresql_moneys (wealth) VALUES ('567.89'::money)") @connection.execute("INSERT INTO postgresql_moneys (wealth) VALUES ('-567.89'::money)") @first_money = PostgresqlMoney.find(1) @@ -62,6 +68,10 @@ class PostgresqlDataTypeTest < ActiveRecord::TestCase assert_equal :string, @first_array.column_for_attribute(:nicknames).type end + def test_data_type_of_tsvector_types + assert_equal :tsvector, @first_tsvector.column_for_attribute(:text_vector).type + end + def test_data_type_of_money_types assert_equal :decimal, @first_money.column_for_attribute(:wealth).type end @@ -95,11 +105,26 @@ class PostgresqlDataTypeTest < ActiveRecord::TestCase assert_equal '{foo,bar,baz}', @first_array.nicknames end + def test_tsvector_values + assert_equal "'text' 'vector'", @first_tsvector.text_vector + end + def test_money_values assert_equal 567.89, @first_money.wealth assert_equal(-567.89, @second_money.wealth) end + def test_update_tsvector + new_text_vector = "'new' 'text' 'vector'" + assert @first_tsvector.text_vector = new_text_vector + assert @first_tsvector.save + assert @first_tsvector.reload + assert @first_tsvector.text_vector = new_text_vector + assert @first_tsvector.save + assert @first_tsvector.reload + assert_equal @first_tsvector.text_vector, new_text_vector + end + def test_number_values assert_equal 123.456, @first_number.single assert_equal 123456.789, @first_number.double diff --git a/activerecord/test/cases/associations/belongs_to_associations_test.rb b/activerecord/test/cases/associations/belongs_to_associations_test.rb index 9006914508..ddcc36c841 100644 --- a/activerecord/test/cases/associations/belongs_to_associations_test.rb +++ b/activerecord/test/cases/associations/belongs_to_associations_test.rb @@ -580,7 +580,7 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase post = posts(:welcome) comment = comments(:greetings) - assert_difference 'post.reload.taggings_count', -1 do + assert_difference lambda { post.reload.taggings_count }, -1 do assert_difference 'comment.reload.taggings_count', +1 do tagging.taggable = comment end diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb index 9bc7910fc6..3e92a77830 100644 --- a/activerecord/test/cases/associations/eager_test.rb +++ b/activerecord/test/cases/associations/eager_test.rb @@ -170,10 +170,10 @@ class EagerAssociationTest < ActiveRecord::TestCase assert_equal [comment], category.posts[0].comments end end - + def test_associations_loaded_for_all_records post = Post.create!(:title => 'foo', :body => "I like cars!") - comment = SpecialComment.create!(:body => 'Come on!', :post => post) + SpecialComment.create!(:body => 'Come on!', :post => post) first_category = Category.create! :name => 'First!', :posts => [post] second_category = Category.create! :name => 'Second!', :posts => [post] diff --git a/activerecord/test/cases/associations/has_many_through_associations_test.rb b/activerecord/test/cases/associations/has_many_through_associations_test.rb index 70a4e06dbe..89117593fd 100644 --- a/activerecord/test/cases/associations/has_many_through_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_through_associations_test.rb @@ -760,7 +760,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase def test_primary_key_option_on_source post = posts(:welcome) category = categories(:general) - categorization = Categorization.create!(:post_id => post.id, :named_category_name => category.name) + Categorization.create!(:post_id => post.id, :named_category_name => category.name) assert_equal [category], post.named_categories assert_equal [category.name], post.named_category_ids # checks when target loaded diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index 815ff7b825..5ee3b2d776 100644 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -18,7 +18,7 @@ require 'models/comment' require 'models/minimalistic' require 'models/warehouse_thing' require 'models/parrot' -require 'models/loose_person' +require 'models/person' require 'models/edge' require 'models/joke' require 'rexml/document' @@ -489,6 +489,12 @@ class BasicsTest < ActiveRecord::TestCase assert_equal 'value2', weird.send('a$b') end + def test_attributes_guard_protected_attributes_is_deprecated + attributes = { "title" => "An amazing title" } + topic = Topic.new + assert_deprecated { topic.send(:attributes=, attributes, false) } + end + def test_multiparameter_attributes_on_date attributes = { "last_read(1i)" => "2004", "last_read(2i)" => "6", "last_read(3i)" => "24" } topic = Topic.find(1) diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb index 655437318f..be4ba18555 100644 --- a/activerecord/test/cases/finder_test.rb +++ b/activerecord/test/cases/finder_test.rb @@ -1045,6 +1045,29 @@ class FinderTest < ActiveRecord::TestCase :order => ' author_addresses_authors.id DESC ', :limit => 3).size end + def test_find_with_nil_inside_set_passed_for_one_attribute + client_of = Company.find( + :all, + :conditions => { + :client_of => [2, 1, nil], + :name => ['37signals', 'Summit', 'Microsoft'] }, + :order => 'client_of DESC' + ).map { |x| x.client_of } + + assert client_of.include?(nil) + assert_equal [2, 1].sort, client_of.compact.sort + end + + def test_find_with_nil_inside_set_passed_for_attribute + client_of = Company.find( + :all, + :conditions => { :client_of => [nil] }, + :order => 'client_of DESC' + ).map { |x| x.client_of } + + assert_equal [], client_of.compact + end + def test_with_limiting_with_custom_select posts = Post.find(:all, :include => :author, :select => ' posts.*, authors.id as "author_id"', :limit => 3, :order => 'posts.id') assert_equal 3, posts.size diff --git a/activerecord/test/cases/fixtures_test.rb b/activerecord/test/cases/fixtures_test.rb index fa40fad56d..3e20155210 100644 --- a/activerecord/test/cases/fixtures_test.rb +++ b/activerecord/test/cases/fixtures_test.rb @@ -45,6 +45,11 @@ class FixturesTest < ActiveRecord::TestCase end end + def test_create_fixtures + Fixtures.create_fixtures(FIXTURES_ROOT, "parrots") + assert Parrot.find_by_name('Curious George'), 'George is in the database' + end + def test_multiple_clean_fixtures fixtures_array = nil assert_nothing_raised { fixtures_array = create_fixtures(*FIXTURES) } diff --git a/activerecord/test/cases/identity_map/middleware_test.rb b/activerecord/test/cases/identity_map/middleware_test.rb new file mode 100644 index 0000000000..60dcad4586 --- /dev/null +++ b/activerecord/test/cases/identity_map/middleware_test.rb @@ -0,0 +1,71 @@ +require "cases/helper" + +module ActiveRecord + module IdentityMap + class MiddlewareTest < ActiveRecord::TestCase + def setup + super + @enabled = IdentityMap.enabled + IdentityMap.enabled = false + end + + def teardown + super + IdentityMap.enabled = @enabled + IdentityMap.clear + end + + def test_delegates + called = false + mw = Middleware.new lambda { |env| + called = true + } + mw.call({}) + assert called, 'middleware delegated' + end + + def test_im_enabled_during_delegation + mw = Middleware.new lambda { |env| + assert IdentityMap.enabled?, 'identity map should be enabled' + } + mw.call({}) + end + + class Enum < Struct.new(:iter) + def each(&b) + iter.call(&b) + end + end + + def test_im_enabled_during_body_each + mw = Middleware.new lambda { |env| + [200, {}, Enum.new(lambda { |&b| + assert IdentityMap.enabled?, 'identity map should be enabled' + b.call "hello" + })] + } + body = mw.call({}).last + body.each { |x| assert_equal 'hello', x } + end + + def test_im_disabled_after_body_close + mw = Middleware.new lambda { |env| [200, {}, []] } + body = mw.call({}).last + assert IdentityMap.enabled?, 'identity map should be enabled' + body.close + assert !IdentityMap.enabled?, 'identity map should be disabled' + end + + def test_im_cleared_after_body_close + mw = Middleware.new lambda { |env| [200, {}, []] } + body = mw.call({}).last + + IdentityMap.repository['hello'] = 'world' + assert !IdentityMap.repository.empty?, 'repo should not be empty' + + body.close + assert IdentityMap.repository.empty?, 'repo should be empty' + end + end + end +end diff --git a/activerecord/test/cases/identity_map_test.rb b/activerecord/test/cases/identity_map_test.rb index 199e59657d..649715fbb5 100644 --- a/activerecord/test/cases/identity_map_test.rb +++ b/activerecord/test/cases/identity_map_test.rb @@ -1,4 +1,5 @@ require "cases/helper" + require 'models/developer' require 'models/project' require 'models/company' @@ -137,8 +138,6 @@ class IdentityMapTest < ActiveRecord::TestCase assert_equal(["name"], swistak.changed) assert_equal({"name" => ["Marcin Raczkowski", "Swistak Sreberkowiec"]}, swistak.changes) - s = Subscriber.find('swistak') - assert swistak.name_changed? assert_equal("Swistak Sreberkowiec", swistak.name) end @@ -149,8 +148,6 @@ class IdentityMapTest < ActiveRecord::TestCase Subscriber.update_all({:name => "Raczkowski Marcin"}, {:name => "Marcin Raczkowski"}) - s = Subscriber.find('swistak') - assert_equal({"name"=>["Marcin Raczkowski", "Swistak Sreberkowiec"]}, swistak.changes) assert_equal("Swistak Sreberkowiec", swistak.name) end @@ -163,8 +160,6 @@ class IdentityMapTest < ActiveRecord::TestCase Subscriber.update_all({:name => "Swistak Sreberkowiec"}, {:name => "Marcin Raczkowski"}) - s = Subscriber.find('swistak') - assert_equal("Swistak Sreberkowiec", swistak.name) assert_equal({"name"=>["Marcin Raczkowski", "Swistak Sreberkowiec"]}, swistak.changes) assert swistak.name_changed? @@ -175,7 +170,7 @@ class IdentityMapTest < ActiveRecord::TestCase pirate.birds.create!(:name => 'Posideons Killer') pirate.birds.create!(:name => 'Killer bandita Dionne') - posideons, killer = pirate.birds + posideons, _ = pirate.birds pirate.reload @@ -388,15 +383,6 @@ class IdentityMapTest < ActiveRecord::TestCase assert_not_nil post.title end - def test_log - log = StringIO.new - ActiveRecord::Base.logger = Logger.new(log) - ActiveRecord::Base.logger.level = Logger::DEBUG - Post.find 1 - Post.find 1 - assert_match(/Post with ID = 1 loaded from Identity Map/, log.string) - end - # Currently AR is not allowing changing primary key (see Persistence#update) # So we ignore it. If this changes, this test needs to be uncommented. # def test_updating_of_pkey diff --git a/activerecord/test/cases/log_subscriber_test.rb b/activerecord/test/cases/log_subscriber_test.rb index 5f55299065..c6c6079490 100644 --- a/activerecord/test/cases/log_subscriber_test.rb +++ b/activerecord/test/cases/log_subscriber_test.rb @@ -1,11 +1,14 @@ require "cases/helper" require "models/developer" +require "models/post" require "active_support/log_subscriber/test_helper" class LogSubscriberTest < ActiveRecord::TestCase include ActiveSupport::LogSubscriber::TestHelper include ActiveSupport::BufferedLogger::Severity + fixtures :posts + def setup @old_logger = ActiveRecord::Base.logger @using_identity_map = ActiveRecord::IdentityMap.enabled? @@ -91,4 +94,13 @@ class LogSubscriberTest < ActiveRecord::TestCase def test_initializes_runtime Thread.new { assert_equal 0, ActiveRecord::LogSubscriber.runtime }.join end + + def test_log + ActiveRecord::IdentityMap.use do + Post.find 1 + Post.find 1 + end + wait + assert_match(/From Identity Map/, @logger.logged(:debug).last) + end end diff --git a/activerecord/test/cases/mass_assignment_security_test.rb b/activerecord/test/cases/mass_assignment_security_test.rb index 025ec1d3fa..fbbae99e8b 100644 --- a/activerecord/test/cases/mass_assignment_security_test.rb +++ b/activerecord/test/cases/mass_assignment_security_test.rb @@ -3,8 +3,65 @@ require 'models/company' require 'models/subscriber' require 'models/keyboard' require 'models/task' +require 'models/person' + + +module MassAssignmentTestHelpers + def setup + # another AR test modifies the columns which causes issues with create calls + TightPerson.reset_column_information + LoosePerson.reset_column_information + end + + def attributes_hash + { + :id => 5, + :first_name => 'Josh', + :gender => 'm', + :comments => 'rides a sweet bike' + } + end + + def assert_default_attributes(person, create = false) + unless create + assert_nil person.id + else + assert !!person.id + end + assert_equal 'Josh', person.first_name + assert_equal 'm', person.gender + assert_nil person.comments + end + + def assert_admin_attributes(person, create = false) + unless create + assert_nil person.id + else + assert !!person.id + end + assert_equal 'Josh', person.first_name + assert_equal 'm', person.gender + assert_equal 'rides a sweet bike', person.comments + end + + def assert_all_attributes(person) + assert_equal 5, person.id + assert_equal 'Josh', person.first_name + assert_equal 'm', person.gender + assert_equal 'rides a sweet bike', person.comments + end +end + +module MassAssignmentRelationTestHelpers + def setup + super + @person = LoosePerson.create(attributes_hash) + end +end + class MassAssignmentSecurityTest < ActiveRecord::TestCase + include MassAssignmentTestHelpers def test_customized_primary_key_remains_protected subscriber = Subscriber.new(:nick => 'webster123', :name => 'nice try') @@ -30,6 +87,120 @@ class MassAssignmentSecurityTest < ActiveRecord::TestCase end end + def test_assign_attributes_uses_default_scope_when_no_scope_is_provided + p = LoosePerson.new + p.assign_attributes(attributes_hash) + + assert_default_attributes(p) + end + + def test_assign_attributes_skips_mass_assignment_security_protection_when_without_protection_is_used + p = LoosePerson.new + p.assign_attributes(attributes_hash, :without_protection => true) + + assert_all_attributes(p) + end + + def test_assign_attributes_with_default_scope_and_attr_protected_attributes + p = LoosePerson.new + p.assign_attributes(attributes_hash, :as => :default) + + assert_default_attributes(p) + end + + def test_assign_attributes_with_admin_scope_and_attr_protected_attributes + p = LoosePerson.new + p.assign_attributes(attributes_hash, :as => :admin) + + assert_admin_attributes(p) + end + + def test_assign_attributes_with_default_scope_and_attr_accessible_attributes + p = TightPerson.new + p.assign_attributes(attributes_hash, :as => :default) + + assert_default_attributes(p) + end + + def test_assign_attributes_with_admin_scope_and_attr_accessible_attributes + p = TightPerson.new + p.assign_attributes(attributes_hash, :as => :admin) + + assert_admin_attributes(p) + end + + def test_new_with_attr_accessible_attributes + p = TightPerson.new(attributes_hash) + + assert_default_attributes(p) + end + + def test_new_with_attr_protected_attributes + p = LoosePerson.new(attributes_hash) + + assert_default_attributes(p) + end + + def test_create_with_attr_accessible_attributes + p = TightPerson.create(attributes_hash) + + assert_default_attributes(p, true) + end + + def test_create_with_attr_protected_attributes + p = LoosePerson.create(attributes_hash) + + assert_default_attributes(p, true) + end + + def test_new_with_admin_scope_with_attr_accessible_attributes + p = TightPerson.new(attributes_hash, :as => :admin) + + assert_admin_attributes(p) + end + + def test_new_with_admin_scope_with_attr_protected_attributes + p = LoosePerson.new(attributes_hash, :as => :admin) + + assert_admin_attributes(p) + end + + def test_create_with_admin_scope_with_attr_accessible_attributes + p = TightPerson.create(attributes_hash, :as => :admin) + + assert_admin_attributes(p, true) + end + + def test_create_with_admin_scope_with_attr_protected_attributes + p = LoosePerson.create(attributes_hash, :as => :admin) + + assert_admin_attributes(p, true) + end + + def test_new_with_without_protection_with_attr_accessible_attributes + p = TightPerson.new(attributes_hash, :without_protection => true) + + assert_all_attributes(p) + end + + def test_new_with_without_protection_with_attr_protected_attributes + p = LoosePerson.new(attributes_hash, :without_protection => true) + + assert_all_attributes(p) + end + + def test_create_with_without_protection_with_attr_accessible_attributes + p = TightPerson.create(attributes_hash, :without_protection => true) + + assert_all_attributes(p) + end + + def test_create_with_without_protection_with_attr_protected_attributes + p = LoosePerson.create(attributes_hash, :without_protection => true) + + assert_all_attributes(p) + end + def test_protection_against_class_attribute_writers [:logger, :configurations, :primary_key_prefix_type, :table_name_prefix, :table_name_suffix, :pluralize_table_names, :default_timezone, :schema_format, :lock_optimistically, :record_timestamps].each do |method| @@ -40,4 +211,268 @@ class MassAssignmentSecurityTest < ActiveRecord::TestCase end end -end
\ No newline at end of file +end + + +class MassAssignmentSecurityHasOneRelationsTest < ActiveRecord::TestCase + include MassAssignmentTestHelpers + include MassAssignmentRelationTestHelpers + + # build + + def test_has_one_build_with_attr_protected_attributes + best_friend = @person.build_best_friend(attributes_hash) + assert_default_attributes(best_friend) + end + + def test_has_one_build_with_attr_accessible_attributes + best_friend = @person.build_best_friend(attributes_hash) + assert_default_attributes(best_friend) + end + + def test_has_one_build_with_admin_scope_with_attr_protected_attributes + best_friend = @person.build_best_friend(attributes_hash, :as => :admin) + assert_admin_attributes(best_friend) + end + + def test_has_one_build_with_admin_scope_with_attr_accessible_attributes + best_friend = @person.build_best_friend(attributes_hash, :as => :admin) + assert_admin_attributes(best_friend) + end + + def test_has_one_build_without_protection + best_friend = @person.build_best_friend(attributes_hash, :without_protection => true) + assert_all_attributes(best_friend) + end + + # create + + def test_has_one_create_with_attr_protected_attributes + best_friend = @person.create_best_friend(attributes_hash) + assert_default_attributes(best_friend, true) + end + + def test_has_one_create_with_attr_accessible_attributes + best_friend = @person.create_best_friend(attributes_hash) + assert_default_attributes(best_friend, true) + end + + def test_has_one_create_with_admin_scope_with_attr_protected_attributes + best_friend = @person.create_best_friend(attributes_hash, :as => :admin) + assert_admin_attributes(best_friend, true) + end + + def test_has_one_create_with_admin_scope_with_attr_accessible_attributes + best_friend = @person.create_best_friend(attributes_hash, :as => :admin) + assert_admin_attributes(best_friend, true) + end + + def test_has_one_create_without_protection + best_friend = @person.create_best_friend(attributes_hash, :without_protection => true) + assert_all_attributes(best_friend) + end + + # create! + + def test_has_one_create_with_bang_with_attr_protected_attributes + best_friend = @person.create_best_friend!(attributes_hash) + assert_default_attributes(best_friend, true) + end + + def test_has_one_create_with_bang_with_attr_accessible_attributes + best_friend = @person.create_best_friend!(attributes_hash) + assert_default_attributes(best_friend, true) + end + + def test_has_one_create_with_bang_with_admin_scope_with_attr_protected_attributes + best_friend = @person.create_best_friend!(attributes_hash, :as => :admin) + assert_admin_attributes(best_friend, true) + end + + def test_has_one_create_with_bang_with_admin_scope_with_attr_accessible_attributes + best_friend = @person.create_best_friend!(attributes_hash, :as => :admin) + assert_admin_attributes(best_friend, true) + end + + def test_has_one_create_with_bang_without_protection + best_friend = @person.create_best_friend!(attributes_hash, :without_protection => true) + assert_all_attributes(best_friend) + end + +end + + +class MassAssignmentSecurityBelongsToRelationsTest < ActiveRecord::TestCase + include MassAssignmentTestHelpers + include MassAssignmentRelationTestHelpers + + # build + + def test_has_one_build_with_attr_protected_attributes + best_friend = @person.build_best_friend_of(attributes_hash) + assert_default_attributes(best_friend) + end + + def test_has_one_build_with_attr_accessible_attributes + best_friend = @person.build_best_friend_of(attributes_hash) + assert_default_attributes(best_friend) + end + + def test_has_one_build_with_admin_scope_with_attr_protected_attributes + best_friend = @person.build_best_friend_of(attributes_hash, :as => :admin) + assert_admin_attributes(best_friend) + end + + def test_has_one_build_with_admin_scope_with_attr_accessible_attributes + best_friend = @person.build_best_friend_of(attributes_hash, :as => :admin) + assert_admin_attributes(best_friend) + end + + def test_has_one_build_without_protection + best_friend = @person.build_best_friend_of(attributes_hash, :without_protection => true) + assert_all_attributes(best_friend) + end + + # create + + def test_has_one_create_with_attr_protected_attributes + best_friend = @person.create_best_friend_of(attributes_hash) + assert_default_attributes(best_friend, true) + end + + def test_has_one_create_with_attr_accessible_attributes + best_friend = @person.create_best_friend_of(attributes_hash) + assert_default_attributes(best_friend, true) + end + + def test_has_one_create_with_admin_scope_with_attr_protected_attributes + best_friend = @person.create_best_friend_of(attributes_hash, :as => :admin) + assert_admin_attributes(best_friend, true) + end + + def test_has_one_create_with_admin_scope_with_attr_accessible_attributes + best_friend = @person.create_best_friend_of(attributes_hash, :as => :admin) + assert_admin_attributes(best_friend, true) + end + + def test_has_one_create_without_protection + best_friend = @person.create_best_friend_of(attributes_hash, :without_protection => true) + assert_all_attributes(best_friend) + end + + # create! + + def test_has_one_create_with_bang_with_attr_protected_attributes + best_friend = @person.create_best_friend!(attributes_hash) + assert_default_attributes(best_friend, true) + end + + def test_has_one_create_with_bang_with_attr_accessible_attributes + best_friend = @person.create_best_friend!(attributes_hash) + assert_default_attributes(best_friend, true) + end + + def test_has_one_create_with_bang_with_admin_scope_with_attr_protected_attributes + best_friend = @person.create_best_friend!(attributes_hash, :as => :admin) + assert_admin_attributes(best_friend, true) + end + + def test_has_one_create_with_bang_with_admin_scope_with_attr_accessible_attributes + best_friend = @person.create_best_friend!(attributes_hash, :as => :admin) + assert_admin_attributes(best_friend, true) + end + + def test_has_one_create_with_bang_without_protection + best_friend = @person.create_best_friend!(attributes_hash, :without_protection => true) + assert_all_attributes(best_friend) + end + +end + + +class MassAssignmentSecurityHasManyRelationsTest < ActiveRecord::TestCase + include MassAssignmentTestHelpers + include MassAssignmentRelationTestHelpers + + # build + + def test_has_one_build_with_attr_protected_attributes + best_friend = @person.best_friends.build(attributes_hash) + assert_default_attributes(best_friend) + end + + def test_has_one_build_with_attr_accessible_attributes + best_friend = @person.best_friends.build(attributes_hash) + assert_default_attributes(best_friend) + end + + def test_has_one_build_with_admin_scope_with_attr_protected_attributes + best_friend = @person.best_friends.build(attributes_hash, :as => :admin) + assert_admin_attributes(best_friend) + end + + def test_has_one_build_with_admin_scope_with_attr_accessible_attributes + best_friend = @person.best_friends.build(attributes_hash, :as => :admin) + assert_admin_attributes(best_friend) + end + + def test_has_one_build_without_protection + best_friend = @person.best_friends.build(attributes_hash, :without_protection => true) + assert_all_attributes(best_friend) + end + + # create + + def test_has_one_create_with_attr_protected_attributes + best_friend = @person.best_friends.create(attributes_hash) + assert_default_attributes(best_friend, true) + end + + def test_has_one_create_with_attr_accessible_attributes + best_friend = @person.best_friends.create(attributes_hash) + assert_default_attributes(best_friend, true) + end + + def test_has_one_create_with_admin_scope_with_attr_protected_attributes + best_friend = @person.best_friends.create(attributes_hash, :as => :admin) + assert_admin_attributes(best_friend, true) + end + + def test_has_one_create_with_admin_scope_with_attr_accessible_attributes + best_friend = @person.best_friends.create(attributes_hash, :as => :admin) + assert_admin_attributes(best_friend, true) + end + + def test_has_one_create_without_protection + best_friend = @person.best_friends.create(attributes_hash, :without_protection => true) + assert_all_attributes(best_friend) + end + + # create! + + def test_has_one_create_with_bang_with_attr_protected_attributes + best_friend = @person.best_friends.create!(attributes_hash) + assert_default_attributes(best_friend, true) + end + + def test_has_one_create_with_bang_with_attr_accessible_attributes + best_friend = @person.best_friends.create!(attributes_hash) + assert_default_attributes(best_friend, true) + end + + def test_has_one_create_with_bang_with_admin_scope_with_attr_protected_attributes + best_friend = @person.best_friends.create!(attributes_hash, :as => :admin) + assert_admin_attributes(best_friend, true) + end + + def test_has_one_create_with_bang_with_admin_scope_with_attr_accessible_attributes + best_friend = @person.best_friends.create!(attributes_hash, :as => :admin) + assert_admin_attributes(best_friend, true) + end + + def test_has_one_create_with_bang_without_protection + best_friend = @person.best_friends.create!(attributes_hash, :without_protection => true) + assert_all_attributes(best_friend) + end + +end diff --git a/activerecord/test/cases/persistence_test.rb b/activerecord/test/cases/persistence_test.rb index 9aa13f04cd..b066575af8 100644 --- a/activerecord/test/cases/persistence_test.rb +++ b/activerecord/test/cases/persistence_test.rb @@ -12,7 +12,7 @@ require 'models/minimalistic' require 'models/warehouse_thing' require 'models/parrot' require 'models/minivan' -require 'models/loose_person' +require 'models/person' require 'rexml/document' require 'active_support/core_ext/exception' @@ -491,6 +491,26 @@ class PersistencesTest < ActiveRecord::TestCase assert_equal "The First Topic", topic.title end + def test_update_attributes_as_admin + person = TightPerson.create({ "first_name" => 'Joshua' }) + person.update_attributes({ "first_name" => 'Josh', "gender" => 'm', "comments" => 'from NZ' }, :as => :admin) + person.reload + + assert_equal 'Josh', person.first_name + assert_equal 'm', person.gender + assert_equal 'from NZ', person.comments + end + + def test_update_attributes_without_protection + person = TightPerson.create({ "first_name" => 'Joshua' }) + person.update_attributes({ "first_name" => 'Josh', "gender" => 'm', "comments" => 'from NZ' }, :without_protection => true) + person.reload + + assert_equal 'Josh', person.first_name + assert_equal 'm', person.gender + assert_equal 'from NZ', person.comments + end + def test_update_attributes! Reply.validates_presence_of(:title) reply = Reply.find(2) @@ -512,6 +532,26 @@ class PersistencesTest < ActiveRecord::TestCase Reply.reset_callbacks(:validate) end + def test_update_attributes_with_bang_as_admin + person = TightPerson.create({ "first_name" => 'Joshua' }) + person.update_attributes!({ "first_name" => 'Josh', "gender" => 'm', "comments" => 'from NZ' }, :as => :admin) + person.reload + + assert_equal 'Josh', person.first_name + assert_equal 'm', person.gender + assert_equal 'from NZ', person.comments + end + + def test_update_attributestes_with_bang_without_protection + person = TightPerson.create({ "first_name" => 'Joshua' }) + person.update_attributes!({ "first_name" => 'Josh', "gender" => 'm', "comments" => 'from NZ' }, :without_protection => true) + person.reload + + assert_equal 'Josh', person.first_name + assert_equal 'm', person.gender + assert_equal 'from NZ', person.comments + end + def test_destroyed_returns_boolean developer = Developer.first assert_equal false, developer.destroyed? diff --git a/activerecord/test/cases/query_cache_test.rb b/activerecord/test/cases/query_cache_test.rb index 287f7e255b..a61180cfaf 100644 --- a/activerecord/test/cases/query_cache_test.rb +++ b/activerecord/test/cases/query_cache_test.rb @@ -10,6 +10,70 @@ class QueryCacheTest < ActiveRecord::TestCase def setup Task.connection.clear_query_cache + ActiveRecord::Base.connection.disable_query_cache! + end + + def test_middleware_delegates + called = false + mw = ActiveRecord::QueryCache.new lambda { |env| + called = true + } + mw.call({}) + assert called, 'middleware should delegate' + end + + def test_middleware_caches + mw = ActiveRecord::QueryCache.new lambda { |env| + Task.find 1 + Task.find 1 + assert_equal 1, ActiveRecord::Base.connection.query_cache.length + } + mw.call({}) + end + + def test_cache_enabled_during_call + assert !ActiveRecord::Base.connection.query_cache_enabled, 'cache off' + + mw = ActiveRecord::QueryCache.new lambda { |env| + assert ActiveRecord::Base.connection.query_cache_enabled, 'cache on' + } + mw.call({}) + end + + def test_cache_on_during_body_write + streaming = Class.new do + def each + yield ActiveRecord::Base.connection.query_cache_enabled + end + end + + mw = ActiveRecord::QueryCache.new lambda { |env| + [200, {}, streaming.new] + } + body = mw.call({}).last + body.each { |x| assert x, 'cache should be on' } + body.close + assert !ActiveRecord::Base.connection.query_cache_enabled, 'cache disabled' + end + + def test_cache_off_after_close + mw = ActiveRecord::QueryCache.new lambda { |env| } + body = mw.call({}).last + + assert ActiveRecord::Base.connection.query_cache_enabled, 'cache enabled' + body.close + assert !ActiveRecord::Base.connection.query_cache_enabled, 'cache disabled' + end + + def test_cache_clear_after_close + mw = ActiveRecord::QueryCache.new lambda { |env| + Post.find(:first) + } + body = mw.call({}).last + + assert !ActiveRecord::Base.connection.query_cache.empty?, 'cache not empty' + body.close + assert ActiveRecord::Base.connection.query_cache.empty?, 'cache should be empty' end def test_find_queries diff --git a/activerecord/test/cases/relation_scoping_test.rb b/activerecord/test/cases/relation_scoping_test.rb index 2ed676fe69..864b3d4846 100644 --- a/activerecord/test/cases/relation_scoping_test.rb +++ b/activerecord/test/cases/relation_scoping_test.rb @@ -355,6 +355,12 @@ class DefaultScopingTest < ActiveRecord::TestCase assert_equal 50000, wheres[:salary] end + def test_default_scope_with_module_includes + wheres = ModuleIncludedPoorDeveloperCalledJamis.scoped.where_values_hash + assert_equal "Jamis", wheres[:name] + assert_equal 50000, wheres[:salary] + end + def test_default_scope_with_multiple_calls wheres = MultiplePoorDeveloperCalledJamis.scoped.where_values_hash assert_equal "Jamis", wheres[:name] @@ -456,18 +462,4 @@ class DefaultScopingTest < ActiveRecord::TestCase assert DeveloperCalledJamis.unscoped.poor.include?(developers(:david).becomes(DeveloperCalledJamis)) assert_equal 10, DeveloperCalledJamis.unscoped.poor.length end - - def test_multiple_default_scope_calls_are_deprecated - klass = Class.new(ActiveRecord::Base) - - assert_not_deprecated do - klass.send(:default_scope, :foo => :bar) - end - - assert_deprecated do - klass.send(:default_scope, :foo => :bar) - end - - assert_equal 2, klass.default_scopes.length - end end diff --git a/activerecord/test/cases/schema_dumper_test.rb b/activerecord/test/cases/schema_dumper_test.rb index 9b2c7c00df..e8f2f44189 100644 --- a/activerecord/test/cases/schema_dumper_test.rb +++ b/activerecord/test/cases/schema_dumper_test.rb @@ -203,6 +203,13 @@ class SchemaDumperTest < ActiveRecord::TestCase assert_match %r{t.xml "data"}, output end end + + def test_schema_dump_includes_tsvector_shorthand_definition + output = standard_dump + if %r{create_table "postgresql_tsvectors"} =~ output + assert_match %r{t.tsvector "text_vector"}, output + end + end end def test_schema_dump_keeps_large_precision_integer_columns_as_decimal diff --git a/activerecord/test/cases/validations/uniqueness_validation_test.rb b/activerecord/test/cases/validations/uniqueness_validation_test.rb index b4f3dd034c..0f1b3667cc 100644 --- a/activerecord/test/cases/validations/uniqueness_validation_test.rb +++ b/activerecord/test/cases/validations/uniqueness_validation_test.rb @@ -162,6 +162,32 @@ class UniquenessValidationTest < ActiveRecord::TestCase end end + def test_validate_case_sensitive_uniqueness_with_special_sql_like_chars + Topic.validates_uniqueness_of(:title, :case_sensitive => true) + + t = Topic.new("title" => "I'm unique!") + assert t.save, "Should save t as unique" + + t2 = Topic.new("title" => "I'm %") + assert t2.save, "Should save t2 as unique" + + t3 = Topic.new("title" => "I'm uniqu_!") + assert t3.save, "Should save t3 as unique" + end + + def test_validate_case_insensitive_uniqueness_with_special_sql_like_chars + Topic.validates_uniqueness_of(:title, :case_sensitive => false) + + t = Topic.new("title" => "I'm unique!") + assert t.save, "Should save t as unique" + + t2 = Topic.new("title" => "I'm %") + assert t2.save, "Should save t2 as unique" + + t3 = Topic.new("title" => "I'm uniqu_!") + assert t3.save, "Should save t3 as unique" + end + def test_validate_case_sensitive_uniqueness Topic.validates_uniqueness_of(:title, :case_sensitive => true, :allow_nil => true) |