From fa487763d98ccf9c3e66fdb44f09af5c37a50fe5 Mon Sep 17 00:00:00 2001 From: Vipul A M Date: Tue, 12 Apr 2016 02:41:06 +0530 Subject: Changed default behaviour of `ActiveSupport::SecurityUtils.secure_compare`, to make it not leak length information even for variable length string. Renamed old `ActiveSupport::SecurityUtils.secure_compare` to `fixed_length_secure_compare`, and started raising `ArgumentError` in case of length mismatch of passed strings. --- activesupport/test/security_utils_test.rb | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'activesupport/test') diff --git a/activesupport/test/security_utils_test.rb b/activesupport/test/security_utils_test.rb index e8f762da22..8d7f7d699a 100644 --- a/activesupport/test/security_utils_test.rb +++ b/activesupport/test/security_utils_test.rb @@ -11,4 +11,15 @@ class SecurityUtilsTest < ActiveSupport::TestCase assert ActiveSupport::SecurityUtils.variable_size_secure_compare("a", "a") assert_not ActiveSupport::SecurityUtils.variable_size_secure_compare("a", "b") end + + def test_fixed_length_secure_compare_should_perform_string_comparison + assert ActiveSupport::SecurityUtils.fixed_length_secure_compare("a", "a") + assert !ActiveSupport::SecurityUtils.fixed_length_secure_compare("a", "b") + end + + def test_fixed_length_secure_compare_raise_on_length_mismatch + assert_raises(ArgumentError, "string length mismatch.") do + ActiveSupport::SecurityUtils.fixed_length_secure_compare("a", "ab") + end + end end -- cgit v1.2.3 From 9e4827a8ae40de50503c530b8cfd0a0789e27956 Mon Sep 17 00:00:00 2001 From: bogdanvlviv Date: Sun, 17 Sep 2017 02:20:02 +0300 Subject: Deprecate `Module#reachable?` method --- .../test/core_ext/module/reachable_test.rb | 28 ++++++++++++++-------- 1 file changed, 18 insertions(+), 10 deletions(-) (limited to 'activesupport/test') diff --git a/activesupport/test/core_ext/module/reachable_test.rb b/activesupport/test/core_ext/module/reachable_test.rb index a69fc6839e..097a72fa5b 100644 --- a/activesupport/test/core_ext/module/reachable_test.rb +++ b/activesupport/test/core_ext/module/reachable_test.rb @@ -5,13 +5,17 @@ require "active_support/core_ext/module/reachable" class AnonymousTest < ActiveSupport::TestCase test "an anonymous class or module is not reachable" do - assert !Module.new.reachable? - assert !Class.new.reachable? + assert_deprecated do + assert !Module.new.reachable? + assert !Class.new.reachable? + end end test "ordinary named classes or modules are reachable" do - assert Kernel.reachable? - assert Object.reachable? + assert_deprecated do + assert Kernel.reachable? + assert Object.reachable? + end end test "a named class or module whose constant has gone is not reachable" do @@ -21,8 +25,10 @@ class AnonymousTest < ActiveSupport::TestCase self.class.send(:remove_const, :C) self.class.send(:remove_const, :M) - assert !c.reachable? - assert !m.reachable? + assert_deprecated do + assert !c.reachable? + assert !m.reachable? + end end test "a named class or module whose constants store different objects are not reachable" do @@ -35,9 +41,11 @@ class AnonymousTest < ActiveSupport::TestCase eval "class C; end" eval "module M; end" - assert C.reachable? - assert M.reachable? - assert !c.reachable? - assert !m.reachable? + assert_deprecated do + assert C.reachable? + assert M.reachable? + assert !c.reachable? + assert !m.reachable? + end end end -- cgit v1.2.3 From 962ce60ff1692f6f2ed1a8322319d73b9790d324 Mon Sep 17 00:00:00 2001 From: "yuuji.yaginuma" Date: Sat, 23 Sep 2017 18:25:16 +0900 Subject: Make bang version work with `InheritableOptions` Currently, bang version does not work with `InheritableOptions`. `InheritableOptions` treats the argument Hash as the default value. However, `Hash#fetch` does not use the default value when key is not found, so can not get the default value. So in bang version, should use `Hash#[]` instead of `Hash#fetch`. --- activesupport/test/ordered_options_test.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'activesupport/test') diff --git a/activesupport/test/ordered_options_test.rb b/activesupport/test/ordered_options_test.rb index 7f2e774c02..2c67bb02ac 100644 --- a/activesupport/test/ordered_options_test.rb +++ b/activesupport/test/ordered_options_test.rb @@ -102,4 +102,17 @@ class OrderedOptionsTest < ActiveSupport::TestCase end assert_raises(KeyError) { a.non_existing_key! } end + + def test_inheritable_options_with_bang + a = ActiveSupport::InheritableOptions.new(foo: :bar) + + assert_nothing_raised { a.foo! } + assert_equal a.foo, a.foo! + + assert_raises(KeyError) do + a.foo = nil + a.foo! + end + assert_raises(KeyError) { a.non_existing_key! } + end end -- cgit v1.2.3 From 39f8ca64cec8667b66628e970211b4d18abbc373 Mon Sep 17 00:00:00 2001 From: Michael Coyne Date: Sat, 23 Sep 2017 17:16:21 -0400 Subject: Add key rotation message Encryptor and Verifier Both classes now have a rotate method where new instances are added for each call. When decryption or verification fails the next rotation instance is tried. --- activesupport/test/message_encryptor_test.rb | 118 +++++++++++++++++++++ activesupport/test/message_verifier_test.rb | 90 ++++++++++++++++ .../test/messages/rotation_configuration_test.rb | 43 ++++++++ 3 files changed, 251 insertions(+) create mode 100644 activesupport/test/messages/rotation_configuration_test.rb (limited to 'activesupport/test') diff --git a/activesupport/test/message_encryptor_test.rb b/activesupport/test/message_encryptor_test.rb index 1fbe655642..17baf3550b 100644 --- a/activesupport/test/message_encryptor_test.rb +++ b/activesupport/test/message_encryptor_test.rb @@ -115,6 +115,124 @@ class MessageEncryptorTest < ActiveSupport::TestCase assert_equal "Ruby on Rails", encryptor.decrypt_and_verify(encrypted_message) end + def test_with_rotated_raw_key + old_raw_key = SecureRandom.random_bytes(32) + old_encryptor = ActiveSupport::MessageEncryptor.new(old_raw_key, cipher: "aes-256-gcm") + old_message = old_encryptor.encrypt_and_sign("message encrypted with old raw key") + + encryptor = ActiveSupport::MessageEncryptor.new(@secret, cipher: "aes-256-gcm") + encryptor.rotate raw_key: old_raw_key, cipher: "aes-256-gcm" + + assert_equal "message encrypted with old raw key", encryptor.decrypt_and_verify(old_message) + end + + def test_with_rotated_secret_and_salt + old_secret, old_salt = SecureRandom.random_bytes(32), "old salt" + old_raw_key = ActiveSupport::KeyGenerator.new(old_secret, iterations: 1000).generate_key(old_salt, 32) + + old_encryptor = ActiveSupport::MessageEncryptor.new(old_raw_key, cipher: "aes-256-gcm") + old_message = old_encryptor.encrypt_and_sign("message encrypted with old secret and salt") + + encryptor = ActiveSupport::MessageEncryptor.new(@secret, cipher: "aes-256-gcm") + encryptor.rotate secret: old_secret, salt: old_salt, cipher: "aes-256-gcm" + + assert_equal "message encrypted with old secret and salt", encryptor.decrypt_and_verify(old_message) + end + + def test_with_rotated_key_generator + old_key_gen, old_salt = ActiveSupport::KeyGenerator.new(SecureRandom.random_bytes(32), iterations: 256), "old salt" + + old_raw_key = old_key_gen.generate_key(old_salt, 32) + old_encryptor = ActiveSupport::MessageEncryptor.new(old_raw_key, cipher: "aes-256-gcm") + old_message = old_encryptor.encrypt_and_sign("message encrypted with old key generator and salt") + + encryptor = ActiveSupport::MessageEncryptor.new(@secret, cipher: "aes-256-gcm") + encryptor.rotate key_generator: old_key_gen, salt: old_salt, cipher: "aes-256-gcm" + + assert_equal "message encrypted with old key generator and salt", encryptor.decrypt_and_verify(old_message) + end + + def test_with_rotated_aes_cbc_encryptor_with_raw_keys + old_raw_key, old_raw_signed_key = SecureRandom.random_bytes(32), SecureRandom.random_bytes(16) + + old_encryptor = ActiveSupport::MessageEncryptor.new(old_raw_key, old_raw_signed_key, cipher: "aes-256-cbc", digest: "SHA1") + old_message = old_encryptor.encrypt_and_sign("message encrypted with old raw keys") + + encryptor = ActiveSupport::MessageEncryptor.new(@secret) + encryptor.rotate raw_key: old_raw_key, raw_signed_key: old_raw_signed_key, cipher: "aes-256-cbc", digest: "SHA1" + + assert_equal "message encrypted with old raw keys", encryptor.decrypt_and_verify(old_message) + end + + def test_with_rotated_aes_cbc_encryptor_with_secret_and_salts + old_secret, old_salt, old_signed_salt = SecureRandom.random_bytes(32), "old salt", "old signed salt" + + old_key_gen = ActiveSupport::KeyGenerator.new(old_secret, iterations: 1000) + old_raw_key = old_key_gen.generate_key(old_salt, 32) + old_raw_signed_key = old_key_gen.generate_key(old_signed_salt) + + old_encryptor = ActiveSupport::MessageEncryptor.new(old_raw_key, old_raw_signed_key, cipher: "aes-256-cbc", digest: "SHA1") + old_message = old_encryptor.encrypt_and_sign("message encrypted with old secret and salts") + + encryptor = ActiveSupport::MessageEncryptor.new(@secret) + encryptor.rotate secret: old_secret, salt: old_salt, signed_salt: old_signed_salt, cipher: "aes-256-cbc", digest: "SHA1" + + assert_equal "message encrypted with old secret and salts", encryptor.decrypt_and_verify(old_message) + end + + def test_with_rotating_multiple_encryptors + older_raw_key, older_raw_signed_key = SecureRandom.random_bytes(32), SecureRandom.random_bytes(16) + old_raw_key, old_raw_signed_key = SecureRandom.random_bytes(32), SecureRandom.random_bytes(16) + + older_encryptor = ActiveSupport::MessageEncryptor.new(older_raw_key, older_raw_signed_key, cipher: "aes-256-cbc", digest: "SHA1") + older_message = older_encryptor.encrypt_and_sign("message encrypted with older raw key") + + old_encryptor = ActiveSupport::MessageEncryptor.new(old_raw_key, old_raw_signed_key, cipher: "aes-256-cbc", digest: "SHA1") + old_message = old_encryptor.encrypt_and_sign("message encrypted with old raw key") + + encryptor = ActiveSupport::MessageEncryptor.new(@secret) + encryptor.rotate raw_key: old_raw_key, raw_signed_key: old_raw_signed_key, cipher: "aes-256-cbc", digest: "SHA1" + encryptor.rotate raw_key: older_raw_key, raw_signed_key: older_raw_signed_key, cipher: "aes-256-cbc", digest: "SHA1" + + assert_equal "encrypted message", encryptor.decrypt_and_verify(encryptor.encrypt_and_sign("encrypted message")) + assert_equal "message encrypted with old raw key", encryptor.decrypt_and_verify(old_message) + assert_equal "message encrypted with older raw key", encryptor.decrypt_and_verify(older_message) + end + + def test_on_rotation_instance_callback_is_called_and_returns_modified_messages + callback_ran, message = nil, nil + + older_raw_key, older_raw_signed_key = SecureRandom.random_bytes(32), SecureRandom.random_bytes(16) + old_raw_key, old_raw_signed_key = SecureRandom.random_bytes(32), SecureRandom.random_bytes(16) + + older_encryptor = ActiveSupport::MessageEncryptor.new(older_raw_key, older_raw_signed_key, cipher: "aes-256-cbc", digest: "SHA1") + older_message = older_encryptor.encrypt_and_sign(encoded: "message") + + encryptor = ActiveSupport::MessageEncryptor.new(@secret) + encryptor.rotate raw_key: old_raw_key, raw_signed_key: old_raw_signed_key, cipher: "aes-256-cbc", digest: "SHA1" + encryptor.rotate raw_key: older_raw_key, raw_signed_key: older_raw_signed_key, cipher: "aes-256-cbc", digest: "SHA1" + + message = encryptor.decrypt_and_verify(older_message, on_rotation: proc { callback_ran = true }) + + assert callback_ran, "callback was ran" + assert_equal({ encoded: "message" }, message) + end + + def test_with_rotated_metadata + old_secret, old_salt = SecureRandom.random_bytes(32), "old salt" + old_raw_key = ActiveSupport::KeyGenerator.new(old_secret, iterations: 1000).generate_key(old_salt, 32) + + old_encryptor = ActiveSupport::MessageEncryptor.new(old_raw_key, cipher: "aes-256-gcm") + old_message = old_encryptor.encrypt_and_sign( + "message encrypted with old secret, salt, and metadata", purpose: "rotation") + + encryptor = ActiveSupport::MessageEncryptor.new(@secret, cipher: "aes-256-gcm") + encryptor.rotate secret: old_secret, salt: old_salt, cipher: "aes-256-gcm" + + assert_equal "message encrypted with old secret, salt, and metadata", + encryptor.decrypt_and_verify(old_message, purpose: "rotation") + end + private def assert_aead_not_decrypted(encryptor, value) assert_raise(ActiveSupport::MessageEncryptor::InvalidMessage) do diff --git a/activesupport/test/message_verifier_test.rb b/activesupport/test/message_verifier_test.rb index fbeafca203..3079c48c02 100644 --- a/activesupport/test/message_verifier_test.rb +++ b/activesupport/test/message_verifier_test.rb @@ -20,6 +20,7 @@ class MessageVerifierTest < ActiveSupport::TestCase def setup @verifier = ActiveSupport::MessageVerifier.new("Hey, I'm a secret!") @data = { some: "data", now: Time.utc(2010) } + @secret = SecureRandom.random_bytes(32) end def test_valid_message @@ -90,6 +91,95 @@ class MessageVerifierTest < ActiveSupport::TestCase signed_message = "BAh7BzoJc29tZUkiCWRhdGEGOgZFVDoIbm93SXU6CVRpbWUNIIAbgAAAAAAHOgtvZmZzZXRpADoJem9uZUkiCFVUQwY7BkY=--d03c52c91dfe4ccc5159417c660461bcce005e96" assert_equal @data, @verifier.verify(signed_message) end + + def test_with_rotated_raw_key + old_raw_key = SecureRandom.random_bytes(32) + + old_verifier = ActiveSupport::MessageVerifier.new(old_raw_key, digest: "SHA1") + old_message = old_verifier.generate("message verified with old raw key") + + verifier = ActiveSupport::MessageVerifier.new(@secret, digest: "SHA1") + verifier.rotate raw_key: old_raw_key, digest: "SHA1" + + assert_equal "message verified with old raw key", verifier.verified(old_message) + end + + def test_with_rotated_secret_and_salt + old_secret, old_salt = SecureRandom.random_bytes(32), "old salt" + + old_raw_key = ActiveSupport::KeyGenerator.new(old_secret, iterations: 1000).generate_key(old_salt) + old_verifier = ActiveSupport::MessageVerifier.new(old_raw_key, digest: "SHA1") + old_message = old_verifier.generate("message verified with old secret and salt") + + verifier = ActiveSupport::MessageVerifier.new(@secret, digest: "SHA1") + verifier.rotate secret: old_secret, salt: old_salt, digest: "SHA1" + + assert_equal "message verified with old secret and salt", verifier.verified(old_message) + end + + def test_with_rotated_key_generator + old_key_gen, old_salt = ActiveSupport::KeyGenerator.new(SecureRandom.random_bytes(32), iterations: 256), "old salt" + + old_raw_key = old_key_gen.generate_key(old_salt) + old_verifier = ActiveSupport::MessageVerifier.new(old_raw_key, digest: "SHA1") + old_message = old_verifier.generate("message verified with old key generator and salt") + + verifier = ActiveSupport::MessageVerifier.new(@secret, digest: "SHA1") + verifier.rotate key_generator: old_key_gen, salt: old_salt, digest: "SHA1" + + assert_equal "message verified with old key generator and salt", verifier.verified(old_message) + end + + def test_with_rotating_multiple_verifiers + old_raw_key, older_raw_key = SecureRandom.random_bytes(32), SecureRandom.random_bytes(32) + + old_verifier = ActiveSupport::MessageVerifier.new(old_raw_key, digest: "SHA256") + old_message = old_verifier.generate("message verified with old raw key") + + older_verifier = ActiveSupport::MessageVerifier.new(older_raw_key, digest: "SHA1") + older_message = older_verifier.generate("message verified with older raw key") + + verifier = ActiveSupport::MessageVerifier.new("new secret", digest: "SHA512") + verifier.rotate raw_key: old_raw_key, digest: "SHA256" + verifier.rotate raw_key: older_raw_key, digest: "SHA1" + + assert_equal "verified message", verifier.verified(verifier.generate("verified message")) + assert_equal "message verified with old raw key", verifier.verified(old_message) + assert_equal "message verified with older raw key", verifier.verified(older_message) + end + + def test_on_rotation_keyword_block_is_called_and_verified_returns_message + callback_ran, message = nil, nil + + old_raw_key, older_raw_key = SecureRandom.random_bytes(32), SecureRandom.random_bytes(32) + + older_verifier = ActiveSupport::MessageVerifier.new(older_raw_key, digest: "SHA1") + older_message = older_verifier.generate(encoded: "message") + + verifier = ActiveSupport::MessageVerifier.new("new secret", digest: "SHA512") + verifier.rotate raw_key: old_raw_key, digest: "SHA256" + verifier.rotate raw_key: older_raw_key, digest: "SHA1" + + message = verifier.verified(older_message, on_rotation: proc { callback_ran = true }) + + assert callback_ran, "callback was ran" + assert_equal({ encoded: "message" }, message) + end + + def test_with_rotated_metadata + old_secret, old_salt = SecureRandom.random_bytes(32), "old salt" + + old_raw_key = ActiveSupport::KeyGenerator.new(old_secret, iterations: 1000).generate_key(old_salt) + old_verifier = ActiveSupport::MessageVerifier.new(old_raw_key, digest: "SHA1") + old_message = old_verifier.generate( + "message verified with old secret, salt, and metadata", purpose: "rotation") + + verifier = ActiveSupport::MessageVerifier.new(@secret, digest: "SHA1") + verifier.rotate secret: old_secret, salt: old_salt, digest: "SHA1" + + assert_equal "message verified with old secret, salt, and metadata", + verifier.verified(old_message, purpose: "rotation") + end end class MessageVerifierMetadataTest < ActiveSupport::TestCase diff --git a/activesupport/test/messages/rotation_configuration_test.rb b/activesupport/test/messages/rotation_configuration_test.rb new file mode 100644 index 0000000000..41d938e119 --- /dev/null +++ b/activesupport/test/messages/rotation_configuration_test.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +require "abstract_unit" +require "active_support/messages/rotation_configuration" + +class MessagesRotationConfiguration < ActiveSupport::TestCase + def setup + @config = ActiveSupport::Messages::RotationConfiguration.new + end + + def test_signed_configurations + @config.rotate :signed, secret: "older secret", salt: "salt", digest: "SHA1" + @config.rotate :signed, secret: "old secret", salt: "salt", digest: "SHA256" + + assert_equal [{ + secret: "older secret", salt: "salt", digest: "SHA1" + }, { + secret: "old secret", salt: "salt", digest: "SHA256" + }], @config.signed + end + + def test_encrypted_configurations + @config.rotate :encrypted, raw_key: "old raw key", cipher: "aes-256-gcm" + + assert_equal [{ + raw_key: "old raw key", cipher: "aes-256-gcm" + }], @config.encrypted + end + + def test_rotate_without_kind + @config.rotate secret: "older secret", salt: "salt", digest: "SHA1" + @config.rotate raw_key: "old raw key", cipher: "aes-256-gcm" + + expected = [{ + secret: "older secret", salt: "salt", digest: "SHA1" + }, { + raw_key: "old raw key", cipher: "aes-256-gcm" + }] + + assert_equal expected, @config.encrypted + assert_equal expected, @config.signed + end +end -- cgit v1.2.3 From 20ba2e762ceab098371122b0c02b4a90239d2ace Mon Sep 17 00:00:00 2001 From: Kasper Timm Hansen Date: Sun, 24 Sep 2017 19:46:10 +0200 Subject: Infer options from the primary verifier. Spares users from passing in non-changing values explicitly. [ Michael Coyne & Kasper Timm Hansen ] --- activesupport/test/message_encryptor_test.rb | 20 ++++++++++++++++---- activesupport/test/message_verifier_test.rb | 8 ++++---- 2 files changed, 20 insertions(+), 8 deletions(-) (limited to 'activesupport/test') diff --git a/activesupport/test/message_encryptor_test.rb b/activesupport/test/message_encryptor_test.rb index 17baf3550b..915038c854 100644 --- a/activesupport/test/message_encryptor_test.rb +++ b/activesupport/test/message_encryptor_test.rb @@ -121,11 +121,23 @@ class MessageEncryptorTest < ActiveSupport::TestCase old_message = old_encryptor.encrypt_and_sign("message encrypted with old raw key") encryptor = ActiveSupport::MessageEncryptor.new(@secret, cipher: "aes-256-gcm") - encryptor.rotate raw_key: old_raw_key, cipher: "aes-256-gcm" + encryptor.rotate raw_key: old_raw_key assert_equal "message encrypted with old raw key", encryptor.decrypt_and_verify(old_message) end + def test_rotating_serializer + old_raw_key = SecureRandom.random_bytes(32) + + old_message = ActiveSupport::MessageEncryptor.new(old_raw_key, cipher: "aes-256-gcm", serializer: JSON). + encrypt_and_sign(ahoy: :hoy) + + encryptor = ActiveSupport::MessageEncryptor.new(@secret, cipher: "aes-256-gcm", serializer: JSON) + encryptor.rotate raw_key: old_raw_key + + assert_equal({ "ahoy" => "hoy" }, encryptor.decrypt_and_verify(old_message)) + end + def test_with_rotated_secret_and_salt old_secret, old_salt = SecureRandom.random_bytes(32), "old salt" old_raw_key = ActiveSupport::KeyGenerator.new(old_secret, iterations: 1000).generate_key(old_salt, 32) @@ -134,7 +146,7 @@ class MessageEncryptorTest < ActiveSupport::TestCase old_message = old_encryptor.encrypt_and_sign("message encrypted with old secret and salt") encryptor = ActiveSupport::MessageEncryptor.new(@secret, cipher: "aes-256-gcm") - encryptor.rotate secret: old_secret, salt: old_salt, cipher: "aes-256-gcm" + encryptor.rotate secret: old_secret, salt: old_salt assert_equal "message encrypted with old secret and salt", encryptor.decrypt_and_verify(old_message) end @@ -147,7 +159,7 @@ class MessageEncryptorTest < ActiveSupport::TestCase old_message = old_encryptor.encrypt_and_sign("message encrypted with old key generator and salt") encryptor = ActiveSupport::MessageEncryptor.new(@secret, cipher: "aes-256-gcm") - encryptor.rotate key_generator: old_key_gen, salt: old_salt, cipher: "aes-256-gcm" + encryptor.rotate key_generator: old_key_gen, salt: old_salt assert_equal "message encrypted with old key generator and salt", encryptor.decrypt_and_verify(old_message) end @@ -227,7 +239,7 @@ class MessageEncryptorTest < ActiveSupport::TestCase "message encrypted with old secret, salt, and metadata", purpose: "rotation") encryptor = ActiveSupport::MessageEncryptor.new(@secret, cipher: "aes-256-gcm") - encryptor.rotate secret: old_secret, salt: old_salt, cipher: "aes-256-gcm" + encryptor.rotate secret: old_secret, salt: old_salt assert_equal "message encrypted with old secret, salt, and metadata", encryptor.decrypt_and_verify(old_message, purpose: "rotation") diff --git a/activesupport/test/message_verifier_test.rb b/activesupport/test/message_verifier_test.rb index 3079c48c02..b43fc4b269 100644 --- a/activesupport/test/message_verifier_test.rb +++ b/activesupport/test/message_verifier_test.rb @@ -99,7 +99,7 @@ class MessageVerifierTest < ActiveSupport::TestCase old_message = old_verifier.generate("message verified with old raw key") verifier = ActiveSupport::MessageVerifier.new(@secret, digest: "SHA1") - verifier.rotate raw_key: old_raw_key, digest: "SHA1" + verifier.rotate raw_key: old_raw_key assert_equal "message verified with old raw key", verifier.verified(old_message) end @@ -112,7 +112,7 @@ class MessageVerifierTest < ActiveSupport::TestCase old_message = old_verifier.generate("message verified with old secret and salt") verifier = ActiveSupport::MessageVerifier.new(@secret, digest: "SHA1") - verifier.rotate secret: old_secret, salt: old_salt, digest: "SHA1" + verifier.rotate secret: old_secret, salt: old_salt assert_equal "message verified with old secret and salt", verifier.verified(old_message) end @@ -125,7 +125,7 @@ class MessageVerifierTest < ActiveSupport::TestCase old_message = old_verifier.generate("message verified with old key generator and salt") verifier = ActiveSupport::MessageVerifier.new(@secret, digest: "SHA1") - verifier.rotate key_generator: old_key_gen, salt: old_salt, digest: "SHA1" + verifier.rotate key_generator: old_key_gen, salt: old_salt assert_equal "message verified with old key generator and salt", verifier.verified(old_message) end @@ -175,7 +175,7 @@ class MessageVerifierTest < ActiveSupport::TestCase "message verified with old secret, salt, and metadata", purpose: "rotation") verifier = ActiveSupport::MessageVerifier.new(@secret, digest: "SHA1") - verifier.rotate secret: old_secret, salt: old_salt, digest: "SHA1" + verifier.rotate secret: old_secret, salt: old_salt assert_equal "message verified with old secret, salt, and metadata", verifier.verified(old_message, purpose: "rotation") -- cgit v1.2.3 From b5aa2e0c495b310cbef90b2185ef28cd00745b23 Mon Sep 17 00:00:00 2001 From: Kasper Timm Hansen Date: Sun, 24 Sep 2017 20:06:38 +0200 Subject: Remove advanced key generator rotations from verifier/encryptor. Noticed that verifiers and encryptors never once mentioned key generators and salts but only concerned themselves with generated secrets. Clears up the confusing naming around raw_key and secret as well. And makes the rotation API follow the constructor signature to the letter. --- activesupport/test/message_encryptor_test.rb | 128 +++++++-------------------- activesupport/test/message_verifier_test.rb | 96 ++++++-------------- 2 files changed, 60 insertions(+), 164 deletions(-) (limited to 'activesupport/test') diff --git a/activesupport/test/message_encryptor_test.rb b/activesupport/test/message_encryptor_test.rb index 915038c854..8fde3928dc 100644 --- a/activesupport/test/message_encryptor_test.rb +++ b/activesupport/test/message_encryptor_test.rb @@ -115,134 +115,70 @@ class MessageEncryptorTest < ActiveSupport::TestCase assert_equal "Ruby on Rails", encryptor.decrypt_and_verify(encrypted_message) end - def test_with_rotated_raw_key - old_raw_key = SecureRandom.random_bytes(32) - old_encryptor = ActiveSupport::MessageEncryptor.new(old_raw_key, cipher: "aes-256-gcm") - old_message = old_encryptor.encrypt_and_sign("message encrypted with old raw key") + def test_rotating_secret + old_message = ActiveSupport::MessageEncryptor.new(secrets[:old], cipher: "aes-256-gcm").encrypt_and_sign("old") encryptor = ActiveSupport::MessageEncryptor.new(@secret, cipher: "aes-256-gcm") - encryptor.rotate raw_key: old_raw_key + encryptor.rotate secrets[:old] - assert_equal "message encrypted with old raw key", encryptor.decrypt_and_verify(old_message) + assert_equal "old", encryptor.decrypt_and_verify(old_message) end def test_rotating_serializer - old_raw_key = SecureRandom.random_bytes(32) - - old_message = ActiveSupport::MessageEncryptor.new(old_raw_key, cipher: "aes-256-gcm", serializer: JSON). + old_message = ActiveSupport::MessageEncryptor.new(secrets[:old], cipher: "aes-256-gcm", serializer: JSON). encrypt_and_sign(ahoy: :hoy) encryptor = ActiveSupport::MessageEncryptor.new(@secret, cipher: "aes-256-gcm", serializer: JSON) - encryptor.rotate raw_key: old_raw_key + encryptor.rotate secrets[:old] assert_equal({ "ahoy" => "hoy" }, encryptor.decrypt_and_verify(old_message)) end - def test_with_rotated_secret_and_salt - old_secret, old_salt = SecureRandom.random_bytes(32), "old salt" - old_raw_key = ActiveSupport::KeyGenerator.new(old_secret, iterations: 1000).generate_key(old_salt, 32) - - old_encryptor = ActiveSupport::MessageEncryptor.new(old_raw_key, cipher: "aes-256-gcm") - old_message = old_encryptor.encrypt_and_sign("message encrypted with old secret and salt") - - encryptor = ActiveSupport::MessageEncryptor.new(@secret, cipher: "aes-256-gcm") - encryptor.rotate secret: old_secret, salt: old_salt - - assert_equal "message encrypted with old secret and salt", encryptor.decrypt_and_verify(old_message) - end - - def test_with_rotated_key_generator - old_key_gen, old_salt = ActiveSupport::KeyGenerator.new(SecureRandom.random_bytes(32), iterations: 256), "old salt" - - old_raw_key = old_key_gen.generate_key(old_salt, 32) - old_encryptor = ActiveSupport::MessageEncryptor.new(old_raw_key, cipher: "aes-256-gcm") - old_message = old_encryptor.encrypt_and_sign("message encrypted with old key generator and salt") - - encryptor = ActiveSupport::MessageEncryptor.new(@secret, cipher: "aes-256-gcm") - encryptor.rotate key_generator: old_key_gen, salt: old_salt - - assert_equal "message encrypted with old key generator and salt", encryptor.decrypt_and_verify(old_message) - end - - def test_with_rotated_aes_cbc_encryptor_with_raw_keys - old_raw_key, old_raw_signed_key = SecureRandom.random_bytes(32), SecureRandom.random_bytes(16) - - old_encryptor = ActiveSupport::MessageEncryptor.new(old_raw_key, old_raw_signed_key, cipher: "aes-256-cbc", digest: "SHA1") - old_message = old_encryptor.encrypt_and_sign("message encrypted with old raw keys") - - encryptor = ActiveSupport::MessageEncryptor.new(@secret) - encryptor.rotate raw_key: old_raw_key, raw_signed_key: old_raw_signed_key, cipher: "aes-256-cbc", digest: "SHA1" - - assert_equal "message encrypted with old raw keys", encryptor.decrypt_and_verify(old_message) - end - - def test_with_rotated_aes_cbc_encryptor_with_secret_and_salts - old_secret, old_salt, old_signed_salt = SecureRandom.random_bytes(32), "old salt", "old signed salt" - - old_key_gen = ActiveSupport::KeyGenerator.new(old_secret, iterations: 1000) - old_raw_key = old_key_gen.generate_key(old_salt, 32) - old_raw_signed_key = old_key_gen.generate_key(old_signed_salt) - - old_encryptor = ActiveSupport::MessageEncryptor.new(old_raw_key, old_raw_signed_key, cipher: "aes-256-cbc", digest: "SHA1") - old_message = old_encryptor.encrypt_and_sign("message encrypted with old secret and salts") + def test_rotating_aes_cbc_secrets + old_encryptor = ActiveSupport::MessageEncryptor.new(secrets[:old], "old sign", cipher: "aes-256-cbc") + old_message = old_encryptor.encrypt_and_sign("old") encryptor = ActiveSupport::MessageEncryptor.new(@secret) - encryptor.rotate secret: old_secret, salt: old_salt, signed_salt: old_signed_salt, cipher: "aes-256-cbc", digest: "SHA1" + encryptor.rotate secrets[:old], "old sign", cipher: "aes-256-cbc" - assert_equal "message encrypted with old secret and salts", encryptor.decrypt_and_verify(old_message) + assert_equal "old", encryptor.decrypt_and_verify(old_message) end - def test_with_rotating_multiple_encryptors - older_raw_key, older_raw_signed_key = SecureRandom.random_bytes(32), SecureRandom.random_bytes(16) - old_raw_key, old_raw_signed_key = SecureRandom.random_bytes(32), SecureRandom.random_bytes(16) - - older_encryptor = ActiveSupport::MessageEncryptor.new(older_raw_key, older_raw_signed_key, cipher: "aes-256-cbc", digest: "SHA1") - older_message = older_encryptor.encrypt_and_sign("message encrypted with older raw key") - - old_encryptor = ActiveSupport::MessageEncryptor.new(old_raw_key, old_raw_signed_key, cipher: "aes-256-cbc", digest: "SHA1") - old_message = old_encryptor.encrypt_and_sign("message encrypted with old raw key") + def test_multiple_rotations + older_message = ActiveSupport::MessageEncryptor.new(secrets[:older], "older sign").encrypt_and_sign("older") + old_message = ActiveSupport::MessageEncryptor.new(secrets[:old], "old sign").encrypt_and_sign("old") encryptor = ActiveSupport::MessageEncryptor.new(@secret) - encryptor.rotate raw_key: old_raw_key, raw_signed_key: old_raw_signed_key, cipher: "aes-256-cbc", digest: "SHA1" - encryptor.rotate raw_key: older_raw_key, raw_signed_key: older_raw_signed_key, cipher: "aes-256-cbc", digest: "SHA1" + encryptor.rotate secrets[:old], "old sign" + encryptor.rotate secrets[:older], "older sign" - assert_equal "encrypted message", encryptor.decrypt_and_verify(encryptor.encrypt_and_sign("encrypted message")) - assert_equal "message encrypted with old raw key", encryptor.decrypt_and_verify(old_message) - assert_equal "message encrypted with older raw key", encryptor.decrypt_and_verify(older_message) + assert_equal "new", encryptor.decrypt_and_verify(encryptor.encrypt_and_sign("new")) + assert_equal "old", encryptor.decrypt_and_verify(old_message) + assert_equal "older", encryptor.decrypt_and_verify(older_message) end - def test_on_rotation_instance_callback_is_called_and_returns_modified_messages - callback_ran, message = nil, nil - - older_raw_key, older_raw_signed_key = SecureRandom.random_bytes(32), SecureRandom.random_bytes(16) - old_raw_key, old_raw_signed_key = SecureRandom.random_bytes(32), SecureRandom.random_bytes(16) - - older_encryptor = ActiveSupport::MessageEncryptor.new(older_raw_key, older_raw_signed_key, cipher: "aes-256-cbc", digest: "SHA1") - older_message = older_encryptor.encrypt_and_sign(encoded: "message") + def test_on_rotation_is_called_and_returns_modified_messages + older_message = ActiveSupport::MessageEncryptor.new(secrets[:older], "older sign").encrypt_and_sign(encoded: "message") encryptor = ActiveSupport::MessageEncryptor.new(@secret) - encryptor.rotate raw_key: old_raw_key, raw_signed_key: old_raw_signed_key, cipher: "aes-256-cbc", digest: "SHA1" - encryptor.rotate raw_key: older_raw_key, raw_signed_key: older_raw_signed_key, cipher: "aes-256-cbc", digest: "SHA1" + encryptor.rotate secrets[:old] + encryptor.rotate secrets[:older], "older sign" - message = encryptor.decrypt_and_verify(older_message, on_rotation: proc { callback_ran = true }) + rotated = false + message = encryptor.decrypt_and_verify(older_message, on_rotation: proc { rotated = true }) - assert callback_ran, "callback was ran" assert_equal({ encoded: "message" }, message) + assert rotated end def test_with_rotated_metadata - old_secret, old_salt = SecureRandom.random_bytes(32), "old salt" - old_raw_key = ActiveSupport::KeyGenerator.new(old_secret, iterations: 1000).generate_key(old_salt, 32) - - old_encryptor = ActiveSupport::MessageEncryptor.new(old_raw_key, cipher: "aes-256-gcm") - old_message = old_encryptor.encrypt_and_sign( - "message encrypted with old secret, salt, and metadata", purpose: "rotation") + old_message = ActiveSupport::MessageEncryptor.new(secrets[:old], cipher: "aes-256-gcm"). + encrypt_and_sign("metadata", purpose: :rotation) encryptor = ActiveSupport::MessageEncryptor.new(@secret, cipher: "aes-256-gcm") - encryptor.rotate secret: old_secret, salt: old_salt + encryptor.rotate secrets[:old] - assert_equal "message encrypted with old secret, salt, and metadata", - encryptor.decrypt_and_verify(old_message, purpose: "rotation") + assert_equal "metadata", encryptor.decrypt_and_verify(old_message, purpose: :rotation) end private @@ -264,6 +200,10 @@ class MessageEncryptorTest < ActiveSupport::TestCase end end + def secrets + @secrets ||= Hash.new { |h,k| h[k] = SecureRandom.random_bytes(32) } + end + def munge(base64_string) bits = ::Base64.strict_decode64(base64_string) bits.reverse! diff --git a/activesupport/test/message_verifier_test.rb b/activesupport/test/message_verifier_test.rb index b43fc4b269..05d5c1cbc3 100644 --- a/activesupport/test/message_verifier_test.rb +++ b/activesupport/test/message_verifier_test.rb @@ -92,93 +92,49 @@ class MessageVerifierTest < ActiveSupport::TestCase assert_equal @data, @verifier.verify(signed_message) end - def test_with_rotated_raw_key - old_raw_key = SecureRandom.random_bytes(32) - - old_verifier = ActiveSupport::MessageVerifier.new(old_raw_key, digest: "SHA1") - old_message = old_verifier.generate("message verified with old raw key") - - verifier = ActiveSupport::MessageVerifier.new(@secret, digest: "SHA1") - verifier.rotate raw_key: old_raw_key - - assert_equal "message verified with old raw key", verifier.verified(old_message) - end - - def test_with_rotated_secret_and_salt - old_secret, old_salt = SecureRandom.random_bytes(32), "old salt" - - old_raw_key = ActiveSupport::KeyGenerator.new(old_secret, iterations: 1000).generate_key(old_salt) - old_verifier = ActiveSupport::MessageVerifier.new(old_raw_key, digest: "SHA1") - old_message = old_verifier.generate("message verified with old secret and salt") + def test_rotating_secret + old_message = ActiveSupport::MessageVerifier.new("old", digest: "SHA1").generate("old") verifier = ActiveSupport::MessageVerifier.new(@secret, digest: "SHA1") - verifier.rotate secret: old_secret, salt: old_salt + verifier.rotate "old" - assert_equal "message verified with old secret and salt", verifier.verified(old_message) + assert_equal "old", verifier.verified(old_message) end - def test_with_rotated_key_generator - old_key_gen, old_salt = ActiveSupport::KeyGenerator.new(SecureRandom.random_bytes(32), iterations: 256), "old salt" + def test_multiple_rotations + old_message = ActiveSupport::MessageVerifier.new("old", digest: "SHA256").generate("old") + older_message = ActiveSupport::MessageVerifier.new("older", digest: "SHA1").generate("older") - old_raw_key = old_key_gen.generate_key(old_salt) - old_verifier = ActiveSupport::MessageVerifier.new(old_raw_key, digest: "SHA1") - old_message = old_verifier.generate("message verified with old key generator and salt") + verifier = ActiveSupport::MessageVerifier.new(@secret, digest: "SHA512") + verifier.rotate "old", digest: "SHA256" + verifier.rotate "older", digest: "SHA1" - verifier = ActiveSupport::MessageVerifier.new(@secret, digest: "SHA1") - verifier.rotate key_generator: old_key_gen, salt: old_salt - - assert_equal "message verified with old key generator and salt", verifier.verified(old_message) + assert_equal "new", verifier.verified(verifier.generate("new")) + assert_equal "old", verifier.verified(old_message) + assert_equal "older", verifier.verified(older_message) end - def test_with_rotating_multiple_verifiers - old_raw_key, older_raw_key = SecureRandom.random_bytes(32), SecureRandom.random_bytes(32) - - old_verifier = ActiveSupport::MessageVerifier.new(old_raw_key, digest: "SHA256") - old_message = old_verifier.generate("message verified with old raw key") + def test_on_rotation_is_called_and_verified_returns_message + older_message = ActiveSupport::MessageVerifier.new("older", digest: "SHA1").generate(encoded: "message") - older_verifier = ActiveSupport::MessageVerifier.new(older_raw_key, digest: "SHA1") - older_message = older_verifier.generate("message verified with older raw key") + verifier = ActiveSupport::MessageVerifier.new(@secret, digest: "SHA512") + verifier.rotate "old", digest: "SHA256" + verifier.rotate "older", digest: "SHA1" - verifier = ActiveSupport::MessageVerifier.new("new secret", digest: "SHA512") - verifier.rotate raw_key: old_raw_key, digest: "SHA256" - verifier.rotate raw_key: older_raw_key, digest: "SHA1" + rotated = false + message = verifier.verified(older_message, on_rotation: proc { rotated = true }) - assert_equal "verified message", verifier.verified(verifier.generate("verified message")) - assert_equal "message verified with old raw key", verifier.verified(old_message) - assert_equal "message verified with older raw key", verifier.verified(older_message) - end - - def test_on_rotation_keyword_block_is_called_and_verified_returns_message - callback_ran, message = nil, nil - - old_raw_key, older_raw_key = SecureRandom.random_bytes(32), SecureRandom.random_bytes(32) - - older_verifier = ActiveSupport::MessageVerifier.new(older_raw_key, digest: "SHA1") - older_message = older_verifier.generate(encoded: "message") - - verifier = ActiveSupport::MessageVerifier.new("new secret", digest: "SHA512") - verifier.rotate raw_key: old_raw_key, digest: "SHA256" - verifier.rotate raw_key: older_raw_key, digest: "SHA1" - - message = verifier.verified(older_message, on_rotation: proc { callback_ran = true }) - - assert callback_ran, "callback was ran" assert_equal({ encoded: "message" }, message) + assert rotated end - def test_with_rotated_metadata - old_secret, old_salt = SecureRandom.random_bytes(32), "old salt" + def test_rotations_with_metadata + old_message = ActiveSupport::MessageVerifier.new("old").generate("old", purpose: :rotation) - old_raw_key = ActiveSupport::KeyGenerator.new(old_secret, iterations: 1000).generate_key(old_salt) - old_verifier = ActiveSupport::MessageVerifier.new(old_raw_key, digest: "SHA1") - old_message = old_verifier.generate( - "message verified with old secret, salt, and metadata", purpose: "rotation") - - verifier = ActiveSupport::MessageVerifier.new(@secret, digest: "SHA1") - verifier.rotate secret: old_secret, salt: old_salt + verifier = ActiveSupport::MessageVerifier.new(@secret) + verifier.rotate "old" - assert_equal "message verified with old secret, salt, and metadata", - verifier.verified(old_message, purpose: "rotation") + assert_equal "old", verifier.verified(old_message, purpose: :rotation) end end -- cgit v1.2.3 From f9a6c00dcc95e9c9f5c064913f0a6b65fd9655a6 Mon Sep 17 00:00:00 2001 From: Kasper Timm Hansen Date: Sun, 24 Sep 2017 22:58:17 +0200 Subject: Fix RotationConfiguration test and remove nil-kind rotates. --- .../test/messages/rotation_configuration_test.rb | 32 +++++----------------- 1 file changed, 7 insertions(+), 25 deletions(-) (limited to 'activesupport/test') diff --git a/activesupport/test/messages/rotation_configuration_test.rb b/activesupport/test/messages/rotation_configuration_test.rb index 41d938e119..2f6824ed21 100644 --- a/activesupport/test/messages/rotation_configuration_test.rb +++ b/activesupport/test/messages/rotation_configuration_test.rb @@ -9,35 +9,17 @@ class MessagesRotationConfiguration < ActiveSupport::TestCase end def test_signed_configurations - @config.rotate :signed, secret: "older secret", salt: "salt", digest: "SHA1" - @config.rotate :signed, secret: "old secret", salt: "salt", digest: "SHA256" + @config.rotate :signed, "older secret", salt: "salt", digest: "SHA1" + @config.rotate :signed, "old secret", salt: "salt", digest: "SHA256" - assert_equal [{ - secret: "older secret", salt: "salt", digest: "SHA1" - }, { - secret: "old secret", salt: "salt", digest: "SHA256" - }], @config.signed + assert_equal [ + [ "older secret", salt: "salt", digest: "SHA1" ], + [ "old secret", salt: "salt", digest: "SHA256" ] ], @config.signed end def test_encrypted_configurations - @config.rotate :encrypted, raw_key: "old raw key", cipher: "aes-256-gcm" + @config.rotate :encrypted, "old raw key", cipher: "aes-256-gcm" - assert_equal [{ - raw_key: "old raw key", cipher: "aes-256-gcm" - }], @config.encrypted - end - - def test_rotate_without_kind - @config.rotate secret: "older secret", salt: "salt", digest: "SHA1" - @config.rotate raw_key: "old raw key", cipher: "aes-256-gcm" - - expected = [{ - secret: "older secret", salt: "salt", digest: "SHA1" - }, { - raw_key: "old raw key", cipher: "aes-256-gcm" - }] - - assert_equal expected, @config.encrypted - assert_equal expected, @config.signed + assert_equal [ [ "old raw key", cipher: "aes-256-gcm" ] ], @config.encrypted end end -- cgit v1.2.3 From 21b975cfd9c725c1fb0ad9a10709f4bf757c3e41 Mon Sep 17 00:00:00 2001 From: dixpac Date: Mon, 25 Sep 2017 14:00:07 +0200 Subject: Fix minor CodeClimate issue --- activesupport/test/message_encryptor_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activesupport/test') diff --git a/activesupport/test/message_encryptor_test.rb b/activesupport/test/message_encryptor_test.rb index 8fde3928dc..9edf07f762 100644 --- a/activesupport/test/message_encryptor_test.rb +++ b/activesupport/test/message_encryptor_test.rb @@ -201,7 +201,7 @@ class MessageEncryptorTest < ActiveSupport::TestCase end def secrets - @secrets ||= Hash.new { |h,k| h[k] = SecureRandom.random_bytes(32) } + @secrets ||= Hash.new { |h, k| h[k] = SecureRandom.random_bytes(32) } end def munge(base64_string) -- cgit v1.2.3 From de9e3238a008f8f20c5beedefb8787b6e51359d0 Mon Sep 17 00:00:00 2001 From: "yuuji.yaginuma" Date: Wed, 27 Sep 2017 13:18:34 +0900 Subject: Ensure `HashWithIndifferentAccess#transform_keys` to return `HashWithIndifferentAccess` Currently, `#transform_values`, `#select` and `#reject` return instance of `HashWithIndifferentAccess`. But `#transform_keys` returns instance of Hash. This behavior is a bit confusing. I think that `HashWithIndifferentAccess#transform_keys` should also return instance of `HashWithIndifferentAccess` as well as other methods. --- activesupport/test/hash_with_indifferent_access_test.rb | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'activesupport/test') diff --git a/activesupport/test/hash_with_indifferent_access_test.rb b/activesupport/test/hash_with_indifferent_access_test.rb index b3788ee65c..b878ac20fa 100644 --- a/activesupport/test/hash_with_indifferent_access_test.rb +++ b/activesupport/test/hash_with_indifferent_access_test.rb @@ -399,6 +399,13 @@ class HashWithIndifferentAccessTest < ActiveSupport::TestCase assert_instance_of ActiveSupport::HashWithIndifferentAccess, indifferent_strings end + def test_indifferent_transform_keys + hash = ActiveSupport::HashWithIndifferentAccess.new(@strings).transform_keys { |k| k * 2 } + + assert_equal({ "aa" => 1, "bb" => 2 }, hash) + assert_instance_of ActiveSupport::HashWithIndifferentAccess, hash + end + def test_indifferent_compact hash_contain_nil_value = @strings.merge("z" => nil) hash = ActiveSupport::HashWithIndifferentAccess.new(hash_contain_nil_value) -- cgit v1.2.3 From d39879435c51af1b9966f9037a9962146ff1ea71 Mon Sep 17 00:00:00 2001 From: Ryuta Kamizono Date: Sat, 30 Sep 2017 18:01:56 +0900 Subject: Testing to ensure both bang and non-bang methods behaves consistently Follow up of #30728. --- .../test/hash_with_indifferent_access_test.rb | 23 ++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'activesupport/test') diff --git a/activesupport/test/hash_with_indifferent_access_test.rb b/activesupport/test/hash_with_indifferent_access_test.rb index b878ac20fa..41d653fa59 100644 --- a/activesupport/test/hash_with_indifferent_access_test.rb +++ b/activesupport/test/hash_with_indifferent_access_test.rb @@ -406,6 +406,29 @@ class HashWithIndifferentAccessTest < ActiveSupport::TestCase assert_instance_of ActiveSupport::HashWithIndifferentAccess, hash end + def test_indifferent_transform_keys_bang + indifferent_strings = ActiveSupport::HashWithIndifferentAccess.new(@strings) + indifferent_strings.transform_keys! { |k| k * 2 } + + assert_equal({ "aa" => 1, "bb" => 2 }, indifferent_strings) + assert_instance_of ActiveSupport::HashWithIndifferentAccess, indifferent_strings + end + + def test_indifferent_transform_values + hash = ActiveSupport::HashWithIndifferentAccess.new(@strings).transform_values { |v| v * 2 } + + assert_equal({ "a" => 2, "b" => 4 }, hash) + assert_instance_of ActiveSupport::HashWithIndifferentAccess, hash + end + + def test_indifferent_transform_values_bang + indifferent_strings = ActiveSupport::HashWithIndifferentAccess.new(@strings) + indifferent_strings.transform_values! { |v| v * 2 } + + assert_equal({ "a" => 2, "b" => 4 }, indifferent_strings) + assert_instance_of ActiveSupport::HashWithIndifferentAccess, indifferent_strings + end + def test_indifferent_compact hash_contain_nil_value = @strings.merge("z" => nil) hash = ActiveSupport::HashWithIndifferentAccess.new(hash_contain_nil_value) -- cgit v1.2.3 From 853abf125a4bdd34cc3a8e2e99e33ac67b0798d6 Mon Sep 17 00:00:00 2001 From: "yuuji.yaginuma" Date: Sun, 1 Oct 2017 08:55:03 +0900 Subject: Remove unused `new_credentials_configuration` `new_credentials_configuration` is no longer used since 081a6ac6f7fd929798481f9ee333fb92b441356c. --- activesupport/test/encrypted_configuration_test.rb | 8 -------- 1 file changed, 8 deletions(-) (limited to 'activesupport/test') diff --git a/activesupport/test/encrypted_configuration_test.rb b/activesupport/test/encrypted_configuration_test.rb index 53ea9e393f..471faa8c12 100644 --- a/activesupport/test/encrypted_configuration_test.rb +++ b/activesupport/test/encrypted_configuration_test.rb @@ -54,12 +54,4 @@ class EncryptedConfigurationTest < ActiveSupport::TestCase test "raises key error when accessing config via bang method" do assert_raise(KeyError) { @credentials.something! } end - - private - def new_credentials_configuration - ActiveSupport::EncryptedConfiguration.new \ - config_path: @credentials_config_path, - key_path: @credentials_key_path, - env_key: "RAILS_MASTER_KEY" - end end -- cgit v1.2.3 From e2dbfe5adac3438e3f8bbd2e2dce2ad39c91221b Mon Sep 17 00:00:00 2001 From: Erich Soares Machado Date: Tue, 3 Oct 2017 00:49:13 +0200 Subject: Fixes ActiveSupport::Cache::FileStore#cleanup bug which prevented it from cleaning up the expired cache keys --- activesupport/test/cache/stores/file_store_test.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'activesupport/test') diff --git a/activesupport/test/cache/stores/file_store_test.rb b/activesupport/test/cache/stores/file_store_test.rb index 391ab60b3a..66231b0a82 100644 --- a/activesupport/test/cache/stores/file_store_test.rb +++ b/activesupport/test/cache/stores/file_store_test.rb @@ -118,6 +118,7 @@ class FileStoreTest < ActiveSupport::TestCase assert_not @cache.exist?("foo") assert @cache.exist?("baz") assert @cache.exist?("quux") + assert_equal 2, Dir.glob(File.join(cache_dir, "**")).size end end -- cgit v1.2.3 From 5e6fa51b01a5da7a09c6365923d5cb2c16a7e7a6 Mon Sep 17 00:00:00 2001 From: Aditya Kapoor Date: Mon, 16 Oct 2017 18:16:23 +0530 Subject: Fix `to_s(:db)` for range comprising of alphabets. --- activesupport/test/core_ext/range_ext_test.rb | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'activesupport/test') diff --git a/activesupport/test/core_ext/range_ext_test.rb b/activesupport/test/core_ext/range_ext_test.rb index a96e3d62e8..0467123e55 100644 --- a/activesupport/test/core_ext/range_ext_test.rb +++ b/activesupport/test/core_ext/range_ext_test.rb @@ -16,6 +16,11 @@ class RangeTest < ActiveSupport::TestCase assert_equal "BETWEEN '2005-12-10 15:30:00' AND '2005-12-10 17:30:00'", date_range.to_s(:db) end + def test_to_s_with_alphabets + alphabet_range = ("a".."z") + assert_equal "BETWEEN 'a' AND 'z'", alphabet_range.to_s(:db) + end + def test_to_s_with_numeric number_range = (1..100) assert_equal "BETWEEN '1' AND '100'", number_range.to_s(:db) -- cgit v1.2.3 From 813f8e333dabb2050d6b668b7bdd68b4979e8af4 Mon Sep 17 00:00:00 2001 From: Paul Kuruvilla Date: Mon, 23 Oct 2017 15:17:31 +0530 Subject: Fix #to_json for unreadable IO objects, fixes #26132 --- activesupport/test/json/encoding_test.rb | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'activesupport/test') diff --git a/activesupport/test/json/encoding_test.rb b/activesupport/test/json/encoding_test.rb index eafa2e1712..96ad8dfbdb 100644 --- a/activesupport/test/json/encoding_test.rb +++ b/activesupport/test/json/encoding_test.rb @@ -454,6 +454,10 @@ EXPECTED assert_equal '{"number":null}', NaNNumber.new.to_json end + def test_to_json_works_on_io_objects + assert_equal STDOUT.to_s.to_json, STDOUT.to_json + end + private def object_keys(json_object) -- cgit v1.2.3 From c792354adcbf8c966f274915c605c6713b840548 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Thu, 19 Oct 2017 16:17:48 -0400 Subject: Remove deprecated `:if` and `:unless` string filter for callbacks --- activesupport/test/callbacks_test.rb | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) (limited to 'activesupport/test') diff --git a/activesupport/test/callbacks_test.rb b/activesupport/test/callbacks_test.rb index 3902e41a60..5f894db46f 100644 --- a/activesupport/test/callbacks_test.rb +++ b/activesupport/test/callbacks_test.rb @@ -193,13 +193,6 @@ module CallbacksTest before_save Proc.new { |r| r.history << "b00m" }, if: :no before_save Proc.new { |r| r.history << [:before_save, :symbol] }, unless: :no before_save Proc.new { |r| r.history << "b00m" }, unless: :yes - # string - ActiveSupport::Deprecation.silence do - before_save Proc.new { |r| r.history << [:before_save, :string] }, if: "yes" - before_save Proc.new { |r| r.history << "b00m" }, if: "no" - before_save Proc.new { |r| r.history << [:before_save, :string] }, unless: "no" - before_save Proc.new { |r| r.history << "b00m" }, unless: "yes" - end # Combined if and unless before_save Proc.new { |r| r.history << [:before_save, :combined_symbol] }, if: :yes, unless: :no before_save Proc.new { |r| r.history << "b00m" }, if: :yes, unless: :yes @@ -592,8 +585,6 @@ module CallbacksTest [:before_save, :proc], [:before_save, :symbol], [:before_save, :symbol], - [:before_save, :string], - [:before_save, :string], [:before_save, :combined_symbol], ], person.history end @@ -1182,14 +1173,15 @@ module CallbacksTest end end - class DeprecatedWarningTest < ActiveSupport::TestCase - def test_deprecate_string_conditional_options + class NotSupportedStringConditionalTest < ActiveSupport::TestCase + def test_string_conditional_options klass = Class.new(Record) - assert_deprecated { klass.before_save :tweedle, if: "true" } - assert_deprecated { klass.after_save :tweedle, unless: "false" } - assert_deprecated { klass.skip_callback :save, :before, :tweedle, if: "true" } - assert_deprecated { klass.skip_callback :save, :after, :tweedle, unless: "false" } + assert_raises(ArgumentError) { klass.before_save :tweedle, if: ["true"] } + assert_raises(ArgumentError) { klass.before_save :tweedle, if: "true" } + assert_raises(ArgumentError) { klass.after_save :tweedle, unless: "false" } + assert_raises(ArgumentError) { klass.skip_callback :save, :before, :tweedle, if: "true" } + assert_raises(ArgumentError) { klass.skip_callback :save, :after, :tweedle, unless: "false" } end end -- cgit v1.2.3 From 61ac2167eff741bffb44aec231f4ea13d004134e Mon Sep 17 00:00:00 2001 From: bogdanvlviv Date: Sat, 16 Sep 2017 17:33:53 +0300 Subject: Allows pass argument for `Time#prev_day` and `Time#next_day` --- activesupport/test/core_ext/date_and_time_behavior.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'activesupport/test') diff --git a/activesupport/test/core_ext/date_and_time_behavior.rb b/activesupport/test/core_ext/date_and_time_behavior.rb index 256353c309..438eb8b755 100644 --- a/activesupport/test/core_ext/date_and_time_behavior.rb +++ b/activesupport/test/core_ext/date_and_time_behavior.rb @@ -9,6 +9,11 @@ module DateAndTimeBehavior end def test_prev_day + assert_equal date_time_init(2005, 2, 24, 10, 10, 10), date_time_init(2005, 2, 22, 10, 10, 10).prev_day(-2) + assert_equal date_time_init(2005, 2, 23, 10, 10, 10), date_time_init(2005, 2, 22, 10, 10, 10).prev_day(-1) + assert_equal date_time_init(2005, 2, 22, 10, 10, 10), date_time_init(2005, 2, 22, 10, 10, 10).prev_day(0) + assert_equal date_time_init(2005, 2, 21, 10, 10, 10), date_time_init(2005, 2, 22, 10, 10, 10).prev_day(1) + assert_equal date_time_init(2005, 2, 20, 10, 10, 10), date_time_init(2005, 2, 22, 10, 10, 10).prev_day(2) assert_equal date_time_init(2005, 2, 21, 10, 10, 10), date_time_init(2005, 2, 22, 10, 10, 10).prev_day assert_equal date_time_init(2005, 2, 28, 10, 10, 10), date_time_init(2005, 3, 2, 10, 10, 10).prev_day.prev_day end @@ -19,6 +24,11 @@ module DateAndTimeBehavior end def test_next_day + assert_equal date_time_init(2005, 2, 20, 10, 10, 10), date_time_init(2005, 2, 22, 10, 10, 10).next_day(-2) + assert_equal date_time_init(2005, 2, 21, 10, 10, 10), date_time_init(2005, 2, 22, 10, 10, 10).next_day(-1) + assert_equal date_time_init(2005, 2, 22, 10, 10, 10), date_time_init(2005, 2, 22, 10, 10, 10).next_day(0) + assert_equal date_time_init(2005, 2, 23, 10, 10, 10), date_time_init(2005, 2, 22, 10, 10, 10).next_day(1) + assert_equal date_time_init(2005, 2, 24, 10, 10, 10), date_time_init(2005, 2, 22, 10, 10, 10).next_day(2) assert_equal date_time_init(2005, 2, 23, 10, 10, 10), date_time_init(2005, 2, 22, 10, 10, 10).next_day assert_equal date_time_init(2005, 3, 2, 10, 10, 10), date_time_init(2005, 2, 28, 10, 10, 10).next_day.next_day end -- cgit v1.2.3 From f2c1e3a793570584d9708aaee387214bc3543530 Mon Sep 17 00:00:00 2001 From: bogdanvlviv Date: Sat, 16 Sep 2017 18:36:49 +0300 Subject: Allows pass argument for `Time#prev_month` and `Time#next_month` --- .../test/core_ext/date_and_time_behavior.rb | 24 ++++++++++++++++++++++ activesupport/test/core_ext/date_ext_test.rb | 4 ---- activesupport/test/core_ext/date_time_ext_test.rb | 4 ---- activesupport/test/core_ext/time_ext_test.rb | 4 ---- 4 files changed, 24 insertions(+), 12 deletions(-) (limited to 'activesupport/test') diff --git a/activesupport/test/core_ext/date_and_time_behavior.rb b/activesupport/test/core_ext/date_and_time_behavior.rb index 438eb8b755..091d5611d0 100644 --- a/activesupport/test/core_ext/date_and_time_behavior.rb +++ b/activesupport/test/core_ext/date_and_time_behavior.rb @@ -161,6 +161,16 @@ module DateAndTimeBehavior assert_equal date_time_init(2015, 1, 5, 15, 15, 10), date_time_init(2015, 1, 3, 15, 15, 10).next_weekday end + def test_next_month + assert_equal date_time_init(2004, 12, 22, 10, 10, 10), date_time_init(2005, 2, 22, 10, 10, 10).next_month(-2) + assert_equal date_time_init(2005, 1, 22, 10, 10, 10), date_time_init(2005, 2, 22, 10, 10, 10).next_month(-1) + assert_equal date_time_init(2005, 2, 22, 10, 10, 10), date_time_init(2005, 2, 22, 10, 10, 10).next_month(0) + assert_equal date_time_init(2005, 3, 22, 10, 10, 10), date_time_init(2005, 2, 22, 10, 10, 10).next_month(1) + assert_equal date_time_init(2005, 4, 22, 10, 10, 10), date_time_init(2005, 2, 22, 10, 10, 10).next_month(2) + assert_equal date_time_init(2005, 3, 22, 10, 10, 10), date_time_init(2005, 2, 22, 10, 10, 10).next_month + assert_equal date_time_init(2005, 4, 22, 10, 10, 10), date_time_init(2005, 2, 22, 10, 10, 10).next_month.next_month + end + def test_next_month_on_31st assert_equal date_time_init(2005, 9, 30, 15, 15, 10), date_time_init(2005, 8, 31, 15, 15, 10).next_month end @@ -213,6 +223,16 @@ module DateAndTimeBehavior assert_equal date_time_init(2015, 1, 2, 15, 15, 10), date_time_init(2015, 1, 4, 15, 15, 10).prev_weekday end + def test_prev_month + assert_equal date_time_init(2005, 4, 22, 10, 10, 10), date_time_init(2005, 2, 22, 10, 10, 10).prev_month(-2) + assert_equal date_time_init(2005, 3, 22, 10, 10, 10), date_time_init(2005, 2, 22, 10, 10, 10).prev_month(-1) + assert_equal date_time_init(2005, 2, 22, 10, 10, 10), date_time_init(2005, 2, 22, 10, 10, 10).prev_month(0) + assert_equal date_time_init(2005, 1, 22, 10, 10, 10), date_time_init(2005, 2, 22, 10, 10, 10).prev_month(1) + assert_equal date_time_init(2004, 12, 22, 10, 10, 10), date_time_init(2005, 2, 22, 10, 10, 10).prev_month(2) + assert_equal date_time_init(2005, 1, 22, 10, 10, 10), date_time_init(2005, 2, 22, 10, 10, 10).prev_month + assert_equal date_time_init(2004, 12, 22, 10, 10, 10), date_time_init(2005, 2, 22, 10, 10, 10).prev_month.prev_month + end + def test_prev_month_on_31st assert_equal date_time_init(2004, 2, 29, 10, 10, 10), date_time_init(2004, 3, 31, 10, 10, 10).prev_month end @@ -225,6 +245,10 @@ module DateAndTimeBehavior assert_equal date_time_init(2004, 6, 5, 10, 10, 10), date_time_init(2005, 6, 5, 10, 10, 10).prev_year end + def test_last_month_on_31st + assert_equal date_time_init(2004, 2, 29, 0, 0, 0), date_time_init(2004, 3, 31, 0, 0, 0).last_month + end + def test_days_to_week_start assert_equal 0, date_time_init(2011, 11, 01, 0, 0, 0).days_to_week_start(:tuesday) assert_equal 1, date_time_init(2011, 11, 02, 0, 0, 0).days_to_week_start(:tuesday) diff --git a/activesupport/test/core_ext/date_ext_test.rb b/activesupport/test/core_ext/date_ext_test.rb index b8672eac4b..1d05ac6157 100644 --- a/activesupport/test/core_ext/date_ext_test.rb +++ b/activesupport/test/core_ext/date_ext_test.rb @@ -185,10 +185,6 @@ class DateExtCalculationsTest < ActiveSupport::TestCase assert_equal Date.new(1582, 10, 18), Date.new(1582, 10, 4).next_week end - def test_last_month_on_31st - assert_equal Date.new(2004, 2, 29), Date.new(2004, 3, 31).last_month - end - def test_last_quarter_on_31st assert_equal Date.new(2004, 2, 29), Date.new(2004, 5, 31).last_quarter end diff --git a/activesupport/test/core_ext/date_time_ext_test.rb b/activesupport/test/core_ext/date_time_ext_test.rb index a3c2018a31..a795ed0102 100644 --- a/activesupport/test/core_ext/date_time_ext_test.rb +++ b/activesupport/test/core_ext/date_time_ext_test.rb @@ -248,10 +248,6 @@ class DateTimeExtCalculationsTest < ActiveSupport::TestCase assert_equal DateTime.civil(2016, 2, 29), DateTime.civil(2016, 3, 7).last_week end - def test_last_month_on_31st - assert_equal DateTime.civil(2004, 2, 29), DateTime.civil(2004, 3, 31).last_month - end - def test_last_quarter_on_31st assert_equal DateTime.civil(2004, 2, 29), DateTime.civil(2004, 5, 31).last_quarter end diff --git a/activesupport/test/core_ext/time_ext_test.rb b/activesupport/test/core_ext/time_ext_test.rb index dc2f4c5ac7..b720e32022 100644 --- a/activesupport/test/core_ext/time_ext_test.rb +++ b/activesupport/test/core_ext/time_ext_test.rb @@ -664,10 +664,6 @@ class TimeExtCalculationsTest < ActiveSupport::TestCase end end - def test_last_month_on_31st - assert_equal Time.local(2004, 2, 29), Time.local(2004, 3, 31).last_month - end - def test_xmlschema_is_available assert_nothing_raised { Time.now.xmlschema } end -- cgit v1.2.3 From ee9d81837b5eba9d5ec869ae7601d7ffce763e3e Mon Sep 17 00:00:00 2001 From: bogdanvlviv Date: Sat, 16 Sep 2017 19:06:45 +0300 Subject: Allows pass argument for `Time#prev_year` and `Time#next_year`. --- activesupport/test/core_ext/date_and_time_behavior.rb | 16 ++++++++++++++++ activesupport/test/core_ext/date_ext_test.rb | 4 ---- activesupport/test/core_ext/date_time_ext_test.rb | 4 ---- activesupport/test/core_ext/time_ext_test.rb | 4 ---- 4 files changed, 16 insertions(+), 12 deletions(-) (limited to 'activesupport/test') diff --git a/activesupport/test/core_ext/date_and_time_behavior.rb b/activesupport/test/core_ext/date_and_time_behavior.rb index 091d5611d0..42da6f6cd0 100644 --- a/activesupport/test/core_ext/date_and_time_behavior.rb +++ b/activesupport/test/core_ext/date_and_time_behavior.rb @@ -180,7 +180,13 @@ module DateAndTimeBehavior end def test_next_year + assert_equal date_time_init(2003, 6, 5, 10, 10, 10), date_time_init(2005, 6, 5, 10, 10, 10).next_year(-2) + assert_equal date_time_init(2004, 6, 5, 10, 10, 10), date_time_init(2005, 6, 5, 10, 10, 10).next_year(-1) + assert_equal date_time_init(2005, 6, 5, 10, 10, 10), date_time_init(2005, 6, 5, 10, 10, 10).next_year(0) + assert_equal date_time_init(2006, 6, 5, 10, 10, 10), date_time_init(2005, 6, 5, 10, 10, 10).next_year(1) + assert_equal date_time_init(2007, 6, 5, 10, 10, 10), date_time_init(2005, 6, 5, 10, 10, 10).next_year(2) assert_equal date_time_init(2006, 6, 5, 10, 10, 10), date_time_init(2005, 6, 5, 10, 10, 10).next_year + assert_equal date_time_init(2007, 6, 5, 10, 10, 10), date_time_init(2005, 6, 5, 10, 10, 10).next_year.next_year end def test_prev_week @@ -242,13 +248,23 @@ module DateAndTimeBehavior end def test_prev_year + assert_equal date_time_init(2007, 6, 5, 10, 10, 10), date_time_init(2005, 6, 5, 10, 10, 10).prev_year(-2) + assert_equal date_time_init(2006, 6, 5, 10, 10, 10), date_time_init(2005, 6, 5, 10, 10, 10).prev_year(-1) + assert_equal date_time_init(2005, 6, 5, 10, 10, 10), date_time_init(2005, 6, 5, 10, 10, 10).prev_year(0) + assert_equal date_time_init(2004, 6, 5, 10, 10, 10), date_time_init(2005, 6, 5, 10, 10, 10).prev_year(1) + assert_equal date_time_init(2003, 6, 5, 10, 10, 10), date_time_init(2005, 6, 5, 10, 10, 10).prev_year(2) assert_equal date_time_init(2004, 6, 5, 10, 10, 10), date_time_init(2005, 6, 5, 10, 10, 10).prev_year + assert_equal date_time_init(2003, 6, 5, 10, 10, 10), date_time_init(2005, 6, 5, 10, 10, 10).prev_year.prev_year end def test_last_month_on_31st assert_equal date_time_init(2004, 2, 29, 0, 0, 0), date_time_init(2004, 3, 31, 0, 0, 0).last_month end + def test_last_year + assert_equal date_time_init(2004, 6, 5, 10, 0, 0), date_time_init(2005, 6, 5, 10, 0, 0).last_year + end + def test_days_to_week_start assert_equal 0, date_time_init(2011, 11, 01, 0, 0, 0).days_to_week_start(:tuesday) assert_equal 1, date_time_init(2011, 11, 02, 0, 0, 0).days_to_week_start(:tuesday) diff --git a/activesupport/test/core_ext/date_ext_test.rb b/activesupport/test/core_ext/date_ext_test.rb index 1d05ac6157..0c6f3f595a 100644 --- a/activesupport/test/core_ext/date_ext_test.rb +++ b/activesupport/test/core_ext/date_ext_test.rb @@ -120,10 +120,6 @@ class DateExtCalculationsTest < ActiveSupport::TestCase assert_equal Date.new(1582, 10, 4), Date.new(1583, 10, 14).prev_year end - def test_last_year - assert_equal Date.new(2004, 6, 5), Date.new(2005, 6, 5).last_year - end - def test_last_year_in_leap_years assert_equal Date.new(1999, 2, 28), Date.new(2000, 2, 29).last_year end diff --git a/activesupport/test/core_ext/date_time_ext_test.rb b/activesupport/test/core_ext/date_time_ext_test.rb index a795ed0102..d942cddb2a 100644 --- a/activesupport/test/core_ext/date_time_ext_test.rb +++ b/activesupport/test/core_ext/date_time_ext_test.rb @@ -162,10 +162,6 @@ class DateTimeExtCalculationsTest < ActiveSupport::TestCase assert_equal DateTime.civil(2005, 4, 30, 23, 59, Rational(59999999999, 1000000000)), DateTime.civil(2005, 4, 20, 10, 10, 10).end_of_month end - def test_last_year - assert_equal DateTime.civil(2004, 6, 5, 10), DateTime.civil(2005, 6, 5, 10, 0, 0).last_year - end - def test_ago assert_equal DateTime.civil(2005, 2, 22, 10, 10, 9), DateTime.civil(2005, 2, 22, 10, 10, 10).ago(1) assert_equal DateTime.civil(2005, 2, 22, 9, 10, 10), DateTime.civil(2005, 2, 22, 10, 10, 10).ago(3600) diff --git a/activesupport/test/core_ext/time_ext_test.rb b/activesupport/test/core_ext/time_ext_test.rb index b720e32022..8cb17df01b 100644 --- a/activesupport/test/core_ext/time_ext_test.rb +++ b/activesupport/test/core_ext/time_ext_test.rb @@ -178,10 +178,6 @@ class TimeExtCalculationsTest < ActiveSupport::TestCase assert_equal Time.local(2005, 2, 4, 19, 30, 59, Rational(999999999, 1000)), Time.local(2005, 2, 4, 19, 30, 10).end_of_minute end - def test_last_year - assert_equal Time.local(2004, 6, 5, 10), Time.local(2005, 6, 5, 10, 0, 0).last_year - end - def test_ago assert_equal Time.local(2005, 2, 22, 10, 10, 9), Time.local(2005, 2, 22, 10, 10, 10).ago(1) assert_equal Time.local(2005, 2, 22, 9, 10, 10), Time.local(2005, 2, 22, 10, 10, 10).ago(3600) -- cgit v1.2.3 From c40b4428e6d3885a8adc0ceba3aeac7599c14879 Mon Sep 17 00:00:00 2001 From: Shuhei Kitagawa Date: Sat, 28 Oct 2017 17:20:38 +0900 Subject: removed unnecessary returns --- activesupport/test/core_ext/module/remove_method_test.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'activesupport/test') diff --git a/activesupport/test/core_ext/module/remove_method_test.rb b/activesupport/test/core_ext/module/remove_method_test.rb index dbf71b477d..8493be8d08 100644 --- a/activesupport/test/core_ext/module/remove_method_test.rb +++ b/activesupport/test/core_ext/module/remove_method_test.rb @@ -6,22 +6,22 @@ require "active_support/core_ext/module/remove_method" module RemoveMethodTests class A def do_something - return 1 + 1 end def do_something_protected - return 1 + 1 end protected :do_something_protected def do_something_private - return 1 + 1 end private :do_something_private class << self def do_something_else - return 2 + 2 end end end -- cgit v1.2.3 From 03dd47ff219098305a588e16d717813eebbfa7a4 Mon Sep 17 00:00:00 2001 From: Shuhei Kitagawa Date: Sat, 28 Oct 2017 17:39:58 +0900 Subject: removed unnecessary semicolons --- activesupport/test/test_case_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activesupport/test') diff --git a/activesupport/test/test_case_test.rb b/activesupport/test/test_case_test.rb index 65b1cb4a14..9bc9183668 100644 --- a/activesupport/test/test_case_test.rb +++ b/activesupport/test/test_case_test.rb @@ -87,7 +87,7 @@ class AssertDifferenceTest < ActiveSupport::TestCase def test_expression_is_evaluated_in_the_appropriate_scope silence_warnings do - local_scope = "foo"; + local_scope = "foo" local_scope = local_scope # to suppress unused variable warning assert_difference("local_scope; @object.num") { @object.increment } end -- cgit v1.2.3 From b2545e4106c8388cb2a4d9e06c31954e5ee2c948 Mon Sep 17 00:00:00 2001 From: Nick LaMuro Date: Mon, 23 Oct 2017 11:11:59 -0500 Subject: Deprecate ActiveSupport::Inflector#acronym_regex To be removed in Rails 6.0 (default for the deprecate helper). Code moved around as well for the ActiveSupport::Deprecation modules, since it was dependent on ActiveSupport::Inflector being loaded for it to work. By "lazy loading" the Inflector code from within the Deprecation code, we can require ActiveSupport::Deprecation from ActiveSupport::Inflector and not get a circular dependency issue. --- activesupport/test/inflector_test.rb | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'activesupport/test') diff --git a/activesupport/test/inflector_test.rb b/activesupport/test/inflector_test.rb index eeec0ab1a5..ad2ec1d67d 100644 --- a/activesupport/test/inflector_test.rb +++ b/activesupport/test/inflector_test.rb @@ -224,6 +224,12 @@ class InflectorTest < ActiveSupport::TestCase assert_equal("json_html_api", ActiveSupport::Inflector.underscore("JSONHTMLAPI")) end + def test_acronym_regexp_is_deprecated + assert_deprecated do + ActiveSupport::Inflector.inflections.acronym_regex + end + end + def test_underscore CamelToUnderscore.each do |camel, underscore| assert_equal(underscore, ActiveSupport::Inflector.underscore(camel)) -- cgit v1.2.3 From 1ede34697539d5094090c7c8e3ab95359f706904 Mon Sep 17 00:00:00 2001 From: Pierre Hedkvist Date: Wed, 1 Nov 2017 10:27:29 +0000 Subject: Fixed typo in test for activesupport parameterize --- activesupport/test/core_ext/string_ext_test.rb | 2 +- activesupport/test/inflector_test_cases.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'activesupport/test') diff --git a/activesupport/test/core_ext/string_ext_test.rb b/activesupport/test/core_ext/string_ext_test.rb index 9fd6d8ac0f..5c5abe9fd1 100644 --- a/activesupport/test/core_ext/string_ext_test.rb +++ b/activesupport/test/core_ext/string_ext_test.rb @@ -197,7 +197,7 @@ class StringInflectionsTest < ActiveSupport::TestCase end def test_string_parameterized_underscore_preserve_case - StringToParameterizePreserceCaseWithUnderscore.each do |normal, slugged| + StringToParameterizePreserveCaseWithUnderscore.each do |normal, slugged| assert_equal(slugged, normal.parameterize(separator: "_", preserve_case: true)) end end diff --git a/activesupport/test/inflector_test_cases.rb b/activesupport/test/inflector_test_cases.rb index f1214671ce..689370cccf 100644 --- a/activesupport/test/inflector_test_cases.rb +++ b/activesupport/test/inflector_test_cases.rb @@ -221,7 +221,7 @@ module InflectorTestCases "Test with malformed utf8 \251" => "test_with_malformed_utf8" } - StringToParameterizePreserceCaseWithUnderscore = { + StringToParameterizePreserveCaseWithUnderscore = { "Donald E. Knuth" => "Donald_E_Knuth", "Random text with *(bad)* characters" => "Random_text_with_bad_characters", "With-some-dashes" => "With-some-dashes", -- cgit v1.2.3 From 0ddde0a8fca6a0ca3158e3329713959acd65605d Mon Sep 17 00:00:00 2001 From: Andrew White Date: Mon, 6 Nov 2017 14:46:42 +0000 Subject: Fix acronym support in `humanize` Acronym inflections are stored with lowercase keys in the hash but the match wasn't being lowercased before being looked up in the hash. This shouldn't have any performance impact because before it would fail to find the acronym and perform the `downcase` operation anyway. Fixes #31052. --- activesupport/test/inflector_test.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'activesupport/test') diff --git a/activesupport/test/inflector_test.rb b/activesupport/test/inflector_test.rb index eeec0ab1a5..6cc1039d8e 100644 --- a/activesupport/test/inflector_test.rb +++ b/activesupport/test/inflector_test.rb @@ -356,6 +356,19 @@ class InflectorTest < ActiveSupport::TestCase assert_equal("Col rpted bugs", ActiveSupport::Inflector.humanize("COL_rpted_bugs")) end + def test_humanize_with_acronyms + ActiveSupport::Inflector.inflections do |inflect| + inflect.acronym "LAX" + inflect.acronym "SFO" + end + assert_equal("LAX roundtrip to SFO", ActiveSupport::Inflector.humanize("LAX ROUNDTRIP TO SFO")) + assert_equal("LAX roundtrip to SFO", ActiveSupport::Inflector.humanize("LAX ROUNDTRIP TO SFO", capitalize: false)) + assert_equal("LAX roundtrip to SFO", ActiveSupport::Inflector.humanize("lax roundtrip to sfo")) + assert_equal("LAX roundtrip to SFO", ActiveSupport::Inflector.humanize("lax roundtrip to sfo", capitalize: false)) + assert_equal("LAX roundtrip to SFO", ActiveSupport::Inflector.humanize("Lax Roundtrip To Sfo")) + assert_equal("LAX roundtrip to SFO", ActiveSupport::Inflector.humanize("Lax Roundtrip To Sfo", capitalize: false)) + end + def test_constantize run_constantize_tests_on do |string| ActiveSupport::Inflector.constantize(string) -- cgit v1.2.3 From bbe437faecca5fd6bdc2327a4bc7a31ba21afe2e Mon Sep 17 00:00:00 2001 From: Genadi Samokovarov Date: Tue, 7 Nov 2017 10:28:19 +0200 Subject: Use plain assert in assert_changes to avoid MT6 refutes Seeing the previously issued PRs about it, we can avoid the `nil` comparisons that can happen in `assert_changes` by using plain `assert` calls. This is to avoid a deprecation warning about comparing `nil` values in `assert_equal` for Minitest 5 and a crash in Minitest 6. You can see the preparations done in [`assert_equal`][ae]. You can also see that [`assert`][a] does not care about `nil`s. [ae]: https://github.com/seattlerb/minitest/blob/ca6a71ca901016db09a5ad466b4adea4b52a504a/lib/minitest/assertions.rb#L159-L188 [a]: https://github.com/seattlerb/minitest/blob/ca6a71ca901016db09a5ad466b4adea4b52a504a/lib/minitest/assertions.rb#L131-L142 --- activesupport/test/test_case_test.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'activesupport/test') diff --git a/activesupport/test/test_case_test.rb b/activesupport/test/test_case_test.rb index 9bc9183668..84e4953fe2 100644 --- a/activesupport/test/test_case_test.rb +++ b/activesupport/test/test_case_test.rb @@ -179,6 +179,7 @@ class AssertDifferenceTest < ActiveSupport::TestCase end def test_assert_changes_works_with_any_object + # Silences: instance variable @new_object not initialized. retval = silence_warnings do assert_changes :@new_object, from: nil, to: 42 do @new_object = 42 @@ -201,7 +202,7 @@ class AssertDifferenceTest < ActiveSupport::TestCase def test_assert_changes_with_to_and_case_operator token = nil - assert_changes -> { token }, to: /\w{32}/ do + assert_changes -> { token }, to: /\w{32}/ do token = SecureRandom.hex end end @@ -236,7 +237,7 @@ class AssertDifferenceTest < ActiveSupport::TestCase end end - assert_equal "@object.num should not change.\n\"@object.num\" did change to 1.\nExpected: 0\n Actual: 1", error.message + assert_equal "@object.num should not change.\n\"@object.num\" did change to 1", error.message end end -- cgit v1.2.3 From 2b434d6f79813dcad162b158fd2b60e34a725ba1 Mon Sep 17 00:00:00 2001 From: Andrew White Date: Tue, 7 Nov 2017 11:33:08 +0000 Subject: Allow `Range#include?` on TWZ ranges In #11474 we prevented TWZ ranges being iterated over which matched Ruby's handling of Time ranges and as a consequence `include?` stopped working with both Time ranges and TWZ ranges. However in ruby/ruby@b061634 support was added for `include?` to use `cover?` for 'linear' objects. Since we have no way of making Ruby consider TWZ instances as 'linear' we have to override `Range#include?`. Fixes #30799. --- activesupport/test/core_ext/range_ext_test.rb | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'activesupport/test') diff --git a/activesupport/test/core_ext/range_ext_test.rb b/activesupport/test/core_ext/range_ext_test.rb index 0467123e55..049fac8fd4 100644 --- a/activesupport/test/core_ext/range_ext_test.rb +++ b/activesupport/test/core_ext/range_ext_test.rb @@ -121,9 +121,12 @@ class RangeTest < ActiveSupport::TestCase def test_include_on_time_with_zone twz = ActiveSupport::TimeWithZone.new(nil, ActiveSupport::TimeZone["Eastern Time (US & Canada)"] , Time.utc(2006, 11, 28, 10, 30)) - assert_raises TypeError do - ((twz - 1.hour)..twz).include?(twz) - end + assert ((twz - 1.hour)..twz).include?(twz) + end + + def test_case_equals_on_time_with_zone + twz = ActiveSupport::TimeWithZone.new(nil, ActiveSupport::TimeZone["Eastern Time (US & Canada)"] , Time.utc(2006, 11, 28, 10, 30)) + assert ((twz - 1.hour)..twz) === twz end def test_date_time_with_each -- cgit v1.2.3 From 1f9f6f6cfc57020ccb35f77872c56f069f337075 Mon Sep 17 00:00:00 2001 From: Brent Wheeldon Date: Thu, 2 Nov 2017 14:53:43 -0400 Subject: Prevent deadlocks with load interlock and DB lock. This fixes an issue where competing threads deadlock each other. - Thread A holds the load interlock but is blocked on getting the DB lock - Thread B holds the DB lock but is blocked on getting the load interlock (for example when there is a `Model.transaction` block that needs to autoload) This solution allows for dependency loading in other threads while a thread is waiting to acquire the DB lock. Fixes #31019 --- .../load_interlock_aware_monitor_test.rb | 55 ++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 activesupport/test/concurrency/load_interlock_aware_monitor_test.rb (limited to 'activesupport/test') diff --git a/activesupport/test/concurrency/load_interlock_aware_monitor_test.rb b/activesupport/test/concurrency/load_interlock_aware_monitor_test.rb new file mode 100644 index 0000000000..2d0f45ec5f --- /dev/null +++ b/activesupport/test/concurrency/load_interlock_aware_monitor_test.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +require "abstract_unit" +require "concurrent/atomic/count_down_latch" +require "active_support/concurrency/load_interlock_aware_monitor" + +module ActiveSupport + module Concurrency + class LoadInterlockAwareMonitorTest < ActiveSupport::TestCase + def setup + @monitor = ActiveSupport::Concurrency::LoadInterlockAwareMonitor.new + end + + def test_entering_with_no_blocking + assert @monitor.mon_enter + end + + def test_entering_with_blocking + load_interlock_latch = Concurrent::CountDownLatch.new + monitor_latch = Concurrent::CountDownLatch.new + + able_to_use_monitor = false + able_to_load = false + + thread_with_load_interlock = Thread.new do + ActiveSupport::Dependencies.interlock.running do + load_interlock_latch.count_down + monitor_latch.wait + + @monitor.synchronize do + able_to_use_monitor = true + end + end + end + + thread_with_monitor_lock = Thread.new do + @monitor.synchronize do + monitor_latch.count_down + load_interlock_latch.wait + + ActiveSupport::Dependencies.interlock.loading do + able_to_load = true + end + end + end + + thread_with_load_interlock.join + thread_with_monitor_lock.join + + assert able_to_use_monitor + assert able_to_load + end + end + end +end -- cgit v1.2.3 From 8c5115f95daa86cc9e79d6ad5c1076fee0f70903 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Fri, 10 Nov 2017 10:37:45 +0900 Subject: Bump RuboCop to 0.51.0 ## Summary RuboCop 0.51.0 was released. https://github.com/bbatsov/rubocop/releases/tag/v0.51.0 And rubocop-0-51 channel is available in Code Climate. https://github.com/codeclimate/codeclimate-rubocop/issues/109 This PR will bump RuboCop to 0.51.0 and fixes the following new offenses. ```console % bundle exec rubocop Inspecting 2358 files (snip) Offenses: actionpack/lib/action_controller/metal/http_authentication.rb:251:59: C: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping. [key.strip, value.to_s.gsub(/^"|"$/, "").delete('\'')] ^^^^ activesupport/test/core_ext/load_error_test.rb:8:39: C: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping. assert_raise(LoadError) { require 'no_this_file_don\'t_exist' } ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2358 files inspected, 2 offenses detected ``` --- activesupport/test/core_ext/load_error_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activesupport/test') diff --git a/activesupport/test/core_ext/load_error_test.rb b/activesupport/test/core_ext/load_error_test.rb index 4fdd228ff8..41b11d0c33 100644 --- a/activesupport/test/core_ext/load_error_test.rb +++ b/activesupport/test/core_ext/load_error_test.rb @@ -5,7 +5,7 @@ require "active_support/core_ext/load_error" class TestLoadError < ActiveSupport::TestCase def test_with_require - assert_raise(LoadError) { require 'no_this_file_don\'t_exist' } + assert_raise(LoadError) { require "no_this_file_don't_exist" } end def test_with_load assert_raise(LoadError) { load "nor_does_this_one" } -- cgit v1.2.3 From 00f5aca3ef5de2637134c40e2e8b5d3c1d5b1a08 Mon Sep 17 00:00:00 2001 From: "yuuji.yaginuma" Date: Sun, 15 Oct 2017 08:10:38 +0900 Subject: Verify credentials format before saving Currently, credentials does not check the format when saving. As a result, incorrect data as yaml is also saved. If credentials is used in config files., an error will occur in credential yaml parsing before edit, and will not be able to edit it. In order to prevent this, verify the format when saving. Related: #30851 --- activesupport/test/encrypted_configuration_test.rb | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'activesupport/test') diff --git a/activesupport/test/encrypted_configuration_test.rb b/activesupport/test/encrypted_configuration_test.rb index 471faa8c12..0bc915be82 100644 --- a/activesupport/test/encrypted_configuration_test.rb +++ b/activesupport/test/encrypted_configuration_test.rb @@ -51,6 +51,14 @@ class EncryptedConfigurationTest < ActiveSupport::TestCase assert_equal "things", @credentials[:new] end + test "raise error when writing an invalid format value" do + assert_raise(Psych::SyntaxError) do + @credentials.change do |config_file| + config_file.write "login: *login\n username: dummy" + end + end + end + test "raises key error when accessing config via bang method" do assert_raise(KeyError) { @credentials.something! } end -- cgit v1.2.3 From 9f8ec3535247ac41a9c92e84ddc7a3b771bc318b Mon Sep 17 00:00:00 2001 From: Jeremy Daer Date: Wed, 17 May 2017 12:09:34 -0700 Subject: Built-in Redis cache store * Supports vanilla Redis, hiredis, and Redis::Distributed. * Supports Memcached-like sharding across Redises with Redis::Distributed. * Fault tolerant. If the Redis server is unavailable, no exceptions are raised. Cache fetches are treated as misses and writes are dropped. * Local cache. Hot in-memory primary cache within block/middleware scope. * `read_/write_multi` support for Redis mget/mset. Use Redis::Distributed 4.0.1+ for distributed mget support. * `delete_matched` support for Redis KEYS globs. --- .../cache_increment_decrement_behavior.rb | 8 +- .../test/cache/behaviors/local_cache_behavior.rb | 6 +- .../test/cache/stores/redis_cache_store_test.rb | 151 +++++++++++++++++++++ 3 files changed, 162 insertions(+), 3 deletions(-) create mode 100644 activesupport/test/cache/stores/redis_cache_store_test.rb (limited to 'activesupport/test') diff --git a/activesupport/test/cache/behaviors/cache_increment_decrement_behavior.rb b/activesupport/test/cache/behaviors/cache_increment_decrement_behavior.rb index 2fa2d7af88..16b7abc679 100644 --- a/activesupport/test/cache/behaviors/cache_increment_decrement_behavior.rb +++ b/activesupport/test/cache/behaviors/cache_increment_decrement_behavior.rb @@ -8,7 +8,9 @@ module CacheIncrementDecrementBehavior assert_equal 2, @cache.read("foo").to_i assert_equal 3, @cache.increment("foo") assert_equal 3, @cache.read("foo").to_i - assert_nil @cache.increment("bar") + + missing = @cache.increment("bar") + assert(missing.nil? || missing == 1) end def test_decrement @@ -18,6 +20,8 @@ module CacheIncrementDecrementBehavior assert_equal 2, @cache.read("foo").to_i assert_equal 1, @cache.decrement("foo") assert_equal 1, @cache.read("foo").to_i - assert_nil @cache.decrement("bar") + + missing = @cache.decrement("bar") + assert(missing.nil? || missing == -1) end end diff --git a/activesupport/test/cache/behaviors/local_cache_behavior.rb b/activesupport/test/cache/behaviors/local_cache_behavior.rb index 8dec8090b1..f7302df4c8 100644 --- a/activesupport/test/cache/behaviors/local_cache_behavior.rb +++ b/activesupport/test/cache/behaviors/local_cache_behavior.rb @@ -20,7 +20,11 @@ module LocalCacheBehavior end def test_cleanup_clears_local_cache_but_not_remote_cache - skip unless @cache.class.instance_methods(false).include?(:cleanup) + begin + @cache.cleanup + rescue NotImplementedError + skip + end @cache.with_local_cache do @cache.write("foo", "bar") diff --git a/activesupport/test/cache/stores/redis_cache_store_test.rb b/activesupport/test/cache/stores/redis_cache_store_test.rb new file mode 100644 index 0000000000..988de9207f --- /dev/null +++ b/activesupport/test/cache/stores/redis_cache_store_test.rb @@ -0,0 +1,151 @@ +# frozen_string_literal: true + +require "abstract_unit" +require "active_support/cache" +require "active_support/cache/redis_cache_store" +require_relative "../behaviors" + +module ActiveSupport::Cache::RedisCacheStoreTests + class LookupTest < ActiveSupport::TestCase + test "may be looked up as :redis_cache_store" do + assert_kind_of ActiveSupport::Cache::RedisCacheStore, + ActiveSupport::Cache.lookup_store(:redis_cache_store) + end + end + + class InitializationTest < ActiveSupport::TestCase + test "omitted URL uses Redis client with default settings" do + assert_called_with Redis, :new, [ + url: nil, + connect_timeout: 20, read_timeout: 1, write_timeout: 1, + reconnect_attempts: 0, + ] do + build + end + end + + test "no URLs uses Redis client with default settings" do + assert_called_with Redis, :new, [ + url: nil, + connect_timeout: 20, read_timeout: 1, write_timeout: 1, + reconnect_attempts: 0, + ] do + build url: [] + end + end + + test "singular URL uses Redis client" do + assert_called_with Redis, :new, [ + url: "redis://localhost:6379/0", + connect_timeout: 20, read_timeout: 1, write_timeout: 1, + reconnect_attempts: 0, + ] do + build url: "redis://localhost:6379/0" + end + end + + test "one URL uses Redis client" do + assert_called_with Redis, :new, [ + url: "redis://localhost:6379/0", + connect_timeout: 20, read_timeout: 1, write_timeout: 1, + reconnect_attempts: 0, + ] do + build url: %w[ redis://localhost:6379/0 ] + end + end + + test "multiple URLs uses Redis::Distributed client" do + assert_called_with Redis, :new, [ + [ url: "redis://localhost:6379/0", + connect_timeout: 20, read_timeout: 1, write_timeout: 1, + reconnect_attempts: 0 ], + [ url: "redis://localhost:6379/1", + connect_timeout: 20, read_timeout: 1, write_timeout: 1, + reconnect_attempts: 0 ], + ], returns: Redis.new do + @cache = build url: %w[ redis://localhost:6379/0 redis://localhost:6379/1 ] + assert_kind_of ::Redis::Distributed, @cache.redis + end + end + + test "block argument uses yielded client" do + block = -> { :custom_redis_client } + assert_called block, :call do + build redis: block + end + end + + private + def build(**kwargs) + ActiveSupport::Cache::RedisCacheStore.new(**kwargs).tap do |cache| + cache.redis + end + end + end + + class StoreTest < ActiveSupport::TestCase + setup do + @namespace = "namespace" + + @cache = ActiveSupport::Cache::RedisCacheStore.new(timeout: 0.1, namespace: @namespace, expires_in: 60) + #@cache.logger = Logger.new($stdout) # For test debugging + + # For LocalCacheBehavior tests + @peek = ActiveSupport::Cache::RedisCacheStore.new(timeout: 0.1, namespace: @namespace) + end + + teardown do + @cache.clear + @cache.redis.disconnect! + end + end + + class RedisCacheStoreCommonBehaviorTest < StoreTest + include CacheStoreBehavior + include CacheStoreVersionBehavior + include LocalCacheBehavior + include CacheIncrementDecrementBehavior + include AutoloadingCacheBehavior + end + + # Separate test class so we can omit the namespace which causes expected, + # appropriate complaints about incompatible string encodings. + class KeyEncodingSafetyTest < StoreTest + include EncodedKeyCacheBehavior + + setup do + @cache = ActiveSupport::Cache::RedisCacheStore.new(timeout: 0.1) + @cache.logger = nil + end + end + + class StoreAPITest < StoreTest + end + + class FailureSafetyTest < StoreTest + test "fetch read failure returns nil" do + end + + test "fetch read failure does not attempt to write" do + end + + test "write failure returns nil" do + end + end + + class DeleteMatchedTest < StoreTest + test "deletes keys matching glob" do + @cache.write("foo", "bar") + @cache.write("fu", "baz") + @cache.delete_matched("foo*") + assert !@cache.exist?("foo") + assert @cache.exist?("fu") + end + + test "fails with regexp matchers" do + assert_raise ArgumentError do + @cache.delete_matched(/OO/i) + end + end + end +end -- cgit v1.2.3 From ed100166874fb4a542c5aaba933a4cca5ed72269 Mon Sep 17 00:00:00 2001 From: Jeremy Daer Date: Mon, 13 Nov 2017 19:16:53 -0700 Subject: Cache: Enable compression by default for values > 1kB. Compression has long been available, but opt-in and at a 16kB threshold. It wasn't enabled by default due to CPU cost. Today it's cheap and typical cache data is eminently compressible, such as HTML or JSON fragments. Compression dramatically reduces Memcached/Redis mem usage, which means the same cache servers can store more data, which means higher hit rates. To disable compression, pass `compress: false` to the initializer. --- activesupport/test/cache/behaviors/cache_store_behavior.rb | 10 ++++++++++ activesupport/test/cache/cache_entry_test.rb | 13 ++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) (limited to 'activesupport/test') diff --git a/activesupport/test/cache/behaviors/cache_store_behavior.rb b/activesupport/test/cache/behaviors/cache_store_behavior.rb index 582e902f72..73a9b2a71c 100644 --- a/activesupport/test/cache/behaviors/cache_store_behavior.rb +++ b/activesupport/test/cache/behaviors/cache_store_behavior.rb @@ -146,6 +146,16 @@ module CacheStoreBehavior assert_nil @cache.read("foo") end + def test_read_and_write_uncompressed_small_data + @cache.write("foo", "bar", compress: false) + assert_equal "bar", @cache.read("foo") + end + + def test_read_and_write_uncompressed_nil + @cache.write("foo", nil, compress: false) + assert_nil @cache.read("foo") + end + def test_cache_key obj = Object.new def obj.cache_key diff --git a/activesupport/test/cache/cache_entry_test.rb b/activesupport/test/cache/cache_entry_test.rb index 51b214ad8f..80ff7ad564 100644 --- a/activesupport/test/cache/cache_entry_test.rb +++ b/activesupport/test/cache/cache_entry_test.rb @@ -14,16 +14,23 @@ class CacheEntryTest < ActiveSupport::TestCase end end - def test_compress_values + def test_compressed_values value = "value" * 100 entry = ActiveSupport::Cache::Entry.new(value, compress: true, compress_threshold: 1) assert_equal value, entry.value assert(value.bytesize > entry.size, "value is compressed") end - def test_non_compress_values + def test_compressed_by_default value = "value" * 100 - entry = ActiveSupport::Cache::Entry.new(value) + entry = ActiveSupport::Cache::Entry.new(value, compress_threshold: 1) + assert_equal value, entry.value + assert(value.bytesize > entry.size, "value is compressed") + end + + def test_uncompressed_values + value = "value" * 100 + entry = ActiveSupport::Cache::Entry.new(value, compress: false) assert_equal value, entry.value assert_equal value.bytesize, entry.size end -- cgit v1.2.3 From 23c41e4657a507c574e555339821f545c819e602 Mon Sep 17 00:00:00 2001 From: Akira Matsuda Date: Tue, 14 Nov 2017 17:15:33 +0900 Subject: These strings should already be frozen where ruby accepts the magic-comment --- activesupport/test/core_ext/object/instance_variables_test.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'activesupport/test') diff --git a/activesupport/test/core_ext/object/instance_variables_test.rb b/activesupport/test/core_ext/object/instance_variables_test.rb index b9ec827954..a3d8daab5b 100644 --- a/activesupport/test/core_ext/object/instance_variables_test.rb +++ b/activesupport/test/core_ext/object/instance_variables_test.rb @@ -19,7 +19,7 @@ class ObjectInstanceVariableTest < ActiveSupport::TestCase end def test_instance_exec_passes_arguments_to_block - assert_equal %w(hello goodbye), "hello".instance_exec("goodbye") { |v| [self, v] } + assert_equal %w(hello goodbye), "hello".dup.instance_exec("goodbye") { |v| [self, v] } end def test_instance_exec_with_frozen_obj @@ -27,7 +27,7 @@ class ObjectInstanceVariableTest < ActiveSupport::TestCase end def test_instance_exec_nested - assert_equal %w(goodbye olleh bar), "hello".instance_exec("goodbye") { |arg| + assert_equal %w(goodbye olleh bar), "hello".dup.instance_exec("goodbye") { |arg| [arg] + instance_exec("bar") { |v| [reverse, v] } } end end -- cgit v1.2.3 From 2eea6458a14d99b19dffe8673015cde0800f128a Mon Sep 17 00:00:00 2001 From: Andrew White Date: Sat, 11 Nov 2017 15:19:29 +0000 Subject: Handle `TZInfo::AmbiguousTime` errors Make `ActiveSupport::TimeWithZone` match Ruby's handling of ambiguous times by choosing the later period, e.g. Ruby: ``` ENV["TZ"] = "Europe/Moscow" Time.local(2014, 10, 26, 1, 0, 0) # => 2014-10-26 01:00:00 +0300 ``` Before: ``` >> "2014-10-26 01:00:00".in_time_zone("Moscow") TZInfo::AmbiguousTime: 26/10/2014 01:00 is an ambiguous local time. ``` After: ``` >> "2014-10-26 01:00:00".in_time_zone("Moscow") => Sun, 26 Oct 2014 01:00:00 MSK +03:00 ``` Fixes #17395. --- activesupport/test/core_ext/time_with_zone_test.rb | 12 ++++++++++ activesupport/test/time_zone_test.rb | 26 ++++++++++++++++++++++ 2 files changed, 38 insertions(+) (limited to 'activesupport/test') diff --git a/activesupport/test/core_ext/time_with_zone_test.rb b/activesupport/test/core_ext/time_with_zone_test.rb index 0f80a24758..ab96568956 100644 --- a/activesupport/test/core_ext/time_with_zone_test.rb +++ b/activesupport/test/core_ext/time_with_zone_test.rb @@ -50,6 +50,12 @@ class TimeWithZoneTest < ActiveSupport::TestCase assert_raise(ArgumentError) { @twz.in_time_zone(Object.new) } end + def test_in_time_zone_with_ambiguous_time + with_env_tz "Europe/Moscow" do + assert_equal Time.utc(2014, 10, 25, 22, 0, 0), Time.local(2014, 10, 26, 1, 0, 0).in_time_zone("Moscow") + end + end + def test_localtime assert_equal @twz.localtime, @twz.utc.getlocal assert_instance_of Time, @twz.localtime @@ -1301,4 +1307,10 @@ class TimeWithZoneMethodsForString < ActiveSupport::TestCase assert_raise(ArgumentError) { @u.in_time_zone(Object.new) } assert_raise(ArgumentError) { @z.in_time_zone(Object.new) } end + + def test_in_time_zone_with_ambiguous_time + with_tz_default "Moscow" do + assert_equal Time.utc(2014, 10, 25, 22, 0, 0), "2014-10-26 01:00:00".in_time_zone + end + end end diff --git a/activesupport/test/time_zone_test.rb b/activesupport/test/time_zone_test.rb index acb0ecd226..862e872494 100644 --- a/activesupport/test/time_zone_test.rb +++ b/activesupport/test/time_zone_test.rb @@ -32,6 +32,12 @@ class TimeZoneTest < ActiveSupport::TestCase end end + def test_period_for_local_with_ambigiuous_time + zone = ActiveSupport::TimeZone["Moscow"] + period = zone.period_for_local(Time.utc(2015, 1, 1)) + assert_equal period, zone.period_for_local(Time.utc(2014, 10, 26, 1, 0, 0)) + end + def test_from_integer_to_map assert_instance_of ActiveSupport::TimeZone, ActiveSupport::TimeZone[-28800] # PST end @@ -195,6 +201,11 @@ class TimeZoneTest < ActiveSupport::TestCase assert_equal "EDT", twz.zone end + def test_local_with_ambiguous_time + zone = ActiveSupport::TimeZone["Moscow"] + assert_equal Time.utc(2014, 10, 25, 22, 0, 0), zone.local(2014, 10, 26, 1, 0, 0) + end + def test_at zone = ActiveSupport::TimeZone["Eastern Time (US & Canada)"] secs = 946684800.0 @@ -303,6 +314,11 @@ class TimeZoneTest < ActiveSupport::TestCase end end + def test_iso8601_with_ambiguous_time + zone = ActiveSupport::TimeZone["Moscow"] + assert_equal Time.utc(2014, 10, 25, 22, 0, 0), zone.parse("2014-10-26T01:00:00") + end + def test_parse zone = ActiveSupport::TimeZone["Eastern Time (US & Canada)"] twz = zone.parse("1999-12-31 19:00:00") @@ -412,6 +428,11 @@ class TimeZoneTest < ActiveSupport::TestCase assert_equal "argument out of range", exception.message end + def test_parse_with_ambiguous_time + zone = ActiveSupport::TimeZone["Moscow"] + assert_equal Time.utc(2014, 10, 25, 22, 0, 0), zone.parse("2014-10-26 01:00:00") + end + def test_rfc3339 zone = ActiveSupport::TimeZone["Eastern Time (US & Canada)"] twz = zone.rfc3339("1999-12-31T14:00:00-10:00") @@ -604,6 +625,11 @@ class TimeZoneTest < ActiveSupport::TestCase end end + def test_strptime_with_ambiguous_time + zone = ActiveSupport::TimeZone["Moscow"] + assert_equal Time.utc(2014, 10, 25, 22, 0, 0), zone.strptime("2014-10-26 01:00:00", "%Y-%m-%d %H:%M:%S") + end + def test_utc_offset_lazy_loaded_from_tzinfo_when_not_passed_in_to_initialize tzinfo = TZInfo::Timezone.get("America/New_York") zone = ActiveSupport::TimeZone.create(tzinfo.name, nil, tzinfo) -- cgit v1.2.3 From b22ee64b5b30c6d5039c292235e10b24b1057f6d Mon Sep 17 00:00:00 2001 From: Takumasa Ochi Date: Sun, 19 Nov 2017 03:50:59 +0900 Subject: MemCacheStore: Support expiring counters Support `expires_in` in `ActiveSupport::Cache::MemCacheStore#increment` and `#decrement`. Closes #30716. --- activesupport/test/cache/stores/mem_cache_store_test.rb | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'activesupport/test') diff --git a/activesupport/test/cache/stores/mem_cache_store_test.rb b/activesupport/test/cache/stores/mem_cache_store_test.rb index 1b73fb65eb..99624caf8a 100644 --- a/activesupport/test/cache/stores/mem_cache_store_test.rb +++ b/activesupport/test/cache/stores/mem_cache_store_test.rb @@ -57,6 +57,22 @@ class MemCacheStoreTest < ActiveSupport::TestCase end end + def test_increment_expires_in + cache = ActiveSupport::Cache.lookup_store(:mem_cache_store, raw: true) + cache.clear + assert_called_with cache.instance_variable_get(:@data), :incr, [ "foo", 1, 60 ] do + cache.increment("foo", 1, expires_in: 60) + end + end + + def test_decrement_expires_in + cache = ActiveSupport::Cache.lookup_store(:mem_cache_store, raw: true) + cache.clear + assert_called_with cache.instance_variable_get(:@data), :decr, [ "foo", 1, 60 ] do + cache.decrement("foo", 1, expires_in: 60) + end + end + def test_local_cache_raw_values_with_marshal cache = ActiveSupport::Cache.lookup_store(:mem_cache_store, raw: true) cache.clear -- cgit v1.2.3 From 078421bacba178eac6a8e607b16f3f4511c5d72f Mon Sep 17 00:00:00 2001 From: Chris LaRose Date: Wed, 22 Nov 2017 09:12:08 -0800 Subject: Make ActiveSupport::TimeZone.all independent of previous lookups (#31176) --- activesupport/test/time_zone_test.rb | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'activesupport/test') diff --git a/activesupport/test/time_zone_test.rb b/activesupport/test/time_zone_test.rb index 862e872494..405c8f315b 100644 --- a/activesupport/test/time_zone_test.rb +++ b/activesupport/test/time_zone_test.rb @@ -718,6 +718,13 @@ class TimeZoneTest < ActiveSupport::TestCase end end + def test_all_uninfluenced_by_time_zone_lookups_delegated_to_tzinfo + ActiveSupport::TimeZone.clear + galapagos = ActiveSupport::TimeZone["Pacific/Galapagos"] + all_zones = ActiveSupport::TimeZone.all + assert_not_includes all_zones, galapagos + end + def test_index assert_nil ActiveSupport::TimeZone["bogus"] assert_instance_of ActiveSupport::TimeZone, ActiveSupport::TimeZone["Central Time (US & Canada)"] -- cgit v1.2.3 From fb30d1267095190fc73edaf1a77209880f6957e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Sat, 25 Nov 2017 15:24:58 -0500 Subject: Renove duplicated and wrong test --- activesupport/test/security_utils_test.rb | 5 ----- 1 file changed, 5 deletions(-) (limited to 'activesupport/test') diff --git a/activesupport/test/security_utils_test.rb b/activesupport/test/security_utils_test.rb index 6945f653e6..0a607594a2 100644 --- a/activesupport/test/security_utils_test.rb +++ b/activesupport/test/security_utils_test.rb @@ -9,11 +9,6 @@ class SecurityUtilsTest < ActiveSupport::TestCase assert_not ActiveSupport::SecurityUtils.secure_compare("a", "b") end - def test_variable_size_secure_compare_should_perform_string_comparison - assert ActiveSupport::SecurityUtils.variable_size_secure_compare("a", "a") - assert_not ActiveSupport::SecurityUtils.variable_size_secure_compare("a", "b") - end - def test_fixed_length_secure_compare_should_perform_string_comparison assert ActiveSupport::SecurityUtils.fixed_length_secure_compare("a", "a") assert !ActiveSupport::SecurityUtils.fixed_length_secure_compare("a", "b") -- cgit v1.2.3 From 7ce8a6af1b8fdbc9ee553bda3fd725bea169c2f3 Mon Sep 17 00:00:00 2001 From: Ryuta Kamizono Date: Mon, 27 Nov 2017 15:16:12 +0900 Subject: Enable `Style/DefWithParentheses` rubocop rule The def with blank `()` was newly added in #31176, but we have not used the blank `()` style in most part of our code base. So I've enabled `Style/DefWithParentheses` to prevent to newly added the code. --- activesupport/test/json/encoding_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activesupport/test') diff --git a/activesupport/test/json/encoding_test.rb b/activesupport/test/json/encoding_test.rb index 96ad8dfbdb..d904f79ccf 100644 --- a/activesupport/test/json/encoding_test.rb +++ b/activesupport/test/json/encoding_test.rb @@ -210,7 +210,7 @@ class TestJSONEncoding < ActiveSupport::TestCase People = Class.new(BasicObject) do include Enumerable - def initialize() + def initialize @people = [ { name: "John", address: { city: "London", country: "UK" } }, { name: "Jean", address: { city: "Paris" , country: "France" } } -- cgit v1.2.3 From 333ff24b8524094d55badb6c7f42f4b53832c0b6 Mon Sep 17 00:00:00 2001 From: "T.J. Schuck" Date: Tue, 28 Nov 2017 17:49:54 -0500 Subject: Refactor Date/Time next_occurring and prev_occurring MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These methods were originally added in https://github.com/rails/rails/pull/26600 This includes a couple of refactors to make these methods behave more similarly to other Date/Time extensions added by Active Support: 1. Use `advance` instead of `since` and `ago` to time-travel — this is particularly important to keep the returned instance’s class matching `self`. Before this change: today = Date.today # => Tue, 28 Nov 2017 today.class # => Date today.next_occurring(:wednesday) # => Wed, 29 Nov 2017 00:00:00 UTC +00:00 today.next_occurring(:wednesday).class # => ActiveSupport::TimeWithZone After this change, a Date (or Time, or DateTime) instance is properly returned (just like is shown in the new docs). This is generally how everything else in DateAndTime::Calculations works. 2. Move the tests from the DateTime tests to the DateAndTimeBehavior tests. The latter location is mixed in to the core_ext tests for _all_ of Date, Time, and DateTime to test the behavior across all of the classes. The previous location is for testing core_ext functionality added specifically just to DateTime. 3. Better docs! --- .../test/core_ext/date_and_time_behavior.rb | 20 ++++++++++++++++++++ activesupport/test/core_ext/date_time_ext_test.rb | 22 ---------------------- 2 files changed, 20 insertions(+), 22 deletions(-) (limited to 'activesupport/test') diff --git a/activesupport/test/core_ext/date_and_time_behavior.rb b/activesupport/test/core_ext/date_and_time_behavior.rb index 42da6f6cd0..91b92043d0 100644 --- a/activesupport/test/core_ext/date_and_time_behavior.rb +++ b/activesupport/test/core_ext/date_and_time_behavior.rb @@ -328,6 +328,26 @@ module DateAndTimeBehavior assert_equal date_time_init(2007, 12, 31, 23, 59, 59, Rational(999999999, 1000)), date_time_init(2007, 12, 31, 10, 10, 10).end_of_year end + def test_next_occurring + assert_equal date_time_init(2017, 12, 18, 3, 14, 15), date_time_init(2017, 12, 14, 3, 14, 15).next_occurring(:monday) + assert_equal date_time_init(2017, 12, 19, 3, 14, 15), date_time_init(2017, 12, 14, 3, 14, 15).next_occurring(:tuesday) + assert_equal date_time_init(2017, 12, 20, 3, 14, 15), date_time_init(2017, 12, 14, 3, 14, 15).next_occurring(:wednesday) + assert_equal date_time_init(2017, 12, 21, 3, 14, 15), date_time_init(2017, 12, 14, 3, 14, 15).next_occurring(:thursday) + assert_equal date_time_init(2017, 12, 15, 3, 14, 15), date_time_init(2017, 12, 14, 3, 14, 15).next_occurring(:friday) + assert_equal date_time_init(2017, 12, 16, 3, 14, 15), date_time_init(2017, 12, 14, 3, 14, 15).next_occurring(:saturday) + assert_equal date_time_init(2017, 12, 17, 3, 14, 15), date_time_init(2017, 12, 14, 3, 14, 15).next_occurring(:sunday) + end + + def test_prev_occurring + assert_equal date_time_init(2017, 12, 11, 3, 14, 15), date_time_init(2017, 12, 14, 3, 14, 15).prev_occurring(:monday) + assert_equal date_time_init(2017, 12, 12, 3, 14, 15), date_time_init(2017, 12, 14, 3, 14, 15).prev_occurring(:tuesday) + assert_equal date_time_init(2017, 12, 13, 3, 14, 15), date_time_init(2017, 12, 14, 3, 14, 15).prev_occurring(:wednesday) + assert_equal date_time_init(2017, 12, 7, 3, 14, 15), date_time_init(2017, 12, 14, 3, 14, 15).prev_occurring(:thursday) + assert_equal date_time_init(2017, 12, 8, 3, 14, 15), date_time_init(2017, 12, 14, 3, 14, 15).prev_occurring(:friday) + assert_equal date_time_init(2017, 12, 9, 3, 14, 15), date_time_init(2017, 12, 14, 3, 14, 15).prev_occurring(:saturday) + assert_equal date_time_init(2017, 12, 10, 3, 14, 15), date_time_init(2017, 12, 14, 3, 14, 15).prev_occurring(:sunday) + end + def test_monday_with_default_beginning_of_week_set with_bw_default(:saturday) do assert_equal date_time_init(2012, 9, 17, 0, 0, 0), date_time_init(2012, 9, 18, 0, 0, 0).monday diff --git a/activesupport/test/core_ext/date_time_ext_test.rb b/activesupport/test/core_ext/date_time_ext_test.rb index d942cddb2a..ed962803fa 100644 --- a/activesupport/test/core_ext/date_time_ext_test.rb +++ b/activesupport/test/core_ext/date_time_ext_test.rb @@ -30,28 +30,6 @@ class DateTimeExtCalculationsTest < ActiveSupport::TestCase end end - def test_next_occur - datetime = DateTime.new(2016, 9, 24, 0, 0) # saturday - assert_equal datetime.next_occurring(:monday), datetime.since(2.days) - assert_equal datetime.next_occurring(:tuesday), datetime.since(3.days) - assert_equal datetime.next_occurring(:wednesday), datetime.since(4.days) - assert_equal datetime.next_occurring(:thursday), datetime.since(5.days) - assert_equal datetime.next_occurring(:friday), datetime.since(6.days) - assert_equal datetime.next_occurring(:saturday), datetime.since(1.week) - assert_equal datetime.next_occurring(:sunday), datetime.since(1.day) - end - - def test_prev_occur - datetime = DateTime.new(2016, 9, 24, 0, 0) # saturday - assert_equal datetime.prev_occurring(:monday), datetime.ago(5.days) - assert_equal datetime.prev_occurring(:tuesday), datetime.ago(4.days) - assert_equal datetime.prev_occurring(:wednesday), datetime.ago(3.days) - assert_equal datetime.prev_occurring(:thursday), datetime.ago(2.days) - assert_equal datetime.prev_occurring(:friday), datetime.ago(1.day) - assert_equal datetime.prev_occurring(:saturday), datetime.ago(1.week) - assert_equal datetime.prev_occurring(:sunday), datetime.ago(6.days) - end - def test_readable_inspect datetime = DateTime.new(2005, 2, 21, 14, 30, 0) assert_equal "Mon, 21 Feb 2005 14:30:00 +0000", datetime.readable_inspect -- cgit v1.2.3