From 01b7eafc49f17dbf5c86835c30c0d0bb1288a09a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20Ve=C4=8Derek?= Date: Wed, 23 Mar 2022 17:54:43 +0100 Subject: [PATCH] Test and improve #valid_ulid? method Co-authored-by: Benjamin Quorning --- lib/ulid/rails/type.rb | 6 +++++- test/ulid/rails/type_test.rb | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 test/ulid/rails/type_test.rb diff --git a/lib/ulid/rails/type.rb b/lib/ulid/rails/type.rb index 8b62961..a39be56 100644 --- a/lib/ulid/rails/type.rb +++ b/lib/ulid/rails/type.rb @@ -44,6 +44,8 @@ def cast_string_to_ulid(value, data_class: Data) end class Data < ActiveModel::Type::Binary::Data + INVALID_CHARACTERS_REGEX = /[ilo]/i.freeze + def self.from_serialized(data) deserialized = Base32::Crockford.encode(data.hex).rjust(26, "0") new(deserialized) @@ -51,8 +53,10 @@ def self.from_serialized(data) def self.valid_ulid?(str) return true if str.nil? + return false unless str.length == 26 + return false if INVALID_CHARACTERS_REGEX.match?(str) - str.length == 26 && Base32::Crockford.valid?(str) + Base32::Crockford.valid?(str) end def initialize(value) diff --git a/test/ulid/rails/type_test.rb b/test/ulid/rails/type_test.rb new file mode 100644 index 0000000..88b9b8e --- /dev/null +++ b/test/ulid/rails/type_test.rb @@ -0,0 +1,34 @@ +require "test_helper" + +class ULID::Rails::Type::DataTest < Minitest::Test + def test_has_26_valid_characters + id = "01BX5ZZKBKACTAV9WEVGEMMVRZ" + + assert ULID::Rails::Type::Data.valid_ulid?(id) + end + + def test_length_less_than_26 + id = "A" * 25 + + refute ULID::Rails::Type::Data.valid_ulid?(id) + end + + def test_length_greater_than_26 + id = "A" * 27 + + refute ULID::Rails::Type::Data.valid_ulid?(id) + end + + # Crockford's Base32 is used as shown. This alphabet excludes + # the letters I, L, O, and U to avoid confusion and abuse. + # https://github.com/ulid/spec#encoding + def test_has_invalid_characters + invalid_characters = %w(I L O U) + + invalid_characters.each do |char| + id = char * 26 + + refute ULID::Rails::Type::Data.valid_ulid?(id) + end + end +end