1515 *
1616 */
1717
18- describe ( 'messaging() modular' , function ( ) {
18+ async function isSimulator ( ) {
19+ return await DeviceInfo . isEmulator ( ) ;
20+ }
21+
22+ async function isAPNSCapableSimulator ( ) {
23+ supportedAbis = await DeviceInfo . supportedAbis ( ) ; // looking for an ARM Simulator implying M1 host
24+ iosVersionMajor = DeviceInfo . getSystemVersion ( ) . split ( '.' ) [ 0 ] ; // looking for iOS16+
25+ macOSVersionMajor = require ( 'os' ) . release ( ) . split ( '.' ) [ 0 ] ; // host macOS13+ has Darwin kernel 22+
26+ if ( macOSVersionMajor >= 22 && supportedAbis . includes ( 'ARM64E' ) && iosVersionMajor >= 16 ) {
27+ return true ;
28+ }
29+ return false ;
30+ }
31+
32+ describe ( 'messaging()' , function ( ) {
1933 describe ( 'firebase v8 compatibility' , function ( ) {
2034 describe ( 'namespace' , function ( ) {
2135 it ( 'accessible from firebase.app()' , function ( ) {
@@ -74,9 +88,10 @@ describe('messaging() modular', function () {
7488 } ) ;
7589 it ( 'successfully unregisters on ios' , async function ( ) {
7690 if ( device . getPlatform ( ) === 'ios' ) {
77- should . equal ( firebase . messaging ( ) . isDeviceRegisteredForRemoteMessages , true ) ;
7891 await firebase . messaging ( ) . unregisterDeviceForRemoteMessages ( ) ;
7992 should . equal ( firebase . messaging ( ) . isDeviceRegisteredForRemoteMessages , false ) ;
93+ await firebase . messaging ( ) . registerDeviceForRemoteMessages ( ) ;
94+ should . equal ( firebase . messaging ( ) . isDeviceRegisteredForRemoteMessages , true ) ;
8095 } else {
8196 this . skip ( ) ;
8297 }
@@ -116,9 +131,84 @@ describe('messaging() modular', function () {
116131 this . skip ( ) ;
117132 }
118133 } ) ;
119- it ( 'resolves null on ios if using simulator' , async function ( ) {
134+ it ( 'resolves on ios with token on supported simulators' , async function ( ) {
135+ // Make sure we are registered for remote notifications, else no token
136+ await firebase . messaging ( ) . registerDeviceForRemoteMessages ( ) ;
137+
120138 if ( device . getPlatform ( ) === 'ios' ) {
121- should . equal ( await firebase . messaging ( ) . getAPNSToken ( ) , null ) ;
139+ apnsToken = await firebase . messaging ( ) . getAPNSToken ( ) ;
140+
141+ simulator = await isSimulator ( ) ;
142+ aPNSCapableSimulator = await isAPNSCapableSimulator ( ) ;
143+
144+ if ( ! simulator || ( simulator && aPNSCapableSimulator ) ) {
145+ apnsToken . should . be . a . String ( ) ;
146+ } else {
147+ // unsupported iOS Simulator returns null (typically,
148+ // can attempt-but-fail if M1 Simulator but not macOS13+/ios16+, rare combo)
149+ if ( apnsToken !== null ) {
150+ apnsToken . should . be . a . String ( ) ;
151+ }
152+ }
153+ } else {
154+ this . skip ( ) ;
155+ }
156+ } ) ;
157+ } ) ;
158+
159+ describe ( 'setAPNSToken' , function ( ) {
160+ it ( 'requires a token parameter' , async function ( ) {
161+ try {
162+ firebase . messaging ( ) . setAPNSToken ( ) ;
163+ return Promise . reject ( new Error ( 'Did not throw Error.' ) ) ;
164+ } catch ( e ) {
165+ e . message . should . containEql ( "'token' expected a string value" ) ;
166+ }
167+ try {
168+ firebase . messaging ( ) . setAPNSToken ( 123 ) ;
169+ return Promise . reject ( new Error ( 'Did not throw Error.' ) ) ;
170+ } catch ( e ) {
171+ e . message . should . containEql ( "'token' expected a string value" ) ;
172+ return Promise . resolve ( ) ;
173+ }
174+ } ) ;
175+
176+ it ( 'verifies type parameter is valid if specified' , async function ( ) {
177+ try {
178+ firebase . messaging ( ) . setAPNSToken ( 'typeparamtest' , 123 ) ;
179+ return Promise . reject ( new Error ( 'Did not throw Error.' ) ) ;
180+ } catch ( e ) {
181+ e . message . should . containEql ( "'type' expected one of 'prod', 'sandbox', or 'unknown'" ) ;
182+ }
183+ try {
184+ firebase . messaging ( ) . setAPNSToken ( 'typeparamtest' , 'bogus' ) ;
185+ return Promise . reject ( new Error ( 'Did not throw Error.' ) ) ;
186+ } catch ( e ) {
187+ e . message . should . containEql ( "'type' expected one of 'prod', 'sandbox', or 'unknown'" ) ;
188+ }
189+ } ) ;
190+
191+ it ( 'resolves on android' , async function ( ) {
192+ if ( device . getPlatform ( ) === 'android' ) {
193+ should . equal ( await firebase . messaging ( ) . setAPNSToken ( 'foo' ) , null ) ;
194+ } else {
195+ this . skip ( ) ;
196+ }
197+ } ) ;
198+
199+ it ( 'correctly sets new token on ios' , async function ( ) {
200+ if ( device . getPlatform ( ) === 'ios' ) {
201+ originalAPNSToken = await firebase . messaging ( ) . getAPNSToken ( ) ;
202+ // 74657374696E67746F6B656E is hex for "testingtoken"
203+ await firebase . messaging ( ) . setAPNSToken ( '74657374696E67746F6B656E' , 'unknown' ) ;
204+ newAPNSToken = await firebase . messaging ( ) . getAPNSToken ( ) ;
205+ newAPNSToken . should . eql ( '74657374696E67746F6B656E' ) ;
206+ newAPNSToken . should . not . eql ( originalAPNSToken ) ;
207+ if ( originalAPNSToken !== null ) {
208+ await firebase . messaging ( ) . setAPNSToken ( originalAPNSToken ) ;
209+ }
210+ } else {
211+ this . skip ( ) ;
122212 }
123213 } ) ;
124214 } ) ;
@@ -367,7 +457,7 @@ describe('messaging() modular', function () {
367457 } ) ;
368458 } ) ;
369459
370- describe ( 'modular' , function ( ) {
460+ describe ( 'firebase v9 modular API ' , function ( ) {
371461 describe ( 'getMessaging' , function ( ) {
372462 it ( 'pass app as argument' , function ( ) {
373463 const { getMessaging } = messagingModular ;
@@ -418,7 +508,7 @@ describe('messaging() modular', function () {
418508 } ) ;
419509 } ) ;
420510
421- describe ( 'isDeviceRegisteredForRemoteMessages' , function ( ) {
511+ describe ( 'isDeviceRegisteredForRemoteMessages default state ' , function ( ) {
422512 it ( 'returns true on android' , function ( ) {
423513 const { getMessaging, isDeviceRegisteredForRemoteMessages } = messagingModular ;
424514
@@ -430,7 +520,7 @@ describe('messaging() modular', function () {
430520 } ) ;
431521 } ) ;
432522
433- describe ( 'unregisterDeviceForRemoteMessages ' , function ( ) {
523+ describe ( 'remote message device register / unregister ' , function ( ) {
434524 it ( 'resolves on android, remains registered' , async function ( ) {
435525 const {
436526 getMessaging,
@@ -450,12 +540,14 @@ describe('messaging() modular', function () {
450540 getMessaging,
451541 unregisterDeviceForRemoteMessages,
452542 isDeviceRegisteredForRemoteMessages,
543+ registerDeviceForRemoteMessages,
453544 } = messagingModular ;
454545
455546 if ( device . getPlatform ( ) === 'ios' ) {
456- should . equal ( isDeviceRegisteredForRemoteMessages ( getMessaging ( ) ) , true ) ;
457547 await unregisterDeviceForRemoteMessages ( getMessaging ( ) ) ;
458548 should . equal ( isDeviceRegisteredForRemoteMessages ( getMessaging ( ) ) , false ) ;
549+ await registerDeviceForRemoteMessages ( getMessaging ( ) ) ;
550+ should . equal ( isDeviceRegisteredForRemoteMessages ( getMessaging ( ) ) , true ) ;
459551 } else {
460552 this . skip ( ) ;
461553 }
@@ -499,10 +591,91 @@ describe('messaging() modular', function () {
499591 this . skip ( ) ;
500592 }
501593 } ) ;
502- it ( 'resolves null on ios if using simulator' , async function ( ) {
503- const { getMessaging, getAPNSToken } = messagingModular ;
594+ it ( 'resolves on ios with token on supported simulators' , async function ( ) {
595+ // Make sure we are registered for remote notifications, else no token
596+ const { getMessaging, getAPNSToken, registerDeviceForRemoteMessages } = messagingModular ;
597+ await registerDeviceForRemoteMessages ( getMessaging ( ) ) ;
598+
504599 if ( device . getPlatform ( ) === 'ios' ) {
505- should . equal ( await getAPNSToken ( getMessaging ( ) ) , null ) ;
600+ apnsToken = await getAPNSToken ( getMessaging ( ) ) ;
601+
602+ simulator = await isSimulator ( ) ;
603+ aPNSCapableSimulator = await isAPNSCapableSimulator ( ) ;
604+
605+ if ( ! simulator || ( simulator && aPNSCapableSimulator ) ) {
606+ apnsToken . should . be . a . String ( ) ;
607+ } else {
608+ // unsupported iOS Simulator returns null (typically,
609+ // can attempt-but-fail if M1 Simulator but not macOS13+/ios16+, rare combo)
610+ if ( apnsToken !== null ) {
611+ apnsToken . should . be . a . String ( ) ;
612+ }
613+ }
614+ } else {
615+ this . skip ( ) ;
616+ }
617+ } ) ;
618+ } ) ;
619+
620+ describe ( 'setAPNSToken' , function ( ) {
621+ it ( 'requires a token parameter' , async function ( ) {
622+ const { getMessaging, setAPNSToken } = messagingModular ;
623+ try {
624+ setAPNSToken ( getMessaging ( ) ) ;
625+ return Promise . reject ( new Error ( 'Did not throw Error.' ) ) ;
626+ } catch ( e ) {
627+ e . message . should . containEql ( "'token' expected a string value" ) ;
628+ }
629+ try {
630+ setAPNSToken ( getMessaging ( ) , 123 ) ;
631+ return Promise . reject ( new Error ( 'Did not throw Error.' ) ) ;
632+ } catch ( e ) {
633+ e . message . should . containEql ( "'token' expected a string value" ) ;
634+ return Promise . resolve ( ) ;
635+ }
636+ } ) ;
637+
638+ it ( 'verifies type parameter is valid if specified' , async function ( ) {
639+ const { getMessaging, setAPNSToken } = messagingModular ;
640+ try {
641+ setAPNSToken ( getMessaging ( ) , 'typeparamtest' , 123 ) ;
642+ return Promise . reject ( new Error ( 'Did not throw Error.' ) ) ;
643+ } catch ( e ) {
644+ e . message . should . containEql ( "'type' expected one of 'prod', 'sandbox', or 'unknown'" ) ;
645+ }
646+ try {
647+ setAPNSToken ( getMessaging ( ) , 'typeparamtest' , 'bogus' ) ;
648+ return Promise . reject ( new Error ( 'Did not throw Error.' ) ) ;
649+ } catch ( e ) {
650+ e . message . should . containEql ( "'type' expected one of 'prod', 'sandbox', or 'unknown'" ) ;
651+ }
652+ } ) ;
653+
654+ it ( 'resolves on android' , async function ( ) {
655+ const { getMessaging, setAPNSToken } = messagingModular ;
656+ if ( device . getPlatform ( ) === 'android' ) {
657+ should . equal ( await setAPNSToken ( getMessaging ( ) , 'foo' ) , null ) ;
658+ } else {
659+ this . skip ( ) ;
660+ }
661+ } ) ;
662+
663+ it ( 'correctly sets new token on ios' , async function ( ) {
664+ const { getMessaging, getAPNSToken, setAPNSToken } = messagingModular ;
665+ if ( device . getPlatform ( ) === 'ios' ) {
666+ originalAPNSToken = await getAPNSToken ( getMessaging ( ) ) ;
667+ // 74657374696E67746F6B656E6D6F64756C6172 is hex for "testingtokenmodular"
668+ await firebase
669+ . messaging ( )
670+ . setAPNSToken ( '74657374696E67746F6B656E6D6F64756C6172' , 'unknown' ) ;
671+ newAPNSToken = await firebase . messaging ( ) . getAPNSToken ( ) ;
672+ newAPNSToken . should . eql ( '74657374696E67746F6B656E6D6F64756C6172' ) ;
673+ newAPNSToken . should . not . eql ( originalAPNSToken ) ;
674+ if ( originalAPNSToken !== null ) {
675+ await setAPNSToken ( getMessaging ( ) , originalAPNSToken ) ;
676+ }
677+ } else {
678+ this . skip ( ) ;
506679 }
507680 } ) ;
508681 } ) ;
0 commit comments