@@ -25,9 +25,19 @@ const resetTestData = async ({ api, cleanupOnly = false }: { api?: any; cleanupO
2525 // This is needed because those tests will modify this data and running them a second time would trigger different code paths
2626 const connection = await MongoClient . connect ( constants . URL_MONGODB ) ;
2727
28- const usernamesToDelete = [ Users . userForSamlMerge , Users . userForSamlMerge2 , Users . samluser1 , Users . samluser2 , Users . samluser4 ] . map (
29- ( { data : { username } } ) => username ,
30- ) ;
28+ const usernamesToDelete = [
29+ ...[
30+ Users . userForSamlMerge ,
31+ Users . userForSamlMerge2 ,
32+ Users . samluser1 ,
33+ Users . samluser2 ,
34+ Users . samluser4 ,
35+ Users . samlusernoname ,
36+ Users . samlusernoname2 ,
37+ ] . map ( ( { data : { username } } ) => username ) ,
38+ 'custom_saml_username' ,
39+ 'custom_saml_username2' ,
40+ ] ;
3141 await connection
3242 . db ( )
3343 . collection ( 'users' )
@@ -50,6 +60,7 @@ const resetTestData = async ({ api, cleanupOnly = false }: { api?: any; cleanupO
5060
5161 const settings = [
5262 { _id : 'Accounts_AllowAnonymousRead' , value : false } ,
63+ { _id : 'Accounts_AllowUsernameChange' , value : true } ,
5364 { _id : 'SAML_Custom_Default_logout_behaviour' , value : 'SAML' } ,
5465 { _id : 'SAML_Custom_Default_immutable_property' , value : 'EMail' } ,
5566 { _id : 'SAML_Custom_Default_mail_overwrite' , value : false } ,
@@ -229,6 +240,27 @@ test.describe('SAML', () => {
229240 } ) ;
230241 } ;
231242
243+ const doLoginStepWithUsernameSelection = async ( page : Page , username : string ) => {
244+ await test . step ( 'expect successful login without username to show username selection screen' , async ( ) => {
245+ await poRegistration . btnLoginWithSaml . click ( ) ;
246+ // Redirect to Idp
247+ await expect ( page ) . toHaveURL ( / .* \/ s i m p l e s a m l \/ m o d u l e .p h p \/ c o r e \/ l o g i n u s e r p a s s .p h p .* / ) ;
248+
249+ // Fill username and password
250+ await page . getByLabel ( 'Username' ) . fill ( username ) ;
251+ await page . getByLabel ( 'Password' ) . fill ( 'password' ) ;
252+ await page . locator ( 'role=button[name="Login"]' ) . click ( ) ;
253+
254+ // Should redirect to username selection screen
255+ await expect ( poRegistration . username ) . toBeVisible ( ) ;
256+ } ) ;
257+ } ;
258+
259+ const doUsernameSelection = async ( customUsername : string ) => {
260+ await poRegistration . username . fill ( customUsername ) ;
261+ await poRegistration . btnRegisterConfirmUsername . click ( ) ;
262+ } ;
263+
232264 const doLogoutStep = async ( page : Page ) => {
233265 await test . step ( 'logout' , async ( ) => {
234266 await page . getByRole ( 'button' , { name : 'User menu' } ) . click ( ) ;
@@ -465,6 +497,64 @@ test.describe('SAML', () => {
465497 await page2 . close ( ) ;
466498 } ) ;
467499
500+ test ( 'Login - User without username can set initial username during first login' , async ( { page, api } ) => {
501+ await doLoginStepWithUsernameSelection ( page , 'samlusernoname2' ) ;
502+
503+ await test . step ( 'expect to be redirected to the username selection page and set the username' , async ( ) => {
504+ await expect ( poRegistration . btnRegisterConfirmUsername ) . toBeVisible ( ) ;
505+ await doUsernameSelection ( 'custom_saml_username2' ) ;
506+ } ) ;
507+
508+ await test . step ( 'expect to be redirected to the homepage after succesful login' , async ( ) => {
509+ await expect ( page ) . toHaveURL ( '/home' ) ;
510+ await expect ( page . getByRole ( 'button' , { name : 'User menu' } ) ) . toBeVisible ( ) ;
511+ } ) ;
512+
513+ await test . step ( 'expect user data to have been created with custom username' , async ( ) => {
514+ const user = await getUserInfo ( api , 'custom_saml_username2' ) ;
515+
516+ expect ( user ) . toBeDefined ( ) ;
517+ expect ( user ?. username ) . toBe ( 'custom_saml_username2' ) ;
518+ expect ( user ?. name ) . toBe ( 'Saml User No Username 2' ) ;
519+ expect ( user ?. emails ) . toBeDefined ( ) ;
520+ expect ( user ?. emails ?. [ 0 ] . address ) . toBe ( 'samlusernoname2@example.com' ) ;
521+ } ) ;
522+ } ) ;
523+
524+ test . describe ( 'Login - Username selection when allow username change is disabled' , ( ) => {
525+ test . beforeAll ( async ( { api } ) => {
526+ await expect ( ( await setSettingValueById ( api , 'Accounts_AllowUsernameChange' , false ) ) . status ( ) ) . toBe ( 200 ) ;
527+ } ) ;
528+
529+ test . afterAll ( async ( { api } ) => {
530+ await expect ( ( await setSettingValueById ( api , 'Accounts_AllowUsernameChange' , true ) ) . status ( ) ) . toBe ( 200 ) ;
531+ } ) ;
532+
533+ test ( 'User without username can set initial username when username changes are disabled' , async ( { page, api } ) => {
534+ await doLoginStepWithUsernameSelection ( page , 'samlusernoname' ) ;
535+
536+ await test . step ( 'expect to be redirected to the username selection page and set the username' , async ( ) => {
537+ await expect ( poRegistration . btnRegisterConfirmUsername ) . toBeVisible ( ) ;
538+ await doUsernameSelection ( 'custom_saml_username' ) ;
539+ } ) ;
540+
541+ await test . step ( 'expect to be redirected to the homepage after succesful login' , async ( ) => {
542+ await expect ( page ) . toHaveURL ( '/home' ) ;
543+ await expect ( page . getByRole ( 'button' , { name : 'User menu' } ) ) . toBeVisible ( ) ;
544+ } ) ;
545+
546+ await test . step ( 'expect user data to have been created with the custom username' , async ( ) => {
547+ const user = await getUserInfo ( api , 'custom_saml_username' ) ;
548+
549+ expect ( user ) . toBeDefined ( ) ;
550+ expect ( user ?. username ) . toBe ( 'custom_saml_username' ) ;
551+ expect ( user ?. name ) . toBe ( 'Saml User No Username' ) ;
552+ expect ( user ?. emails ) . toBeDefined ( ) ;
553+ expect ( user ?. emails ?. [ 0 ] . address ) . toBe ( 'samlusernoname@example.com' ) ;
554+ } ) ;
555+ } ) ;
556+ } ) ;
557+
468558 test . fixme ( 'User Merge - By Custom Identifier' , async ( ) => {
469559 // Test user merge with a custom identifier configured in the fieldmap
470560 } ) ;
0 commit comments