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

feat : Add Phone Number Module : [ATLAS-24] #1

Merged
merged 38 commits into from
Dec 6, 2023
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
e9973b5
add phone number module code
RgnDunes Oct 26, 2023
764e2b6
remove currency import
RgnDunes Oct 26, 2023
f664286
handle edge case
RgnDunes Oct 26, 2023
b9e0652
refactored regex
RgnDunes Oct 26, 2023
17445a0
revert: remove currency module
RgnDunes Oct 27, 2023
a6ee52e
feat: Add UT's for Phone number Module [ATLAS-23] (#4)
RgnDunes Nov 1, 2023
6a987f2
refactor code
RgnDunes Nov 1, 2023
e0ea2b0
refactor types
RgnDunes Nov 1, 2023
64dd4d9
refactor test cases
RgnDunes Nov 1, 2023
41b4c85
refactor test cases
RgnDunes Nov 1, 2023
2ef4db2
Merge origin/master
RgnDunes Nov 10, 2023
48a91c6
wrap phone functions with error boundries
RgnDunes Nov 10, 2023
636fa12
remove redundant file
RgnDunes Nov 10, 2023
d1cc70d
remove comment
RgnDunes Nov 16, 2023
2437533
Merge branch 'master' of github.com:razorpay/i18nify into phone-numbe…
tarun-khanna Nov 17, 2023
e30e571
add parsePhoneNumber
RgnDunes Nov 20, 2023
eab9c10
Merge remote-tracking branch 'origin/master' into phone-number-module
RgnDunes Nov 20, 2023
8bb554f
Merge remote-tracking branch 'origin/phone-number-module' into phone-…
RgnDunes Nov 20, 2023
b1a0544
refactor regex
RgnDunes Nov 20, 2023
a759eeb
refactor code
RgnDunes Nov 20, 2023
13f010a
extend country code support and refactor api contract for phone numbe…
RgnDunes Nov 27, 2023
4f7c6f7
rename validatePhoneNumber to isValidPhoneNumber
RgnDunes Nov 27, 2023
6f244b5
add UT
RgnDunes Nov 27, 2023
5612f03
resolve review comments
RgnDunes Nov 28, 2023
4659a99
revert yarn.lock changes
RgnDunes Nov 28, 2023
7f2e817
Merge remote-tracking branch 'origin/master' into phone-number-module
RgnDunes Nov 28, 2023
9472398
fix lint errors
RgnDunes Dec 5, 2023
1937131
change detectCountryCodeFromDialCode logic
RgnDunes Dec 5, 2023
937107a
fix test cases
RgnDunes Dec 5, 2023
bb04c19
fix lint issue
RgnDunes Dec 5, 2023
b394243
fix lint issue
RgnDunes Dec 5, 2023
f020356
fix lint issue
RgnDunes Dec 5, 2023
8149d33
fix lint issue
RgnDunes Dec 5, 2023
147ba3a
fix lint issue
RgnDunes Dec 5, 2023
5f87c74
resolve review comments
RgnDunes Dec 6, 2023
042af09
add console in error boundary
RgnDunes Dec 6, 2023
ade2656
remove ternary
RgnDunes Dec 6, 2023
a3af1fd
remove unused import
RgnDunes Dec 6, 2023
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
43 changes: 43 additions & 0 deletions src/modules/phoneNumber/__tests__/cleanPhoneNumber.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { cleanPhoneNumber } from '../utils';

describe('cleanPhoneNumber', () => {
it('should remove non-numeric characters from a phone number', () => {
const phoneNumber = '+1 (123)-456-7890'; // Phone number with various non-numeric characters

const cleanedNumber = cleanPhoneNumber(phoneNumber);

expect(cleanedNumber).toBe('+11234567890'); // Expecting only numeric characters and '+' at the start
});

it('should handle an already clean phone number without non-numeric characters', () => {
const phoneNumber = '+9876543210'; // Clean phone number without non-numeric characters

const cleanedNumber = cleanPhoneNumber(phoneNumber);

expect(cleanedNumber).toBe('+9876543210'); // Expecting no change in the phone number
});

it('should handle an empty phone number string', () => {
const phoneNumber = '';

const cleanedNumber = cleanPhoneNumber(phoneNumber);

expect(cleanedNumber).toBe('');
});

it('should handle a phone number starting with non-numeric characters', () => {
const phoneNumber = 'abc+123456789'; // Phone number starting with non-numeric characters

const cleanedNumber = cleanPhoneNumber(phoneNumber);

expect(cleanedNumber).toBe('123456789'); // Expecting non-numeric characters at the start to be removed, will also remove + as it is not the starting character
});

it('should handle a phone number with only non-numeric characters', () => {
const phoneNumber = '---'; // Phone number with only non-numeric characters

const cleanedNumber = cleanPhoneNumber(phoneNumber);

expect(cleanedNumber).toBe('');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { detectCountryCodeFromDialCode } from '../utils';

describe('detectCountryCodeFromDialCode', () => {
it('should detect country code for valid phone numbers', () => {
expect(detectCountryCodeFromDialCode('+919876543210')).toBe('IN');
expect(detectCountryCodeFromDialCode('60123456789')).toBe('MY');
expect(detectCountryCodeFromDialCode('+12125551234')).toBe('US');
});

it('should throw an error for invalid phone numbers', () => {
expect(() => detectCountryCodeFromDialCode('123')).toThrowError(
'Unable to detect `country code` from phone number.',
);
expect(() => detectCountryCodeFromDialCode('invalidNumber')).toThrowError(
'Unable to detect `country code` from phone number.',
);
});
});
34 changes: 34 additions & 0 deletions src/modules/phoneNumber/__tests__/formatPhoneNumber.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { describe, expect, it } from '@jest/globals';
import formatPhoneNumber from '../formatPhoneNumber';

describe('formatPhoneNumber', () => {
it('should format an Indian phone number', () => {
const phoneNumber = '+917394926646';
const countryCode = 'IN';
const formatted = formatPhoneNumber(phoneNumber, countryCode);
expect(formatted).toBe('+91 7394 926646');
tarun-khanna marked this conversation as resolved.
Show resolved Hide resolved
});

it('should format a Malaysian phone number', () => {
const phoneNumber = '+60123456789';
const countryCode = 'MY';
const formatted = formatPhoneNumber(phoneNumber, countryCode);
expect(formatted).toBe('+60 12 34567 89');
});

it('should handle a missing country code', () => {
const phoneNumber = '1234567890';
const countryCode = 'XYZ';
expect(() => formatPhoneNumber(phoneNumber, countryCode)).toThrow(
'Parameter `countryCode` is invalid!',
);
});

it('should handle a missing phoneNumber', () => {
const phoneNumber = '';
const countryCode = 'MY';
expect(() => formatPhoneNumber(phoneNumber, countryCode)).toThrow(
'Parameter `phoneNumber` is invalid!',
);
});
});
47 changes: 47 additions & 0 deletions src/modules/phoneNumber/__tests__/isValidPhoneNumber.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { describe, expect, it } from '@jest/globals';
tarun-khanna marked this conversation as resolved.
Show resolved Hide resolved
import isValidPhoneNumber from '../isValidPhoneNumber';

describe('isValidPhoneNumber', () => {
it('should validate a valid Indian phone number', () => {
tarun-khanna marked this conversation as resolved.
Show resolved Hide resolved
const phoneNumber = '+917394926646';
const countryCode = 'IN';
const isValid = isValidPhoneNumber(phoneNumber, countryCode);
expect(isValid).toBe(true);
});

it('should validate a valid Malaysian phone number', () => {
const phoneNumber = '+60123456789';
const countryCode = 'MY';
const isValid = isValidPhoneNumber(phoneNumber, countryCode);
expect(isValid).toBe(true);
});

it('should reject an invalid Indian phone number', () => {
const phoneNumber = '1234'; // Invalid Indian number
const countryCode = 'IN';
const isValid = isValidPhoneNumber(phoneNumber, countryCode);
expect(isValid).toBe(false);
});

it('should reject an invalid Malaysian phone number', () => {
const phoneNumber = '60123'; // Invalid Malaysian number
const countryCode = 'MY';
const isValid = isValidPhoneNumber(phoneNumber, countryCode);
expect(isValid).toBe(false);
});

it('should handle a missing country code', () => {
const phoneNumber = '1234567890';
const countryCode = 'XYZ';
const isValid = isValidPhoneNumber(phoneNumber, countryCode);
expect(isValid).toBe(false);
});

it('should handle a missing phoneNumber', () => {
const phoneNumber = '';
const countryCode = 'MY';
expect(() => isValidPhoneNumber(phoneNumber, countryCode)).toThrow(
'Parameter `phoneNumber` is invalid!',
);
});
});
50 changes: 50 additions & 0 deletions src/modules/phoneNumber/__tests__/parsePhoneNumber.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import parsePhoneNumber from '../parsePhoneNumber';

describe('parsePhoneNumber function', () => {
it('should correctly parse a valid phone number with country code', () => {
const phoneNumber = '+15853042806';
const country = 'US';

const parsedInfo = parsePhoneNumber(phoneNumber, country);

expect(parsedInfo).toEqual({
countryCode: 'US',
dialCode: '+1',
formattedPhoneNumber: '+1 585-304-2806',
formatTemplate: 'xxx-xxx-xxxx',
});
});

it('should correctly parse a valid phone number without specifying country', () => {
const phoneNumber = '+447123456789';

const parsedInfo = parsePhoneNumber(phoneNumber);

expect(parsedInfo.countryCode).toBeDefined();
tarun-khanna marked this conversation as resolved.
Show resolved Hide resolved
expect(parsedInfo.dialCode).toBeDefined();
expect(parsedInfo.formattedPhoneNumber).toBeDefined();
expect(parsedInfo.formatTemplate).toBeDefined();
});

it('should throw an error for an invalid phone number', () => {
tarun-khanna marked this conversation as resolved.
Show resolved Hide resolved
const phoneNumber = '+1969123456789';

expect(() => parsePhoneNumber(phoneNumber)).toThrow(
'Unable to detect `country code` from phone number.',
);
});

it('should correctly parse a valid phone number with different country code', () => {
tarun-khanna marked this conversation as resolved.
Show resolved Hide resolved
const phoneNumber = '+61412123123'; // Australian phone number
const country = 'AU'; // Expected country code

const parsedInfo = parsePhoneNumber(phoneNumber, country);

expect(parsedInfo).toEqual({
countryCode: 'AU',
formattedPhoneNumber: '+6 1412 123 123',
dialCode: '+6',
formatTemplate: 'xxxx xxx xxx',
});
});
});
131 changes: 131 additions & 0 deletions src/modules/phoneNumber/data/phoneFormatterMapper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
export const PHONE_FORMATTER_MAPPER: { [key: string]: string } = {
IN: 'xxxx xxxxxx',
tarun-khanna marked this conversation as resolved.
Show resolved Hide resolved
MY: 'xx xxxxx xx',
AE: 'xx xxx xxxx',
AL: 'xxx xx xxxx',
AM: 'xx xx xx xx',
AR: 'xxxx-xxxx',
AU: 'xxxx xxx xxx',
AW: 'xxx-xxxx',
BB: 'xxx-xxxx',
BD: 'xxxx-xxxxxx',
BM: 'xxx-xxxx',
BN: 'xxxx-xxxx',
BO: 'xxxx-xxxx',
BS: 'xxx-xxxx',
BW: 'xx xxxx xxxx',
BZ: 'xxx-xxxx',
CA: 'xxx-xxx-xxxx',
CH: 'xxx xxx xxx',
CN: 'xxxx-xxxxxxx',
CO: 'xxxx-xxxxxxx',
CR: 'xxxx-xxxx',
CU: 'xxxx-xxxx',
CZ: 'xxx xxx xxx',
DK: 'xx xx xx xx',
DO: 'xxx-xxxxxxx',
DZ: 'xxxx-xxxx-xxx',
EG: 'xx xxx xxxx',
ET: 'xx xxx xxxx',
EU: 'xxx xx xx xx',
FJ: 'xxxx xxxx',
GB: 'xxxx xxx xxx',
GH: 'xxx xxx xxxx',
GI: 'xxxx xxxx',
GM: 'xxxx-xxxx',
GT: 'xxxx-xxxx',
GY: 'xxx-xxxx',
HK: 'xxxx xxxx',
HN: 'xxxx-xxxx',
HR: 'xxx xxx xxxx',
HT: 'xxx-xxxx',
HU: 'xxx xxx xxxx',
ID: 'xxxx-xxxx-xxxx',
IL: 'xxxx-xxx-xxx',
JM: 'xxx-xxxx',
KE: 'xxx xxxxxx',
KG: 'xxx-xx-xx-xx',
KH: 'xxx-xxx-xxx',
KY: 'xxx-xxxx',
KZ: 'xxx-xxx-xx-xx',
LA: 'xxx xx xxxx',
LK: 'xx xxx xxxx',
LR: 'xxx-xxx-xxxx',
LS: 'xxx xx xxxx',
LT: 'xxx xxxxx',
LU: 'xxx xx xxx',
LV: 'xxxx xxxx',
MA: 'xxxx-xxxxxx',
MD: 'xx xxxxxx',
ME: 'xx xxxxxx',
MG: 'xx xx xx xx xx',
MK: 'xx xx xx xx',
MM: 'xx xxxxxx',
MN: 'xxx-xx-xxxx',
MO: 'xxxx xxxx',
MU: 'xx xxxx xxxx',
MV: 'xxxxxx',
MW: 'xx xxxx xxxx',
MX: 'xxx-xxx-xxxx',
MZ: 'xx xxxxxxx',
NA: 'xx xxxx xxxx',
NG: 'xxx xxx xxxx',
NI: 'xxxx-xxxx',
NL: 'xxx-xxxxxxx',
NO: 'xxxx xxxx',
NP: 'xxxx-xxxxxxx',
NZ: 'xxx-xxxxxxx',
OM: 'xxxx-xxxx',
PA: 'xxx-xxxx',
PE: 'xxx-xxx-xxx',
PG: 'xxx-xxxxxx',
PH: 'xxx-xxxx',
PK: 'xxx-xxxxxxx',
PL: 'xxx xxx xxx',
PR: 'xxx-xxx-xxxx',
PS: 'xxxx-xxxxxxx',
PT: 'xxx xxx xxx',
PY: 'xxx-xxxxxx',
QA: 'xxxx xxxx',
RO: 'xxx xxx xxxx',
RS: 'xxx xxxxx',
RU: 'xxx xxx-xx-xx',
RW: 'xxx xxxxxx',
SA: 'xxx-xxxxxxx',
SC: 'xx xxxxx',
SE: 'xxx-xxx xx xx',
SG: 'xxxx xxxx',
SI: 'xx xxxxxx',
SK: 'xxx xxx xxx',
SL: 'xxx-xxxxxx',
SM: 'xxxxx xxxxx',
SN: 'xx xxx xx xx',
SO: 'xxx xxxxxxx',
SR: 'xxx-xxxx',
SS: 'xxx xxxx xxx',
SV: 'xxxx-xxxx',
SZ: 'xxx xx xxxx',
TG: 'xx xx xx xx',
TH: 'xxx-xxxxxxx',
TJ: 'xxx xx xx xx',
TL: 'xxx-xxxxxxx',
TN: 'xx xxxxxx',
TR: 'xxx xxx xx xx',
TT: 'xxx-xxxx',
TW: 'xxxx-xxxxxx',
TZ: 'xxx xxx xxxx',
UA: 'xx xxx xx xx',
UG: 'xxx xxxxxxx',
US: 'xxx-xxx-xxxx',
UY: 'xxx-xxxxx',
UZ: 'xxx-xxx-xx-xx',
VC: 'xxx-xxxx',
VE: 'xxxx-xxx-xxxx',
VN: 'xxxx-xxxxxxx',
YE: 'xxxx-xxxx',
ZA: 'xxx-xxx-xxxx',
ZM: 'xxx-xxxxxxx',
ZW: 'xx xxx xxxx',
KW: 'xxx xx xxxx',
BH: 'xxxx xxxx',
};
Loading
Loading