aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/test
diff options
context:
space:
mode:
Diffstat (limited to 'activesupport/test')
-rw-r--r--activesupport/test/clean_backtrace_test.rb4
-rw-r--r--activesupport/test/core_ext/hash_ext_test.rb7
-rw-r--r--activesupport/test/hash_with_indifferent_access_test.rb26
-rw-r--r--activesupport/test/message_encryptor_test.rb44
-rw-r--r--activesupport/test/message_verifier_test.rb41
-rw-r--r--activesupport/test/metadata/shared_metadata_tests.rb88
-rw-r--r--activesupport/test/multibyte_grapheme_break_conformance_test.rb1
-rw-r--r--activesupport/test/multibyte_normalization_conformance_test.rb1
8 files changed, 205 insertions, 7 deletions
diff --git a/activesupport/test/clean_backtrace_test.rb b/activesupport/test/clean_backtrace_test.rb
index e9361ecd26..1b44c7c9bf 100644
--- a/activesupport/test/clean_backtrace_test.rb
+++ b/activesupport/test/clean_backtrace_test.rb
@@ -10,8 +10,8 @@ class BacktraceCleanerFilterTest < ActiveSupport::TestCase
test "backtrace should filter all lines in a backtrace, removing prefixes" do
assert_equal \
- ["/my/class.rb", "/my/module.rb"],
- @bc.clean(["/my/prefix/my/class.rb", "/my/prefix/my/module.rb"])
+ ["/my/class.rb", "/my/module.rb"],
+ @bc.clean(["/my/prefix/my/class.rb", "/my/prefix/my/module.rb"])
end
test "backtrace cleaner should allow removing filters" do
diff --git a/activesupport/test/core_ext/hash_ext_test.rb b/activesupport/test/core_ext/hash_ext_test.rb
index c537fb86fe..746d7ad416 100644
--- a/activesupport/test/core_ext/hash_ext_test.rb
+++ b/activesupport/test/core_ext/hash_ext_test.rb
@@ -302,9 +302,9 @@ class HashExtTest < ActiveSupport::TestCase
end
def test_reverse_merge
- defaults = { a: "x", b: "y", c: 10 }.freeze
+ defaults = { d: 0, a: "x", b: "y", c: 10 }.freeze
options = { a: 1, b: 2 }
- expected = { a: 1, b: 2, c: 10 }
+ expected = { d: 0, a: 1, b: 2, c: 10 }
# Should merge defaults into options, creating a new hash.
assert_equal expected, options.reverse_merge(defaults)
@@ -315,6 +315,9 @@ class HashExtTest < ActiveSupport::TestCase
assert_equal expected, merged.reverse_merge!(defaults)
assert_equal expected, merged
+ # Make the order consistent with the non-overwriting reverse merge.
+ assert_equal expected.keys, merged.keys
+
# Should be an alias for reverse_merge!
merged = options.dup
assert_equal expected, merged.reverse_update(defaults)
diff --git a/activesupport/test/hash_with_indifferent_access_test.rb b/activesupport/test/hash_with_indifferent_access_test.rb
index 4acdd10de6..77fc039459 100644
--- a/activesupport/test/hash_with_indifferent_access_test.rb
+++ b/activesupport/test/hash_with_indifferent_access_test.rb
@@ -537,6 +537,32 @@ class HashWithIndifferentAccessTest < ActiveSupport::TestCase
assert_equal 1234, data.dig(:this, :views)
end
+ def test_argless_default_with_existing_nil_key
+ h = Hash.new(:default).merge(nil => "defined").with_indifferent_access
+
+ assert_equal :default, h.default
+ end
+
+ def test_default_with_argument
+ h = Hash.new { 5 }.merge(1 => 2).with_indifferent_access
+
+ assert_equal 5, h.default(1)
+ end
+
+ def test_default_proc
+ h = ActiveSupport::HashWithIndifferentAccess.new { |hash, key| key }
+
+ assert_nil h.default
+ assert_equal "foo", h.default("foo")
+ assert_equal "foo", h.default(:foo)
+ end
+
+ def test_double_conversion_with_nil_key
+ h = { nil => "defined" }.with_indifferent_access.with_indifferent_access
+
+ assert_equal nil, h[:undefined_key]
+ end
+
def test_assorted_keys_not_stringified
original = { Object.new => 2, 1 => 2, [] => true }
indiff = original.with_indifferent_access
diff --git a/activesupport/test/message_encryptor_test.rb b/activesupport/test/message_encryptor_test.rb
index 832841597f..1fbe655642 100644
--- a/activesupport/test/message_encryptor_test.rb
+++ b/activesupport/test/message_encryptor_test.rb
@@ -4,6 +4,7 @@ require "abstract_unit"
require "openssl"
require "active_support/time"
require "active_support/json"
+require_relative "metadata/shared_metadata_tests"
class MessageEncryptorTest < ActiveSupport::TestCase
class JSONSerializer
@@ -106,8 +107,15 @@ class MessageEncryptorTest < ActiveSupport::TestCase
assert_aead_not_decrypted(encryptor, [text, iv, auth_tag[0..-2]] * "--")
end
- private
+ def test_backwards_compatibility_decrypt_previously_encrypted_messages_without_metadata
+ secret = "\xB7\xF0\xBCW\xB1\x18`\xAB\xF0\x81\x10\xA4$\xF44\xEC\xA1\xDC\xC1\xDDD\xAF\xA9\xB8\x14\xCD\x18\x9A\x99 \x80)"
+ encryptor = ActiveSupport::MessageEncryptor.new(secret, cipher: "aes-256-gcm")
+ encrypted_message = "9cVnFs2O3lL9SPvIJuxBOLS51nDiBMw=--YNI5HAfHEmZ7VDpl--ddFJ6tXA0iH+XGcCgMINYQ=="
+
+ assert_equal "Ruby on Rails", encryptor.decrypt_and_verify(encrypted_message)
+ end
+ private
def assert_aead_not_decrypted(encryptor, value)
assert_raise(ActiveSupport::MessageEncryptor::InvalidMessage) do
encryptor.decrypt_and_verify(value)
@@ -132,3 +140,37 @@ class MessageEncryptorTest < ActiveSupport::TestCase
::Base64.strict_encode64(bits)
end
end
+
+class MessageEncryptorMetadataTest < ActiveSupport::TestCase
+ include SharedMessageMetadataTests
+
+ setup do
+ @secret = SecureRandom.random_bytes(32)
+ @encryptor = ActiveSupport::MessageEncryptor.new(@secret, encryptor_options)
+ end
+
+ private
+ def generate(message, **options)
+ @encryptor.encrypt_and_sign(message, options)
+ end
+
+ def parse(data, **options)
+ @encryptor.decrypt_and_verify(data, options)
+ end
+
+ def encryptor_options; end
+end
+
+class MessageEncryptorMetadataMarshalTest < MessageEncryptorMetadataTest
+ private
+ def encryptor_options
+ { serializer: Marshal }
+ end
+end
+
+class MessageEncryptorMetadataJSONTest < MessageEncryptorMetadataTest
+ private
+ def encryptor_options
+ { serializer: MessageEncryptorTest::JSONSerializer.new }
+ end
+end
diff --git a/activesupport/test/message_verifier_test.rb b/activesupport/test/message_verifier_test.rb
index ba886f9fb4..d4a8ce762a 100644
--- a/activesupport/test/message_verifier_test.rb
+++ b/activesupport/test/message_verifier_test.rb
@@ -4,6 +4,7 @@ require "abstract_unit"
require "openssl"
require "active_support/time"
require "active_support/json"
+require_relative "metadata/shared_metadata_tests"
class MessageVerifierTest < ActiveSupport::TestCase
class JSONSerializer
@@ -84,4 +85,44 @@ class MessageVerifierTest < ActiveSupport::TestCase
end
assert_equal "Secret should not be nil.", exception.message
end
+
+ def test_backward_compatibility_messages_signed_without_metadata
+ signed_message = "BAh7BzoJc29tZUkiCWRhdGEGOgZFVDoIbm93SXU6CVRpbWUNIIAbgAAAAAAHOgtvZmZzZXRpADoJem9uZUkiCFVUQwY7BkY=--d03c52c91dfe4ccc5159417c660461bcce005e96"
+ assert_equal @data, @verifier.verify(signed_message)
+ end
+end
+
+class MessageVerifierMetadataTest < ActiveSupport::TestCase
+ include SharedMessageMetadataTests
+
+ setup do
+ @verifier = ActiveSupport::MessageVerifier.new("Hey, I'm a secret!", verifier_options)
+ end
+
+ private
+ def generate(message, **options)
+ @verifier.generate(message, options)
+ end
+
+ def parse(message, **options)
+ @verifier.verified(message, options)
+ end
+
+ def verifier_options
+ Hash.new
+ end
+end
+
+class MessageVerifierMetadataMarshalTest < MessageVerifierMetadataTest
+ private
+ def verifier_options
+ { serializer: Marshal }
+ end
+end
+
+class MessageVerifierMetadataJSONTest < MessageVerifierMetadataTest
+ private
+ def verifier_options
+ { serializer: MessageVerifierTest::JSONSerializer.new }
+ end
end
diff --git a/activesupport/test/metadata/shared_metadata_tests.rb b/activesupport/test/metadata/shared_metadata_tests.rb
new file mode 100644
index 0000000000..7d88e255c7
--- /dev/null
+++ b/activesupport/test/metadata/shared_metadata_tests.rb
@@ -0,0 +1,88 @@
+# frozen_string_literal: true
+
+module SharedMessageMetadataTests
+ def setup
+ @message = { "credit_card_no" => "5012-6784-9087-5678", "card_holder" => { "name" => "Donald" } }
+
+ super
+ end
+
+ def teardown
+ travel_back
+
+ super
+ end
+
+ def test_encryption_and_decryption_with_same_purpose
+ assert_equal @message, parse(generate(@message, purpose: "checkout"), purpose: "checkout")
+ assert_equal @message, parse(generate(@message))
+
+ string_message = "address: #23, main street"
+ assert_equal string_message, parse(generate(string_message, purpose: "shipping"), purpose: "shipping")
+
+ array_message = ["credit_card_no: 5012-6748-9087-5678", { "card_holder" => "Donald", "issued_on" => Time.local(2017) }, 12345]
+ assert_equal array_message, parse(generate(array_message, purpose: "registration"), purpose: "registration")
+ end
+
+ def test_encryption_and_decryption_with_different_purposes_returns_nil
+ assert_nil parse(generate(@message, purpose: "payment"), purpose: "sign up")
+ assert_nil parse(generate(@message, purpose: "payment"))
+ assert_nil parse(generate(@message), purpose: "sign up")
+ assert_nil parse(generate(@message), purpose: "")
+ end
+
+ def test_purpose_using_symbols
+ assert_equal @message, parse(generate(@message, purpose: :checkout), purpose: :checkout)
+ assert_equal @message, parse(generate(@message, purpose: :checkout), purpose: "checkout")
+ assert_equal @message, parse(generate(@message, purpose: "checkout"), purpose: :checkout)
+ end
+
+ def test_passing_expires_at_sets_expiration_date
+ encrypted_message = generate(@message, expires_at: 1.hour.from_now)
+
+ travel 59.minutes
+ assert_equal @message, parse(encrypted_message)
+
+ travel 2.minutes
+ assert_nil parse(encrypted_message)
+ end
+
+ def test_set_relative_expiration_date_by_passing_expires_in
+ encrypted_message = generate(@message, expires_in: 2.hours)
+
+ travel 1.hour
+ assert_equal @message, parse(encrypted_message)
+
+ travel 1.hour + 1.second
+ assert_nil parse(encrypted_message)
+ end
+
+ def test_passing_expires_in_less_than_a_second_is_not_expired
+ freeze_time do
+ encrypted_message = generate(@message, expires_in: 1.second)
+
+ travel 0.5.seconds
+ assert_equal @message, parse(encrypted_message)
+
+ travel 1.second
+ assert_nil parse(encrypted_message)
+ end
+ end
+
+ def test_favor_expires_at_over_expires_in
+ payment_related_message = generate(@message, purpose: "payment", expires_at: 2.year.from_now, expires_in: 1.second)
+
+ travel 1.year
+ assert_equal @message, parse(payment_related_message, purpose: :payment)
+
+ travel 1.year + 1.day
+ assert_nil parse(payment_related_message, purpose: "payment")
+ end
+
+ def test_skip_expires_at_and_expires_in_to_disable_expiration_check
+ payment_related_message = generate(@message, purpose: "payment")
+
+ travel 100.years
+ assert_equal @message, parse(payment_related_message, purpose: "payment")
+ end
+end
diff --git a/activesupport/test/multibyte_grapheme_break_conformance_test.rb b/activesupport/test/multibyte_grapheme_break_conformance_test.rb
index 855626e779..fac74cd80f 100644
--- a/activesupport/test/multibyte_grapheme_break_conformance_test.rb
+++ b/activesupport/test/multibyte_grapheme_break_conformance_test.rb
@@ -1,4 +1,3 @@
-# encoding: utf-8
# frozen_string_literal: true
require "abstract_unit"
diff --git a/activesupport/test/multibyte_normalization_conformance_test.rb b/activesupport/test/multibyte_normalization_conformance_test.rb
index deb94a7aa3..1173a94e81 100644
--- a/activesupport/test/multibyte_normalization_conformance_test.rb
+++ b/activesupport/test/multibyte_normalization_conformance_test.rb
@@ -1,4 +1,3 @@
-# encoding: utf-8
# frozen_string_literal: true
require "abstract_unit"