From eb144ac069275d9e34d24686769346234e232935 Mon Sep 17 00:00:00 2001 From: Kamil Owczarz Date: Tue, 12 Sep 2023 16:16:16 +0200 Subject: [PATCH 1/4] Rewrite LoginUtils to typescript --- src/libs/{LoginUtils.js => LoginUtils.ts} | 39 ++++++++--------------- 1 file changed, 14 insertions(+), 25 deletions(-) rename src/libs/{LoginUtils.js => LoginUtils.ts} (56%) diff --git a/src/libs/LoginUtils.js b/src/libs/LoginUtils.ts similarity index 56% rename from src/libs/LoginUtils.js rename to src/libs/LoginUtils.ts index fdf73ea236dc..2542c485d61c 100644 --- a/src/libs/LoginUtils.js +++ b/src/libs/LoginUtils.ts @@ -1,4 +1,3 @@ -import _ from 'underscore'; import Str from 'expensify-common/lib/str'; import Onyx from 'react-native-onyx'; import {PUBLIC_DOMAINS} from 'expensify-common/lib/CONST'; @@ -6,53 +5,44 @@ import {parsePhoneNumber} from 'awesome-phonenumber'; import CONST from '../CONST'; import ONYXKEYS from '../ONYXKEYS'; -let countryCodeByIP; +let countryCodeByIP: number; Onyx.connect({ key: ONYXKEYS.COUNTRY_CODE, - callback: (val) => (countryCodeByIP = val || 1), + callback: (val) => (countryCodeByIP = val ?? 1), }); /** * Remove the special chars from the phone number - * - * @param {String} phone - * @return {String} */ -function getPhoneNumberWithoutSpecialChars(phone) { +function getPhoneNumberWithoutSpecialChars(phone: string): string { return phone.replace(CONST.REGEX.SPECIAL_CHARS_WITHOUT_NEWLINE, ''); } /** * Append user country code to the phone number - * - * @param {String} phone - * @return {String} */ -function appendCountryCode(phone) { +function appendCountryCode(phone: string): string { return phone.startsWith('+') ? phone : `+${countryCodeByIP}${phone}`; } /** * Check email is public domain or not - * - * @param {String} email - * @return {Boolean} */ -function isEmailPublicDomain(email) { - const emailDomain = Str.extractEmailDomain(email); - return _.includes(PUBLIC_DOMAINS, emailDomain.toLowerCase(), false); +function isEmailPublicDomain(email: string): boolean { + const emailDomain = Str.extractEmailDomain(email).toLowerCase(); + // That's the place where it's being checked if a general string is included in the union + return (PUBLIC_DOMAINS as readonly string[]).includes(emailDomain); } /** * Check if number is valid - * @param {String} values - * @returns {String} - Returns valid phone number formatted + * @returns a valid phone number formatted */ -function validateNumber(values) { +function validateNumber(values: string): string { const parsedPhoneNumber = parsePhoneNumber(values); if (parsedPhoneNumber.possible && Str.isValidPhone(values.slice(0))) { - return parsedPhoneNumber.number.e164 + CONST.SMS.DOMAIN; + return parsedPhoneNumber.number?.e164 + CONST.SMS.DOMAIN; } return ''; @@ -60,11 +50,10 @@ function validateNumber(values) { /** * Check number is valid and attach country code - * @param {String} partnerUserID - * @returns {String} - Returns valid phone number with country code + * @returns a valid phone number with country code */ -function getPhoneLogin(partnerUserID) { - if (_.isEmpty(partnerUserID)) { +function getPhoneLogin(partnerUserID: string): string { + if (partnerUserID.length === 0) { return ''; } From c5245b44bb1e128ac2bd88fa480ab659e5b3022d Mon Sep 17 00:00:00 2001 From: Kamil Owczarz <91068263+kowczarz@users.noreply.github.com> Date: Fri, 15 Sep 2023 18:52:09 +0200 Subject: [PATCH 2/4] Update src/libs/LoginUtils.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fábio Henriques --- src/libs/LoginUtils.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libs/LoginUtils.ts b/src/libs/LoginUtils.ts index 2542c485d61c..32f6aece6f96 100644 --- a/src/libs/LoginUtils.ts +++ b/src/libs/LoginUtils.ts @@ -30,7 +30,6 @@ function appendCountryCode(phone: string): string { */ function isEmailPublicDomain(email: string): boolean { const emailDomain = Str.extractEmailDomain(email).toLowerCase(); - // That's the place where it's being checked if a general string is included in the union return (PUBLIC_DOMAINS as readonly string[]).includes(emailDomain); } From 104e1d0100ce707abe6cac0ed5c2ddcb2920afed Mon Sep 17 00:00:00 2001 From: Kamil Owczarz Date: Fri, 22 Sep 2023 15:04:42 +0200 Subject: [PATCH 3/4] Add login utils tests --- tests/unit/LoginUtilsTest.ts | 101 +++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 tests/unit/LoginUtilsTest.ts diff --git a/tests/unit/LoginUtilsTest.ts b/tests/unit/LoginUtilsTest.ts new file mode 100644 index 000000000000..e642588287d3 --- /dev/null +++ b/tests/unit/LoginUtilsTest.ts @@ -0,0 +1,101 @@ +import Onyx from "react-native-onyx"; +import ONYXKEYS from '../../src/ONYXKEYS'; +import waitForPromisesToResolve from '../utils/waitForPromisesToResolve'; +import { + appendCountryCode, getPhoneLogin, + getPhoneNumberWithoutSpecialChars, + isEmailPublicDomain, + validateNumber +} from '../../src/libs/LoginUtils' + +describe('LoginUtils', () => { + beforeAll(() => { + Onyx.init({ + keys: ONYXKEYS, + initialKeyStates: { + [ONYXKEYS.COUNTRY_CODE]: 1, + }, + }); + return waitForPromisesToResolve(); + }); + + afterEach(() => { + jest.useRealTimers(); + Onyx.clear(); + }); + describe('getPhoneNumberWithoutSpecialChars', () => { + it('Should return valid phone number', () =>{ + const givenPhone = '+12345678901' + const parsedPhone = getPhoneNumberWithoutSpecialChars(givenPhone) + expect(parsedPhone).toBe('+12345678901') + }) + it('Should return valid phone number even if received special chars', () =>{ + const givenPhone = '+1(234) 56-7\t8-9 01' + const parsedPhone = getPhoneNumberWithoutSpecialChars(givenPhone) + expect(parsedPhone).toBe('+12345678901') + }) + }) + describe('appendCountryCode', () => { + it('Should return valid phone number with country code when received a phone with country code', () =>{ + const givenPhone = '+12345678901' + const parsedPhone = appendCountryCode(givenPhone) + expect(parsedPhone).toBe('+12345678901') + }) + it('Should return valid phone number with country code when received a phone without country code', () =>{ + const givenPhone = '2345678901' + const parsedPhone = appendCountryCode(givenPhone) + expect(parsedPhone).toBe('+12345678901') + }) + }) + describe('isEmailPublicDomain', () => { + it('Should return true if email is from public domain', () =>{ + const givenEmail = 'test@gmail.com' + const parsedEmail = isEmailPublicDomain(givenEmail) + expect(parsedEmail).toBe(true) + }) + it('Should return false if email is not from public domain', () =>{ + const givenEmail = 'test@test.com' + const parsedEmail = isEmailPublicDomain(givenEmail) + expect(parsedEmail).toBe(false) + }) + it("Should return false if provided string isn't email", () =>{ + const givenEmail = 'test' + const parsedEmail = isEmailPublicDomain(givenEmail) + expect(parsedEmail).toBe(false) + }) + }) + describe('validateNumber', () => { + it("Should return valid phone number with '@expensify.sms' suffix if provided phone number is valid", () =>{ + const givenPhone = '+12345678901' + const parsedPhone = validateNumber(givenPhone) + expect(parsedPhone).toBe('+12345678901@expensify.sms') + }) + it('Should return empty string if provided phone number is not valid', () =>{ + const givenPhone = '786' + const parsedPhone = validateNumber(givenPhone) + expect(parsedPhone).toBe('') + }) + it('Should return empty string if provided phone number is empty', () =>{ + const givenPhone = '' + const parsedPhone = validateNumber(givenPhone) + expect(parsedPhone).toBe('') + }) + }) + describe('getPhoneLogin', () => { + it("Should return valid phone number with country code if provided phone number is valid and with country code", () =>{ + const givenPhone = '+12345678901' + const parsedPhone = getPhoneLogin(givenPhone) + expect(parsedPhone).toBe('+12345678901') + }) + it('Should return valid phone number with country code if provided phone number is valid and without country code', () =>{ + const givenPhone = '2345678901' + const parsedPhone = getPhoneLogin(givenPhone) + expect(parsedPhone).toBe('+12345678901') + }) + it('Should return empty string if provided phone number is empty', () =>{ + const givenPhone = '' + const parsedPhone = getPhoneLogin(givenPhone) + expect(parsedPhone).toBe('') + }) + }) +}) From 8f4994ec9a3a672c7e5cb23c16399f5076ce9680 Mon Sep 17 00:00:00 2001 From: Kamil Owczarz Date: Fri, 22 Sep 2023 15:07:56 +0200 Subject: [PATCH 4/4] Cleanup login utils tests --- tests/unit/LoginUtilsTest.js | 96 +++++++++++++++++++++++++++++++++ tests/unit/LoginUtilsTest.ts | 101 ----------------------------------- 2 files changed, 96 insertions(+), 101 deletions(-) create mode 100644 tests/unit/LoginUtilsTest.js delete mode 100644 tests/unit/LoginUtilsTest.ts diff --git a/tests/unit/LoginUtilsTest.js b/tests/unit/LoginUtilsTest.js new file mode 100644 index 000000000000..e49d710b8f49 --- /dev/null +++ b/tests/unit/LoginUtilsTest.js @@ -0,0 +1,96 @@ +import Onyx from 'react-native-onyx'; +import ONYXKEYS from '../../src/ONYXKEYS'; +import waitForBatchedUpdates from '../utils/waitForBatchedUpdates'; +import * as LoginUtils from '../../src/libs/LoginUtils'; + +describe('LoginUtils', () => { + beforeAll(() => { + Onyx.init({ + keys: ONYXKEYS, + initialKeyStates: { + [ONYXKEYS.COUNTRY_CODE]: 1, + }, + }); + return waitForBatchedUpdates(); + }); + + afterEach(() => { + jest.useRealTimers(); + Onyx.clear(); + }); + describe('getPhoneNumberWithoutSpecialChars', () => { + it('Should return valid phone number', () => { + const givenPhone = '+12345678901'; + const parsedPhone = LoginUtils.getPhoneNumberWithoutSpecialChars(givenPhone); + expect(parsedPhone).toBe('+12345678901'); + }); + it('Should return valid phone number even if received special chars', () => { + const givenPhone = '+1(234) 56-7\t8-9 01'; + const parsedPhone = LoginUtils.getPhoneNumberWithoutSpecialChars(givenPhone); + expect(parsedPhone).toBe('+12345678901'); + }); + }); + describe('appendCountryCode', () => { + it('Should return valid phone number with country code when received a phone with country code', () => { + const givenPhone = '+12345678901'; + const parsedPhone = LoginUtils.appendCountryCode(givenPhone); + expect(parsedPhone).toBe('+12345678901'); + }); + it('Should return valid phone number with country code when received a phone without country code', () => { + const givenPhone = '2345678901'; + const parsedPhone = LoginUtils.appendCountryCode(givenPhone); + expect(parsedPhone).toBe('+12345678901'); + }); + }); + describe('isEmailPublicDomain', () => { + it('Should return true if email is from public domain', () => { + const givenEmail = 'test@gmail.com'; + const parsedEmail = LoginUtils.isEmailPublicDomain(givenEmail); + expect(parsedEmail).toBe(true); + }); + it('Should return false if email is not from public domain', () => { + const givenEmail = 'test@test.com'; + const parsedEmail = LoginUtils.isEmailPublicDomain(givenEmail); + expect(parsedEmail).toBe(false); + }); + it("Should return false if provided string isn't email", () => { + const givenEmail = 'test'; + const parsedEmail = LoginUtils.isEmailPublicDomain(givenEmail); + expect(parsedEmail).toBe(false); + }); + }); + describe('validateNumber', () => { + it("Should return valid phone number with '@expensify.sms' suffix if provided phone number is valid", () => { + const givenPhone = '+12345678901'; + const parsedPhone = LoginUtils.validateNumber(givenPhone); + expect(parsedPhone).toBe('+12345678901@expensify.sms'); + }); + it('Should return empty string if provided phone number is not valid', () => { + const givenPhone = '786'; + const parsedPhone = LoginUtils.validateNumber(givenPhone); + expect(parsedPhone).toBe(''); + }); + it('Should return empty string if provided phone number is empty', () => { + const givenPhone = ''; + const parsedPhone = LoginUtils.validateNumber(givenPhone); + expect(parsedPhone).toBe(''); + }); + }); + describe('getPhoneLogin', () => { + it('Should return valid phone number with country code if provided phone number is valid and with country code', () => { + const givenPhone = '+12345678901'; + const parsedPhone = LoginUtils.getPhoneLogin(givenPhone); + expect(parsedPhone).toBe('+12345678901'); + }); + it('Should return valid phone number with country code if provided phone number is valid and without country code', () => { + const givenPhone = '2345678901'; + const parsedPhone = LoginUtils.getPhoneLogin(givenPhone); + expect(parsedPhone).toBe('+12345678901'); + }); + it('Should return empty string if provided phone number is empty', () => { + const givenPhone = ''; + const parsedPhone = LoginUtils.getPhoneLogin(givenPhone); + expect(parsedPhone).toBe(''); + }); + }); +}); diff --git a/tests/unit/LoginUtilsTest.ts b/tests/unit/LoginUtilsTest.ts deleted file mode 100644 index e642588287d3..000000000000 --- a/tests/unit/LoginUtilsTest.ts +++ /dev/null @@ -1,101 +0,0 @@ -import Onyx from "react-native-onyx"; -import ONYXKEYS from '../../src/ONYXKEYS'; -import waitForPromisesToResolve from '../utils/waitForPromisesToResolve'; -import { - appendCountryCode, getPhoneLogin, - getPhoneNumberWithoutSpecialChars, - isEmailPublicDomain, - validateNumber -} from '../../src/libs/LoginUtils' - -describe('LoginUtils', () => { - beforeAll(() => { - Onyx.init({ - keys: ONYXKEYS, - initialKeyStates: { - [ONYXKEYS.COUNTRY_CODE]: 1, - }, - }); - return waitForPromisesToResolve(); - }); - - afterEach(() => { - jest.useRealTimers(); - Onyx.clear(); - }); - describe('getPhoneNumberWithoutSpecialChars', () => { - it('Should return valid phone number', () =>{ - const givenPhone = '+12345678901' - const parsedPhone = getPhoneNumberWithoutSpecialChars(givenPhone) - expect(parsedPhone).toBe('+12345678901') - }) - it('Should return valid phone number even if received special chars', () =>{ - const givenPhone = '+1(234) 56-7\t8-9 01' - const parsedPhone = getPhoneNumberWithoutSpecialChars(givenPhone) - expect(parsedPhone).toBe('+12345678901') - }) - }) - describe('appendCountryCode', () => { - it('Should return valid phone number with country code when received a phone with country code', () =>{ - const givenPhone = '+12345678901' - const parsedPhone = appendCountryCode(givenPhone) - expect(parsedPhone).toBe('+12345678901') - }) - it('Should return valid phone number with country code when received a phone without country code', () =>{ - const givenPhone = '2345678901' - const parsedPhone = appendCountryCode(givenPhone) - expect(parsedPhone).toBe('+12345678901') - }) - }) - describe('isEmailPublicDomain', () => { - it('Should return true if email is from public domain', () =>{ - const givenEmail = 'test@gmail.com' - const parsedEmail = isEmailPublicDomain(givenEmail) - expect(parsedEmail).toBe(true) - }) - it('Should return false if email is not from public domain', () =>{ - const givenEmail = 'test@test.com' - const parsedEmail = isEmailPublicDomain(givenEmail) - expect(parsedEmail).toBe(false) - }) - it("Should return false if provided string isn't email", () =>{ - const givenEmail = 'test' - const parsedEmail = isEmailPublicDomain(givenEmail) - expect(parsedEmail).toBe(false) - }) - }) - describe('validateNumber', () => { - it("Should return valid phone number with '@expensify.sms' suffix if provided phone number is valid", () =>{ - const givenPhone = '+12345678901' - const parsedPhone = validateNumber(givenPhone) - expect(parsedPhone).toBe('+12345678901@expensify.sms') - }) - it('Should return empty string if provided phone number is not valid', () =>{ - const givenPhone = '786' - const parsedPhone = validateNumber(givenPhone) - expect(parsedPhone).toBe('') - }) - it('Should return empty string if provided phone number is empty', () =>{ - const givenPhone = '' - const parsedPhone = validateNumber(givenPhone) - expect(parsedPhone).toBe('') - }) - }) - describe('getPhoneLogin', () => { - it("Should return valid phone number with country code if provided phone number is valid and with country code", () =>{ - const givenPhone = '+12345678901' - const parsedPhone = getPhoneLogin(givenPhone) - expect(parsedPhone).toBe('+12345678901') - }) - it('Should return valid phone number with country code if provided phone number is valid and without country code', () =>{ - const givenPhone = '2345678901' - const parsedPhone = getPhoneLogin(givenPhone) - expect(parsedPhone).toBe('+12345678901') - }) - it('Should return empty string if provided phone number is empty', () =>{ - const givenPhone = '' - const parsedPhone = getPhoneLogin(givenPhone) - expect(parsedPhone).toBe('') - }) - }) -})