injects the phonenumberutil and adds testcases around the parsing

This commit is contained in:
Adam Brown 2022-05-20 14:30:18 +01:00
parent 27b1bc9e66
commit 0bbc74b193
4 changed files with 108 additions and 4 deletions

View file

@ -21,6 +21,7 @@ import android.content.Context
import android.content.Context.MODE_PRIVATE import android.content.Context.MODE_PRIVATE
import android.content.SharedPreferences import android.content.SharedPreferences
import android.content.res.Resources import android.content.res.Resources
import com.google.i18n.phonenumbers.PhoneNumberUtil
import dagger.Binds import dagger.Binds
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
@ -193,6 +194,9 @@ object VectorStaticModule {
return analyticsConfig return analyticsConfig
} }
@Provides
fun providesPhoneNumberUtil(): PhoneNumberUtil = PhoneNumberUtil.getInstance()
@Provides @Provides
@Singleton @Singleton
fun providesBuildMeta() = BuildMeta() fun providesBuildMeta() = BuildMeta()

View file

@ -20,7 +20,9 @@ import com.google.i18n.phonenumbers.NumberParseException
import com.google.i18n.phonenumbers.PhoneNumberUtil import com.google.i18n.phonenumbers.PhoneNumberUtil
import javax.inject.Inject import javax.inject.Inject
class PhoneNumberParser @Inject constructor() { class PhoneNumberParser @Inject constructor(
private val phoneNumberUtil: PhoneNumberUtil
) {
fun parseInternationalNumber(rawPhoneNumber: String): Result { fun parseInternationalNumber(rawPhoneNumber: String): Result {
return when { return when {
@ -30,9 +32,8 @@ class PhoneNumberParser @Inject constructor() {
} }
private fun parseNumber(rawPhoneNumber: String) = try { private fun parseNumber(rawPhoneNumber: String) = try {
val instance = PhoneNumberUtil.getInstance() val phoneNumber = phoneNumberUtil.parse(rawPhoneNumber, null)
val phoneNumber = instance.parse(rawPhoneNumber, null) Result.Success(phoneNumberUtil.getRegionCodeForCountryCode(phoneNumber.countryCode), rawPhoneNumber)
Result.Success(instance.getRegionCodeForCountryCode(phoneNumber.countryCode), rawPhoneNumber)
} catch (e: NumberParseException) { } catch (e: NumberParseException) {
Result.ErrorInvalidNumber Result.ErrorInvalidNumber
} }

View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 2022 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.app.features.onboarding.ftueauth
import im.vector.app.test.fakes.FakePhoneNumberUtil
import org.amshove.kluent.shouldBeEqualTo
import org.junit.Test
private const val AN_INTERNATIONAL_PHONE_NUMBER = "+4411111111111"
private const val A_NON_INTERNATIONAL_PHONE_NUMBER = "111111111111"
private const val AN_INVALID_INTERNATIONAL_NUMBER = "+abc"
private const val A_COUNTRY_CODE = "GB"
private const val A_COUNTRY_CALLING_CODE = 44
class PhoneNumberParserTest {
private val fakePhoneNumberUtil = FakePhoneNumberUtil()
private val phoneNumberParser = PhoneNumberParser(fakePhoneNumberUtil.instance)
@Test
fun `given a calling code and country code are successfully read when parsing, then returns success with country code`() {
fakePhoneNumberUtil.givenCountryCallingCodeFor(AN_INTERNATIONAL_PHONE_NUMBER, callingCode = A_COUNTRY_CALLING_CODE)
fakePhoneNumberUtil.givenRegionCodeFor(A_COUNTRY_CALLING_CODE, countryCode = A_COUNTRY_CODE)
val result = phoneNumberParser.parseInternationalNumber(AN_INTERNATIONAL_PHONE_NUMBER)
result shouldBeEqualTo PhoneNumberParser.Result.Success(A_COUNTRY_CODE, AN_INTERNATIONAL_PHONE_NUMBER)
}
@Test
fun `given a non internation phone number, when parsing, then returns MissingInternationCode error`() {
val result = phoneNumberParser.parseInternationalNumber(A_NON_INTERNATIONAL_PHONE_NUMBER)
result shouldBeEqualTo PhoneNumberParser.Result.ErrorMissingInternationalCode
}
@Test
fun `given an invalid phone number, when parsing, then returns ErrorInvalidNumber error`() {
fakePhoneNumberUtil.givenFailsToParse(AN_INVALID_INTERNATIONAL_NUMBER)
val result = phoneNumberParser.parseInternationalNumber(AN_INVALID_INTERNATIONAL_NUMBER)
result shouldBeEqualTo PhoneNumberParser.Result.ErrorInvalidNumber
}
}

View file

@ -0,0 +1,40 @@
/*
* Copyright (c) 2022 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.app.test.fakes
import com.google.i18n.phonenumbers.NumberParseException
import com.google.i18n.phonenumbers.PhoneNumberUtil
import com.google.i18n.phonenumbers.Phonenumber
import io.mockk.every
import io.mockk.mockk
class FakePhoneNumberUtil {
val instance = mockk<PhoneNumberUtil>()
fun givenCountryCallingCodeFor(phoneNumber: String, callingCode: Int) {
every { instance.parse(phoneNumber, null) } returns Phonenumber.PhoneNumber().setCountryCode(callingCode)
}
fun givenRegionCodeFor(callingCode: Int, countryCode: String) {
every { instance.getRegionCodeForCountryCode(callingCode) } returns countryCode
}
fun givenFailsToParse(phoneNumber: String) {
every { instance.parse(phoneNumber, null) } throws NumberParseException(NumberParseException.ErrorType.NOT_A_NUMBER, "")
}
}