@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.
- package/CHANGELOG.md +48 -0
- package/README.md +10 -27
- package/RNFBApp.podspec +13 -5
- package/android/build.gradle +3 -0
- package/android/src/main/java/io/invertase/firebase/common/RNFBHandleCollisionException.kt +29 -0
- package/android/src/main/java/io/invertase/firebase/common/RNFBHandleMap.kt +146 -0
- package/android/src/main/java/io/invertase/firebase/common/TaskExecutorService.kt +156 -0
- package/android/src/main/java/io/invertase/firebase/common/UniversalFirebaseModule.kt +44 -0
- package/android/src/main/java/io/invertase/firebase/common/UniversalFirebasePreferences.kt +100 -0
- package/android/src/reactnative/java/io/invertase/firebase/app/NativeRNFBTurboApp.kt +250 -0
- package/android/src/reactnative/java/io/invertase/firebase/app/ReactNativeFirebaseApp.kt +64 -0
- package/android/src/reactnative/java/io/invertase/firebase/app/{ReactNativeFirebaseAppInitProvider.java → ReactNativeFirebaseAppInitProvider.kt} +3 -4
- package/android/src/reactnative/java/io/invertase/firebase/app/ReactNativeFirebaseAppPackage.kt +47 -0
- package/android/src/reactnative/java/io/invertase/firebase/app/ReactNativeFirebaseAppRegistrar.kt +33 -0
- package/android/src/reactnative/java/io/invertase/firebase/app/ReactNativeFirebaseVersion.java +1 -1
- package/android/src/reactnative/java/io/invertase/firebase/common/RCTConvertFirebase.kt +185 -0
- package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseEvent.kt +35 -0
- package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseEventEmitter.kt +662 -0
- package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseJSON.kt +103 -0
- package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseMeta.kt +96 -0
- package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseModule.kt +140 -0
- package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebasePreferences.kt +109 -0
- package/android/src/reactnative/java/io/invertase/firebase/common/SharedUtils.kt +451 -0
- package/android/src/reactnative/java/io/invertase/firebase/interfaces/{ContextProvider.java → ContextProvider.kt} +8 -8
- package/android/src/reactnative/java/io/invertase/firebase/interfaces/{NativeError.java → NativeError.kt} +8 -8
- package/android/src/reactnative/java/io/invertase/firebase/interfaces/{NativeEvent.java → NativeEvent.kt} +6 -6
- package/android/src/reactnative/java/io/invertase/firebase/utils/NativeRNFBTurboUtils.kt +219 -0
- package/android/src/test/java/expo/core/ModuleRegistry.java +9 -0
- package/android/src/test/java/io/invertase/firebase/app/NativeRNFBTurboAppTest.java +182 -59
- package/android/src/test/java/io/invertase/firebase/app/ReactNativeFirebaseAppComponentsJavaCompatibilityTest.java +70 -0
- package/android/src/test/java/io/invertase/firebase/app/ReactNativeFirebaseAppJavaCompatibilityTest.java +60 -0
- package/android/src/test/java/io/invertase/firebase/app/ReactNativeFirebaseAppPackageTest.java +165 -0
- package/android/src/test/java/io/invertase/firebase/app/ReactNativeFirebaseAppTest.kt +167 -0
- package/android/src/test/java/io/invertase/firebase/common/RCTConvertFirebaseJavaCompatibilityTest.java +112 -0
- package/android/src/test/java/io/invertase/firebase/common/RCTConvertFirebaseTest.kt +317 -0
- package/android/src/test/java/io/invertase/firebase/common/RNFBHandleMapTest.kt +309 -0
- package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebaseEventEmitterJavaCompatibilityTest.java +176 -0
- package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebaseEventEmitterTest.java +143 -12
- package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebaseEventTest.kt +61 -0
- package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebaseJSONJavaCompatibilityTest.java +85 -0
- package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebaseJSONTest.kt +296 -0
- package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebaseMetaJavaCompatibilityTest.java +67 -0
- package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebaseMetaTest.kt +246 -0
- package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebaseModuleTest.kt +254 -0
- package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebasePreferencesJavaCompatibilityTest.java +87 -0
- package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebasePreferencesTest.kt +260 -0
- package/android/src/test/java/io/invertase/firebase/common/SharedUtilsJavaCompatibilityTest.java +255 -0
- package/android/src/test/java/io/invertase/firebase/common/SharedUtilsTest.kt +674 -0
- package/android/src/test/java/io/invertase/firebase/common/TaskExecutorServiceTest.kt +290 -0
- package/android/src/test/java/io/invertase/firebase/common/UniversalFirebaseModuleJavaCompatibilityTest.java +178 -0
- package/android/src/test/java/io/invertase/firebase/common/UniversalFirebasePreferencesJavaCompatibilityTest.java +99 -0
- package/android/src/test/java/io/invertase/firebase/common/UniversalFirebasePreferencesTest.kt +217 -0
- package/android/src/test/java/io/invertase/firebase/commoncompat/ReactNativeFirebaseModuleJavaCompatibilityTest.java +176 -0
- package/android/src/test/java/io/invertase/firebase/commoncompat/ReactNativeFirebaseModuleKotlinCompatibilityTest.kt +52 -0
- package/android/src/test/java/io/invertase/firebase/interfaces/InterfacesJavaCompatibilityTest.java +144 -0
- package/android/src/test/java/io/invertase/firebase/interfaces/NativeEventTest.kt +56 -0
- package/android/src/test/java/io/invertase/firebase/utils/NativeRNFBTurboUtilsTest.java +517 -21
- package/dist/module/FirebaseApp.js +10 -0
- package/dist/module/FirebaseApp.js.map +1 -1
- package/dist/module/common/deeps.js +3 -0
- package/dist/module/common/deeps.js.map +1 -1
- package/dist/module/internal/FirebaseModule.js.map +1 -1
- package/dist/module/internal/RNFBNativeEventEmitter.js +12 -1
- package/dist/module/internal/RNFBNativeEventEmitter.js.map +1 -1
- package/dist/module/internal/SharedEventEmitter.js +3 -1
- package/dist/module/internal/SharedEventEmitter.js.map +1 -1
- package/dist/module/internal/index.js +1 -0
- package/dist/module/internal/index.js.map +1 -1
- package/dist/module/internal/registry/app.js +7 -1
- package/dist/module/internal/registry/app.js.map +1 -1
- package/dist/module/types/app.js.map +1 -1
- package/dist/module/types/internal.js +2 -0
- package/dist/module/version.js +1 -1
- package/dist/typescript/lib/FirebaseApp.d.ts +7 -0
- package/dist/typescript/lib/FirebaseApp.d.ts.map +1 -1
- package/dist/typescript/lib/common/deeps.d.ts.map +1 -1
- package/dist/typescript/lib/internal/FirebaseModule.d.ts +2 -3
- package/dist/typescript/lib/internal/FirebaseModule.d.ts.map +1 -1
- package/dist/typescript/lib/internal/NativeModules.d.ts +4 -1
- package/dist/typescript/lib/internal/NativeModules.d.ts.map +1 -1
- package/dist/typescript/lib/internal/RNFBNativeEventEmitter.d.ts +2 -2
- package/dist/typescript/lib/internal/RNFBNativeEventEmitter.d.ts.map +1 -1
- package/dist/typescript/lib/internal/SharedEventEmitter.d.ts +3 -3
- package/dist/typescript/lib/internal/SharedEventEmitter.d.ts.map +1 -1
- package/dist/typescript/lib/internal/index.d.ts +1 -0
- package/dist/typescript/lib/internal/index.d.ts.map +1 -1
- package/dist/typescript/lib/internal/registry/app.d.ts.map +1 -1
- package/dist/typescript/lib/types/app.d.ts +10 -3
- package/dist/typescript/lib/types/app.d.ts.map +1 -1
- package/dist/typescript/lib/types/internal.d.ts +12 -0
- package/dist/typescript/lib/types/internal.d.ts.map +1 -1
- package/dist/typescript/lib/version.d.ts +1 -1
- package/firebase-schema.json +4 -0
- package/firebase_spm.rb +552 -96
- package/ios/RNFBApp/RCTConvert+FIRApp.h +2 -5
- package/ios/RNFBApp/RCTConvert+FIRApp.m +11 -6
- package/ios/RNFBApp/RCTConvert+FIROptions.h +2 -5
- package/ios/RNFBApp/RCTConvert+FIROptions.m +11 -10
- package/ios/RNFBApp/RCTConvertFIRApp.swift +86 -0
- package/ios/RNFBApp/RCTConvertFIROptions.swift +259 -0
- package/ios/RNFBApp/RNFBAppCustomAuthDomains.swift +63 -0
- package/ios/RNFBApp/RNFBAppInitializeOptionsMapper.swift +113 -0
- package/ios/RNFBApp/RNFBAppLogLevelMapper.swift +53 -0
- package/ios/RNFBApp/RNFBAppModule+CustomAuthDomain.m +35 -0
- package/ios/RNFBApp/RNFBAppModule.h +6 -2
- package/ios/RNFBApp/RNFBAppModule.mm +65 -228
- package/ios/RNFBApp/RNFBAppModuleFirebase.swift +439 -0
- package/ios/RNFBApp/RNFBAppModuleImplementation.h +68 -0
- package/ios/RNFBApp/RNFBAppModuleImplementation.m +195 -0
- package/ios/RNFBApp/RNFBHandleMap.m +27 -56
- package/ios/RNFBApp/RNFBHandleMapStorage.swift +90 -0
- package/ios/RNFBApp/RNFBInitializeAppArguments.swift +82 -0
- package/ios/RNFBApp/RNFBJSON.m +22 -38
- package/ios/RNFBApp/RNFBJSONImplementation.swift +71 -0
- package/ios/RNFBApp/RNFBMeta.m +24 -26
- package/ios/RNFBApp/RNFBMetaStorage.swift +76 -0
- package/ios/RNFBApp/RNFBNullSentinelDecoding.swift +135 -0
- package/ios/RNFBApp/RNFBNullSentinelInterceptor.h +30 -3
- package/ios/RNFBApp/RNFBNullSentinelInterceptor.m +28 -5
- package/ios/RNFBApp/RNFBPreferences.m +22 -20
- package/ios/RNFBApp/RNFBPreferencesStorage.swift +101 -0
- package/ios/RNFBApp/RNFBRCTEventEmitter.m +36 -93
- package/ios/RNFBApp/RNFBRCTEventEmitterCore.swift +161 -0
- package/ios/RNFBApp/RNFBSharedUtils.h +2 -5
- package/ios/RNFBApp/RNFBSharedUtils.m +109 -198
- package/ios/RNFBApp/RNFBSharedUtilsConfig.swift +72 -0
- package/ios/RNFBApp/RNFBSharedUtilsFIRApp.swift +271 -0
- package/ios/RNFBApp/RNFBSharedUtilsFormatting.swift +59 -0
- package/ios/RNFBApp/RNFBSharedUtilsPromiseRejection.swift +88 -0
- package/ios/RNFBApp/RNFBUtilsHelpers.swift +116 -0
- package/ios/RNFBApp/RNFBUtilsModule+Foundation.m +44 -0
- package/ios/RNFBApp/RNFBUtilsModule+PhotoAssets.m +47 -0
- package/ios/RNFBApp/RNFBUtilsModule.h +11 -1
- package/ios/RNFBApp/RNFBUtilsModule.mm +10 -85
- package/ios/RNFBApp/RNFBUtilsModuleImplementation.h +32 -0
- package/ios/RNFBApp/RNFBUtilsModuleImplementation.m +56 -0
- package/ios/RNFBApp/RNFBVersion.m +1 -1
- package/ios/RNFBApp.xcodeproj/project.pbxproj +100 -0
- package/ios/RNFBAppUnitTests/HostStubs/FirebaseCore/FIRApp.m +171 -0
- package/ios/RNFBAppUnitTests/HostStubs/FirebaseCore/FirebaseCore.h +78 -0
- package/ios/RNFBAppUnitTests/HostStubs/FirebaseInstallations/FIRInstallations.m +7 -0
- package/ios/RNFBAppUnitTests/HostStubs/FirebaseInstallations/FirebaseInstallations.h +8 -0
- package/ios/RNFBAppUnitTests/HostStubs/RNFBAppModuleHostStub.m +55 -0
- package/ios/RNFBAppUnitTests/HostStubs/RNFBAppTurboModules.h +89 -0
- package/ios/RNFBAppUnitTests/HostStubs/RNFBAppTurboModules.mm +30 -0
- package/ios/RNFBAppUnitTests/HostStubs/React/RCTBridge.h +19 -0
- package/ios/RNFBAppUnitTests/HostStubs/React/RCTBridge.m +32 -0
- package/ios/RNFBAppUnitTests/HostStubs/React/RCTBridgeModule.h +19 -0
- package/ios/RNFBAppUnitTests/HostStubs/React/RCTConvert.h +28 -0
- package/ios/RNFBAppUnitTests/HostStubs/React/RCTConvert.m +23 -0
- package/ios/RNFBAppUnitTests/HostStubs/React/RCTEventEmitter.h +9 -0
- package/ios/RNFBAppUnitTests/HostStubs/React/RCTInvalidating.h +24 -0
- package/ios/RNFBAppUnitTests/HostStubs/React/RCTUtils.h +9 -0
- package/ios/RNFBAppUnitTests/HostStubs/module.modulemap +13 -0
- package/ios/RNFBAppUnitTests/RCTConvertFIRAppFacadeTests.m +61 -0
- package/ios/RNFBAppUnitTests/RCTConvertFIRAppTests.swift +73 -0
- package/ios/RNFBAppUnitTests/RCTConvertFIROptionsFacadeTests.m +57 -0
- package/ios/RNFBAppUnitTests/RCTConvertFIROptionsTests.swift +243 -0
- package/ios/RNFBAppUnitTests/RNFBAppCustomAuthDomainsFacadeTests.m +73 -0
- package/ios/RNFBAppUnitTests/RNFBAppCustomAuthDomainsTests.swift +70 -0
- package/ios/RNFBAppUnitTests/RNFBAppInitializeOptionsMapperTests.swift +190 -0
- package/ios/RNFBAppUnitTests/RNFBAppLogLevelFacadeTests.m +76 -0
- package/ios/RNFBAppUnitTests/RNFBAppLogLevelMapperTests.swift +59 -0
- package/ios/RNFBAppUnitTests/RNFBAppModuleFirebaseFacadeTests.m +215 -0
- package/ios/RNFBAppUnitTests/RNFBAppModuleFirebaseTests.swift +430 -0
- package/ios/RNFBAppUnitTests/RNFBAppModuleLifecycleTests.m +206 -0
- package/ios/RNFBAppUnitTests/RNFBAppModuleShellTests.mm +367 -0
- package/ios/RNFBAppUnitTests/RNFBAppUnitTests.xcodeproj/project.pbxproj +355 -2
- package/ios/RNFBAppUnitTests/RNFBFirebaseAppClientTests.swift +165 -0
- package/ios/RNFBAppUnitTests/RNFBHandleMapStorageTests.swift +121 -0
- package/ios/RNFBAppUnitTests/RNFBInitializeAppArgumentsTests.swift +256 -0
- package/ios/RNFBAppUnitTests/RNFBJSONImplementationTests.swift +126 -0
- package/ios/RNFBAppUnitTests/RNFBJSONTests.m +172 -0
- package/ios/RNFBAppUnitTests/RNFBMetaStorageTests.swift +106 -0
- package/ios/RNFBAppUnitTests/RNFBMetaTests.m +65 -0
- package/ios/RNFBAppUnitTests/RNFBNullSentinelDecodingTests.swift +286 -0
- package/ios/RNFBAppUnitTests/RNFBNullSentinelInterceptorTests.m +312 -0
- package/ios/RNFBAppUnitTests/RNFBPreferencesStorageTests.swift +105 -0
- package/ios/RNFBAppUnitTests/RNFBPreferencesTests.m +110 -0
- package/ios/RNFBAppUnitTests/RNFBRCTEventEmitterCoreTests.swift +163 -0
- package/ios/RNFBAppUnitTests/RNFBRCTEventEmitterFacadeTests.m +141 -0
- package/ios/RNFBAppUnitTests/RNFBSharedUtilsConfigFacadeTests.m +100 -0
- package/ios/RNFBAppUnitTests/RNFBSharedUtilsConfigTests.swift +234 -0
- package/ios/RNFBAppUnitTests/RNFBSharedUtilsFIRAppFacadeTests.m +145 -0
- package/ios/RNFBAppUnitTests/RNFBSharedUtilsFIRAppTests.swift +173 -0
- package/ios/RNFBAppUnitTests/RNFBSharedUtilsFormattingFacadeTests.m +38 -0
- package/ios/RNFBAppUnitTests/RNFBSharedUtilsFormattingTests.swift +82 -0
- package/ios/RNFBAppUnitTests/RNFBSharedUtilsNullSentinelTests.m +35 -0
- package/ios/RNFBAppUnitTests/RNFBSharedUtilsPromiseRejectionFacadeTests.m +107 -0
- package/ios/RNFBAppUnitTests/RNFBSharedUtilsPromiseRejectionTests.swift +133 -0
- package/ios/RNFBAppUnitTests/RNFBUtilsHelpersTests.swift +144 -0
- package/ios/RNFBAppUnitTests/RNFBUtilsModuleFacadeTests.m +72 -0
- package/ios/RNFBAppUnitTests/RNFBUtilsModuleShellTests.mm +282 -0
- package/ios/RNFBFirebase/Package.swift +53 -0
- package/ios/RNFBFirebase/Sources/RNFBFirebase/RNFBFirebase.swift +285 -0
- package/ios/RNFBFirebase/Sources/RNFBFirebaseBridge/Public/.gitkeep +0 -0
- package/ios/RNFBFirebase/Sources/RNFBFirebaseBridge/RNFBFirebaseBridge.m +169 -0
- package/ios/RNFBFirebase/Sources/RNFBFirebaseBridge/include/RNFBFirebaseBridge.h +52 -0
- package/ios/RNFBFirebaseUnitTests/RNFBAppDynamicFacadeTests.swift +240 -0
- package/{android/src/main/java/io/invertase/firebase/common/RNFBHandleCollisionException.java → ios/RNFBFirebaseUnitTests/RNFBFirebaseClientImport.swift} +23 -14
- package/ios/RNFBFirebaseUnitTests/RNFBFirebaseUnitTests.xcodeproj/project.pbxproj +588 -0
- package/ios/RNFBFirebaseUnitTests/RNFBFirebaseUnitTests.xcodeproj/xcshareddata/xcschemes/RNFBFirebaseUnitTests.xcscheme +83 -0
- package/ios_config.sh +50 -22
- package/lib/FirebaseApp.ts +10 -0
- package/lib/common/deeps.ts +3 -0
- package/lib/internal/FirebaseModule.ts +6 -3
- package/lib/internal/NativeModules.ts +4 -1
- package/lib/internal/RNFBNativeEventEmitter.ts +14 -5
- package/lib/internal/SharedEventEmitter.ts +5 -1
- package/lib/internal/index.ts +1 -0
- package/lib/internal/react-native-vendor-emitter.d.ts +11 -0
- package/lib/internal/registry/app.ts +7 -1
- package/lib/types/app.ts +10 -3
- package/lib/types/internal.ts +19 -0
- package/lib/version.ts +1 -1
- package/package.json +8 -8
- package/plugin/build/ios/appDelegate.js +2 -2
- package/plugin/build/ios/podfile.js +16 -16
- package/plugin/build/pluginConfig.d.ts +4 -2
- package/plugin/src/ios/appDelegate.ts +2 -2
- package/plugin/src/ios/podfile.ts +20 -23
- package/plugin/src/pluginConfig.ts +4 -2
- package/android/src/main/java/io/invertase/firebase/common/RNFBHandleMap.java +0 -150
- package/android/src/main/java/io/invertase/firebase/common/TaskExecutorService.java +0 -148
- package/android/src/main/java/io/invertase/firebase/common/UniversalFirebaseModule.java +0 -62
- package/android/src/main/java/io/invertase/firebase/common/UniversalFirebasePreferences.java +0 -91
- package/android/src/reactnative/java/io/invertase/firebase/app/NativeRNFBTurboApp.java +0 -224
- package/android/src/reactnative/java/io/invertase/firebase/app/ReactNativeFirebaseApp.java +0 -46
- package/android/src/reactnative/java/io/invertase/firebase/app/ReactNativeFirebaseAppPackage.java +0 -49
- package/android/src/reactnative/java/io/invertase/firebase/app/ReactNativeFirebaseAppRegistrar.java +0 -35
- package/android/src/reactnative/java/io/invertase/firebase/common/RCTConvertFirebase.java +0 -192
- package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseEvent.java +0 -53
- package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseEventEmitter.java +0 -606
- package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseJSON.java +0 -109
- package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseMeta.java +0 -101
- package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseModule.java +0 -146
- package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebasePreferences.java +0 -96
- package/android/src/reactnative/java/io/invertase/firebase/common/SharedUtils.java +0 -441
- package/android/src/reactnative/java/io/invertase/firebase/utils/NativeRNFBTurboUtils.java +0 -223
- package/android/src/test/java/io/invertase/firebase/common/RNFBHandleMapTest.java +0 -275
- package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebaseJSONTest.java +0 -108
- package/android/src/test/java/io/invertase/firebase/common/TaskExecutorServiceTest.java +0 -97
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this library except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import Foundation
|
|
18
|
+
import XCTest
|
|
19
|
+
|
|
20
|
+
final class RNFBUtilsHelpersTests: XCTestCase {
|
|
21
|
+
func testPathForDirectoryReturnsSearchPathFirstObject() {
|
|
22
|
+
let caches = RNFBUtilsHelpers.path(
|
|
23
|
+
forDirectory: Int32(FileManager.SearchPathDirectory.cachesDirectory.rawValue)
|
|
24
|
+
)
|
|
25
|
+
let expected = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true)
|
|
26
|
+
.first
|
|
27
|
+
XCTAssertEqual(caches, expected)
|
|
28
|
+
XCTAssertNotNil(caches)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
func testUtilsConstantsDictionaryIncludesRequiredKeys() {
|
|
32
|
+
let constants = RNFBUtilsHelpers.utilsConstantsDictionary(
|
|
33
|
+
bundlePath: "/App.app",
|
|
34
|
+
appVersion: "1.2.3",
|
|
35
|
+
pathProvider: { directory in "path-\(directory)" },
|
|
36
|
+
temporaryDirectory: "/tmp/rnfb"
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
XCTAssertEqual(constants["isRunningInTestLab"] as? Bool, false)
|
|
40
|
+
XCTAssertEqual(constants["MAIN_BUNDLE"] as? String, "/App.app")
|
|
41
|
+
XCTAssertEqual(
|
|
42
|
+
constants["CACHES_DIRECTORY"] as? String,
|
|
43
|
+
"path-\(FileManager.SearchPathDirectory.cachesDirectory.rawValue)"
|
|
44
|
+
)
|
|
45
|
+
XCTAssertEqual(
|
|
46
|
+
constants["DOCUMENT_DIRECTORY"] as? String,
|
|
47
|
+
"path-\(FileManager.SearchPathDirectory.documentDirectory.rawValue)"
|
|
48
|
+
)
|
|
49
|
+
XCTAssertEqual(
|
|
50
|
+
constants["PICTURES_DIRECTORY"] as? String,
|
|
51
|
+
"path-\(FileManager.SearchPathDirectory.picturesDirectory.rawValue)"
|
|
52
|
+
)
|
|
53
|
+
XCTAssertEqual(
|
|
54
|
+
constants["MOVIES_DIRECTORY"] as? String,
|
|
55
|
+
"path-\(FileManager.SearchPathDirectory.moviesDirectory.rawValue)"
|
|
56
|
+
)
|
|
57
|
+
XCTAssertEqual(constants["TEMP_DIRECTORY"] as? String, "/tmp/rnfb")
|
|
58
|
+
XCTAssertEqual(
|
|
59
|
+
constants["LIBRARY_DIRECTORY"] as? String,
|
|
60
|
+
"path-\(FileManager.SearchPathDirectory.libraryDirectory.rawValue)"
|
|
61
|
+
)
|
|
62
|
+
XCTAssertEqual(constants["appVersion"] as? String, "1.2.3")
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
func testUtilsConstantsDictionaryOmitsAppVersionWhenMissingEmptyOrNonString() {
|
|
66
|
+
let pathProvider: RNFBUtilsPathProvider = { _ in "/p" }
|
|
67
|
+
|
|
68
|
+
let missing = RNFBUtilsHelpers.utilsConstantsDictionary(
|
|
69
|
+
bundlePath: "/b",
|
|
70
|
+
appVersion: nil,
|
|
71
|
+
pathProvider: pathProvider,
|
|
72
|
+
temporaryDirectory: "/t"
|
|
73
|
+
)
|
|
74
|
+
XCTAssertNil(missing["appVersion"])
|
|
75
|
+
|
|
76
|
+
let empty = RNFBUtilsHelpers.utilsConstantsDictionary(
|
|
77
|
+
bundlePath: "/b",
|
|
78
|
+
appVersion: "",
|
|
79
|
+
pathProvider: pathProvider,
|
|
80
|
+
temporaryDirectory: "/t"
|
|
81
|
+
)
|
|
82
|
+
XCTAssertNil(empty["appVersion"])
|
|
83
|
+
|
|
84
|
+
let nonString = RNFBUtilsHelpers.utilsConstantsDictionary(
|
|
85
|
+
bundlePath: "/b",
|
|
86
|
+
appVersion: NSNumber(value: 42),
|
|
87
|
+
pathProvider: pathProvider,
|
|
88
|
+
temporaryDirectory: "/t"
|
|
89
|
+
)
|
|
90
|
+
XCTAssertNil(nonString["appVersion"])
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
func testUtilsConstantsDictionaryDefaultUsesMainBundle() {
|
|
94
|
+
let constants = RNFBUtilsHelpers.utilsConstantsDictionary()
|
|
95
|
+
XCTAssertEqual(constants["MAIN_BUNDLE"] as? String, Bundle.main.bundlePath)
|
|
96
|
+
XCTAssertEqual(constants["isRunningInTestLab"] as? Bool, false)
|
|
97
|
+
XCTAssertNotNil(constants["CACHES_DIRECTORY"])
|
|
98
|
+
XCTAssertNotNil(constants["TEMP_DIRECTORY"])
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
func testIsRemoteAssetPrefixChecks() {
|
|
102
|
+
XCTAssertTrue(RNFBUtilsHelpers.isRemoteAsset("assets-library://asset/foo"))
|
|
103
|
+
XCTAssertTrue(RNFBUtilsHelpers.isRemoteAsset("ph://LOCAL-ID"))
|
|
104
|
+
XCTAssertFalse(RNFBUtilsHelpers.isRemoteAsset("file:///tmp/x.jpg"))
|
|
105
|
+
XCTAssertFalse(RNFBUtilsHelpers.isRemoteAsset(""))
|
|
106
|
+
XCTAssertFalse(RNFBUtilsHelpers.isRemoteAsset(nil))
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
func testUnusedIsHeicCaseInsensitiveAndNilMessaging() {
|
|
110
|
+
XCTAssertTrue(RNFBUtilsHelpers.unusedIsHeic("photo.heic"))
|
|
111
|
+
XCTAssertTrue(RNFBUtilsHelpers.unusedIsHeic("photo.HEIC"))
|
|
112
|
+
XCTAssertTrue(RNFBUtilsHelpers.unusedIsHeic("photo.Heic"))
|
|
113
|
+
XCTAssertFalse(RNFBUtilsHelpers.unusedIsHeic("photo.jpg"))
|
|
114
|
+
XCTAssertFalse(RNFBUtilsHelpers.unusedIsHeic("heic"))
|
|
115
|
+
// Pre-port ObjC nil messaging → YES
|
|
116
|
+
XCTAssertTrue(RNFBUtilsHelpers.unusedIsHeic(nil))
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
func testValueForKeyFromQueryItemsUsesNamePredicateAndFirstObject() {
|
|
120
|
+
let items = [
|
|
121
|
+
URLQueryItem(name: "other", value: "a"),
|
|
122
|
+
URLQueryItem(name: "id", value: "first-id"),
|
|
123
|
+
URLQueryItem(name: "id", value: "second-id"),
|
|
124
|
+
]
|
|
125
|
+
|
|
126
|
+
XCTAssertEqual(
|
|
127
|
+
RNFBUtilsHelpers.value(forKey: "id", fromQueryItems: items),
|
|
128
|
+
"first-id"
|
|
129
|
+
)
|
|
130
|
+
XCTAssertEqual(
|
|
131
|
+
RNFBUtilsHelpers.value(forKey: "other", fromQueryItems: items),
|
|
132
|
+
"a"
|
|
133
|
+
)
|
|
134
|
+
XCTAssertNil(RNFBUtilsHelpers.value(forKey: "missing", fromQueryItems: items))
|
|
135
|
+
XCTAssertNil(RNFBUtilsHelpers.value(forKey: "id", fromQueryItems: nil))
|
|
136
|
+
XCTAssertNil(RNFBUtilsHelpers.value(forKey: "id", fromQueryItems: []))
|
|
137
|
+
XCTAssertNil(
|
|
138
|
+
RNFBUtilsHelpers.value(
|
|
139
|
+
forKey: "id",
|
|
140
|
+
fromQueryItems: [URLQueryItem(name: "id", value: nil)]
|
|
141
|
+
)
|
|
142
|
+
)
|
|
143
|
+
}
|
|
144
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this library except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
#import <XCTest/XCTest.h>
|
|
18
|
+
|
|
19
|
+
#import "RNFBHandleMapStorage-Swift.inc"
|
|
20
|
+
#import "RNFBUtilsModule.h"
|
|
21
|
+
|
|
22
|
+
@interface RNFBUtilsModuleFacadeTests : XCTestCase
|
|
23
|
+
@end
|
|
24
|
+
|
|
25
|
+
@implementation RNFBUtilsModuleFacadeTests
|
|
26
|
+
|
|
27
|
+
- (void)testFacadePathForDirectoryMatchesSearchPath {
|
|
28
|
+
NSString *path = [RNFBUtilsHelpers pathForDirectory:(int)NSCachesDirectory];
|
|
29
|
+
NSString *expected =
|
|
30
|
+
[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
|
|
31
|
+
XCTAssertEqualObjects(path, expected);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
- (void)testFacadeUtilsConstantsDictionaryKeys {
|
|
35
|
+
NSDictionary *constants = [RNFBUtilsHelpers
|
|
36
|
+
utilsConstantsDictionaryWithBundlePath:@"/Bundle.app"
|
|
37
|
+
appVersion:@"9.9.9"
|
|
38
|
+
pathProvider:^NSString *(int directory) {
|
|
39
|
+
return [NSString stringWithFormat:@"dir-%d", directory];
|
|
40
|
+
}
|
|
41
|
+
temporaryDirectory:@"/tmp/facade"];
|
|
42
|
+
|
|
43
|
+
XCTAssertEqualObjects(constants[@"isRunningInTestLab"], @NO);
|
|
44
|
+
XCTAssertEqualObjects(constants[@"MAIN_BUNDLE"], @"/Bundle.app");
|
|
45
|
+
XCTAssertEqualObjects(constants[@"TEMP_DIRECTORY"], @"/tmp/facade");
|
|
46
|
+
XCTAssertEqualObjects(constants[@"appVersion"], @"9.9.9");
|
|
47
|
+
XCTAssertEqualObjects(constants[@"CACHES_DIRECTORY"],
|
|
48
|
+
([NSString stringWithFormat:@"dir-%d", (int)NSCachesDirectory]));
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
- (void)testFacadeIsRemoteAsset {
|
|
52
|
+
XCTAssertTrue([RNFBUtilsModule isRemoteAsset:@"assets-library://x"]);
|
|
53
|
+
XCTAssertTrue([RNFBUtilsModule isRemoteAsset:@"ph://y"]);
|
|
54
|
+
XCTAssertFalse([RNFBUtilsModule isRemoteAsset:@"/local/file.jpg"]);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
- (void)testFacadeUnusedIsHeic {
|
|
58
|
+
XCTAssertTrue([RNFBUtilsModule unused_isHeic:@"a.HEIC"]);
|
|
59
|
+
XCTAssertFalse([RNFBUtilsModule unused_isHeic:@"a.png"]);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
- (void)testFacadeValueForKeyFromQueryItems {
|
|
63
|
+
NSArray *items = @[
|
|
64
|
+
[NSURLQueryItem queryItemWithName:@"id" value:@"asset-1"],
|
|
65
|
+
[NSURLQueryItem queryItemWithName:@"w" value:@"100"],
|
|
66
|
+
];
|
|
67
|
+
XCTAssertEqualObjects([RNFBUtilsModule valueForKey:@"id" fromQueryItems:items], @"asset-1");
|
|
68
|
+
XCTAssertEqualObjects([RNFBUtilsModule valueForKey:@"w" fromQueryItems:items], @"100");
|
|
69
|
+
XCTAssertNil([RNFBUtilsModule valueForKey:@"missing" fromQueryItems:items]);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
@end
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this library except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
#import <Photos/Photos.h>
|
|
18
|
+
#import <XCTest/XCTest.h>
|
|
19
|
+
#import <objc/runtime.h>
|
|
20
|
+
|
|
21
|
+
#import "RNFBAppTurboModules.h"
|
|
22
|
+
#import "RNFBUtilsModule.h"
|
|
23
|
+
#import "RNFBUtilsModuleImplementation.h"
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Exercises the shipped `RNFBUtilsModule.mm` shell, the Android-only stubs in
|
|
27
|
+
* `RNFBUtilsModuleImplementation.m` and the PhotoKit category in
|
|
28
|
+
* `RNFBUtilsModule+PhotoAssets.m`. All three are compiled into this target.
|
|
29
|
+
*/
|
|
30
|
+
@interface RNFBUtilsModule (ShellTesting)
|
|
31
|
+
- (facebook::react::ModuleConstants<JS::NativeRNFBTurboUtils::Constants>)constantsToExport;
|
|
32
|
+
- (facebook::react::ModuleConstants<JS::NativeRNFBTurboUtils::Constants>)getConstants;
|
|
33
|
+
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
|
|
34
|
+
(const facebook::react::ObjCTurboModule::InitParams &)params;
|
|
35
|
+
+ (BOOL)requiresMainQueueSetup;
|
|
36
|
+
+ (NSString *)moduleName;
|
|
37
|
+
- (void)androidGetPlayServicesStatus:(RCTPromiseResolveBlock)resolve
|
|
38
|
+
reject:(RCTPromiseRejectBlock)reject;
|
|
39
|
+
- (void)androidPromptForPlayServices:(RCTPromiseResolveBlock)resolve
|
|
40
|
+
reject:(RCTPromiseRejectBlock)reject;
|
|
41
|
+
- (void)androidResolutionForPlayServices:(RCTPromiseResolveBlock)resolve
|
|
42
|
+
reject:(RCTPromiseRejectBlock)reject;
|
|
43
|
+
- (void)androidMakePlayServicesAvailable:(RCTPromiseResolveBlock)resolve
|
|
44
|
+
reject:(RCTPromiseRejectBlock)reject;
|
|
45
|
+
@end
|
|
46
|
+
|
|
47
|
+
/** `PHFetchResult` stand-in whose `firstObject` is controlled by the test. */
|
|
48
|
+
@interface RNFBFakeFetchResult : PHFetchResult
|
|
49
|
+
@property(nonatomic, strong, nullable) PHAsset *stubbedFirstObject;
|
|
50
|
+
@end
|
|
51
|
+
|
|
52
|
+
@implementation RNFBFakeFetchResult
|
|
53
|
+
- (id)firstObject {
|
|
54
|
+
return self.stubbedFirstObject;
|
|
55
|
+
}
|
|
56
|
+
@end
|
|
57
|
+
|
|
58
|
+
static SEL PHAssetFetchSelector(void) {
|
|
59
|
+
return @selector(fetchAssetsWithLocalIdentifiers:options:);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
@interface RNFBUtilsModuleShellTests : XCTestCase
|
|
63
|
+
@property(nonatomic, strong) PHAsset *fakeAsset;
|
|
64
|
+
@property(nonatomic, strong) NSMutableArray<NSArray<NSString *> *> *fetchedIdentifiers;
|
|
65
|
+
@property(nonatomic, strong) NSMutableArray<NSNumber *> *fetchedOptionsWereNil;
|
|
66
|
+
@property(nonatomic, assign) IMP originalFetchImplementation;
|
|
67
|
+
@end
|
|
68
|
+
|
|
69
|
+
@implementation RNFBUtilsModuleShellTests
|
|
70
|
+
|
|
71
|
+
#pragma mark - Module shell
|
|
72
|
+
|
|
73
|
+
- (void)testExportedModuleNameAndMainQueueSetup {
|
|
74
|
+
XCTAssertEqualObjects([RNFBUtilsModule moduleName], @"NativeRNFBTurboUtils");
|
|
75
|
+
XCTAssertFalse([RNFBUtilsModule requiresMainQueueSetup]);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
- (void)testGetTurboModuleCreatesTheUtilsSpecModule {
|
|
79
|
+
RNFBUtilsModule *module = [[RNFBUtilsModule alloc] init];
|
|
80
|
+
facebook::react::ObjCTurboModule::InitParams params;
|
|
81
|
+
|
|
82
|
+
auto turboModule = [module getTurboModule:params];
|
|
83
|
+
|
|
84
|
+
XCTAssertTrue(turboModule != nullptr);
|
|
85
|
+
XCTAssertTrue(std::dynamic_pointer_cast<facebook::react::NativeRNFBTurboUtilsSpecJSI>(
|
|
86
|
+
turboModule) != nullptr);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
- (void)testConstantsToExportAndGetConstantsReturnUtilsConstants {
|
|
90
|
+
RNFBUtilsModule *module = [[RNFBUtilsModule alloc] init];
|
|
91
|
+
|
|
92
|
+
auto exported = [module constantsToExport];
|
|
93
|
+
auto fetched = [module getConstants];
|
|
94
|
+
|
|
95
|
+
for (NSDictionary *constants in @[ exported.dictionary, fetched.dictionary ]) {
|
|
96
|
+
XCTAssertEqualObjects(constants[@"isRunningInTestLab"], @NO);
|
|
97
|
+
XCTAssertNotNil(constants[@"MAIN_BUNDLE"]);
|
|
98
|
+
XCTAssertNotNil(constants[@"TEMP_DIRECTORY"]);
|
|
99
|
+
XCTAssertNotNil(constants[@"CACHES_DIRECTORY"]);
|
|
100
|
+
}
|
|
101
|
+
XCTAssertEqualObjects(RNFBUtilsModuleConstantsDictionary()[@"isRunningInTestLab"], @NO);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
#pragma mark - Android-only stubs
|
|
105
|
+
|
|
106
|
+
- (void)testAndroidPlayServicesStatusReportsAvailableOnIOS {
|
|
107
|
+
RNFBUtilsModule *module = [[RNFBUtilsModule alloc] init];
|
|
108
|
+
__block NSDictionary *viaModule = nil;
|
|
109
|
+
__block NSDictionary *viaFunction = nil;
|
|
110
|
+
|
|
111
|
+
[module
|
|
112
|
+
androidGetPlayServicesStatus:^(id result) {
|
|
113
|
+
viaModule = result;
|
|
114
|
+
}
|
|
115
|
+
reject:^(NSString *code, NSString *message, NSError *error) {
|
|
116
|
+
XCTFail(@"unexpected reject %@", message);
|
|
117
|
+
}];
|
|
118
|
+
RNFBUtilsModuleAndroidGetPlayServicesStatus(
|
|
119
|
+
^(id result) {
|
|
120
|
+
viaFunction = result;
|
|
121
|
+
},
|
|
122
|
+
^(NSString *code, NSString *message, NSError *error) {
|
|
123
|
+
XCTFail(@"unexpected reject %@", message);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
NSDictionary *expected = @{
|
|
127
|
+
@"isAvailable" : @YES,
|
|
128
|
+
@"status" : @0,
|
|
129
|
+
@"hasResolution" : @NO,
|
|
130
|
+
@"isUserResolvableError" : @NO,
|
|
131
|
+
};
|
|
132
|
+
XCTAssertEqualObjects(viaModule, expected);
|
|
133
|
+
XCTAssertEqualObjects(viaFunction, expected);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
- (void)testAndroidPromptResolutionAndMakeAvailableResolveNil {
|
|
137
|
+
RNFBUtilsModule *module = [[RNFBUtilsModule alloc] init];
|
|
138
|
+
RCTPromiseRejectBlock failOnReject = ^(NSString *code, NSString *message, NSError *error) {
|
|
139
|
+
XCTFail(@"unexpected reject %@", message);
|
|
140
|
+
};
|
|
141
|
+
__block NSUInteger resolveCount = 0;
|
|
142
|
+
__block BOOL sawNonNil = NO;
|
|
143
|
+
RCTPromiseResolveBlock countNil = ^(id result) {
|
|
144
|
+
resolveCount += 1;
|
|
145
|
+
sawNonNil = sawNonNil || result != nil;
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
[module androidPromptForPlayServices:countNil reject:failOnReject];
|
|
149
|
+
[module androidResolutionForPlayServices:countNil reject:failOnReject];
|
|
150
|
+
[module androidMakePlayServicesAvailable:countNil reject:failOnReject];
|
|
151
|
+
RNFBUtilsModuleAndroidPromptForPlayServices(countNil, failOnReject);
|
|
152
|
+
RNFBUtilsModuleAndroidResolutionForPlayServices(countNil, failOnReject);
|
|
153
|
+
RNFBUtilsModuleAndroidMakePlayServicesAvailable(countNil, failOnReject);
|
|
154
|
+
|
|
155
|
+
XCTAssertEqual(resolveCount, 6);
|
|
156
|
+
XCTAssertFalse(sawNonNil);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
#pragma mark - PhotoKit category
|
|
160
|
+
|
|
161
|
+
- (void)testAssetsLibraryPathsAreUnsupportedAndNeverQueryPhotos {
|
|
162
|
+
[self stubPhotoLibraryReturning:[self fetchResultContaining:self.fakeAsset]];
|
|
163
|
+
|
|
164
|
+
// The one-time warning is suppressed on later calls; the result stays nil and PhotoKit is never
|
|
165
|
+
// consulted for the removed `assets-library://` scheme, even when an id is present.
|
|
166
|
+
XCTAssertNil([RNFBUtilsModule fetchAssetForPath:@"assets-library://asset/asset.JPG?id=1"]);
|
|
167
|
+
XCTAssertNil([RNFBUtilsModule fetchAssetForPath:@"assets-library://asset/asset.JPG?id=2"]);
|
|
168
|
+
|
|
169
|
+
XCTAssertEqual(self.fetchedIdentifiers.count, 0);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
- (void)testPhotoLibraryPathPassesEverythingAfterTheSchemeToPhotoKit {
|
|
173
|
+
[self stubPhotoLibraryReturning:[self fetchResultContaining:self.fakeAsset]];
|
|
174
|
+
|
|
175
|
+
PHAsset *asset = [RNFBUtilsModule fetchAssetForPath:@"ph://ABC-123/L0/001"];
|
|
176
|
+
|
|
177
|
+
XCTAssertEqual(asset, self.fakeAsset);
|
|
178
|
+
XCTAssertEqualObjects(self.fetchedIdentifiers, @[ @[ @"ABC-123/L0/001" ] ]);
|
|
179
|
+
XCTAssertEqual(self.fetchedOptionsWereNil.count, 1);
|
|
180
|
+
XCTAssertEqualObjects(self.fetchedOptionsWereNil.firstObject, @YES);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
- (void)testPhotoLibraryPathWithNoMatchingAssetReturnsNil {
|
|
184
|
+
[self stubPhotoLibraryReturning:[self fetchResultContaining:nil]];
|
|
185
|
+
|
|
186
|
+
XCTAssertNil([RNFBUtilsModule fetchAssetForPath:@"ph://missing-local-identifier"]);
|
|
187
|
+
XCTAssertEqualObjects(self.fetchedIdentifiers, @[ @[ @"missing-local-identifier" ] ]);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
- (void)testPhotoLibraryPathWithNoIdentifierLooksUpTheEmptyIdentifier {
|
|
191
|
+
[self stubPhotoLibraryReturning:[self fetchResultContaining:nil]];
|
|
192
|
+
|
|
193
|
+
XCTAssertNil([RNFBUtilsModule fetchAssetForPath:@"ph://"]);
|
|
194
|
+
XCTAssertEqualObjects(self.fetchedIdentifiers, @[ @[ @"" ] ]);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
- (void)testOtherPathsLookUpTheIdQueryItem {
|
|
198
|
+
[self stubPhotoLibraryReturning:[self fetchResultContaining:self.fakeAsset]];
|
|
199
|
+
|
|
200
|
+
PHAsset *asset =
|
|
201
|
+
[RNFBUtilsModule fetchAssetForPath:@"file:///asset.jpg?w=100&id=local-identifier&h=50"];
|
|
202
|
+
|
|
203
|
+
XCTAssertEqual(asset, self.fakeAsset);
|
|
204
|
+
XCTAssertEqualObjects(self.fetchedIdentifiers, @[ @[ @"local-identifier" ] ]);
|
|
205
|
+
XCTAssertEqualObjects(self.fetchedOptionsWereNil.firstObject, @YES);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
- (void)testOtherPathsWithNoMatchingAssetReturnNil {
|
|
209
|
+
[self stubPhotoLibraryReturning:[self fetchResultContaining:nil]];
|
|
210
|
+
|
|
211
|
+
XCTAssertNil(
|
|
212
|
+
[RNFBUtilsModule fetchAssetForPath:@"file:///asset.jpg?id=missing-local-identifier"]);
|
|
213
|
+
XCTAssertEqualObjects(self.fetchedIdentifiers, @[ @[ @"missing-local-identifier" ] ]);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
- (void)testOtherPathsWithoutAnIdQueryItemRaiseBeforeQueryingPhotos {
|
|
217
|
+
[self stubPhotoLibraryReturning:[self fetchResultContaining:self.fakeAsset]];
|
|
218
|
+
|
|
219
|
+
// Pre-port parity: a missing `id` yields a nil identifier and the `@[ assetId ]` literal
|
|
220
|
+
// raises. `RNFBStorageCommon` only reaches this method for `ph://` / `assets-library://`
|
|
221
|
+
// paths (`isRemoteAsset:`), so this is not reachable from the storage upload flow.
|
|
222
|
+
for (NSString *path in @[ @"file:///asset.jpg", @"file:///asset.jpg?other=1", @"" ]) {
|
|
223
|
+
XCTAssertThrowsSpecificNamed([RNFBUtilsModule fetchAssetForPath:path], NSException,
|
|
224
|
+
NSInvalidArgumentException, @"%@", path);
|
|
225
|
+
}
|
|
226
|
+
XCTAssertEqual(self.fetchedIdentifiers.count, 0);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
- (void)testUnknownIdentifiersReturnNilWhenPhotoKitFindsNothing {
|
|
230
|
+
// Hostless macOS XCTest has no NSPhotoLibraryUsageDescription; never touch live PhotoKit.
|
|
231
|
+
// Stub an empty fetch for both lookup branches (`ph://` and `file://?id=`).
|
|
232
|
+
[self stubPhotoLibraryReturning:[self fetchResultContaining:nil]];
|
|
233
|
+
|
|
234
|
+
XCTAssertNil([RNFBUtilsModule fetchAssetForPath:@"ph://missing-local-identifier"]);
|
|
235
|
+
XCTAssertNil(
|
|
236
|
+
[RNFBUtilsModule fetchAssetForPath:@"file:///asset.jpg?id=missing-local-identifier"]);
|
|
237
|
+
XCTAssertEqualObjects(self.fetchedIdentifiers, (@[
|
|
238
|
+
@[ @"missing-local-identifier" ],
|
|
239
|
+
@[ @"missing-local-identifier" ],
|
|
240
|
+
]));
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
#pragma mark - PhotoKit stubbing
|
|
244
|
+
|
|
245
|
+
- (void)setUp {
|
|
246
|
+
[super setUp];
|
|
247
|
+
self.fakeAsset = (PHAsset *)class_createInstance([PHAsset class], 0);
|
|
248
|
+
self.fetchedIdentifiers = [NSMutableArray array];
|
|
249
|
+
self.fetchedOptionsWereNil = [NSMutableArray array];
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
- (void)tearDown {
|
|
253
|
+
if (self.originalFetchImplementation != NULL) {
|
|
254
|
+
Method method = class_getClassMethod([PHAsset class], PHAssetFetchSelector());
|
|
255
|
+
method_setImplementation(method, self.originalFetchImplementation);
|
|
256
|
+
self.originalFetchImplementation = NULL;
|
|
257
|
+
}
|
|
258
|
+
[super tearDown];
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
- (id)fetchResultContaining:(PHAsset *)asset {
|
|
262
|
+
RNFBFakeFetchResult *result =
|
|
263
|
+
(RNFBFakeFetchResult *)class_createInstance([RNFBFakeFetchResult class], 0);
|
|
264
|
+
result.stubbedFirstObject = asset;
|
|
265
|
+
return result;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/** Replaces `+[PHAsset fetchAssetsWithLocalIdentifiers:options:]`, recording each call. */
|
|
269
|
+
- (void)stubPhotoLibraryReturning:(id)fetchResult {
|
|
270
|
+
Method method = class_getClassMethod([PHAsset class], PHAssetFetchSelector());
|
|
271
|
+
self.originalFetchImplementation = method_getImplementation(method);
|
|
272
|
+
__weak RNFBUtilsModuleShellTests *weakSelf = self;
|
|
273
|
+
IMP stub = imp_implementationWithBlock(
|
|
274
|
+
^id(id _self, NSArray<NSString *> *identifiers, PHFetchOptions *options) {
|
|
275
|
+
[weakSelf.fetchedIdentifiers addObject:identifiers];
|
|
276
|
+
[weakSelf.fetchedOptionsWereNil addObject:@(options == nil)];
|
|
277
|
+
return fetchResult;
|
|
278
|
+
});
|
|
279
|
+
method_setImplementation(method, stub);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
@end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// swift-tools-version: 5.9
|
|
2
|
+
//
|
|
3
|
+
// CI probe only (RNFB_TEST_RN_BARE_DYNAMIC_FIREBASE=1). Shipped podspecs keep
|
|
4
|
+
// spm_dependency on firebase-ios-sdk. Exact pin tracks packages/app/package.json
|
|
5
|
+
// sdkVersions.ios.firebase (checked by .github/workflows/scripts/check-ios-probe-sdk-pin.js).
|
|
6
|
+
//
|
|
7
|
+
// This package resolver rejects mixed Swift and Objective-C sources in one
|
|
8
|
+
// target. SDK calls live in RNFBFirebaseBridge. The dynamic product links that
|
|
9
|
+
// target beside the Swift target. The Swift target does not depend on it, so
|
|
10
|
+
// the emitted module does not record FirebaseCore for clients.
|
|
11
|
+
|
|
12
|
+
import PackageDescription
|
|
13
|
+
|
|
14
|
+
let package = Package(
|
|
15
|
+
name: "RNFBFirebase",
|
|
16
|
+
platforms: [
|
|
17
|
+
.iOS(.v15),
|
|
18
|
+
.macOS(.v11),
|
|
19
|
+
.tvOS(.v15),
|
|
20
|
+
],
|
|
21
|
+
products: [
|
|
22
|
+
.library(
|
|
23
|
+
name: "RNFBFirebase",
|
|
24
|
+
type: .dynamic,
|
|
25
|
+
targets: ["RNFBFirebase", "RNFBFirebaseBridge"]
|
|
26
|
+
),
|
|
27
|
+
],
|
|
28
|
+
dependencies: [
|
|
29
|
+
.package(
|
|
30
|
+
url: "https://github.com/firebase/firebase-ios-sdk.git",
|
|
31
|
+
exact: "13.0.0"
|
|
32
|
+
),
|
|
33
|
+
],
|
|
34
|
+
targets: [
|
|
35
|
+
.target(
|
|
36
|
+
name: "RNFBFirebaseBridge",
|
|
37
|
+
dependencies: [
|
|
38
|
+
.product(name: "FirebaseCore", package: "firebase-ios-sdk"),
|
|
39
|
+
.product(name: "FirebaseInstallations", package: "firebase-ios-sdk"),
|
|
40
|
+
],
|
|
41
|
+
// Public headers stay empty so this clang target does not publish a
|
|
42
|
+
// module. The dynamic product still links the object file. The Swift
|
|
43
|
+
// target does not depend on it, so clients do not inherit FirebaseCore.
|
|
44
|
+
publicHeadersPath: "Public",
|
|
45
|
+
cSettings: [
|
|
46
|
+
.headerSearchPath("include"),
|
|
47
|
+
]
|
|
48
|
+
),
|
|
49
|
+
.target(
|
|
50
|
+
name: "RNFBFirebase"
|
|
51
|
+
),
|
|
52
|
+
]
|
|
53
|
+
)
|