@react-native-firebase/app 26.4.0 → 27.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (242) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/README.md +10 -27
  3. package/RNFBApp.podspec +13 -5
  4. package/android/build.gradle +3 -0
  5. package/android/src/main/java/io/invertase/firebase/common/RNFBHandleCollisionException.kt +29 -0
  6. package/android/src/main/java/io/invertase/firebase/common/RNFBHandleMap.kt +146 -0
  7. package/android/src/main/java/io/invertase/firebase/common/TaskExecutorService.kt +156 -0
  8. package/android/src/main/java/io/invertase/firebase/common/UniversalFirebaseModule.kt +44 -0
  9. package/android/src/main/java/io/invertase/firebase/common/UniversalFirebasePreferences.kt +100 -0
  10. package/android/src/reactnative/java/io/invertase/firebase/app/NativeRNFBTurboApp.kt +250 -0
  11. package/android/src/reactnative/java/io/invertase/firebase/app/ReactNativeFirebaseApp.kt +64 -0
  12. package/android/src/reactnative/java/io/invertase/firebase/app/{ReactNativeFirebaseAppInitProvider.java → ReactNativeFirebaseAppInitProvider.kt} +3 -4
  13. package/android/src/reactnative/java/io/invertase/firebase/app/ReactNativeFirebaseAppPackage.kt +47 -0
  14. package/android/src/reactnative/java/io/invertase/firebase/app/ReactNativeFirebaseAppRegistrar.kt +33 -0
  15. package/android/src/reactnative/java/io/invertase/firebase/app/ReactNativeFirebaseVersion.java +1 -1
  16. package/android/src/reactnative/java/io/invertase/firebase/common/RCTConvertFirebase.kt +185 -0
  17. package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseEvent.kt +35 -0
  18. package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseEventEmitter.kt +662 -0
  19. package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseJSON.kt +103 -0
  20. package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseMeta.kt +96 -0
  21. package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseModule.kt +140 -0
  22. package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebasePreferences.kt +109 -0
  23. package/android/src/reactnative/java/io/invertase/firebase/common/SharedUtils.kt +451 -0
  24. package/android/src/reactnative/java/io/invertase/firebase/interfaces/{ContextProvider.java → ContextProvider.kt} +8 -8
  25. package/android/src/reactnative/java/io/invertase/firebase/interfaces/{NativeError.java → NativeError.kt} +8 -8
  26. package/android/src/reactnative/java/io/invertase/firebase/interfaces/{NativeEvent.java → NativeEvent.kt} +6 -6
  27. package/android/src/reactnative/java/io/invertase/firebase/utils/NativeRNFBTurboUtils.kt +219 -0
  28. package/android/src/test/java/expo/core/ModuleRegistry.java +9 -0
  29. package/android/src/test/java/io/invertase/firebase/app/NativeRNFBTurboAppTest.java +182 -59
  30. package/android/src/test/java/io/invertase/firebase/app/ReactNativeFirebaseAppComponentsJavaCompatibilityTest.java +70 -0
  31. package/android/src/test/java/io/invertase/firebase/app/ReactNativeFirebaseAppJavaCompatibilityTest.java +60 -0
  32. package/android/src/test/java/io/invertase/firebase/app/ReactNativeFirebaseAppPackageTest.java +165 -0
  33. package/android/src/test/java/io/invertase/firebase/app/ReactNativeFirebaseAppTest.kt +167 -0
  34. package/android/src/test/java/io/invertase/firebase/common/RCTConvertFirebaseJavaCompatibilityTest.java +112 -0
  35. package/android/src/test/java/io/invertase/firebase/common/RCTConvertFirebaseTest.kt +317 -0
  36. package/android/src/test/java/io/invertase/firebase/common/RNFBHandleMapTest.kt +309 -0
  37. package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebaseEventEmitterJavaCompatibilityTest.java +176 -0
  38. package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebaseEventEmitterTest.java +143 -12
  39. package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebaseEventTest.kt +61 -0
  40. package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebaseJSONJavaCompatibilityTest.java +85 -0
  41. package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebaseJSONTest.kt +296 -0
  42. package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebaseMetaJavaCompatibilityTest.java +67 -0
  43. package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebaseMetaTest.kt +246 -0
  44. package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebaseModuleTest.kt +254 -0
  45. package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebasePreferencesJavaCompatibilityTest.java +87 -0
  46. package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebasePreferencesTest.kt +260 -0
  47. package/android/src/test/java/io/invertase/firebase/common/SharedUtilsJavaCompatibilityTest.java +255 -0
  48. package/android/src/test/java/io/invertase/firebase/common/SharedUtilsTest.kt +674 -0
  49. package/android/src/test/java/io/invertase/firebase/common/TaskExecutorServiceTest.kt +290 -0
  50. package/android/src/test/java/io/invertase/firebase/common/UniversalFirebaseModuleJavaCompatibilityTest.java +178 -0
  51. package/android/src/test/java/io/invertase/firebase/common/UniversalFirebasePreferencesJavaCompatibilityTest.java +99 -0
  52. package/android/src/test/java/io/invertase/firebase/common/UniversalFirebasePreferencesTest.kt +217 -0
  53. package/android/src/test/java/io/invertase/firebase/commoncompat/ReactNativeFirebaseModuleJavaCompatibilityTest.java +176 -0
  54. package/android/src/test/java/io/invertase/firebase/commoncompat/ReactNativeFirebaseModuleKotlinCompatibilityTest.kt +52 -0
  55. package/android/src/test/java/io/invertase/firebase/interfaces/InterfacesJavaCompatibilityTest.java +144 -0
  56. package/android/src/test/java/io/invertase/firebase/interfaces/NativeEventTest.kt +56 -0
  57. package/android/src/test/java/io/invertase/firebase/utils/NativeRNFBTurboUtilsTest.java +517 -21
  58. package/dist/module/FirebaseApp.js +10 -0
  59. package/dist/module/FirebaseApp.js.map +1 -1
  60. package/dist/module/common/deeps.js +3 -0
  61. package/dist/module/common/deeps.js.map +1 -1
  62. package/dist/module/internal/FirebaseModule.js.map +1 -1
  63. package/dist/module/internal/RNFBNativeEventEmitter.js +12 -1
  64. package/dist/module/internal/RNFBNativeEventEmitter.js.map +1 -1
  65. package/dist/module/internal/SharedEventEmitter.js +3 -1
  66. package/dist/module/internal/SharedEventEmitter.js.map +1 -1
  67. package/dist/module/internal/index.js +1 -0
  68. package/dist/module/internal/index.js.map +1 -1
  69. package/dist/module/internal/registry/app.js +7 -1
  70. package/dist/module/internal/registry/app.js.map +1 -1
  71. package/dist/module/types/app.js.map +1 -1
  72. package/dist/module/types/internal.js +2 -0
  73. package/dist/module/version.js +1 -1
  74. package/dist/typescript/lib/FirebaseApp.d.ts +7 -0
  75. package/dist/typescript/lib/FirebaseApp.d.ts.map +1 -1
  76. package/dist/typescript/lib/common/deeps.d.ts.map +1 -1
  77. package/dist/typescript/lib/internal/FirebaseModule.d.ts +2 -3
  78. package/dist/typescript/lib/internal/FirebaseModule.d.ts.map +1 -1
  79. package/dist/typescript/lib/internal/NativeModules.d.ts +4 -1
  80. package/dist/typescript/lib/internal/NativeModules.d.ts.map +1 -1
  81. package/dist/typescript/lib/internal/RNFBNativeEventEmitter.d.ts +2 -2
  82. package/dist/typescript/lib/internal/RNFBNativeEventEmitter.d.ts.map +1 -1
  83. package/dist/typescript/lib/internal/SharedEventEmitter.d.ts +3 -3
  84. package/dist/typescript/lib/internal/SharedEventEmitter.d.ts.map +1 -1
  85. package/dist/typescript/lib/internal/index.d.ts +1 -0
  86. package/dist/typescript/lib/internal/index.d.ts.map +1 -1
  87. package/dist/typescript/lib/internal/registry/app.d.ts.map +1 -1
  88. package/dist/typescript/lib/types/app.d.ts +10 -3
  89. package/dist/typescript/lib/types/app.d.ts.map +1 -1
  90. package/dist/typescript/lib/types/internal.d.ts +12 -0
  91. package/dist/typescript/lib/types/internal.d.ts.map +1 -1
  92. package/dist/typescript/lib/version.d.ts +1 -1
  93. package/firebase-schema.json +4 -0
  94. package/firebase_spm.rb +552 -96
  95. package/ios/RNFBApp/RCTConvert+FIRApp.h +2 -5
  96. package/ios/RNFBApp/RCTConvert+FIRApp.m +11 -6
  97. package/ios/RNFBApp/RCTConvert+FIROptions.h +2 -5
  98. package/ios/RNFBApp/RCTConvert+FIROptions.m +11 -10
  99. package/ios/RNFBApp/RCTConvertFIRApp.swift +86 -0
  100. package/ios/RNFBApp/RCTConvertFIROptions.swift +259 -0
  101. package/ios/RNFBApp/RNFBAppCustomAuthDomains.swift +63 -0
  102. package/ios/RNFBApp/RNFBAppInitializeOptionsMapper.swift +113 -0
  103. package/ios/RNFBApp/RNFBAppLogLevelMapper.swift +53 -0
  104. package/ios/RNFBApp/RNFBAppModule+CustomAuthDomain.m +35 -0
  105. package/ios/RNFBApp/RNFBAppModule.h +6 -2
  106. package/ios/RNFBApp/RNFBAppModule.mm +65 -228
  107. package/ios/RNFBApp/RNFBAppModuleFirebase.swift +439 -0
  108. package/ios/RNFBApp/RNFBAppModuleImplementation.h +68 -0
  109. package/ios/RNFBApp/RNFBAppModuleImplementation.m +195 -0
  110. package/ios/RNFBApp/RNFBHandleMap.m +27 -56
  111. package/ios/RNFBApp/RNFBHandleMapStorage.swift +90 -0
  112. package/ios/RNFBApp/RNFBInitializeAppArguments.swift +82 -0
  113. package/ios/RNFBApp/RNFBJSON.m +22 -38
  114. package/ios/RNFBApp/RNFBJSONImplementation.swift +71 -0
  115. package/ios/RNFBApp/RNFBMeta.m +24 -26
  116. package/ios/RNFBApp/RNFBMetaStorage.swift +76 -0
  117. package/ios/RNFBApp/RNFBNullSentinelDecoding.swift +135 -0
  118. package/ios/RNFBApp/RNFBNullSentinelInterceptor.h +30 -3
  119. package/ios/RNFBApp/RNFBNullSentinelInterceptor.m +28 -5
  120. package/ios/RNFBApp/RNFBPreferences.m +22 -20
  121. package/ios/RNFBApp/RNFBPreferencesStorage.swift +101 -0
  122. package/ios/RNFBApp/RNFBRCTEventEmitter.m +36 -93
  123. package/ios/RNFBApp/RNFBRCTEventEmitterCore.swift +161 -0
  124. package/ios/RNFBApp/RNFBSharedUtils.h +2 -5
  125. package/ios/RNFBApp/RNFBSharedUtils.m +109 -198
  126. package/ios/RNFBApp/RNFBSharedUtilsConfig.swift +72 -0
  127. package/ios/RNFBApp/RNFBSharedUtilsFIRApp.swift +271 -0
  128. package/ios/RNFBApp/RNFBSharedUtilsFormatting.swift +59 -0
  129. package/ios/RNFBApp/RNFBSharedUtilsPromiseRejection.swift +88 -0
  130. package/ios/RNFBApp/RNFBUtilsHelpers.swift +116 -0
  131. package/ios/RNFBApp/RNFBUtilsModule+Foundation.m +44 -0
  132. package/ios/RNFBApp/RNFBUtilsModule+PhotoAssets.m +47 -0
  133. package/ios/RNFBApp/RNFBUtilsModule.h +11 -1
  134. package/ios/RNFBApp/RNFBUtilsModule.mm +10 -85
  135. package/ios/RNFBApp/RNFBUtilsModuleImplementation.h +32 -0
  136. package/ios/RNFBApp/RNFBUtilsModuleImplementation.m +56 -0
  137. package/ios/RNFBApp/RNFBVersion.m +1 -1
  138. package/ios/RNFBApp.xcodeproj/project.pbxproj +100 -0
  139. package/ios/RNFBAppUnitTests/HostStubs/FirebaseCore/FIRApp.m +171 -0
  140. package/ios/RNFBAppUnitTests/HostStubs/FirebaseCore/FirebaseCore.h +78 -0
  141. package/ios/RNFBAppUnitTests/HostStubs/FirebaseInstallations/FIRInstallations.m +7 -0
  142. package/ios/RNFBAppUnitTests/HostStubs/FirebaseInstallations/FirebaseInstallations.h +8 -0
  143. package/ios/RNFBAppUnitTests/HostStubs/RNFBAppModuleHostStub.m +55 -0
  144. package/ios/RNFBAppUnitTests/HostStubs/RNFBAppTurboModules.h +89 -0
  145. package/ios/RNFBAppUnitTests/HostStubs/RNFBAppTurboModules.mm +30 -0
  146. package/ios/RNFBAppUnitTests/HostStubs/React/RCTBridge.h +19 -0
  147. package/ios/RNFBAppUnitTests/HostStubs/React/RCTBridge.m +32 -0
  148. package/ios/RNFBAppUnitTests/HostStubs/React/RCTBridgeModule.h +19 -0
  149. package/ios/RNFBAppUnitTests/HostStubs/React/RCTConvert.h +28 -0
  150. package/ios/RNFBAppUnitTests/HostStubs/React/RCTConvert.m +23 -0
  151. package/ios/RNFBAppUnitTests/HostStubs/React/RCTEventEmitter.h +9 -0
  152. package/ios/RNFBAppUnitTests/HostStubs/React/RCTInvalidating.h +24 -0
  153. package/ios/RNFBAppUnitTests/HostStubs/React/RCTUtils.h +9 -0
  154. package/ios/RNFBAppUnitTests/HostStubs/module.modulemap +13 -0
  155. package/ios/RNFBAppUnitTests/RCTConvertFIRAppFacadeTests.m +61 -0
  156. package/ios/RNFBAppUnitTests/RCTConvertFIRAppTests.swift +73 -0
  157. package/ios/RNFBAppUnitTests/RCTConvertFIROptionsFacadeTests.m +57 -0
  158. package/ios/RNFBAppUnitTests/RCTConvertFIROptionsTests.swift +243 -0
  159. package/ios/RNFBAppUnitTests/RNFBAppCustomAuthDomainsFacadeTests.m +73 -0
  160. package/ios/RNFBAppUnitTests/RNFBAppCustomAuthDomainsTests.swift +70 -0
  161. package/ios/RNFBAppUnitTests/RNFBAppInitializeOptionsMapperTests.swift +190 -0
  162. package/ios/RNFBAppUnitTests/RNFBAppLogLevelFacadeTests.m +76 -0
  163. package/ios/RNFBAppUnitTests/RNFBAppLogLevelMapperTests.swift +59 -0
  164. package/ios/RNFBAppUnitTests/RNFBAppModuleFirebaseFacadeTests.m +215 -0
  165. package/ios/RNFBAppUnitTests/RNFBAppModuleFirebaseTests.swift +430 -0
  166. package/ios/RNFBAppUnitTests/RNFBAppModuleLifecycleTests.m +206 -0
  167. package/ios/RNFBAppUnitTests/RNFBAppModuleShellTests.mm +367 -0
  168. package/ios/RNFBAppUnitTests/RNFBAppUnitTests.xcodeproj/project.pbxproj +355 -2
  169. package/ios/RNFBAppUnitTests/RNFBFirebaseAppClientTests.swift +165 -0
  170. package/ios/RNFBAppUnitTests/RNFBHandleMapStorageTests.swift +121 -0
  171. package/ios/RNFBAppUnitTests/RNFBInitializeAppArgumentsTests.swift +256 -0
  172. package/ios/RNFBAppUnitTests/RNFBJSONImplementationTests.swift +126 -0
  173. package/ios/RNFBAppUnitTests/RNFBJSONTests.m +172 -0
  174. package/ios/RNFBAppUnitTests/RNFBMetaStorageTests.swift +106 -0
  175. package/ios/RNFBAppUnitTests/RNFBMetaTests.m +65 -0
  176. package/ios/RNFBAppUnitTests/RNFBNullSentinelDecodingTests.swift +286 -0
  177. package/ios/RNFBAppUnitTests/RNFBNullSentinelInterceptorTests.m +312 -0
  178. package/ios/RNFBAppUnitTests/RNFBPreferencesStorageTests.swift +105 -0
  179. package/ios/RNFBAppUnitTests/RNFBPreferencesTests.m +110 -0
  180. package/ios/RNFBAppUnitTests/RNFBRCTEventEmitterCoreTests.swift +163 -0
  181. package/ios/RNFBAppUnitTests/RNFBRCTEventEmitterFacadeTests.m +141 -0
  182. package/ios/RNFBAppUnitTests/RNFBSharedUtilsConfigFacadeTests.m +100 -0
  183. package/ios/RNFBAppUnitTests/RNFBSharedUtilsConfigTests.swift +234 -0
  184. package/ios/RNFBAppUnitTests/RNFBSharedUtilsFIRAppFacadeTests.m +145 -0
  185. package/ios/RNFBAppUnitTests/RNFBSharedUtilsFIRAppTests.swift +173 -0
  186. package/ios/RNFBAppUnitTests/RNFBSharedUtilsFormattingFacadeTests.m +38 -0
  187. package/ios/RNFBAppUnitTests/RNFBSharedUtilsFormattingTests.swift +82 -0
  188. package/ios/RNFBAppUnitTests/RNFBSharedUtilsNullSentinelTests.m +35 -0
  189. package/ios/RNFBAppUnitTests/RNFBSharedUtilsPromiseRejectionFacadeTests.m +107 -0
  190. package/ios/RNFBAppUnitTests/RNFBSharedUtilsPromiseRejectionTests.swift +133 -0
  191. package/ios/RNFBAppUnitTests/RNFBUtilsHelpersTests.swift +144 -0
  192. package/ios/RNFBAppUnitTests/RNFBUtilsModuleFacadeTests.m +72 -0
  193. package/ios/RNFBAppUnitTests/RNFBUtilsModuleShellTests.mm +282 -0
  194. package/ios/RNFBFirebase/Package.swift +53 -0
  195. package/ios/RNFBFirebase/Sources/RNFBFirebase/RNFBFirebase.swift +285 -0
  196. package/ios/RNFBFirebase/Sources/RNFBFirebaseBridge/Public/.gitkeep +0 -0
  197. package/ios/RNFBFirebase/Sources/RNFBFirebaseBridge/RNFBFirebaseBridge.m +169 -0
  198. package/ios/RNFBFirebase/Sources/RNFBFirebaseBridge/include/RNFBFirebaseBridge.h +52 -0
  199. package/ios/RNFBFirebaseUnitTests/RNFBAppDynamicFacadeTests.swift +240 -0
  200. package/{android/src/main/java/io/invertase/firebase/common/RNFBHandleCollisionException.java → ios/RNFBFirebaseUnitTests/RNFBFirebaseClientImport.swift} +23 -14
  201. package/ios/RNFBFirebaseUnitTests/RNFBFirebaseUnitTests.xcodeproj/project.pbxproj +588 -0
  202. package/ios/RNFBFirebaseUnitTests/RNFBFirebaseUnitTests.xcodeproj/xcshareddata/xcschemes/RNFBFirebaseUnitTests.xcscheme +83 -0
  203. package/ios_config.sh +50 -22
  204. package/lib/FirebaseApp.ts +10 -0
  205. package/lib/common/deeps.ts +3 -0
  206. package/lib/internal/FirebaseModule.ts +6 -3
  207. package/lib/internal/NativeModules.ts +4 -1
  208. package/lib/internal/RNFBNativeEventEmitter.ts +14 -5
  209. package/lib/internal/SharedEventEmitter.ts +5 -1
  210. package/lib/internal/index.ts +1 -0
  211. package/lib/internal/react-native-vendor-emitter.d.ts +11 -0
  212. package/lib/internal/registry/app.ts +7 -1
  213. package/lib/types/app.ts +10 -3
  214. package/lib/types/internal.ts +19 -0
  215. package/lib/version.ts +1 -1
  216. package/package.json +8 -8
  217. package/plugin/build/ios/appDelegate.js +2 -2
  218. package/plugin/build/ios/podfile.js +16 -16
  219. package/plugin/build/pluginConfig.d.ts +4 -2
  220. package/plugin/src/ios/appDelegate.ts +2 -2
  221. package/plugin/src/ios/podfile.ts +20 -23
  222. package/plugin/src/pluginConfig.ts +4 -2
  223. package/android/src/main/java/io/invertase/firebase/common/RNFBHandleMap.java +0 -150
  224. package/android/src/main/java/io/invertase/firebase/common/TaskExecutorService.java +0 -148
  225. package/android/src/main/java/io/invertase/firebase/common/UniversalFirebaseModule.java +0 -62
  226. package/android/src/main/java/io/invertase/firebase/common/UniversalFirebasePreferences.java +0 -91
  227. package/android/src/reactnative/java/io/invertase/firebase/app/NativeRNFBTurboApp.java +0 -224
  228. package/android/src/reactnative/java/io/invertase/firebase/app/ReactNativeFirebaseApp.java +0 -46
  229. package/android/src/reactnative/java/io/invertase/firebase/app/ReactNativeFirebaseAppPackage.java +0 -49
  230. package/android/src/reactnative/java/io/invertase/firebase/app/ReactNativeFirebaseAppRegistrar.java +0 -35
  231. package/android/src/reactnative/java/io/invertase/firebase/common/RCTConvertFirebase.java +0 -192
  232. package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseEvent.java +0 -53
  233. package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseEventEmitter.java +0 -606
  234. package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseJSON.java +0 -109
  235. package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseMeta.java +0 -101
  236. package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseModule.java +0 -146
  237. package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebasePreferences.java +0 -96
  238. package/android/src/reactnative/java/io/invertase/firebase/common/SharedUtils.java +0 -441
  239. package/android/src/reactnative/java/io/invertase/firebase/utils/NativeRNFBTurboUtils.java +0 -223
  240. package/android/src/test/java/io/invertase/firebase/common/RNFBHandleMapTest.java +0 -275
  241. package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebaseJSONTest.java +0 -108
  242. package/android/src/test/java/io/invertase/firebase/common/TaskExecutorServiceTest.java +0 -97
@@ -0,0 +1,254 @@
1
+ package io.invertase.firebase.common
2
+
3
+ /*
4
+ * Copyright (c) 2016-present Invertase Limited & Contributors
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this library except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+
19
+ import android.app.Activity
20
+ import android.content.Context
21
+ import com.facebook.react.bridge.Arguments
22
+ import com.facebook.react.bridge.Promise
23
+ import com.facebook.react.bridge.ReactApplicationContext
24
+ import com.facebook.react.bridge.ReadableMap
25
+ import com.facebook.react.bridge.WritableMap
26
+ import org.json.JSONObject
27
+ import org.junit.After
28
+ import org.junit.Assert.assertEquals
29
+ import org.junit.Assert.assertNotSame
30
+ import org.junit.Assert.assertNull
31
+ import org.junit.Assert.assertSame
32
+ import org.junit.Assert.assertThrows
33
+ import org.junit.Assert.assertTrue
34
+ import org.junit.Before
35
+ import org.junit.Test
36
+ import org.mockito.ArgumentMatchers.anyInt
37
+ import org.mockito.ArgumentMatchers.anyString
38
+ import org.mockito.Mockito.mock
39
+ import org.mockito.Mockito.mockStatic
40
+ import org.mockito.Mockito.never
41
+ import org.mockito.Mockito.verify
42
+ import org.mockito.Mockito.`when`
43
+
44
+ /** Plain JUnit4 + Mockito coverage for the module's bridge and lifecycle contracts. */
45
+ class ReactNativeFirebaseModuleTest {
46
+ private lateinit var jsonObjectField: java.lang.reflect.Field
47
+ private var originalJsonObject: Any? = null
48
+
49
+ @Before
50
+ fun setUp() {
51
+ val jsonObject = mock(JSONObject::class.java)
52
+ `when`(jsonObject.optInt(anyString(), anyInt())).thenAnswer { it.getArgument(1) }
53
+ val json = ReactNativeFirebaseJSON.getSharedInstance()
54
+ jsonObjectField = ReactNativeFirebaseJSON::class.java.getDeclaredField("jsonObject")
55
+ jsonObjectField.isAccessible = true
56
+ originalJsonObject = jsonObjectField.get(json)
57
+ jsonObjectField.set(json, jsonObject)
58
+ }
59
+
60
+ @After
61
+ fun tearDown() {
62
+ jsonObjectField.set(ReactNativeFirebaseJSON.getSharedInstance(), originalJsonObject)
63
+ }
64
+
65
+ @Test
66
+ fun constructorUsesVirtualNameAfterAssigningModuleName() {
67
+ val subject = VirtualNameModule(mock(ReactApplicationContext::class.java))
68
+ val field = ReactNativeFirebaseModule::class.java.getDeclaredField("executorService")
69
+ field.isAccessible = true
70
+ val service = field.get(subject) as TaskExecutorService
71
+
72
+ assertEquals("ExternalChildExecutor", service.getExecutorName(false, ""))
73
+ assertEquals("ExternalChild", subject.name)
74
+ }
75
+
76
+ @Test
77
+ fun namePreservesJavaNullConcatenation() {
78
+ val subject = ReactNativeFirebaseModule(mock(ReactApplicationContext::class.java), null)
79
+
80
+ assertEquals("RNFBnullModule", subject.name)
81
+ }
82
+
83
+ @Test
84
+ fun contextActivityAndApplicationContextDelegateToReactContext() {
85
+ val reactContext = mock(ReactApplicationContext::class.java)
86
+ val applicationContext = mock(Context::class.java)
87
+ val activity = mock(Activity::class.java)
88
+ `when`(reactContext.applicationContext).thenReturn(applicationContext)
89
+ `when`(reactContext.currentActivity).thenReturn(activity)
90
+ val subject = ReactNativeFirebaseModule(reactContext, "App")
91
+
92
+ assertSame(reactContext, subject.getContext())
93
+ assertSame(applicationContext, subject.getApplicationContext())
94
+ assertSame(activity, subject.getActivity())
95
+ subject.initialize()
96
+ }
97
+
98
+ @Test
99
+ fun nullCurrentActivityAndApplicationContextAreReturned() {
100
+ val reactContext = mock(ReactApplicationContext::class.java)
101
+ `when`(reactContext.applicationContext).thenReturn(null)
102
+ `when`(reactContext.currentActivity).thenReturn(null)
103
+ val subject = ReactNativeFirebaseModule(reactContext, "App")
104
+
105
+ assertNull(subject.getApplicationContext())
106
+ assertNull(subject.getActivity())
107
+ }
108
+
109
+ @Test
110
+ fun executorAccessorsAndRemovalPreserveTransactionalBehavior() {
111
+ val subject = ReactNativeFirebaseModule(mock(ReactApplicationContext::class.java), "App")
112
+ val defaultExecutor = subject.getExecutor()
113
+ val transactionalExecutor = subject.getTransactionalExecutor()
114
+ val identifiedExecutor = subject.getTransactionalExecutor("listener")
115
+
116
+ assertSame(defaultExecutor, transactionalExecutor)
117
+ assertNotSame(transactionalExecutor, identifiedExecutor)
118
+ assertSame(identifiedExecutor, subject.getTransactionalExecutor("listener"))
119
+
120
+ subject.removeEventListeningExecutor("listener")
121
+
122
+ assertTrue(identifiedExecutor.isShutdown)
123
+ assertNotSame(identifiedExecutor, subject.getTransactionalExecutor("listener"))
124
+ subject.invalidate()
125
+ assertTrue(defaultExecutor.isShutdown)
126
+ }
127
+
128
+ @Suppress("DEPRECATION")
129
+ @Test
130
+ fun catalystDestroyDynamicallyInvokesChildInvalidate() {
131
+ val subject = LifecycleModule(mock(ReactApplicationContext::class.java))
132
+ val executor = subject.getTransactionalExecutor()
133
+
134
+ subject.onCatalystInstanceDestroy()
135
+
136
+ assertEquals(1, subject.invalidations)
137
+ assertTrue(executor.isShutdown)
138
+ }
139
+
140
+ @Test
141
+ fun constantsAreFreshMutableHashMaps() {
142
+ val subject = ReactNativeFirebaseModule(mock(ReactApplicationContext::class.java), "App")
143
+ val first = subject.constants
144
+ val second = subject.constants
145
+
146
+ first["value"] = 1
147
+ assertTrue(first is HashMap<*, *>)
148
+ assertTrue(second is HashMap<*, *>)
149
+ assertNotSame(first, second)
150
+ assertTrue(second.isEmpty())
151
+ }
152
+
153
+ @Test
154
+ fun rejectionHelpersPreserveMapsAndPromiseOverloads() {
155
+ val promise = mock(Promise::class.java)
156
+ val map = mock(WritableMap::class.java)
157
+ val resolver = mock(ReadableMap::class.java)
158
+ mockStatic(Arguments::class.java).use { arguments ->
159
+ arguments.`when`<WritableMap> { Arguments.createMap() }.thenReturn(map)
160
+
161
+ ReactNativeFirebaseModule.rejectPromiseWithCodeAndMessage(
162
+ promise,
163
+ "code",
164
+ "message",
165
+ resolver,
166
+ )
167
+ verify(map).putString("code", "code")
168
+ verify(map).putString("message", "message")
169
+ verify(map).putMap("resolver", resolver)
170
+ verify(promise).reject("code", "message", map)
171
+
172
+ ReactNativeFirebaseModule.rejectPromiseWithCodeAndMessage(
173
+ promise,
174
+ "without-resolver",
175
+ "message",
176
+ null as ReadableMap?,
177
+ )
178
+ verify(promise).reject("without-resolver", "message", map)
179
+
180
+ ReactNativeFirebaseModule.rejectPromiseWithCodeAndMessage(promise, null, null)
181
+ verify(map).putString("code", null)
182
+ verify(map).putString("message", null)
183
+ verify(promise).reject(null as String?, null as String?, map)
184
+
185
+ ReactNativeFirebaseModule.rejectPromiseWithCodeAndMessage(
186
+ promise,
187
+ "native-code",
188
+ "native-message",
189
+ null as String?,
190
+ )
191
+ verify(map).putString("nativeErrorMessage", null)
192
+ verify(map, never()).putMap("resolver", null)
193
+ verify(promise).reject("native-code", "native-message", map)
194
+
195
+ assertThrows(NullPointerException::class.java) {
196
+ ReactNativeFirebaseModule.rejectPromiseWithCodeAndMessage(null, "code", "message")
197
+ }
198
+ assertThrows(NullPointerException::class.java) {
199
+ ReactNativeFirebaseModule.rejectPromiseWithCodeAndMessage(
200
+ null,
201
+ "code",
202
+ "message",
203
+ resolver,
204
+ )
205
+ }
206
+ assertThrows(NullPointerException::class.java) {
207
+ ReactNativeFirebaseModule.rejectPromiseWithCodeAndMessage(
208
+ null,
209
+ "code",
210
+ "message",
211
+ "native",
212
+ )
213
+ }
214
+ }
215
+ }
216
+
217
+ @Test
218
+ fun exceptionRejectionUsesSharedExceptionMapAndExactOverload() {
219
+ val promise = mock(Promise::class.java)
220
+ val exception = Exception("failure")
221
+ val map = mock(WritableMap::class.java)
222
+ mockStatic(Arguments::class.java).use { arguments ->
223
+ arguments.`when`<WritableMap>(Arguments::createMap).thenReturn(map)
224
+
225
+ ReactNativeFirebaseModule.rejectPromiseWithExceptionMap(promise, exception)
226
+
227
+ verify(promise).reject(exception, map)
228
+ verify(map).putString("code", "unknown")
229
+ verify(map).putString("nativeErrorCode", "unknown")
230
+ verify(map).putString("message", "failure")
231
+ verify(map).putString("nativeErrorMessage", "failure")
232
+ assertThrows(NullPointerException::class.java) {
233
+ ReactNativeFirebaseModule.rejectPromiseWithExceptionMap(null, exception)
234
+ }
235
+ }
236
+ }
237
+
238
+ private class VirtualNameModule(
239
+ reactContext: ReactApplicationContext?,
240
+ ) : ReactNativeFirebaseModule(reactContext, "Ignored") {
241
+ override fun getName(): String = "ExternalChild"
242
+ }
243
+
244
+ private class LifecycleModule(
245
+ reactContext: ReactApplicationContext?,
246
+ ) : ReactNativeFirebaseModule(reactContext, "Lifecycle") {
247
+ var invalidations = 0
248
+
249
+ override fun invalidate() {
250
+ invalidations += 1
251
+ super.invalidate()
252
+ }
253
+ }
254
+ }
@@ -0,0 +1,87 @@
1
+ package io.invertase.firebase.common;
2
+
3
+ /*
4
+ * Copyright (c) 2016-present Invertase Limited & Contributors
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this library except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+
19
+ import static org.junit.Assert.assertFalse;
20
+ import static org.junit.Assert.assertNull;
21
+ import static org.mockito.Mockito.mock;
22
+ import static org.mockito.Mockito.times;
23
+ import static org.mockito.Mockito.verify;
24
+ import static org.mockito.Mockito.when;
25
+
26
+ import android.content.SharedPreferences;
27
+ import java.lang.reflect.Field;
28
+ import org.junit.Before;
29
+ import org.junit.Test;
30
+
31
+ /** Proves the Kotlin port preserves calls that Java permits with null reference arguments. */
32
+ public class ReactNativeFirebasePreferencesJavaCompatibilityTest {
33
+ private SharedPreferences preferences;
34
+ private SharedPreferences.Editor editor;
35
+ private ReactNativeFirebasePreferences subject;
36
+
37
+ @Before
38
+ public void setUp() throws Exception {
39
+ preferences = mock(SharedPreferences.class);
40
+ editor = mock(SharedPreferences.Editor.class);
41
+ when(preferences.edit()).thenReturn(editor);
42
+ when(editor.putBoolean(null, true)).thenReturn(editor);
43
+ when(editor.putInt(null, 42)).thenReturn(editor);
44
+ when(editor.putLong(null, 4294967296L)).thenReturn(editor);
45
+ when(editor.putString(null, null)).thenReturn(editor);
46
+ when(preferences.contains(null)).thenReturn(false);
47
+ when(preferences.getBoolean(null, true)).thenReturn(false);
48
+ when(preferences.getInt(null, 42)).thenReturn(42);
49
+ when(preferences.getLong(null, 4294967296L)).thenReturn(4294967296L);
50
+ when(preferences.getString(null, null)).thenReturn(null);
51
+
52
+ subject = new ReactNativeFirebasePreferences();
53
+ Field field = ReactNativeFirebasePreferences.class.getDeclaredField("preferences");
54
+ field.setAccessible(true);
55
+ field.set(subject, preferences);
56
+ }
57
+
58
+ @Test
59
+ public void publicAccessorsAcceptNullKeysFromJava() {
60
+ assertFalse(subject.contains(null));
61
+ subject.setBooleanValue(null, true);
62
+ assertFalse(subject.getBooleanValue(null, true));
63
+ subject.setIntValue(null, 42);
64
+ subject.getIntValue(null, 42);
65
+ subject.setLongValue(null, 4294967296L);
66
+ subject.getLongValue(null, 4294967296L);
67
+
68
+ verify(preferences).contains(null);
69
+ verify(editor).putBoolean(null, true);
70
+ verify(preferences).getBoolean(null, true);
71
+ verify(editor).putInt(null, 42);
72
+ verify(preferences).getInt(null, 42);
73
+ verify(editor).putLong(null, 4294967296L);
74
+ verify(preferences).getLong(null, 4294967296L);
75
+ verify(editor, times(3)).apply();
76
+ }
77
+
78
+ @Test
79
+ public void stringAccessorsAcceptNullKeyValueAndDefaultAndReturnNullToJava() {
80
+ subject.setStringValue(null, null);
81
+
82
+ assertNull(subject.getStringValue(null, null));
83
+ verify(editor).putString(null, null);
84
+ verify(editor).apply();
85
+ verify(preferences).getString(null, null);
86
+ }
87
+ }
@@ -0,0 +1,260 @@
1
+ package io.invertase.firebase.common
2
+
3
+ /*
4
+ * Copyright (c) 2016-present Invertase Limited & Contributors
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this library except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+
19
+ import android.content.Context
20
+ import android.content.SharedPreferences
21
+ import android.util.Log
22
+ import com.facebook.react.bridge.Arguments
23
+ import com.facebook.react.bridge.WritableMap
24
+ import io.invertase.firebase.app.ReactNativeFirebaseApp
25
+ import org.junit.Assert.assertEquals
26
+ import org.junit.Assert.assertFalse
27
+ import org.junit.Assert.assertSame
28
+ import org.junit.Assert.assertTrue
29
+ import org.junit.Test
30
+ import org.mockito.Mockito.mock
31
+ import org.mockito.Mockito.mockStatic
32
+ import org.mockito.Mockito.times
33
+ import org.mockito.Mockito.verify
34
+ import org.mockito.Mockito.verifyNoMoreInteractions
35
+ import org.mockito.Mockito.`when`
36
+ import java.lang.reflect.Modifier
37
+ import java.util.LinkedHashMap
38
+
39
+ /** Plain JUnit4 + Mockito coverage for the preferences bridge (AndroidTest-AD-1). */
40
+ class ReactNativeFirebasePreferencesTest {
41
+ @Test
42
+ fun javaVisibleApiPreservesConstructorSingletonAndExactMethodTypes() {
43
+ val preferencesClass = ReactNativeFirebasePreferences::class.java
44
+ val constructor = preferencesClass.getConstructor()
45
+ val sharedInstanceMethod = preferencesClass.getMethod("getSharedInstance")
46
+
47
+ assertTrue(Modifier.isPublic(constructor.modifiers))
48
+ assertFalse(Modifier.isFinal(preferencesClass.modifiers))
49
+ assertTrue(Modifier.isStatic(sharedInstanceMethod.modifiers))
50
+ assertEquals(preferencesClass, sharedInstanceMethod.returnType)
51
+ assertSame(
52
+ ReactNativeFirebasePreferences.getSharedInstance(),
53
+ ReactNativeFirebasePreferences.getSharedInstance(),
54
+ )
55
+ assertEquals(
56
+ Boolean::class.javaPrimitiveType,
57
+ preferencesClass.getMethod("contains", String::class.java).returnType,
58
+ )
59
+ assertEquals(
60
+ Void.TYPE,
61
+ preferencesClass
62
+ .getMethod("setBooleanValue", String::class.java, Boolean::class.javaPrimitiveType)
63
+ .returnType,
64
+ )
65
+ assertEquals(
66
+ Boolean::class.javaPrimitiveType,
67
+ preferencesClass
68
+ .getMethod("getBooleanValue", String::class.java, Boolean::class.javaPrimitiveType)
69
+ .returnType,
70
+ )
71
+ assertEquals(
72
+ Void.TYPE,
73
+ preferencesClass
74
+ .getMethod("setIntValue", String::class.java, Int::class.javaPrimitiveType)
75
+ .returnType,
76
+ )
77
+ assertEquals(
78
+ Int::class.javaPrimitiveType,
79
+ preferencesClass
80
+ .getMethod("getIntValue", String::class.java, Int::class.javaPrimitiveType)
81
+ .returnType,
82
+ )
83
+ assertEquals(
84
+ Void.TYPE,
85
+ preferencesClass
86
+ .getMethod("setLongValue", String::class.java, Long::class.javaPrimitiveType)
87
+ .returnType,
88
+ )
89
+ assertEquals(
90
+ Long::class.javaPrimitiveType,
91
+ preferencesClass
92
+ .getMethod("getLongValue", String::class.java, Long::class.javaPrimitiveType)
93
+ .returnType,
94
+ )
95
+ assertEquals(
96
+ Void.TYPE,
97
+ preferencesClass
98
+ .getMethod("setStringValue", String::class.java, String::class.java)
99
+ .returnType,
100
+ )
101
+ assertEquals(
102
+ String::class.java,
103
+ preferencesClass
104
+ .getMethod("getStringValue", String::class.java, String::class.java)
105
+ .returnType,
106
+ )
107
+ assertEquals(WritableMap::class.java, preferencesClass.getMethod("getAll").returnType)
108
+ assertEquals(Void.TYPE, preferencesClass.getMethod("clearAll").returnType)
109
+ preferencesClass.declaredMethods
110
+ .filterNot { Modifier.isStatic(it.modifiers) || Modifier.isPrivate(it.modifiers) }
111
+ .forEach { method -> assertFalse("${method.name} must remain overridable", Modifier.isFinal(method.modifiers)) }
112
+ }
113
+
114
+ @Test
115
+ fun lazyPreferencesUseApplicationContextFileAndModeOnce() {
116
+ val preferences = mock(SharedPreferences::class.java)
117
+ val applicationContext = mock(Context::class.java)
118
+ `when`(
119
+ applicationContext.getSharedPreferences("io.invertase.firebase", Context.MODE_PRIVATE),
120
+ ).thenReturn(preferences)
121
+ `when`(preferences.contains("present")).thenReturn(true)
122
+
123
+ val previous: Context? = ReactNativeFirebaseApp.getApplicationContext()
124
+ mockStatic(Log::class.java).use {
125
+ ReactNativeFirebaseApp.setApplicationContext(applicationContext)
126
+ }
127
+ try {
128
+ val subject = ReactNativeFirebasePreferences()
129
+
130
+ assertTrue(subject.contains("present"))
131
+ assertTrue(subject.contains("present"))
132
+
133
+ verify(applicationContext, times(1))
134
+ .getSharedPreferences("io.invertase.firebase", Context.MODE_PRIVATE)
135
+ verify(preferences, times(2)).contains("present")
136
+ } finally {
137
+ mockStatic(Log::class.java).use {
138
+ ReactNativeFirebaseApp.setApplicationContext(previous)
139
+ }
140
+ }
141
+ }
142
+
143
+ @Test
144
+ fun scalarGettersDelegateAndReturnStoredValues() {
145
+ val preferences = mock(SharedPreferences::class.java)
146
+ val subject = subjectWith(preferences)
147
+ `when`(preferences.contains("present")).thenReturn(true)
148
+ `when`(preferences.getBoolean("boolean", false)).thenReturn(true)
149
+ `when`(preferences.getInt("integer", 0)).thenReturn(42)
150
+ `when`(preferences.getLong("long", 0L)).thenReturn(4_294_967_296L)
151
+ `when`(preferences.getString("string", "fallback")).thenReturn("value")
152
+
153
+ assertTrue(subject.contains("present"))
154
+ assertTrue(subject.getBooleanValue("boolean", false))
155
+ assertEquals(42, subject.getIntValue("integer", 0))
156
+ assertEquals(4_294_967_296L, subject.getLongValue("long", 0L))
157
+ assertEquals("value", subject.getStringValue("string", "fallback"))
158
+ }
159
+
160
+ @Test
161
+ fun scalarSettersApplyAsynchronously() {
162
+ val preferences = mock(SharedPreferences::class.java)
163
+ val editor = mock(SharedPreferences.Editor::class.java)
164
+ val subject = subjectWith(preferences)
165
+ `when`(preferences.edit()).thenReturn(editor)
166
+ `when`(editor.putBoolean("boolean", true)).thenReturn(editor)
167
+ `when`(editor.putInt("integer", 42)).thenReturn(editor)
168
+ `when`(editor.putLong("long", 4_294_967_296L)).thenReturn(editor)
169
+ `when`(editor.putString("string", "value")).thenReturn(editor)
170
+
171
+ subject.setBooleanValue("boolean", true)
172
+ subject.setIntValue("integer", 42)
173
+ subject.setLongValue("long", 4_294_967_296L)
174
+ subject.setStringValue("string", "value")
175
+
176
+ verify(editor).putBoolean("boolean", true)
177
+ verify(editor).putInt("integer", 42)
178
+ verify(editor).putLong("long", 4_294_967_296L)
179
+ verify(editor).putString("string", "value")
180
+ verify(editor, times(4)).apply()
181
+ verifyNoMoreInteractions(editor)
182
+ }
183
+
184
+ @Test
185
+ fun getAllConvertsEveryEntryThroughSharedUtils() {
186
+ val preferences = mock(SharedPreferences::class.java)
187
+ val writableMap = mock(WritableMap::class.java)
188
+ val values =
189
+ LinkedHashMap<String, Any?>().apply {
190
+ put("boolean", true)
191
+ put("integer", 42)
192
+ put("long", 4_294_967_296L)
193
+ put("string", "value")
194
+ put("null", null)
195
+ }
196
+ val subject = subjectWith(preferences)
197
+ `when`(preferences.all).thenReturn(values)
198
+
199
+ mockStatic(Arguments::class.java).use { arguments ->
200
+ arguments.`when`<WritableMap>(Arguments::createMap).thenReturn(writableMap)
201
+
202
+ assertSame(writableMap, subject.getAll())
203
+
204
+ verify(writableMap).putBoolean("boolean", true)
205
+ verify(writableMap).putInt("integer", 42)
206
+ verify(writableMap).putDouble("long", 4_294_967_296.0)
207
+ verify(writableMap).putString("string", "value")
208
+ verify(writableMap).putNull("null")
209
+ }
210
+ }
211
+
212
+ @Test
213
+ fun getAllReturnsCreatedMapWhenPreferencesAreEmpty() {
214
+ val preferences = mock(SharedPreferences::class.java)
215
+ val writableMap = mock(WritableMap::class.java)
216
+ val subject = subjectWith(preferences)
217
+ `when`(preferences.all).thenReturn(emptyMap())
218
+
219
+ mockStatic(Arguments::class.java).use { arguments ->
220
+ arguments.`when`<WritableMap>(Arguments::createMap).thenReturn(writableMap)
221
+
222
+ assertSame(writableMap, subject.getAll())
223
+
224
+ verifyNoMoreInteractions(writableMap)
225
+ }
226
+ }
227
+
228
+ @Test
229
+ fun clearAllClearsAndAppliesAsynchronously() {
230
+ val preferences = mock(SharedPreferences::class.java)
231
+ val editor = mock(SharedPreferences.Editor::class.java)
232
+ val subject = subjectWith(preferences)
233
+ `when`(preferences.edit()).thenReturn(editor)
234
+ `when`(editor.clear()).thenReturn(editor)
235
+
236
+ subject.clearAll()
237
+
238
+ verify(editor).clear()
239
+ verify(editor).apply()
240
+ verifyNoMoreInteractions(editor)
241
+ verify(preferences).edit()
242
+ }
243
+
244
+ @Test
245
+ fun containsReturnsUnderlyingFalseValue() {
246
+ val preferences = mock(SharedPreferences::class.java)
247
+ val subject = subjectWith(preferences)
248
+ `when`(preferences.contains("missing")).thenReturn(false)
249
+
250
+ assertFalse(subject.contains("missing"))
251
+ }
252
+
253
+ private fun subjectWith(preferences: SharedPreferences): ReactNativeFirebasePreferences {
254
+ val subject = ReactNativeFirebasePreferences()
255
+ val field = ReactNativeFirebasePreferences::class.java.getDeclaredField("preferences")
256
+ field.isAccessible = true
257
+ field.set(subject, preferences)
258
+ return subject
259
+ }
260
+ }