@@ -698,6 +698,147 @@ describe('SignUp', () => {
698698 ) ;
699699 } ) ;
700700
701+ it ( 'includes browser locale when creating a new signup' , async ( ) => {
702+ vi . stubGlobal ( 'window' , { location : { origin : 'https://example.com' } } ) ;
703+ vi . stubGlobal ( 'navigator' , { language : 'fr-FR' } ) ;
704+
705+ const mockBuildUrlWithAuth = vi . fn ( ) . mockReturnValue ( 'https://example.com/sso-callback' ) ;
706+ SignUp . clerk = {
707+ buildUrlWithAuth : mockBuildUrlWithAuth ,
708+ __internal_environment : {
709+ displayConfig : {
710+ captchaOauthBypass : [ ] ,
711+ } ,
712+ } ,
713+ } as any ;
714+
715+ const mockFetch = vi . fn ( ) . mockResolvedValue ( {
716+ client : null ,
717+ response : {
718+ id : 'signup_123' ,
719+ verifications : {
720+ externalAccount : {
721+ status : 'unverified' ,
722+ externalVerificationRedirectURL : 'https://sso.example.com/auth' ,
723+ } ,
724+ } ,
725+ } ,
726+ } ) ;
727+ BaseResource . _fetch = mockFetch ;
728+
729+ const signUp = new SignUp ( ) ;
730+ await signUp . __internal_future . sso ( {
731+ strategy : 'oauth_google' ,
732+ redirectUrl : '/complete' ,
733+ redirectCallbackUrl : '/sso-callback' ,
734+ } ) ;
735+
736+ expect ( mockFetch ) . toHaveBeenCalledWith (
737+ expect . objectContaining ( {
738+ method : 'POST' ,
739+ path : '/client/sign_ups' ,
740+ body : expect . objectContaining ( {
741+ strategy : 'oauth_google' ,
742+ locale : 'fr-FR' ,
743+ } ) ,
744+ } ) ,
745+ ) ;
746+ } ) ;
747+
748+ it ( 'prefers an explicitly provided locale over the browser locale' , async ( ) => {
749+ vi . stubGlobal ( 'window' , { location : { origin : 'https://example.com' } } ) ;
750+ vi . stubGlobal ( 'navigator' , { language : 'fr-FR' } ) ;
751+
752+ const mockBuildUrlWithAuth = vi . fn ( ) . mockReturnValue ( 'https://example.com/sso-callback' ) ;
753+ SignUp . clerk = {
754+ buildUrlWithAuth : mockBuildUrlWithAuth ,
755+ __internal_environment : {
756+ displayConfig : {
757+ captchaOauthBypass : [ ] ,
758+ } ,
759+ } ,
760+ } as any ;
761+
762+ const mockFetch = vi . fn ( ) . mockResolvedValue ( {
763+ client : null ,
764+ response : {
765+ id : 'signup_123' ,
766+ verifications : {
767+ externalAccount : {
768+ status : 'unverified' ,
769+ externalVerificationRedirectURL : 'https://sso.example.com/auth' ,
770+ } ,
771+ } ,
772+ } ,
773+ } ) ;
774+ BaseResource . _fetch = mockFetch ;
775+
776+ const signUp = new SignUp ( ) ;
777+ await signUp . __internal_future . sso ( {
778+ strategy : 'oauth_google' ,
779+ redirectUrl : '/complete' ,
780+ redirectCallbackUrl : '/sso-callback' ,
781+ locale : 'el-GR' ,
782+ } ) ;
783+
784+ expect ( mockFetch ) . toHaveBeenCalledWith (
785+ expect . objectContaining ( {
786+ method : 'POST' ,
787+ path : '/client/sign_ups' ,
788+ body : expect . objectContaining ( {
789+ strategy : 'oauth_google' ,
790+ locale : 'el-GR' ,
791+ } ) ,
792+ } ) ,
793+ ) ;
794+ } ) ;
795+
796+ it ( 'does not inject browser locale when continuing an existing signup' , async ( ) => {
797+ vi . stubGlobal ( 'window' , { location : { origin : 'https://example.com' } } ) ;
798+ vi . stubGlobal ( 'navigator' , { language : 'fr-FR' } ) ;
799+
800+ const mockBuildUrlWithAuth = vi . fn ( ) . mockReturnValue ( 'https://example.com/sso-callback' ) ;
801+ SignUp . clerk = {
802+ buildUrlWithAuth : mockBuildUrlWithAuth ,
803+ __internal_environment : {
804+ displayConfig : {
805+ captchaOauthBypass : [ ] ,
806+ } ,
807+ } ,
808+ } as any ;
809+
810+ const mockFetch = vi . fn ( ) . mockResolvedValue ( {
811+ client : null ,
812+ response : {
813+ id : 'signup_123' ,
814+ verifications : {
815+ externalAccount : {
816+ status : 'unverified' ,
817+ externalVerificationRedirectURL : 'https://sso.example.com/auth' ,
818+ } ,
819+ } ,
820+ } ,
821+ } ) ;
822+ BaseResource . _fetch = mockFetch ;
823+
824+ const signUp = new SignUp ( { id : 'signup_123' } as any ) ;
825+ await signUp . __internal_future . sso ( {
826+ strategy : 'oauth_google' ,
827+ redirectUrl : '/complete' ,
828+ redirectCallbackUrl : '/sso-callback' ,
829+ } ) ;
830+
831+ expect ( mockFetch ) . toHaveBeenCalledWith (
832+ expect . objectContaining ( {
833+ method : 'PATCH' ,
834+ path : '/client/sign_ups/signup_123' ,
835+ body : expect . not . objectContaining ( {
836+ locale : expect . anything ( ) ,
837+ } ) ,
838+ } ) ,
839+ ) ;
840+ } ) ;
841+
701842 it ( 'continues an existing sign up via the resource URL' , async ( ) => {
702843 vi . stubGlobal ( 'window' , { location : { origin : 'https://example.com' } } ) ;
703844
@@ -1180,6 +1321,63 @@ describe('SignUp', () => {
11801321 // Verify error is returned without retry
11811322 expect ( result . error ) . toBeTruthy ( ) ;
11821323 } ) ;
1324+
1325+ it ( 'passes locale and name params through to the created signup' , async ( ) => {
1326+ vi . stubGlobal ( 'navigator' , { language : 'fr-FR' } ) ;
1327+
1328+ const mockFetch = vi
1329+ . fn ( )
1330+ . mockResolvedValueOnce ( {
1331+ client : null ,
1332+ response : {
1333+ id : 'signup_123' ,
1334+ verifications : {
1335+ web3_wallet : { status : 'unverified' } ,
1336+ } ,
1337+ } ,
1338+ } )
1339+ . mockResolvedValueOnce ( {
1340+ client : null ,
1341+ response : {
1342+ id : 'signup_123' ,
1343+ verifications : {
1344+ web3_wallet : { status : 'unverified' , message : 'nonce_123' } ,
1345+ } ,
1346+ } ,
1347+ } )
1348+ . mockResolvedValueOnce ( {
1349+ client : null ,
1350+ response : { id : 'signup_123' , status : 'complete' } ,
1351+ } ) ;
1352+ BaseResource . _fetch = mockFetch ;
1353+
1354+ const utilsModule = await import ( '../../../utils' ) ;
1355+ vi . spyOn ( utilsModule , 'web3' ) . mockReturnValue ( {
1356+ getMetamaskIdentifier : vi . fn ( ) . mockResolvedValue ( '0x1234567890123456789012345678901234567890' ) ,
1357+ generateSignatureWithMetamask : vi . fn ( ) . mockResolvedValue ( 'signature_123' ) ,
1358+ } as any ) ;
1359+
1360+ const signUp = new SignUp ( ) ;
1361+ await signUp . __internal_future . web3 ( {
1362+ strategy : 'web3_metamask_signature' ,
1363+ firstName : 'Vitalik' ,
1364+ lastName : 'Nakamoto' ,
1365+ locale : 'el-GR' ,
1366+ } ) ;
1367+
1368+ expect ( mockFetch ) . toHaveBeenNthCalledWith (
1369+ 1 ,
1370+ expect . objectContaining ( {
1371+ method : 'POST' ,
1372+ path : '/client/sign_ups' ,
1373+ body : expect . objectContaining ( {
1374+ firstName : 'Vitalik' ,
1375+ lastName : 'Nakamoto' ,
1376+ locale : 'el-GR' ,
1377+ } ) ,
1378+ } ) ,
1379+ ) ;
1380+ } ) ;
11831381 } ) ;
11841382
11851383 describe ( 'password' , ( ) => {
@@ -1255,6 +1453,77 @@ describe('SignUp', () => {
12551453
12561454 expect ( result ) . toHaveProperty ( 'error' , null ) ;
12571455 } ) ;
1456+
1457+ it ( 'includes browser locale when creating a new signup' , async ( ) => {
1458+ vi . stubGlobal ( 'navigator' , { language : 'fr-FR' } ) ;
1459+
1460+ const mockFetch = vi . fn ( ) . mockResolvedValue ( {
1461+ client : null ,
1462+ response : { id : 'signup_123' , status : 'missing_requirements' } ,
1463+ } ) ;
1464+ BaseResource . _fetch = mockFetch ;
1465+
1466+ const signUp = new SignUp ( ) ;
1467+ await signUp . __internal_future . password ( { password : 'test-password-123' } ) ;
1468+
1469+ expect ( mockFetch ) . toHaveBeenCalledWith (
1470+ expect . objectContaining ( {
1471+ method : 'POST' ,
1472+ path : '/client/sign_ups' ,
1473+ body : expect . objectContaining ( {
1474+ strategy : 'password' ,
1475+ locale : 'fr-FR' ,
1476+ } ) ,
1477+ } ) ,
1478+ ) ;
1479+ } ) ;
1480+
1481+ it ( 'prefers an explicitly provided locale over the browser locale' , async ( ) => {
1482+ vi . stubGlobal ( 'navigator' , { language : 'fr-FR' } ) ;
1483+
1484+ const mockFetch = vi . fn ( ) . mockResolvedValue ( {
1485+ client : null ,
1486+ response : { id : 'signup_123' , status : 'missing_requirements' } ,
1487+ } ) ;
1488+ BaseResource . _fetch = mockFetch ;
1489+
1490+ const signUp = new SignUp ( ) ;
1491+ await signUp . __internal_future . password ( { password : 'test-password-123' , locale : 'el-GR' } ) ;
1492+
1493+ expect ( mockFetch ) . toHaveBeenCalledWith (
1494+ expect . objectContaining ( {
1495+ method : 'POST' ,
1496+ path : '/client/sign_ups' ,
1497+ body : expect . objectContaining ( {
1498+ strategy : 'password' ,
1499+ locale : 'el-GR' ,
1500+ } ) ,
1501+ } ) ,
1502+ ) ;
1503+ } ) ;
1504+
1505+ it ( 'does not inject browser locale when updating an existing signup' , async ( ) => {
1506+ vi . stubGlobal ( 'navigator' , { language : 'fr-FR' } ) ;
1507+
1508+ const mockFetch = vi . fn ( ) . mockResolvedValue ( {
1509+ client : null ,
1510+ response : { id : 'signup_123' , status : 'missing_requirements' } ,
1511+ } ) ;
1512+ BaseResource . _fetch = mockFetch ;
1513+
1514+ const signUp = new SignUp ( { id : 'signup_123' } as any ) ;
1515+ await signUp . __internal_future . password ( { password : 'test-password-123' } ) ;
1516+
1517+ expect ( mockFetch ) . toHaveBeenCalledWith (
1518+ expect . objectContaining ( {
1519+ method : 'PATCH' ,
1520+ path : '/client/sign_ups/signup_123' ,
1521+ body : expect . not . objectContaining ( {
1522+ locale : expect . anything ( ) ,
1523+ } ) ,
1524+ } ) ,
1525+ ) ;
1526+ } ) ;
12581527 } ) ;
12591528
12601529 describe ( 'ticket' , ( ) => {
0 commit comments