aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionpack/lib/action_dispatch/routing/route_set.rb9
-rw-r--r--actionpack/lib/action_view/template/error.rb2
-rw-r--r--actionpack/lib/sprockets/railtie.rb2
-rw-r--r--actionpack/test/dispatch/request_test.rb7
-rw-r--r--actionpack/test/template/lookup_context_test.rb9
-rw-r--r--activemodel/lib/active_model/mass_assignment_security.rb46
-rw-r--r--activemodel/test/cases/mass_assignment_security_test.rb4
-rw-r--r--activerecord/lib/active_record/base.rb12
-rw-r--r--activerecord/lib/active_record/locking/optimistic.rb2
-rw-r--r--activerecord/lib/active_record/persistence.rb2
-rw-r--r--activerecord/lib/active_record/relation/calculations.rb2
-rw-r--r--activerecord/test/cases/locking_test.rb36
-rw-r--r--activerecord/test/cases/mass_assignment_security_test.rb54
-rw-r--r--activerecord/test/cases/relation_scoping_test.rb4
-rw-r--r--activerecord/test/fixtures/string_key_objects.yml7
-rw-r--r--activerecord/test/models/string_key_object.rb3
-rw-r--r--activerecord/test/schema/schema.rb6
-rw-r--r--activesupport/lib/active_support/core_ext/date/conversions.rb5
-rw-r--r--activesupport/lib/active_support/core_ext/hash/indifferent_access.rb12
-rw-r--r--activesupport/lib/active_support/hash_with_indifferent_access.rb4
-rw-r--r--activesupport/lib/active_support/inflector/methods.rb4
-rw-r--r--activesupport/lib/active_support/log_subscriber/test_helper.rb1
-rw-r--r--activesupport/lib/active_support/ordered_hash.rb4
-rw-r--r--activesupport/lib/active_support/xml_mini.rb5
-rw-r--r--activesupport/test/class_cache_test.rb2
-rw-r--r--activesupport/test/core_ext/hash_ext_test.rb15
-rw-r--r--activesupport/test/ordered_hash_test.rb5
-rw-r--r--activesupport/test/xml_mini_test.rb12
-rw-r--r--railties/guides/source/security.textile10
-rw-r--r--railties/lib/rails/application.rb6
-rw-r--r--railties/lib/rails/commands.rb3
-rw-r--r--railties/test/application/assets_test.rb27
-rw-r--r--railties/test/application/middleware_test.rb4
-rw-r--r--railties/test/application/rack/logger_test.rb40
-rw-r--r--railties/test/application/routing_test.rb4
-rw-r--r--railties/test/railties/shared_tests.rb3
36 files changed, 281 insertions, 92 deletions
diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb
index 97e8ccc9a5..5097f6732d 100644
--- a/actionpack/lib/action_dispatch/routing/route_set.rb
+++ b/actionpack/lib/action_dispatch/routing/route_set.rb
@@ -224,6 +224,7 @@ module ActionDispatch
self.valid_conditions.push(:controller, :action)
@append = []
+ @prepend = []
@disable_clear_and_finalize = false
clear!
end
@@ -232,7 +233,6 @@ module ActionDispatch
clear! unless @disable_clear_and_finalize
eval_block(block)
finalize! unless @disable_clear_and_finalize
-
nil
end
@@ -240,6 +240,10 @@ module ActionDispatch
@append << block
end
+ def prepend(&block)
+ @prepend << block
+ end
+
def eval_block(block)
if block.arity == 1
raise "You are using the old router DSL which has been removed in Rails 3.1. " <<
@@ -262,8 +266,6 @@ module ActionDispatch
end
def clear!
- # Clear the controller cache so we may discover new ones
- @controller_constraints = nil
@finalized = false
routes.clear
named_routes.clear
@@ -271,6 +273,7 @@ module ActionDispatch
:parameters_key => PARAMETERS_KEY,
:request_class => request_class
)
+ @prepend.each { |blk| eval_block(blk) }
end
def install_helpers(destinations = [ActionController::Base, ActionView::Base], regenerate_code = false)
diff --git a/actionpack/lib/action_view/template/error.rb b/actionpack/lib/action_view/template/error.rb
index e246646963..d4448a7b33 100644
--- a/actionpack/lib/action_view/template/error.rb
+++ b/actionpack/lib/action_view/template/error.rb
@@ -1,3 +1,4 @@
+require "active_support/core_ext/array/wrap"
require "active_support/core_ext/enumerable"
module ActionView
@@ -29,6 +30,7 @@ module ActionView
def initialize(paths, path, prefixes, partial, details, *)
@path = path
+ prefixes = Array.wrap(prefixes)
display_paths = paths.compact.map{ |p| p.to_s.inspect }.join(", ")
template_type = if partial
"partial"
diff --git a/actionpack/lib/sprockets/railtie.rb b/actionpack/lib/sprockets/railtie.rb
index 9c10decd60..0b4b0638b2 100644
--- a/actionpack/lib/sprockets/railtie.rb
+++ b/actionpack/lib/sprockets/railtie.rb
@@ -39,7 +39,7 @@ module Sprockets
end
end
- app.routes.append do
+ app.routes.prepend do
mount app.assets => assets.prefix
end
diff --git a/actionpack/test/dispatch/request_test.rb b/actionpack/test/dispatch/request_test.rb
index d128006404..25b1b4f745 100644
--- a/actionpack/test/dispatch/request_test.rb
+++ b/actionpack/test/dispatch/request_test.rb
@@ -358,6 +358,13 @@ class RequestTest < ActiveSupport::TestCase
assert request.head?
end
+ test "post masquerading as put" do
+ request = stub_request 'REQUEST_METHOD' => 'PUT', "rack.methodoverride.original_method" => "POST"
+ assert_equal "POST", request.method
+ assert_equal "PUT", request.request_method
+ assert request.put?
+ end
+
test "xml format" do
request = stub_request
request.expects(:parameters).at_least_once.returns({ :format => 'xml' })
diff --git a/actionpack/test/template/lookup_context_test.rb b/actionpack/test/template/lookup_context_test.rb
index f34a40795a..47b70f05ab 100644
--- a/actionpack/test/template/lookup_context_test.rb
+++ b/actionpack/test/template/lookup_context_test.rb
@@ -256,4 +256,13 @@ class TestMissingTemplate < ActiveSupport::TestCase
end
assert_match %r{Missing partial parent/foo, child/foo with .* Searched in:\n \* "/Path/to/views"\n}, e.message
end
+
+ test "if a single prefix is passed as a string and the lookup fails, MissingTemplate accepts it" do
+ e = assert_raise ActionView::MissingTemplate do
+ details = {:handlers=>[], :formats=>[], :locale=>[]}
+ @lookup_context.view_paths.find("foo", "parent", true, details)
+ end
+ assert_match %r{Missing partial parent/foo with .* Searched in:\n \* "/Path/to/views"\n}, e.message
+ end
+
end
diff --git a/activemodel/lib/active_model/mass_assignment_security.rb b/activemodel/lib/active_model/mass_assignment_security.rb
index 01eef762fd..483b577681 100644
--- a/activemodel/lib/active_model/mass_assignment_security.rb
+++ b/activemodel/lib/active_model/mass_assignment_security.rb
@@ -35,17 +35,17 @@ module ActiveModel
# protected
#
# def account_params
- # scope = admin ? :admin : :default
- # sanitize_for_mass_assignment(params[:account], scope)
+ # role = admin ? :admin : :default
+ # sanitize_for_mass_assignment(params[:account], role)
# end
#
# end
#
module ClassMethods
# Attributes named in this macro are protected from mass-assignment
- # whenever attributes are sanitized before assignment. A scope for the
- # attributes is optional, if no scope is provided then :default is used.
- # A scope can be defined by using the :as option.
+ # whenever attributes are sanitized before assignment. A role for the
+ # attributes is optional, if no role is provided then :default is used.
+ # A role can be defined by using the :as option.
#
# Mass-assignment to these attributes will simply be ignored, to assign
# to them you can use direct writer methods. This is meant to protect
@@ -67,7 +67,7 @@ module ActiveModel
# end
# end
#
- # When using a :default scope :
+ # When using the :default role :
#
# customer = Customer.new
# customer.assign_attributes({ "name" => "David", "credit_rating" => "Excellent", :last_login => 1.day.ago }, :as => :default)
@@ -78,7 +78,7 @@ module ActiveModel
# customer.credit_rating = "Average"
# customer.credit_rating # => "Average"
#
- # And using the :admin scope :
+ # And using the :admin role :
#
# customer = Customer.new
# customer.assign_attributes({ "name" => "David", "credit_rating" => "Excellent", :last_login => 1.day.ago }, :as => :admin)
@@ -93,10 +93,10 @@ module ActiveModel
# to sanitize attributes won't provide sufficient protection.
def attr_protected(*args)
options = args.extract_options!
- scope = options[:as] || :default
+ role = options[:as] || :default
self._protected_attributes = protected_attributes_configs.dup
- self._protected_attributes[scope] = self.protected_attributes(scope) + args
+ self._protected_attributes[role] = self.protected_attributes(role) + args
self._active_authorizer = self._protected_attributes
end
@@ -104,8 +104,8 @@ module ActiveModel
# Specifies a white list of model attributes that can be set via
# mass-assignment.
#
- # Like +attr_protected+, a scope for the attributes is optional,
- # if no scope is provided then :default is used. A scope can be defined by
+ # Like +attr_protected+, a role for the attributes is optional,
+ # if no role is provided then :default is used. A role can be defined by
# using the :as option.
#
# This is the opposite of the +attr_protected+ macro: Mass-assignment
@@ -131,7 +131,7 @@ module ActiveModel
# end
# end
#
- # When using a :default scope :
+ # When using the :default role :
#
# customer = Customer.new
# customer.assign_attributes({ "name" => "David", "credit_rating" => "Excellent", :last_login => 1.day.ago }, :as => :default)
@@ -141,7 +141,7 @@ module ActiveModel
# customer.credit_rating = "Average"
# customer.credit_rating # => "Average"
#
- # And using the :admin scope :
+ # And using the :admin role :
#
# customer = Customer.new
# customer.assign_attributes({ "name" => "David", "credit_rating" => "Excellent", :last_login => 1.day.ago }, :as => :admin)
@@ -152,20 +152,20 @@ module ActiveModel
# to sanitize attributes won't provide sufficient protection.
def attr_accessible(*args)
options = args.extract_options!
- scope = options[:as] || :default
+ role = options[:as] || :default
self._accessible_attributes = accessible_attributes_configs.dup
- self._accessible_attributes[scope] = self.accessible_attributes(scope) + args
+ self._accessible_attributes[role] = self.accessible_attributes(role) + args
self._active_authorizer = self._accessible_attributes
end
- def protected_attributes(scope = :default)
- protected_attributes_configs[scope]
+ def protected_attributes(role = :default)
+ protected_attributes_configs[role]
end
- def accessible_attributes(scope = :default)
- accessible_attributes_configs[scope]
+ def accessible_attributes(role = :default)
+ accessible_attributes_configs[role]
end
def active_authorizers
@@ -198,12 +198,12 @@ module ActiveModel
protected
- def sanitize_for_mass_assignment(attributes, scope = :default)
- mass_assignment_authorizer(scope).sanitize(attributes)
+ def sanitize_for_mass_assignment(attributes, role = :default)
+ mass_assignment_authorizer(role).sanitize(attributes)
end
- def mass_assignment_authorizer(scope = :default)
- self.class.active_authorizer[scope]
+ def mass_assignment_authorizer(role = :default)
+ self.class.active_authorizer[role]
end
end
end
diff --git a/activemodel/test/cases/mass_assignment_security_test.rb b/activemodel/test/cases/mass_assignment_security_test.rb
index b22ce874ea..43a12eed61 100644
--- a/activemodel/test/cases/mass_assignment_security_test.rb
+++ b/activemodel/test/cases/mass_assignment_security_test.rb
@@ -10,7 +10,7 @@ class MassAssignmentSecurityTest < ActiveModel::TestCase
assert_equal expected, sanitized
end
- def test_only_moderator_scope_attribute_accessible
+ def test_only_moderator_role_attribute_accessible
user = SpecialUser.new
expected = { "name" => "John Smith", "email" => "john@smith.com" }
sanitized = user.sanitize_for_mass_assignment(expected.merge("admin" => true), :moderator)
@@ -27,7 +27,7 @@ class MassAssignmentSecurityTest < ActiveModel::TestCase
assert_equal expected, sanitized
end
- def test_admin_scoped_attributes_accessible
+ def test_attributes_accessible_with_admin_role
user = Person.new
expected = { "name" => "John Smith", "email" => "john@smith.com", "admin" => true }
sanitized = user.sanitize_for_mass_assignment(expected.merge("super_powers" => true), :admin)
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index 78318b1be0..67af21c9a0 100644
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -482,7 +482,7 @@ module ActiveRecord #:nodoc:
# # Create a single new object
# User.create(:first_name => 'Jamie')
#
- # # Create a single new object using the :admin mass-assignment security scope
+ # # Create a single new object using the :admin mass-assignment security role
# User.create({ :first_name => 'Jamie', :is_admin => true }, :as => :admin)
#
# # Create a single new object bypassing mass-assignment security
@@ -1486,7 +1486,7 @@ MSG
# # Instantiates a single new object
# User.new(:first_name => 'Jamie')
#
- # # Instantiates a single new object using the :admin mass-assignment security scope
+ # # Instantiates a single new object using the :admin mass-assignment security role
# User.new({ :first_name => 'Jamie', :is_admin => true }, :as => :admin)
#
# # Instantiates a single new object bypassing mass-assignment security
@@ -1661,8 +1661,8 @@ MSG
end
# Allows you to set all the attributes for a particular mass-assignment
- # security scope by passing in a hash of attributes with keys matching
- # the attribute names (which again matches the column names) and the scope
+ # security role by passing in a hash of attributes with keys matching
+ # the attribute names (which again matches the column names) and the role
# name using the :as option.
#
# To bypass mass-assignment security you can use the :without_protection => true
@@ -1689,12 +1689,12 @@ MSG
# user.is_admin? # => true
def assign_attributes(new_attributes, options = {})
attributes = new_attributes.stringify_keys
- scope = options[:as] || :default
+ role = options[:as] || :default
multi_parameter_attributes = []
unless options[:without_protection]
- attributes = sanitize_for_mass_assignment(attributes, scope)
+ attributes = sanitize_for_mass_assignment(attributes, role)
end
attributes.each do |k, v|
diff --git a/activerecord/lib/active_record/locking/optimistic.rb b/activerecord/lib/active_record/locking/optimistic.rb
index 9a31675782..cdedcde0eb 100644
--- a/activerecord/lib/active_record/locking/optimistic.rb
+++ b/activerecord/lib/active_record/locking/optimistic.rb
@@ -94,7 +94,7 @@ module ActiveRecord
relation = self.class.unscoped
stmt = relation.where(
- relation.table[self.class.primary_key].eq(quoted_id).and(
+ relation.table[self.class.primary_key].eq(id).and(
relation.table[lock_col].eq(quote_value(previous_lock_value))
)
).arel.compile_update(arel_attributes_values(false, false, attribute_names))
diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb
index b4531ed35f..b9041f44d8 100644
--- a/activerecord/lib/active_record/persistence.rb
+++ b/activerecord/lib/active_record/persistence.rb
@@ -146,7 +146,7 @@ module ActiveRecord
# will fail and false will be returned.
#
# When updating model attributes, mass-assignment security protection is respected.
- # If no +:as+ option is supplied then the +:default+ scope will be used.
+ # If no +:as+ option is supplied then the +:default+ role will be used.
# If you want to bypass the protection given by +attr_protected+ and
# +attr_accessible+ then you can do so using the +:without_protection+ option.
def update_attributes(attributes, options = {})
diff --git a/activerecord/lib/active_record/relation/calculations.rb b/activerecord/lib/active_record/relation/calculations.rb
index 869eebfa34..a8a52867ce 100644
--- a/activerecord/lib/active_record/relation/calculations.rb
+++ b/activerecord/lib/active_record/relation/calculations.rb
@@ -197,7 +197,7 @@ module ActiveRecord
def execute_simple_calculation(operation, column_name, distinct) #:nodoc:
# Postgresql doesn't like ORDER BY when there are no GROUP BY
- relation = except(:order)
+ relation = reorder(nil)
if operation == "count" && (relation.limit_value || relation.offset_value)
# Shortcut when limit is zero.
diff --git a/activerecord/test/cases/locking_test.rb b/activerecord/test/cases/locking_test.rb
index 636a709924..61baa55027 100644
--- a/activerecord/test/cases/locking_test.rb
+++ b/activerecord/test/cases/locking_test.rb
@@ -5,6 +5,7 @@ require 'models/job'
require 'models/reader'
require 'models/legacy_thing'
require 'models/reference'
+require 'models/string_key_object'
class LockWithoutDefault < ActiveRecord::Base; end
@@ -18,7 +19,40 @@ class ReadonlyFirstNamePerson < Person
end
class OptimisticLockingTest < ActiveRecord::TestCase
- fixtures :people, :legacy_things, :references
+ fixtures :people, :legacy_things, :references, :string_key_objects
+
+ def test_non_integer_lock_existing
+ s1 = StringKeyObject.find("record1")
+ s2 = StringKeyObject.find("record1")
+ assert_equal 0, s1.lock_version
+ assert_equal 0, s2.lock_version
+
+ s1.name = 'updated record'
+ s1.save!
+ assert_equal 1, s1.lock_version
+ assert_equal 0, s2.lock_version
+
+ s2.name = 'doubly updated record'
+ assert_raise(ActiveRecord::StaleObjectError) { s2.save! }
+ end
+
+ def test_non_integer_lock_destroy
+ s1 = StringKeyObject.find("record1")
+ s2 = StringKeyObject.find("record1")
+ assert_equal 0, s1.lock_version
+ assert_equal 0, s2.lock_version
+
+ s1.name = 'updated record'
+ s1.save!
+ assert_equal 1, s1.lock_version
+ assert_equal 0, s2.lock_version
+ assert_raise(ActiveRecord::StaleObjectError) { s2.destroy }
+
+ assert s1.destroy
+ assert s1.frozen?
+ assert s1.destroyed?
+ assert_raises(ActiveRecord::RecordNotFound) { StringKeyObject.find("record1") }
+ end
def test_lock_existing
p1 = Person.find(1)
diff --git a/activerecord/test/cases/mass_assignment_security_test.rb b/activerecord/test/cases/mass_assignment_security_test.rb
index fbbae99e8b..c81015b7c2 100644
--- a/activerecord/test/cases/mass_assignment_security_test.rb
+++ b/activerecord/test/cases/mass_assignment_security_test.rb
@@ -87,7 +87,7 @@ class MassAssignmentSecurityTest < ActiveRecord::TestCase
end
end
- def test_assign_attributes_uses_default_scope_when_no_scope_is_provided
+ def test_assign_attributes_uses_default_role_when_no_role_is_provided
p = LoosePerson.new
p.assign_attributes(attributes_hash)
@@ -101,28 +101,28 @@ class MassAssignmentSecurityTest < ActiveRecord::TestCase
assert_all_attributes(p)
end
- def test_assign_attributes_with_default_scope_and_attr_protected_attributes
+ def test_assign_attributes_with_default_role_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
+ def test_assign_attributes_with_admin_role_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
+ def test_assign_attributes_with_default_role_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
+ def test_assign_attributes_with_admin_role_and_attr_accessible_attributes
p = TightPerson.new
p.assign_attributes(attributes_hash, :as => :admin)
@@ -153,25 +153,25 @@ class MassAssignmentSecurityTest < ActiveRecord::TestCase
assert_default_attributes(p, true)
end
- def test_new_with_admin_scope_with_attr_accessible_attributes
+ def test_new_with_admin_role_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
+ def test_new_with_admin_role_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
+ def test_create_with_admin_role_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
+ def test_create_with_admin_role_with_attr_protected_attributes
p = LoosePerson.create(attributes_hash, :as => :admin)
assert_admin_attributes(p, true)
@@ -230,12 +230,12 @@ class MassAssignmentSecurityHasOneRelationsTest < ActiveRecord::TestCase
assert_default_attributes(best_friend)
end
- def test_has_one_build_with_admin_scope_with_attr_protected_attributes
+ def test_has_one_build_with_admin_role_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
+ def test_has_one_build_with_admin_role_with_attr_accessible_attributes
best_friend = @person.build_best_friend(attributes_hash, :as => :admin)
assert_admin_attributes(best_friend)
end
@@ -257,12 +257,12 @@ class MassAssignmentSecurityHasOneRelationsTest < ActiveRecord::TestCase
assert_default_attributes(best_friend, true)
end
- def test_has_one_create_with_admin_scope_with_attr_protected_attributes
+ def test_has_one_create_with_admin_role_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
+ def test_has_one_create_with_admin_role_with_attr_accessible_attributes
best_friend = @person.create_best_friend(attributes_hash, :as => :admin)
assert_admin_attributes(best_friend, true)
end
@@ -284,12 +284,12 @@ class MassAssignmentSecurityHasOneRelationsTest < ActiveRecord::TestCase
assert_default_attributes(best_friend, true)
end
- def test_has_one_create_with_bang_with_admin_scope_with_attr_protected_attributes
+ def test_has_one_create_with_bang_with_admin_role_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
+ def test_has_one_create_with_bang_with_admin_role_with_attr_accessible_attributes
best_friend = @person.create_best_friend!(attributes_hash, :as => :admin)
assert_admin_attributes(best_friend, true)
end
@@ -318,12 +318,12 @@ class MassAssignmentSecurityBelongsToRelationsTest < ActiveRecord::TestCase
assert_default_attributes(best_friend)
end
- def test_has_one_build_with_admin_scope_with_attr_protected_attributes
+ def test_has_one_build_with_admin_role_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
+ def test_has_one_build_with_admin_role_with_attr_accessible_attributes
best_friend = @person.build_best_friend_of(attributes_hash, :as => :admin)
assert_admin_attributes(best_friend)
end
@@ -345,12 +345,12 @@ class MassAssignmentSecurityBelongsToRelationsTest < ActiveRecord::TestCase
assert_default_attributes(best_friend, true)
end
- def test_has_one_create_with_admin_scope_with_attr_protected_attributes
+ def test_has_one_create_with_admin_role_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
+ def test_has_one_create_with_admin_role_with_attr_accessible_attributes
best_friend = @person.create_best_friend_of(attributes_hash, :as => :admin)
assert_admin_attributes(best_friend, true)
end
@@ -372,12 +372,12 @@ class MassAssignmentSecurityBelongsToRelationsTest < ActiveRecord::TestCase
assert_default_attributes(best_friend, true)
end
- def test_has_one_create_with_bang_with_admin_scope_with_attr_protected_attributes
+ def test_has_one_create_with_bang_with_admin_role_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
+ def test_has_one_create_with_bang_with_admin_role_with_attr_accessible_attributes
best_friend = @person.create_best_friend!(attributes_hash, :as => :admin)
assert_admin_attributes(best_friend, true)
end
@@ -406,12 +406,12 @@ class MassAssignmentSecurityHasManyRelationsTest < ActiveRecord::TestCase
assert_default_attributes(best_friend)
end
- def test_has_one_build_with_admin_scope_with_attr_protected_attributes
+ def test_has_one_build_with_admin_role_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
+ def test_has_one_build_with_admin_role_with_attr_accessible_attributes
best_friend = @person.best_friends.build(attributes_hash, :as => :admin)
assert_admin_attributes(best_friend)
end
@@ -433,12 +433,12 @@ class MassAssignmentSecurityHasManyRelationsTest < ActiveRecord::TestCase
assert_default_attributes(best_friend, true)
end
- def test_has_one_create_with_admin_scope_with_attr_protected_attributes
+ def test_has_one_create_with_admin_role_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
+ def test_has_one_create_with_admin_role_with_attr_accessible_attributes
best_friend = @person.best_friends.create(attributes_hash, :as => :admin)
assert_admin_attributes(best_friend, true)
end
@@ -460,12 +460,12 @@ class MassAssignmentSecurityHasManyRelationsTest < ActiveRecord::TestCase
assert_default_attributes(best_friend, true)
end
- def test_has_one_create_with_bang_with_admin_scope_with_attr_protected_attributes
+ def test_has_one_create_with_bang_with_admin_role_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
+ def test_has_one_create_with_bang_with_admin_role_with_attr_accessible_attributes
best_friend = @person.best_friends.create!(attributes_hash, :as => :admin)
assert_admin_attributes(best_friend, true)
end
diff --git a/activerecord/test/cases/relation_scoping_test.rb b/activerecord/test/cases/relation_scoping_test.rb
index 864b3d4846..c215602567 100644
--- a/activerecord/test/cases/relation_scoping_test.rb
+++ b/activerecord/test/cases/relation_scoping_test.rb
@@ -462,4 +462,8 @@ class DefaultScopingTest < ActiveRecord::TestCase
assert DeveloperCalledJamis.unscoped.poor.include?(developers(:david).becomes(DeveloperCalledJamis))
assert_equal 10, DeveloperCalledJamis.unscoped.poor.length
end
+
+ def test_default_scope_order_ignored_by_aggregations
+ assert_equal DeveloperOrderedBySalary.all.count, DeveloperOrderedBySalary.count
+ end
end
diff --git a/activerecord/test/fixtures/string_key_objects.yml b/activerecord/test/fixtures/string_key_objects.yml
new file mode 100644
index 0000000000..fa1299915b
--- /dev/null
+++ b/activerecord/test/fixtures/string_key_objects.yml
@@ -0,0 +1,7 @@
+first:
+ id: record1
+ name: first record
+
+second:
+ id: record2
+ name: second record
diff --git a/activerecord/test/models/string_key_object.rb b/activerecord/test/models/string_key_object.rb
new file mode 100644
index 0000000000..f8d4c6e0e4
--- /dev/null
+++ b/activerecord/test/models/string_key_object.rb
@@ -0,0 +1,3 @@
+class StringKeyObject < ActiveRecord::Base
+ set_primary_key :id
+end
diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb
index 9479242e4f..c20304c0e2 100644
--- a/activerecord/test/schema/schema.rb
+++ b/activerecord/test/schema/schema.rb
@@ -543,6 +543,12 @@ ActiveRecord::Schema.define do
t.string :sponsorable_type
end
+ create_table :string_key_objects, :id => false, :primary_key => :id, :force => true do |t|
+ t.string :id
+ t.string :name
+ t.integer :lock_version, :null => false, :default => 0
+ end
+
create_table :students, :force => true do |t|
t.string :name
end
diff --git a/activesupport/lib/active_support/core_ext/date/conversions.rb b/activesupport/lib/active_support/core_ext/date/conversions.rb
index 769ead9544..338104fd05 100644
--- a/activesupport/lib/active_support/core_ext/date/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/date/conversions.rb
@@ -1,6 +1,7 @@
require 'date'
require 'active_support/inflector/methods'
require 'active_support/core_ext/date/zones'
+require 'active_support/core_ext/module/remove_method'
class Date
DATE_FORMATS = {
@@ -13,10 +14,10 @@ class Date
}
# Ruby 1.9 has Date#to_time which converts to localtime only.
- remove_method :to_time if method_defined?(:to_time)
+ remove_possible_method :to_time
# Ruby 1.9 has Date#xmlschema which converts to a string without the time component.
- remove_method :xmlschema if method_defined?(:xmlschema)
+ remove_possible_method :xmlschema
# Convert to a formatted string. See DATE_FORMATS for predefined formats.
#
diff --git a/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb b/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb
index aad4b61e16..c2a6476604 100644
--- a/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb
+++ b/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb
@@ -9,4 +9,16 @@ class Hash
def with_indifferent_access
ActiveSupport::HashWithIndifferentAccess.new_from_hash_copying_default(self)
end
+
+ # Called when object is nested under an object that receives
+ # #with_indifferent_access. This method with be called on the current object
+ # by the enclosing object and is aliased to #with_indifferent_access by
+ # default. Subclasses of Hash may overwrite this method to return +self+ if
+ # converting to an +ActiveSupport::HashWithIndifferentAccess+ would not be
+ # desirable.
+ #
+ # b = {:b => 1}
+ # {:a => b}.with_indifferent_access["a"] # calls b.nested_under_indifferent_access
+ #
+ alias nested_under_indifferent_access with_indifferent_access
end
diff --git a/activesupport/lib/active_support/hash_with_indifferent_access.rb b/activesupport/lib/active_support/hash_with_indifferent_access.rb
index 79a0de7940..8ec4f6e09a 100644
--- a/activesupport/lib/active_support/hash_with_indifferent_access.rb
+++ b/activesupport/lib/active_support/hash_with_indifferent_access.rb
@@ -140,8 +140,8 @@ module ActiveSupport
end
def convert_value(value)
- if value.class == Hash
- self.class.new_from_hash_copying_default(value)
+ if value.is_a? Hash
+ value.nested_under_indifferent_access
elsif value.is_a?(Array)
value.dup.replace(value.map { |e| convert_value(e) })
else
diff --git a/activesupport/lib/active_support/inflector/methods.rb b/activesupport/lib/active_support/inflector/methods.rb
index dd2beef89d..a2c4f7bfda 100644
--- a/activesupport/lib/active_support/inflector/methods.rb
+++ b/activesupport/lib/active_support/inflector/methods.rb
@@ -135,6 +135,8 @@ module ActiveSupport
# ordinalize(2) # => "2nd"
# ordinalize(1002) # => "1002nd"
# ordinalize(1003) # => "1003rd"
+ # ordinalize(-11) # => "-11th"
+ # ordinalize(-1021) # => "-1021st"
def ordinalize(number)
if (11..13).include?(number.to_i.abs % 100)
"#{number}th"
@@ -148,4 +150,4 @@ module ActiveSupport
end
end
end
-end \ No newline at end of file
+end
diff --git a/activesupport/lib/active_support/log_subscriber/test_helper.rb b/activesupport/lib/active_support/log_subscriber/test_helper.rb
index 392e33edbc..3e54134c5c 100644
--- a/activesupport/lib/active_support/log_subscriber/test_helper.rb
+++ b/activesupport/lib/active_support/log_subscriber/test_helper.rb
@@ -1,5 +1,6 @@
require 'active_support/log_subscriber'
require 'active_support/buffered_logger'
+require 'active_support/notifications'
module ActiveSupport
class LogSubscriber
diff --git a/activesupport/lib/active_support/ordered_hash.rb b/activesupport/lib/active_support/ordered_hash.rb
index fbc40d1b69..762a64a881 100644
--- a/activesupport/lib/active_support/ordered_hash.rb
+++ b/activesupport/lib/active_support/ordered_hash.rb
@@ -43,6 +43,10 @@ module ActiveSupport
end
end
+ def nested_under_indifferent_access
+ self
+ end
+
# Hash is ordered in Ruby 1.9!
if RUBY_VERSION < '1.9'
diff --git a/activesupport/lib/active_support/xml_mini.rb b/activesupport/lib/active_support/xml_mini.rb
index dff8a8f4c4..d8f40ab8b1 100644
--- a/activesupport/lib/active_support/xml_mini.rb
+++ b/activesupport/lib/active_support/xml_mini.rb
@@ -139,7 +139,10 @@ module ActiveSupport
protected
def _dasherize(key)
- key.gsub(/(?!^[_]*)_(?![_]*$)/, '-')
+ left = key.strip.rpartition(/^_*/)
+ right = left.pop.partition(/_*$/)
+ right.first.tr!('_ ', '--')
+ left.concat(right).join
end
# TODO: Add support for other encodings
diff --git a/activesupport/test/class_cache_test.rb b/activesupport/test/class_cache_test.rb
index 8445af8d25..fc2d54515d 100644
--- a/activesupport/test/class_cache_test.rb
+++ b/activesupport/test/class_cache_test.rb
@@ -58,7 +58,7 @@ module ActiveSupport
assert @cache.key?(ClassCacheTest.name)
end
- def test_new_rejects_strings
+ def test_new_rejects_strings_when_called_on_a_new_string
assert_deprecated do
@cache.new ClassCacheTest.name
end
diff --git a/activesupport/test/core_ext/hash_ext_test.rb b/activesupport/test/core_ext/hash_ext_test.rb
index 3ef080e1cb..4557a10688 100644
--- a/activesupport/test/core_ext/hash_ext_test.rb
+++ b/activesupport/test/core_ext/hash_ext_test.rb
@@ -16,6 +16,12 @@ class HashExtTest < Test::Unit::TestCase
class SubclassingHash < Hash
end
+ class NonIndifferentHash < Hash
+ def nested_under_indifferent_access
+ self
+ end
+ end
+
def setup
@strings = { 'a' => 1, 'b' => 2 }
@symbols = { :a => 1, :b => 2 }
@@ -109,9 +115,12 @@ class HashExtTest < Test::Unit::TestCase
assert_equal @strings, @mixed.with_indifferent_access.dup.stringify_keys!
end
- def test_hash_subclass
- flash = { "foo" => SubclassingHash.new.tap { |h| h["bar"] = "baz" } }.with_indifferent_access
- assert_kind_of SubclassingHash, flash["foo"]
+ def test_nested_under_indifferent_access
+ foo = { "foo" => SubclassingHash.new.tap { |h| h["bar"] = "baz" } }.with_indifferent_access
+ assert_kind_of ActiveSupport::HashWithIndifferentAccess, foo["foo"]
+
+ foo = { "foo" => NonIndifferentHash.new.tap { |h| h["bar"] = "baz" } }.with_indifferent_access
+ assert_kind_of NonIndifferentHash, foo["foo"]
end
def test_indifferent_assorted
diff --git a/activesupport/test/ordered_hash_test.rb b/activesupport/test/ordered_hash_test.rb
index 50168fa78f..bf99a701a6 100644
--- a/activesupport/test/ordered_hash_test.rb
+++ b/activesupport/test/ordered_hash_test.rb
@@ -243,6 +243,11 @@ class OrderedHashTest < Test::Unit::TestCase
assert_equal @other_ordered_hash.keys, @ordered_hash.keys
end
+ def test_nested_under_indifferent_access
+ flash = {:a => ActiveSupport::OrderedHash[:b, 1, :c, 2]}.with_indifferent_access
+ assert_kind_of ActiveSupport::OrderedHash, flash[:a]
+ end
+
def test_each_after_yaml_serialization
values = []
@deserialized_ordered_hash = YAML.load(YAML.dump(@ordered_hash))
diff --git a/activesupport/test/xml_mini_test.rb b/activesupport/test/xml_mini_test.rb
index bf6b0b283d..e2b90ae16e 100644
--- a/activesupport/test/xml_mini_test.rb
+++ b/activesupport/test/xml_mini_test.rb
@@ -48,7 +48,7 @@ module XmlMiniTest
assert_equal "__id", ActiveSupport::XmlMini.rename_key("__id")
end
- def test_rename_key_does_not_dasherize_multiple_leading_underscores
+ def test_rename_key_does_not_dasherize_multiple_trailing_underscores
assert_equal "id__", ActiveSupport::XmlMini.rename_key("id__")
end
end
@@ -87,6 +87,16 @@ module XmlMiniTest
@xml.to_tag(:b, "Howdy", @options)
assert_xml "<b>Howdy</b>"
end
+
+ test "#to_tag should dasherize the space when passed a string with spaces as a key" do
+ @xml.to_tag("New York", 33, @options)
+ assert_xml "<New---York type=\"integer\">33</New---York>"
+ end
+
+ test "#to_tag should dasherize the space when passed a symbol with spaces as a key" do
+ @xml.to_tag(:"New York", 33, @options)
+ assert_xml "<New---York type=\"integer\">33</New---York>"
+ end
# TODO: test the remaining functions hidden in #to_tag.
end
end
diff --git a/railties/guides/source/security.textile b/railties/guides/source/security.textile
index 8c408ec06b..e0ccc7a6e6 100644
--- a/railties/guides/source/security.textile
+++ b/railties/guides/source/security.textile
@@ -372,7 +372,7 @@ def signup
end
</ruby>
-Mass-assignment saves you much work, because you don't have to set each value individually. Simply pass a hash to the new() method, or assign attributes=(attributes) a hash value, to set the model's attributes to the values in the hash. The problem is that it is often used in conjunction with the parameters (params) hash available in the controller, which may be manipulated by an attacker. He may do so by changing the URL like this:
+Mass-assignment saves you much work, because you don't have to set each value individually. Simply pass a hash to the +new+ method, or +assign_attributes=+ a hash value, to set the model's attributes to the values in the hash. The problem is that it is often used in conjunction with the parameters (params) hash available in the controller, which may be manipulated by an attacker. He may do so by changing the URL like this:
<pre>
"name":http://www.example.com/user/signup?user[name]=ow3ned&user[admin]=1
@@ -386,7 +386,7 @@ params[:user] # => {:name => “ow3ned”, :admin => true}
So if you create a new user using mass-assignment, it may be too easy to become an administrator.
-Note that this vulnerability is not restricted to database columns. Any setter method, unless explicitly protected, is accessible via the <tt>attributes=</tt> method. In fact, this vulnerability is extended even further with the introduction of nested mass assignment (and nested object forms) in Rails 2.3. The +accepts_nested_attributes_for+ declaration provides us the ability to extend mass assignment to model associations (+has_many+, +has_one+, +has_and_belongs_to_many+). For example:
+Note that this vulnerability is not restricted to database columns. Any setter method, unless explicitly protected, is accessible via the <tt>attributes=</tt> method. In fact, this vulnerability is extended even further with the introduction of nested mass assignment (and nested object forms) in Rails 2.3+. The +accepts_nested_attributes_for+ declaration provides us the ability to extend mass assignment to model associations (+has_many+, +has_one+, +has_and_belongs_to_many+). For example:
<ruby>
class Person < ActiveRecord::Base
@@ -410,7 +410,7 @@ To avoid this, Rails provides two class methods in your Active Record class to c
attr_protected :admin
</ruby>
-+attr_protected+ also optionally takes a scope option using :as which allows you to define multiple mass-assignment groupings. If no scope is defined then attributes will be added to the default group.
++attr_protected+ also optionally takes a role option using :as which allows you to define multiple mass-assignment groupings. If no role is defined then attributes will be added to the :default role.
<ruby>
attr_protected :last_login, :as => :admin
@@ -433,7 +433,7 @@ params[:user] # => {:name => "ow3ned", :admin => true}
@user.admin # => true
</ruby>
-When assigning attributes in Active Record using +attributes=+, or +update_attributes+ the :default scope will be used. To assign attributes using different scopes you should use +assign_attributes+ which accepts an optional :as options parameter. If no :as option is provided then the :default scope will be used. You can also bypass mass-assignment security by using the +:without_protection+ option. Here is an example:
+When assigning attributes in Active Record using +attributes=+ the :default role will be used. To assign attributes using different roles you should use +assign_attributes+ which accepts an optional :as options parameter. If no :as option is provided then the :default role will be used. You can also bypass mass-assignment security by using the +:without_protection+ option. Here is an example:
<ruby>
@user = User.new
@@ -451,7 +451,7 @@ When assigning attributes in Active Record using +attributes=+, or +update_attri
@user.is_admin # => true
</ruby>
-In a similar way, +new+, +create+ and <tt>create!</tt> methods respect mass-assignment security and accepts either +:as+ or +:without_protection+ options. For example:
+In a similar way, +new+, +create+, <tt>create!</tt>, +update_attributes+, and +update_attributes!+ methods all respect mass-assignment security and accept either +:as+ or +:without_protection+ options. For example:
<ruby>
@user = User.new({ :name => 'Sebastian', :is_admin => true }, :as => :admin)
diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb
index dd01bbab1d..1e4d25f18c 100644
--- a/railties/lib/rails/application.rb
+++ b/railties/lib/rails/application.rb
@@ -157,7 +157,8 @@ module Rails
middleware.use ::Rack::Lock unless config.allow_concurrency
middleware.use ::Rack::Runtime
- middleware.use ::Rails::Rack::Logger
+ middleware.use ::Rack::MethodOverride
+ middleware.use ::Rails::Rack::Logger # must come after Rack::MethodOverride to properly log overridden methods
middleware.use ::ActionDispatch::ShowExceptions, config.consider_all_requests_local
middleware.use ::ActionDispatch::RemoteIp, config.action_dispatch.ip_spoofing_check, config.action_dispatch.trusted_proxies
middleware.use ::Rack::Sendfile, config.action_dispatch.x_sendfile_header
@@ -171,7 +172,6 @@ module Rails
end
middleware.use ::ActionDispatch::ParamsParser
- middleware.use ::Rack::MethodOverride
middleware.use ::ActionDispatch::Head
middleware.use ::Rack::ConditionalGet
middleware.use ::Rack::ETag, "no-cache"
@@ -199,4 +199,4 @@ module Rails
require "rails/console/helpers"
end
end
-end \ No newline at end of file
+end
diff --git a/railties/lib/rails/commands.rb b/railties/lib/rails/commands.rb
index 4182757346..4a082aedb8 100644
--- a/railties/lib/rails/commands.rb
+++ b/railties/lib/rails/commands.rb
@@ -6,7 +6,8 @@ aliases = {
"g" => "generate",
"c" => "console",
"s" => "server",
- "db" => "dbconsole"
+ "db" => "dbconsole",
+ "r" => "runner"
}
command = ARGV.shift
diff --git a/railties/test/application/assets_test.rb b/railties/test/application/assets_test.rb
new file mode 100644
index 0000000000..b03dc3132b
--- /dev/null
+++ b/railties/test/application/assets_test.rb
@@ -0,0 +1,27 @@
+require 'isolation/abstract_unit'
+require 'rack/test'
+
+module ApplicationTests
+ class RoutingTest < Test::Unit::TestCase
+ include ActiveSupport::Testing::Isolation
+ include Rack::Test::Methods
+
+ def setup
+ build_app
+ boot_rails
+ end
+
+ test "assets routes have higher priority" do
+ app_file "app/assets/javascripts/demo.js.erb", "<%= :alert %>();"
+
+ app_file 'config/routes.rb', <<-RUBY
+ AppTemplate::Application.routes.draw do
+ match '*path', :to => lambda { |env| [200, { "Content-Type" => "text/html" }, "Not an asset"] }
+ end
+ RUBY
+
+ get "/assets/demo.js"
+ assert_match "alert()", last_response.body
+ end
+ end
+end
diff --git a/railties/test/application/middleware_test.rb b/railties/test/application/middleware_test.rb
index 01e6c49d9c..fd6dc46271 100644
--- a/railties/test/application/middleware_test.rb
+++ b/railties/test/application/middleware_test.rb
@@ -23,7 +23,8 @@ module ApplicationTests
"Rack::Lock",
"ActiveSupport::Cache::Strategy::LocalCache",
"Rack::Runtime",
- "Rails::Rack::Logger",
+ "Rack::MethodOverride",
+ "Rails::Rack::Logger", # must come after Rack::MethodOverride to properly log overridden methods
"ActionDispatch::ShowExceptions",
"ActionDispatch::RemoteIp",
"Rack::Sendfile",
@@ -36,7 +37,6 @@ module ApplicationTests
"ActionDispatch::Session::CookieStore",
"ActionDispatch::Flash",
"ActionDispatch::ParamsParser",
- "Rack::MethodOverride",
"ActionDispatch::Head",
"Rack::ConditionalGet",
"Rack::ETag",
diff --git a/railties/test/application/rack/logger_test.rb b/railties/test/application/rack/logger_test.rb
new file mode 100644
index 0000000000..a29244357c
--- /dev/null
+++ b/railties/test/application/rack/logger_test.rb
@@ -0,0 +1,40 @@
+require "isolation/abstract_unit"
+require "active_support/log_subscriber/test_helper"
+require "rack/test"
+
+module ApplicationTests
+ module RackTests
+ class LoggerTest < Test::Unit::TestCase
+ include ActiveSupport::LogSubscriber::TestHelper
+ include Rack::Test::Methods
+
+ def setup
+ build_app
+ require "#{app_path}/config/environment"
+ super
+ end
+
+ def logs
+ @logs ||= @logger.logged(:info)
+ end
+
+ test "logger logs proper HTTP verb and path" do
+ get "/blah"
+ wait
+ assert_match /^Started GET "\/blah"/, logs[0]
+ end
+
+ test "logger logs HTTP verb override" do
+ post "/", {:_method => 'put'}
+ wait
+ assert_match /^Started PUT "\/"/, logs[0]
+ end
+
+ test "logger logs HEAD requests" do
+ post "/", {:_method => 'head'}
+ wait
+ assert_match /^Started HEAD "\/"/, logs[0]
+ end
+ end
+ end
+end
diff --git a/railties/test/application/routing_test.rb b/railties/test/application/routing_test.rb
index 62589c998d..e3a7f8a63c 100644
--- a/railties/test/application/routing_test.rb
+++ b/railties/test/application/routing_test.rb
@@ -1,14 +1,14 @@
require 'isolation/abstract_unit'
+require 'rack/test'
module ApplicationTests
class RoutingTest < Test::Unit::TestCase
include ActiveSupport::Testing::Isolation
+ include Rack::Test::Methods
def setup
build_app
boot_rails
- require 'rack/test'
- extend Rack::Test::Methods
end
test "rails/info/properties in development" do
diff --git a/railties/test/railties/shared_tests.rb b/railties/test/railties/shared_tests.rb
index e975950b85..e5debf29ae 100644
--- a/railties/test/railties/shared_tests.rb
+++ b/railties/test/railties/shared_tests.rb
@@ -15,11 +15,10 @@ module RailtiesTest
boot_rails
require 'rack/test'
- require 'coffee_script'
extend Rack::Test::Methods
get "/assets/engine.js"
- assert_match "alert();", last_response.body
+ assert_match "alert()", last_response.body
end
def test_copying_migrations