Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ExPhoneNumber.Utilities#truncate_too_long_number/1 #49

Merged
merged 2 commits into from
Oct 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions lib/ex_phone_number/extraction.ex
Original file line number Diff line number Diff line change
Expand Up @@ -232,4 +232,38 @@ defmodule ExPhoneNumber.Extraction do
{false, number}
end
end

@doc """
Attempts to extract a valid number from a phone number that is too long to be
valid, and resets the PhoneNumber object passed in to that valid version. If
no valid number could be extracted, the PhoneNumber object passed in will not
be modified.

Implements `i18n.phonenumbers.PhoneNumberUtil.prototype.truncateTooLongNumber`
"""
@spec truncate_too_long_number(%PhoneNumber{}) :: {boolean(), %PhoneNumber{}}
def truncate_too_long_number(%PhoneNumber{} = phone_number) do
if is_valid_number?(phone_number) do
{true, phone_number}
else
national_number = PhoneNumber.get_national_number_or_default(phone_number)
truncate_too_long_number(phone_number, national_number)
end
end

defp truncate_too_long_number(%PhoneNumber{} = phone_number, national_number) do
national_number = div(national_number, 10)
phone_number_copy = %PhoneNumber{phone_number | national_number: national_number}

cond do
national_number == 0 or is_possible_number_with_reason?(phone_number_copy) == ValidationResults.too_short() ->
{false, phone_number}

not is_valid_number?(phone_number_copy) ->
truncate_too_long_number(phone_number, national_number)

true ->
{true, phone_number_copy}
end
end
end
9 changes: 9 additions & 0 deletions lib/ex_phone_number/model/phone_number.ex
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ defmodule ExPhoneNumber.Model.PhoneNumber do
not is_nil(phone_number.country_code)
end

@national_number_default 0
def get_national_number_or_default(phone_number = %PhoneNumber{}) do
if is_nil(phone_number.national_number) do
@national_number_default
else
phone_number.national_number
end
end

@spec has_national_number?(%PhoneNumber{}) :: boolean()
def has_national_number?(phone_number = %PhoneNumber{}) do
not is_nil(phone_number.national_number)
Expand Down
19 changes: 19 additions & 0 deletions test/ex_phone_number/extraction_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ defmodule ExPhoneNumber.ExtractionTest do
import ExPhoneNumber.Extraction

alias ExPhoneNumber.Metadata
alias ExPhoneNumber.PhoneNumberFixture
alias ExPhoneNumber.RegionCodeFixture
alias ExPhoneNumber.Constants.CountryCodeSource
alias ExPhoneNumber.Constants.ErrorMessages
Expand Down Expand Up @@ -233,4 +234,22 @@ defmodule ExPhoneNumber.ExtractionTest do
assert CountryCodeSource.from_default_country() == phone_number.country_code_source
end
end

describe ".truncate_too_long_number/1" do
test "TruncateTooLongNumber" do
assert {true, PhoneNumberFixture.gb_toll_free()} == truncate_too_long_number(PhoneNumberFixture.gb_toll_free_too_long())

assert {true, PhoneNumberFixture.it_number2()} == truncate_too_long_number(PhoneNumberFixture.it_number2_too_long())

assert {true, PhoneNumberFixture.us_number()} == truncate_too_long_number(PhoneNumberFixture.us_long_number())

assert {true, PhoneNumberFixture.international_toll_free()} == truncate_too_long_number(PhoneNumberFixture.international_toll_free_too_long())

assert {true, PhoneNumberFixture.gb_toll_free()} == truncate_too_long_number(PhoneNumberFixture.gb_toll_free())

assert {false, PhoneNumberFixture.us_invalid_prefix()} == truncate_too_long_number(PhoneNumberFixture.us_invalid_prefix())

assert {false, PhoneNumberFixture.us_short_number()} == truncate_too_long_number(PhoneNumberFixture.us_short_number())
end
end
end
39 changes: 38 additions & 1 deletion test/support/phone_number_fixture.ex
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ defmodule ExPhoneNumber.PhoneNumberFixture do
def ad_number() do
%PhoneNumber{
country_code: 376,
national_number: 12345
national_number: 12_345
}
end

Expand Down Expand Up @@ -291,6 +291,13 @@ defmodule ExPhoneNumber.PhoneNumberFixture do
}
end

def gb_toll_free_too_long() do
%PhoneNumber{
country_code: 44,
national_number: 80_123_456_780_123
}
end

def gb_shared_cost() do
%PhoneNumber{
country_code: 44,
Expand Down Expand Up @@ -357,6 +364,22 @@ defmodule ExPhoneNumber.PhoneNumberFixture do
}
end

def it_number2() do
%PhoneNumber{
country_code: 39,
national_number: 2_234_567_890,
italian_leading_zero: true
}
end

def it_number2_too_long() do
%PhoneNumber{
country_code: 39,
national_number: 2_234_567_890_123,
italian_leading_zero: true
}
end

def it_premium() do
%PhoneNumber{
country_code: 39,
Expand Down Expand Up @@ -598,6 +621,13 @@ defmodule ExPhoneNumber.PhoneNumberFixture do
}
end

def us_short_number() do
%PhoneNumber{
country_code: 1,
national_number: 1_234
}
end

def us_short_by_one_number() do
%PhoneNumber{
country_code: 1,
Expand Down Expand Up @@ -658,6 +688,13 @@ defmodule ExPhoneNumber.PhoneNumberFixture do
}
end

def us_invalid_prefix() do
%PhoneNumber{
country_code: 1,
national_number: 2_401_234_567
}
end

def uz_fixed_line() do
%PhoneNumber{
country_code: 998,
Expand Down