@@ -285,6 +285,25 @@ describe('/linked_account', () => {
285285 glean . thirdPartyAuth . googleRegComplete ,
286286 mockRequest
287287 ) ;
288+
289+ // Should emit SNS verified + login + profileDataChange events so
290+ // Basket/Braze learn about the new account.
291+ const notifyEvents = mockLog . notifyAttachedServices . args . map (
292+ ( call : any [ ] ) => call [ 0 ]
293+ ) ;
294+ expect ( notifyEvents ) . toContain ( 'verified' ) ;
295+ expect ( notifyEvents ) . toContain ( 'login' ) ;
296+ expect ( notifyEvents ) . toContain ( 'profileDataChange' ) ;
297+ sinon . assert . calledWithMatch (
298+ mockLog . notifyAttachedServices ,
299+ 'verified' ,
300+ mockRequest ,
301+ sinon . match ( {
302+ email : mockGoogleUser . email ,
303+ uid : UID ,
304+ service : 'sync' ,
305+ } )
306+ ) ;
288307 } ) ;
289308
290309 it ( 'should link existing fxa account and new google account and return session' , async ( ) => {
@@ -315,6 +334,15 @@ describe('/linked_account', () => {
315334 mockRequest ,
316335 { reason : 'linking' }
317336 ) ;
337+
338+ // Should emit SNS login + profileDataChange but NOT verified
339+ // (the account already existed).
340+ const notifyEvents = mockLog . notifyAttachedServices . args . map (
341+ ( call : any [ ] ) => call [ 0 ]
342+ ) ;
343+ expect ( notifyEvents ) . not . toContain ( 'verified' ) ;
344+ expect ( notifyEvents ) . toContain ( 'login' ) ;
345+ expect ( notifyEvents ) . toContain ( 'profileDataChange' ) ;
318346 } ) ;
319347
320348 it ( 'should return session with valid google id token' , async ( ) => {
@@ -338,6 +366,12 @@ describe('/linked_account', () => {
338366 expect ( mockDB . createSessionToken . calledOnce ) . toBe ( true ) ;
339367 expect ( result . uid ) . toBe ( UID ) ;
340368 expect ( result . sessionToken ) . toBeTruthy ( ) ;
369+
370+ // Re-login: login event only, no verified, no profileDataChange.
371+ const notifyEvents = mockLog . notifyAttachedServices . args . map (
372+ ( call : any [ ] ) => call [ 0 ]
373+ ) ;
374+ expect ( notifyEvents ) . toEqual ( [ 'login' ] ) ;
341375 sinon . assert . calledOnceWithExactly (
342376 glean . thirdPartyAuth . googleLoginComplete ,
343377 mockRequest
@@ -516,6 +550,14 @@ describe('/linked_account', () => {
516550 glean . thirdPartyAuth . appleRegComplete ,
517551 mockRequest
518552 ) ;
553+
554+ // Should emit SNS verified + login + profileDataChange events.
555+ const notifyEvents = mockLog . notifyAttachedServices . args . map (
556+ ( call : any [ ] ) => call [ 0 ]
557+ ) ;
558+ expect ( notifyEvents ) . toContain ( 'verified' ) ;
559+ expect ( notifyEvents ) . toContain ( 'login' ) ;
560+ expect ( notifyEvents ) . toContain ( 'profileDataChange' ) ;
519561 } ) ;
520562
521563 it ( 'should link existing fxa account and new apple account and return session' , async ( ) => {
@@ -544,6 +586,14 @@ describe('/linked_account', () => {
544586 mockRequest ,
545587 { reason : 'linking' }
546588 ) ;
589+
590+ // New link on existing account: login + profileDataChange, no verified.
591+ const notifyEvents = mockLog . notifyAttachedServices . args . map (
592+ ( call : any [ ] ) => call [ 0 ]
593+ ) ;
594+ expect ( notifyEvents ) . not . toContain ( 'verified' ) ;
595+ expect ( notifyEvents ) . toContain ( 'login' ) ;
596+ expect ( notifyEvents ) . toContain ( 'profileDataChange' ) ;
547597 } ) ;
548598
549599 it ( 'should return session with valid apple id token' , async ( ) => {
@@ -571,6 +621,12 @@ describe('/linked_account', () => {
571621 glean . thirdPartyAuth . appleLoginComplete ,
572622 mockRequest
573623 ) ;
624+
625+ // Re-login: login event only.
626+ const notifyEvents = mockLog . notifyAttachedServices . args . map (
627+ ( call : any [ ] ) => call [ 0 ]
628+ ) ;
629+ expect ( notifyEvents ) . toEqual ( [ 'login' ] ) ;
574630 } ) ;
575631 } ) ;
576632 } ) ;
@@ -912,11 +968,7 @@ describe('/linked_account', () => {
912968 mockLog . debug ,
913969 'Revoked 1 third party sessions for user fxauid'
914970 ) ;
915- sinon . assert . calledWithExactly (
916- mockDB . deleteLinkedAccount ,
917- UID ,
918- 'google'
919- ) ;
971+ sinon . assert . calledWithExactly ( mockDB . deleteLinkedAccount , UID , 'google' ) ;
920972 } ) ;
921973
922974 it ( 'handles credentials changed event' , async ( ) => {
@@ -967,11 +1019,7 @@ describe('/linked_account', () => {
9671019 mockLog . debug ,
9681020 'Revoked 1 third party sessions for user fxauid'
9691021 ) ;
970- sinon . assert . calledWithExactly (
971- mockDB . deleteLinkedAccount ,
972- UID ,
973- 'google'
974- ) ;
1022+ sinon . assert . calledWithExactly ( mockDB . deleteLinkedAccount , UID , 'google' ) ;
9751023 } ) ;
9761024
9771025 it ( 'handles account enabled event' , async ( ) => {
@@ -1204,9 +1252,7 @@ describe('/linked_account', () => {
12041252 } ,
12051253 ] ,
12061254 } ) ;
1207- mockDB . getLinkedAccount = sinon . spy ( ( ) =>
1208- Promise . resolve ( { uid : UID } )
1209- ) ;
1255+ mockDB . getLinkedAccount = sinon . spy ( ( ) => Promise . resolve ( { uid : UID } ) ) ;
12101256 const mockConfig = {
12111257 appleAuthConfig : { clientId : 'OooOoo' , teamId : 'teamId' } ,
12121258 } ;
@@ -1288,11 +1334,7 @@ describe('/linked_account', () => {
12881334 mockLog . debug ,
12891335 'Revoked 1 third party sessions for user fxauid'
12901336 ) ;
1291- sinon . assert . calledWithExactly (
1292- mockDB . deleteLinkedAccount ,
1293- UID ,
1294- 'apple'
1295- ) ;
1337+ sinon . assert . calledWithExactly ( mockDB . deleteLinkedAccount , UID , 'apple' ) ;
12961338 sinon . assert . calledWithExactly (
12971339 statsd . increment ,
12981340 'handleAppleSET.processed.consent-revoked'
@@ -1319,11 +1361,7 @@ describe('/linked_account', () => {
13191361 mockLog . debug ,
13201362 'Revoked 1 third party sessions for user fxauid'
13211363 ) ;
1322- sinon . assert . calledWithExactly (
1323- mockDB . deleteLinkedAccount ,
1324- UID ,
1325- 'apple'
1326- ) ;
1364+ sinon . assert . calledWithExactly ( mockDB . deleteLinkedAccount , UID , 'apple' ) ;
13271365 sinon . assert . calledWithExactly (
13281366 statsd . increment ,
13291367 'handleAppleSET.processed.account-delete'
0 commit comments