diff --git a/lib/rails_ext/active_record_uuid_type.rb b/lib/rails_ext/active_record_uuid_type.rb index 28fff61f3..6ac0ea801 100644 --- a/lib/rails_ext/active_record_uuid_type.rb +++ b/lib/rails_ext/active_record_uuid_type.rb @@ -7,7 +7,11 @@ module ActiveRecord def self.generate uuid = SecureRandom.uuid_v7 hex = uuid.delete("-") - hex.to_i(16).to_s(36).rjust(25, "0") + normalize_base36(hex.to_i(16)) + end + + def self.normalize_base36(integer) + integer.to_s(36).rjust(BASE36_LENGTH, "0") end def serialize(value) @@ -15,19 +19,18 @@ module ActiveRecord hex = value.to_s.to_i(36).to_s(16).rjust(32, "0") binary = hex.scan(/../).map(&:hex).pack("C*") - binary.force_encoding(Encoding::BINARY) - Data.new(binary) + super(binary) end def deserialize(value) return unless value hex = value.to_s.unpack1("H*") - hex.to_i(16).to_s(36).rjust(BASE36_LENGTH, "0") + Uuid.normalize_base36(hex.to_i(16)) end def cast(value) - deserialize(serialize(value)) + value end end end diff --git a/test/lib/rails_ext/active_record_uuid_type_test.rb b/test/lib/rails_ext/active_record_uuid_type_test.rb new file mode 100644 index 000000000..f168fc3c0 --- /dev/null +++ b/test/lib/rails_ext/active_record_uuid_type_test.rb @@ -0,0 +1,50 @@ +require "test_helper" + +class ActiveRecordUuidTypeTest < ActiveSupport::TestCase + setup do + @type = ActiveRecord::Type::Uuid.new + @sample_uuid = "01jcqzx8h0000000000000000" # base36 UUID + end + + test "cast nil returns nil" do + assert_nil @type.cast(nil) + end + + test "cast returns value as-is" do + result = @type.cast(@sample_uuid) + assert_equal @sample_uuid, result + end + + test "serialize returns binary Data object" do + result = @type.serialize(@sample_uuid) + + assert_instance_of ActiveModel::Type::Binary::Data, result + assert_equal 16, result.to_s.bytesize + assert_equal Encoding::BINARY, result.to_s.encoding + end + + test "serialize nil returns nil" do + assert_nil @type.serialize(nil) + end + + test "deserialize converts binary to base36" do + binary_data = @type.serialize(@sample_uuid) + + result = @type.deserialize(binary_data) + + assert_equal @sample_uuid, result + end + + test "deserialize handles raw binary string" do + binary_data = @type.serialize(@sample_uuid) + raw_binary = binary_data.to_s + + result = @type.deserialize(raw_binary) + + assert_equal @sample_uuid, result + end + + test "deserialize nil returns nil" do + assert_nil @type.deserialize(nil) + end +end