1+ const validatePhoneNumber = require ( '../../utils/validatePhoneNumber' ) ;
2+
3+ describe ( 'validatePhoneNumber' , ( ) => {
4+ let mockHelpers ;
5+
6+ beforeEach ( ( ) => {
7+ // Clear all mocks before each test
8+ jest . clearAllMocks ( ) ;
9+
10+ // Mock Joi helpers
11+ mockHelpers = {
12+ error : jest . fn ( ( code ) => ( { code, message : `Validation error: ${ code } ` } ) )
13+ } ;
14+ } ) ;
15+
16+ describe ( 'Valid phone numbers' , ( ) => {
17+ it ( 'should accept valid US/Canada phone numbers with exactly 10 digits after +1' , ( ) => {
18+ const validNumbers = [
19+ '+12345678901' ,
20+ '+15551234567' ,
21+ '+19876543210' ,
22+ '+11234567890'
23+ ] ;
24+
25+ validNumbers . forEach ( number => {
26+ const result = validatePhoneNumber ( number , mockHelpers ) ;
27+
28+ expect ( result ) . toBe ( number ) ;
29+ expect ( mockHelpers . error ) . not . toHaveBeenCalled ( ) ;
30+ } ) ;
31+ } ) ;
32+
33+ it ( 'should reject phone numbers with less than or more than 10 digits after +1' , ( ) => {
34+ const invalidNumbers = [
35+ '+123456789' , // 9 digits
36+ '+123456789012' , // 12 digits
37+ '+1' , // only +1
38+ '+12' , // only +1 and 1 digit
39+ '+123' , // only +1 and 2 digits
40+ '+1234' , // only +1 and 3 digits
41+ '+12345' , // only +1 and 4 digits
42+ '+123456' , // only +1 and 5 digits
43+ '+1234567' , // only +1 and 6 digits
44+ '+12345678' , // only +1 and 7 digits
45+ '+123456789' // only +1 and 9 digits
46+ ] ;
47+
48+ invalidNumbers . forEach ( number => {
49+ const result = validatePhoneNumber ( number , mockHelpers ) ;
50+
51+ expect ( result ) . toEqual ( { code : 'any.invalid' , message : 'Validation error: any.invalid' } ) ;
52+ expect ( mockHelpers . error ) . toHaveBeenCalledWith ( 'any.invalid' ) ;
53+ } ) ;
54+ } ) ;
55+ } ) ;
56+
57+ describe ( 'Invalid phone numbers' , ( ) => {
58+ it ( 'should reject phone numbers that do not start with +' , ( ) => {
59+ const invalidNumbers = [
60+ '1234567890' ,
61+ '1555123456' ,
62+ '1987654321' ,
63+ '1123456789'
64+ ] ;
65+
66+ invalidNumbers . forEach ( number => {
67+ const result = validatePhoneNumber ( number , mockHelpers ) ;
68+
69+ expect ( result ) . toEqual ( { code : 'any.invalid' , message : 'Validation error: any.invalid' } ) ;
70+ expect ( mockHelpers . error ) . toHaveBeenCalledWith ( 'any.invalid' ) ;
71+ } ) ;
72+ } ) ;
73+
74+ it ( 'should reject phone numbers that do not start with +1' , ( ) => {
75+ const invalidNumbers = [
76+ '+21234567890' , // +2
77+ '+31234567890' , // +3
78+ '+41234567890' , // +4
79+ '+51234567890' , // +5
80+ '+61234567890' , // +6
81+ '+71234567890' , // +7
82+ '+81234567890' , // +8
83+ '+91234567890' // +9
84+ ] ;
85+
86+ invalidNumbers . forEach ( number => {
87+ const result = validatePhoneNumber ( number , mockHelpers ) ;
88+
89+ expect ( result ) . toEqual ( { code : 'any.invalid' , message : 'Validation error: any.invalid' } ) ;
90+ expect ( mockHelpers . error ) . toHaveBeenCalledWith ( 'any.invalid' ) ;
91+ } ) ;
92+ } ) ;
93+
94+ it ( 'should reject phone numbers with non-digit characters after +1' , ( ) => {
95+ const invalidNumbers = [
96+ '+1a23456789' ,
97+ '+1-234-567-8900' ,
98+ '+1 (234) 567-8900' ,
99+ '+1.234.567.8900' ,
100+ '+1_234_567_8900' ,
101+ '+1 234 567 8900'
102+ ] ;
103+
104+ invalidNumbers . forEach ( number => {
105+ const result = validatePhoneNumber ( number , mockHelpers ) ;
106+
107+ expect ( result ) . toEqual ( { code : 'any.invalid' , message : 'Validation error: any.invalid' } ) ;
108+ expect ( mockHelpers . error ) . toHaveBeenCalledWith ( 'any.invalid' ) ;
109+ } ) ;
110+ } ) ;
111+
112+ it ( 'should reject phone numbers that are too short' , ( ) => {
113+ const invalidNumbers = [
114+ '+1' , // Only +1, no digits
115+ '+' , // Only +
116+ '' // Empty string
117+ ] ;
118+
119+ invalidNumbers . forEach ( number => {
120+ const result = validatePhoneNumber ( number , mockHelpers ) ;
121+
122+ expect ( result ) . toEqual ( { code : 'any.invalid' , message : 'Validation error: any.invalid' } ) ;
123+ expect ( mockHelpers . error ) . toHaveBeenCalledWith ( 'any.invalid' ) ;
124+ } ) ;
125+ } ) ;
126+ } ) ;
127+
128+ describe ( 'Edge cases' , ( ) => {
129+ it ( 'should handle null and undefined values' , ( ) => {
130+ const invalidValues = [ null , undefined ] ;
131+
132+ invalidValues . forEach ( value => {
133+ const result = validatePhoneNumber ( value , mockHelpers ) ;
134+
135+ expect ( result ) . toEqual ( { code : 'any.invalid' , message : 'Validation error: any.invalid' } ) ;
136+ expect ( mockHelpers . error ) . toHaveBeenCalledWith ( 'any.invalid' ) ;
137+ } ) ;
138+ } ) ;
139+
140+ it ( 'should handle non-string values' , ( ) => {
141+ const invalidValues = [ 123 , { } , [ ] , true , false ] ;
142+
143+ invalidValues . forEach ( value => {
144+ const result = validatePhoneNumber ( value , mockHelpers ) ;
145+
146+ expect ( result ) . toEqual ( { code : 'any.invalid' , message : 'Validation error: any.invalid' } ) ;
147+ expect ( mockHelpers . error ) . toHaveBeenCalledWith ( 'any.invalid' ) ;
148+ } ) ;
149+ } ) ;
150+
151+ it ( 'should handle strings with leading/trailing whitespace' , ( ) => {
152+ const invalidNumbers = [
153+ ' +1234567890' ,
154+ '+1234567890 ' ,
155+ ' +1234567890 ' ,
156+ '\t+1234567890' ,
157+ '+1234567890\n'
158+ ] ;
159+
160+ invalidNumbers . forEach ( number => {
161+ const result = validatePhoneNumber ( number , mockHelpers ) ;
162+
163+ expect ( result ) . toEqual ( { code : 'any.invalid' , message : 'Validation error: any.invalid' } ) ;
164+ expect ( mockHelpers . error ) . toHaveBeenCalledWith ( 'any.invalid' ) ;
165+ } ) ;
166+ } ) ;
167+ } ) ;
168+
169+ describe ( 'Function behavior' , ( ) => {
170+ it ( 'should return the original value for valid phone numbers' , ( ) => {
171+ const validNumber = '+12345678901' ;
172+ const result = validatePhoneNumber ( validNumber , mockHelpers ) ;
173+
174+ expect ( result ) . toBe ( validNumber ) ;
175+ expect ( typeof result ) . toBe ( 'string' ) ;
176+ } ) ;
177+
178+ it ( 'should call helpers.error with correct error code for invalid numbers' , ( ) => {
179+ const invalidNumber = '1234567890' ;
180+
181+ validatePhoneNumber ( invalidNumber , mockHelpers ) ;
182+
183+ expect ( mockHelpers . error ) . toHaveBeenCalledTimes ( 1 ) ;
184+ expect ( mockHelpers . error ) . toHaveBeenCalledWith ( 'any.invalid' ) ;
185+ } ) ;
186+
187+ it ( 'should return error object from helpers.error for invalid numbers' , ( ) => {
188+ const invalidNumber = '1234567890' ;
189+ const result = validatePhoneNumber ( invalidNumber , mockHelpers ) ;
190+
191+ expect ( result ) . toEqual ( { code : 'any.invalid' , message : 'Validation error: any.invalid' } ) ;
192+ } ) ;
193+ } ) ;
194+ } ) ;
0 commit comments