@@ -29,6 +29,12 @@ static void test_is_valid_user_name_nok_empty(MAYBE_UNUSED void ** _1);
2929static void test_is_valid_user_name_nok_numeric (MAYBE_UNUSED void * * _1 );
3030static void test_is_valid_user_name_nok_otherchars (MAYBE_UNUSED void * * _1 );
3131static void test_is_valid_user_name_long (MAYBE_UNUSED void * * _1 );
32+ static void test_is_valid_upn_ok (MAYBE_UNUSED void * * _1 );
33+ static void test_is_valid_upn_nok_not_upn (MAYBE_UNUSED void * * _1 );
34+ static void test_is_valid_upn_nok_structure (MAYBE_UNUSED void * * _1 );
35+ static void test_is_valid_upn_nok_domain (MAYBE_UNUSED void * * _1 );
36+ static void test_is_valid_upn_ok_limits (MAYBE_UNUSED void * * _1 );
37+ static void test_is_valid_upn_nok_limits (MAYBE_UNUSED void * * _1 );
3238
3339
3440int
@@ -44,6 +50,12 @@ main(void)
4450 cmocka_unit_test (test_is_valid_user_name_nok_numeric ),
4551 cmocka_unit_test (test_is_valid_user_name_nok_otherchars ),
4652 cmocka_unit_test (test_is_valid_user_name_long ),
53+ cmocka_unit_test (test_is_valid_upn_ok ),
54+ cmocka_unit_test (test_is_valid_upn_nok_not_upn ),
55+ cmocka_unit_test (test_is_valid_upn_nok_structure ),
56+ cmocka_unit_test (test_is_valid_upn_nok_domain ),
57+ cmocka_unit_test (test_is_valid_upn_ok_limits ),
58+ cmocka_unit_test (test_is_valid_upn_nok_limits ),
4759 };
4860
4961 return cmocka_run_group_tests (tests , NULL , NULL );
@@ -147,3 +159,123 @@ test_is_valid_user_name_long(MAYBE_UNUSED void ** _1)
147159
148160 free (name );
149161}
162+
163+
164+ static void
165+ test_is_valid_upn_ok (MAYBE_UNUSED void * * _1 )
166+ {
167+ assert_true (is_valid_upn ("user@example.com" ));
168+ assert_true (is_valid_upn ("john.doe@corp.example.org" ));
169+ assert_true (is_valid_upn ("test@sub.domain.net" ));
170+ assert_true (is_valid_upn ("a@b.c" ));
171+ assert_true (is_valid_upn ("user123@test123.example" ));
172+ assert_true (is_valid_upn ("user_name@example-domain.com" ));
173+ assert_true (is_valid_upn ("test.user@example.domain.org" ));
174+ }
175+
176+
177+ static void
178+ test_is_valid_upn_nok_not_upn (MAYBE_UNUSED void * * _1 )
179+ {
180+ assert_true (false == is_valid_upn ("regularuser" ));
181+ assert_true (false == is_valid_upn ("user.name" ));
182+ assert_true (false == is_valid_upn ("user_name" ));
183+ assert_true (false == is_valid_upn ("123user" ));
184+ assert_true (false == is_valid_upn ("USER" ));
185+ }
186+
187+
188+ static void
189+ test_is_valid_upn_nok_structure (MAYBE_UNUSED void * * _1 )
190+ {
191+ // Empty parts
192+ assert_true (false == is_valid_upn ("@domain.com" ));
193+ assert_true (false == is_valid_upn ("user@" ));
194+ assert_true (false == is_valid_upn ("@" ));
195+
196+ // Multiple @ symbols
197+ assert_true (false == is_valid_upn ("user@domain@com" ));
198+ assert_true (false == is_valid_upn ("@@domain.com" ));
199+ assert_true (false == is_valid_upn ("user@@domain.com" ));
200+
201+ // Empty string
202+ assert_true (false == is_valid_upn ("" ));
203+
204+ // Invalid suffix
205+ assert_true (false == is_valid_upn ("-user@domain.com" ));
206+ assert_true (false == is_valid_upn ("123@domain.com" ));
207+ assert_true (false == is_valid_upn ("user space@domain.com" ));
208+ }
209+
210+
211+ static void
212+ test_is_valid_upn_nok_domain (MAYBE_UNUSED void * * _1 )
213+ {
214+ // Invalid domain formats
215+ assert_true (false == is_valid_upn ("user@domain" ));
216+ assert_true (false == is_valid_upn ("user@.domain.com" ));
217+ assert_true (false == is_valid_upn ("user@domain.com." ));
218+ assert_true (false == is_valid_upn ("user@domain..com" ));
219+ assert_true (false == is_valid_upn ("user@sub." ));
220+
221+ // Invalid domain characters
222+ assert_true (false == is_valid_upn ("user@domain_name.com" ));
223+ assert_true (false == is_valid_upn ("user@domain name.com" ));
224+ }
225+
226+
227+ static void
228+ test_is_valid_upn_ok_limits (MAYBE_UNUSED void * * _1 )
229+ {
230+ char * upn ;
231+ char * domain ;
232+
233+ // Test domain at maximum allowed length (253 chars)
234+ domain = malloc_T (253 + 1 , char );
235+ assert_true (domain != NULL );
236+ strcpy (domain ,
237+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." // 63 a's + dot
238+ "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb." // 63 b's + dot
239+ "ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc." // 63 c's + dot
240+ "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddd." // 58 d's + dot
241+ "co" ); // 2
242+ // Total: 63 + 1 + 63 + 1 + 63 + 1 + 58 + 1 + 2 = 253 chars
243+
244+ upn = malloc_T (5 + 253 + 1 , char ); // "user@" + domain + '\0'
245+ assert_true (upn != NULL );
246+ strcpy (upn , "user@" );
247+ strcat (upn , domain );
248+ assert_true (is_valid_upn (upn ));
249+
250+ free (upn );
251+ free (domain );
252+ }
253+
254+
255+ static void
256+ test_is_valid_upn_nok_limits (MAYBE_UNUSED void * * _1 )
257+ {
258+ char * upn ;
259+ char * domain ;
260+
261+ // Test domain exceeding maximum length (254 chars)
262+ domain = malloc_T (254 + 1 , char );
263+ assert_true (domain != NULL );
264+ memset (domain , 'a' , 251 );
265+ strcpy (& domain [251 ], ".co" );
266+ domain [254 ] = '\0' ;
267+
268+ upn = malloc_T (5 + 254 + 1 , char ); // "user@" + domain + '\0'
269+ assert_true (upn != NULL );
270+ strcpy (upn , "user@" );
271+ strcat (upn , domain );
272+ assert_true (false == is_valid_upn (upn ));
273+
274+ free (upn );
275+ free (domain );
276+
277+ // Domain label too long (>63 chars)
278+ assert_true (false == is_valid_upn ("user@"
279+ "verylongdomainlabelthatexceedssixtythreecharacterslimitsetbyRFC1035"
280+ ".com" ));
281+ }
0 commit comments