From 7e19e1ce01552c326ba4d26ec3e60dd2904db268 Mon Sep 17 00:00:00 2001 From: Joe Stein Date: Wed, 24 May 2023 11:23:38 -0400 Subject: [PATCH 1/3] Write failing tests --- test/integration/mysql_integration_test.rb | 55 ++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/test/integration/mysql_integration_test.rb b/test/integration/mysql_integration_test.rb index de1ce75..420ac1d 100644 --- a/test/integration/mysql_integration_test.rb +++ b/test/integration/mysql_integration_test.rb @@ -4,10 +4,33 @@ class MyUuidModel < ActiveRecord::Base attribute :the_uuid, MySQLBinUUID::Type.new end +class UuidPkeyModel < ActiveRecord::Base + self.abstract_class = true + + attribute :id, MySQLBinUUID::Type.new + + after_initialize :set_id + + private + + def set_id + self.id ||= SecureRandom.uuid + end +end + class MyUuidModelWithValidations < MyUuidModel validates :the_uuid, uniqueness: true end +class UuidParent < UuidPkeyModel + has_many :uuid_children +end + +class UuidChild < UuidPkeyModel + belongs_to :uuid_parent + attribute :uuid_parent_id, MySQLBinUUID::Type.new +end + class MySQLIntegrationTest < ActiveSupport::TestCase def connection ActiveRecord::Base.connection @@ -35,6 +58,9 @@ def db_config ActiveRecord::Base.establish_connection(db_config) connection.create_table("my_uuid_models") connection.add_column("my_uuid_models", "the_uuid", :binary, limit: 16) + connection.create_table('uuid_parents', id: 'binary(16)') + connection.create_table('uuid_children', id: 'binary(16)') + connection.add_columns('uuid_children', 'uuid_parent_id', type: 'binary(16)') # Uncomment this line to get logging on stdout # ActiveRecord::Base.logger = Logger.new(STDOUT) @@ -122,5 +148,34 @@ class AfterPersistedTest < MySQLIntegrationTest MyUuidModel.create!(the_uuid: "40' + x'40") end end + + test "always downcases the user-supplied value" do + @my_model.the_uuid = @sample_uuid.upcase + assert_equal @sample_uuid, @my_model.the_uuid + end + + test "treats case-only changes as non-dirtying" do + @my_model.the_uuid = @sample_uuid.upcase + assert_equal false, @my_model.will_save_change_to_the_uuid? + end + end + + class ComplexRelationTest < MySQLIntegrationTest + setup do + @parent = UuidParent.new(id: SecureRandom.uuid.upcase) + end + + teardown do + UuidParent.delete_all + UuidChild.delete_all + end + + test "beep boop" do + @parent.uuid_children.build + @parent.save! + @parent.uuid_children.reload + + refute @parent.uuid_children.first.uuid_parent_id_changed? + end end end From 99094761ccd64308142e8a3e454077999b59ccca Mon Sep 17 00:00:00 2001 From: Joe Stein Date: Wed, 24 May 2023 13:34:56 -0400 Subject: [PATCH 2/3] Always downcase UUID string --- lib/mysql-binuuid/type.rb | 18 +++++++++++------- test/integration/mysql_integration_test.rb | 2 +- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/lib/mysql-binuuid/type.rb b/lib/mysql-binuuid/type.rb index 8273fa6..15e2130 100644 --- a/lib/mysql-binuuid/type.rb +++ b/lib/mysql-binuuid/type.rb @@ -12,13 +12,17 @@ def cast(value) if value.is_a?(MySQLBinUUID::Type::Data) # It could be a Data object, in which case we should add dashes to the # string value from there. - add_dashes(value.to_s) - elsif value.is_a?(String) && value.encoding == Encoding::ASCII_8BIT && strip_dashes(value).length != 32 - # We cannot unpack something that looks like a UUID, with or without - # dashes. Not entirely sure why ActiveRecord does a weird combination of - # cast and serialize before anything needs to be saved.. - undashed_uuid = value.unpack1('H*') - add_dashes(undashed_uuid.to_s) + add_dashes(value.to_s.downcase) + elsif value.is_a?(String) + if value.encoding == Encoding::ASCII_8BIT && strip_dashes(value).length != 32 + # We cannot unpack something that looks like a UUID, with or without + # dashes. Not entirely sure why ActiveRecord does a weird combination of + # cast and serialize before anything needs to be saved.. + undashed_uuid = value.unpack1('H*') + add_dashes(undashed_uuid.to_s.downcase) + else + value.downcase + end else super end diff --git a/test/integration/mysql_integration_test.rb b/test/integration/mysql_integration_test.rb index 420ac1d..23ef1e3 100644 --- a/test/integration/mysql_integration_test.rb +++ b/test/integration/mysql_integration_test.rb @@ -170,7 +170,7 @@ class ComplexRelationTest < MySQLIntegrationTest UuidChild.delete_all end - test "beep boop" do + test "does not dirty data on association reloads" do @parent.uuid_children.build @parent.save! @parent.uuid_children.reload From ab3c409dab6f92a28ecbd2cae00aa6de4ec161ad Mon Sep 17 00:00:00 2001 From: Joe Stein Date: Wed, 24 May 2023 16:27:55 -0400 Subject: [PATCH 3/3] Version bump --- lib/mysql-binuuid/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/mysql-binuuid/version.rb b/lib/mysql-binuuid/version.rb index 36b21fb..82d6a9a 100644 --- a/lib/mysql-binuuid/version.rb +++ b/lib/mysql-binuuid/version.rb @@ -1,3 +1,3 @@ module MySQLBinUUID - VERSION = "1.3.0" + VERSION = "2.0.0" end