catalyst-core 0.3.0-beta.4 → 0.3.0-canary.1
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 +80 -0
- package/dist/errors/generateDocs.js +100 -0
- package/dist/errors/index.js +243 -0
- package/dist/errors/registry.js +483 -0
- package/dist/errors-index.json +506 -0
- package/dist/globals.d.ts +62 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.jsx +5 -8
- package/dist/logger.js +1 -1
- package/dist/native/androidProject/app/build.gradle.kts +142 -7
- package/dist/native/androidProject/app/src/main/AndroidManifest.xml +4 -0
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/NativeBridge.kt +2 -2
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/camera/BarcodeDetector.kt +3 -0
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/camera/CameraSessionManager.kt +3 -0
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/FrameworkServerUtils.kt +43 -8
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/BridgeUtilsTest.kt +181 -1
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/CameraUtilsTest.kt +156 -236
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/FileSizeRouterUtilsTest.kt +471 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/FileUtilsTest.kt +222 -226
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/FrameworkServerUtilsTest.kt +300 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/IntentUtilsTest.kt +244 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/MetricsMonitorTest.kt +359 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/NativeBridgeTest.kt +108 -63
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/NotificationUtilsTest.kt +329 -385
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/OfflineCacheServiceTest.kt +302 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/PerfEventBufferTest.kt +133 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/UtilsKtTest.kt +152 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/WebCacheManagerTest.kt +145 -324
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/camera/BarcodeDetectorTest.kt +132 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/camera/HoldControllerTest.kt +155 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/camera/TorchControllerTest.kt +150 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/camera/VideoStreamStateMachineTest.kt +120 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/camera/VideoStreamStateTest.kt +62 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/camera/ViewfinderMapperTest.kt +143 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/camera/ZoomControllerTest.kt +421 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/design/DesignTokensTest.kt +207 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/plugins/PluginBridgeTest.kt +368 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/security/FridaDetectorTest.kt +193 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/security/SecurityCheckManagerTest.kt +260 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/security/SecurityCheckSchedulerTest.kt +166 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/utils/DeviceInfoUtilsTest.kt +167 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/utils/DownloadUtilsTest.kt +197 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/utils/NetworkMonitorTest.kt +271 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/utils/PushNotificationUtilsTest.kt +119 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/utils/SafeAreaUtilsTest.kt +108 -0
- package/dist/native/androidProject/build.gradle.kts +1 -0
- package/dist/native/androidProject/gradle/libs.versions.toml +26 -0
- package/dist/native/androidProject/settings.gradle.kts +11 -8
- package/dist/native/androidSetup.js +2 -2
- package/dist/native/bridge/WebBridge.d.ts +98 -0
- package/dist/native/bridge/WebBridge.js +40 -6
- package/dist/native/bridge/constants/NativeInterfaces.d.ts +391 -0
- package/dist/native/bridge/errors.d.ts +67 -0
- package/dist/native/bridge/errors.js +66 -151
- package/dist/native/bridge/hooks/index.d.ts +13 -0
- package/dist/native/bridge/hooks/index.js +0 -6
- package/dist/native/bridge/hooks/useAI.d.ts +1 -0
- package/dist/native/bridge/hooks/useAI.js +3 -1
- package/dist/native/bridge/hooks/useCamera.d.ts +86 -0
- package/dist/native/bridge/hooks/useCamera.js +35 -6
- package/dist/native/bridge/hooks/useDataProtection.d.ts +17 -0
- package/dist/native/bridge/hooks/useDeviceInfo.d.ts +34 -0
- package/dist/native/bridge/hooks/useDeviceInfo.js +5 -0
- package/dist/native/bridge/hooks/useFilePicker.d.ts +53 -0
- package/dist/native/bridge/hooks/useFilePicker.js +13 -0
- package/dist/native/bridge/hooks/useGoogleSignIn.d.ts +12 -0
- package/dist/native/bridge/hooks/useHapticFeedback.d.ts +76 -0
- package/dist/native/bridge/hooks/useHapticFeedback.js +6 -1
- package/dist/native/bridge/hooks/useIntent.d.ts +33 -0
- package/dist/native/bridge/hooks/useIntent.js +2 -0
- package/dist/native/bridge/hooks/useNativeTransition.d.ts +53 -0
- package/dist/native/bridge/hooks/useNativeTransition.js +14 -7
- package/dist/native/bridge/hooks/useNetworkStatus.d.ts +22 -0
- package/dist/native/bridge/hooks/useNetworkStatus.js +7 -0
- package/dist/native/bridge/hooks/useNotification.d.ts +83 -0
- package/dist/native/bridge/hooks/useNotification.js +81 -34
- package/dist/native/bridge/hooks/useSafeArea.d.ts +12 -0
- package/dist/native/bridge/hooks/useSafeArea.js +8 -0
- package/dist/native/bridge/hooks/useVideoStream.d.ts +67 -0
- package/dist/native/bridge/hooks/useVideoStream.js +38 -52
- package/dist/native/bridge/hooks/utils.d.ts +4 -0
- package/dist/native/bridge/hooks.d.ts +1 -0
- package/dist/native/bridge/perf/collectors/ApiCollector.d.ts +30 -0
- package/dist/native/bridge/perf/collectors/ApiCollector.js +4 -0
- package/dist/native/bridge/perf/collectors/CacheCollector.d.ts +43 -0
- package/dist/native/bridge/perf/collectors/CacheCollector.js +4 -0
- package/dist/native/bridge/perf/collectors/HookCollector.d.ts +37 -0
- package/dist/native/bridge/perf/collectors/HookCollector.js +4 -0
- package/dist/native/bridge/perf/collectors/InsightsCollector.d.ts +103 -0
- package/dist/native/bridge/perf/collectors/InsightsCollector.js +4 -0
- package/dist/native/bridge/perf/collectors/InteractionCollector.d.ts +53 -0
- package/dist/native/bridge/perf/collectors/InteractionCollector.js +4 -0
- package/dist/native/bridge/perf/collectors/KeyboardCollector.d.ts +30 -0
- package/dist/native/bridge/perf/collectors/KeyboardCollector.js +4 -0
- package/dist/native/bridge/perf/collectors/NavigationCollector.d.ts +37 -0
- package/dist/native/bridge/perf/collectors/NavigationCollector.js +4 -0
- package/dist/native/bridge/perf/collectors/NetworkTimingCollector.d.ts +30 -0
- package/dist/native/bridge/perf/collectors/NetworkTimingCollector.js +4 -0
- package/dist/native/bridge/perf/collectors/RenderCollector.d.ts +47 -0
- package/dist/native/bridge/perf/collectors/RenderCollector.js +8 -0
- package/dist/native/bridge/perf/collectors/ScrollCollector.d.ts +29 -0
- package/dist/native/bridge/perf/collectors/ScrollCollector.js +4 -0
- package/dist/native/bridge/perf/collectors/ThreadCollector.d.ts +31 -0
- package/dist/native/bridge/perf/collectors/ThreadCollector.js +4 -0
- package/dist/native/bridge/perf/core/constants.d.ts +76 -0
- package/dist/native/bridge/perf/core/measure.d.ts +39 -0
- package/dist/native/bridge/perf/core/measure.js +4 -0
- package/dist/native/bridge/perf/core/session.d.ts +49 -0
- package/dist/native/bridge/perf/core/session.js +4 -0
- package/dist/native/bridge/perf/core/store.d.ts +37 -0
- package/dist/native/bridge/perf/core/store.js +4 -0
- package/dist/native/bridge/perf/core/summary.d.ts +60 -0
- package/dist/native/bridge/perf/core/traceExport.d.ts +10 -0
- package/dist/native/bridge/perf/core/waterfalls.d.ts +2 -0
- package/dist/native/bridge/perf/index.d.ts +63 -0
- package/dist/native/bridge/perf/index.js +4 -0
- package/dist/native/bridge/safeArea.d.ts +11 -0
- package/dist/native/bridge/safeArea.js +2 -0
- package/dist/native/bridge/useBaseHook.d.ts +137 -0
- package/dist/native/bridge/useBaseHook.js +34 -4
- package/dist/native/bridge/utils/CameraUtils.d.ts +94 -0
- package/dist/native/bridge/utils/CameraUtils.js +4 -0
- package/dist/native/bridge/utils/FileObjectConverter.d.ts +36 -0
- package/dist/native/bridge/utils/NativeBridge.d.ts +270 -0
- package/dist/native/bridge/utils/NativeBridge.js +10 -0
- package/dist/native/buildAndroid/index.js +1 -1
- package/dist/native/buildAppAndroid.js +9 -0
- package/dist/native/buildAppIos.js +16 -1
- package/dist/native/buildErrorFormat.js +57 -0
- package/dist/native/buildIos/config.js +15 -1
- package/dist/native/buildIos/index.js +1 -1
- package/dist/native/buildIos/plugins.js +10 -1
- package/dist/native/iosnativeWebView/CoreLogic/Package.swift +36 -0
- package/dist/native/iosnativeWebView/{Sources/Core → CoreLogic/Sources/CatalystCoreLogic}/Camera/VideoStreamState.swift +1 -1
- package/dist/native/iosnativeWebView/{Sources/Core → CoreLogic/Sources/CatalystCoreLogic}/Camera/VideoStreamStateMachine.swift +6 -4
- package/dist/native/iosnativeWebView/{Sources/Core → CoreLogic/Sources/CatalystCoreLogic}/Utils/BootTimingUtility.swift +3 -3
- package/dist/native/iosnativeWebView/{Sources/Core → CoreLogic/Sources/CatalystCoreLogic}/Utils/FrameworkServerUtils.swift +14 -9
- package/dist/native/iosnativeWebView/{Sources/Core → CoreLogic/Sources/CatalystCoreLogic}/Utils/NetworkMonitor.swift +11 -9
- package/dist/native/iosnativeWebView/{Sources/Core → CoreLogic/Sources/CatalystCoreLogic}/Utils/NotificationHandlerProvider.swift +1 -1
- package/dist/native/iosnativeWebView/{Sources/Core → CoreLogic/Sources/CatalystCoreLogic}/Utils/URLWhitelistManager.swift +7 -7
- package/dist/native/iosnativeWebView/CoreLogic/Tests/CatalystCoreLogicTests/AnyCodableTests.swift +154 -0
- package/dist/native/iosnativeWebView/{iosnativeWebViewTests → CoreLogic/Tests/CatalystCoreLogicTests}/BootTimingUtilityTests.swift +23 -5
- package/dist/native/iosnativeWebView/CoreLogic/Tests/CatalystCoreLogicTests/CatalystConstantsTests.swift +192 -0
- package/dist/native/iosnativeWebView/{iosnativeWebViewTests → CoreLogic/Tests/CatalystCoreLogicTests}/ConfigMappingTests.swift +1 -1
- package/dist/native/iosnativeWebView/CoreLogic/Tests/CatalystCoreLogicTests/FrameworkServerUtilsErrorPathTests.swift +106 -0
- package/dist/native/iosnativeWebView/CoreLogic/Tests/CatalystCoreLogicTests/FrameworkServerUtilsLoopbackTests.swift +243 -0
- package/dist/native/iosnativeWebView/{iosnativeWebViewTests → CoreLogic/Tests/CatalystCoreLogicTests}/FrameworkServerUtilsTests.swift +1 -1
- package/dist/native/iosnativeWebView/CoreLogic/Tests/CatalystCoreLogicTests/NetworkMonitorTests.swift +119 -0
- package/dist/native/iosnativeWebView/CoreLogic/Tests/CatalystCoreLogicTests/NotificationHandlerProviderTests.swift +59 -0
- package/dist/native/iosnativeWebView/{iosnativeWebViewTests → CoreLogic/Tests/CatalystCoreLogicTests}/NotificationHandlerTests.swift +1 -1
- package/dist/native/iosnativeWebView/{iosnativeWebViewTests → CoreLogic/Tests/CatalystCoreLogicTests}/URLWhitelistManagerTests.swift +1 -1
- package/dist/native/iosnativeWebView/CoreLogic/Tests/CatalystCoreLogicTests/VideoStreamStateMachineTests.swift +171 -0
- package/dist/native/iosnativeWebView/CoreLogic/Tests/CatalystCoreLogicTests/VideoStreamStateTests.swift +91 -0
- package/dist/native/iosnativeWebView/Package.swift +10 -9
- package/dist/native/iosnativeWebView/Sources/CatalystNotifications/LocalNotificationHandler.swift +7 -2
- package/dist/native/iosnativeWebView/Sources/CatalystNotifications/NotificationManager.swift +1 -2
- package/dist/native/iosnativeWebView/Sources/CatalystNotifications/PushNotificationHandler.swift +5 -4
- package/dist/native/iosnativeWebView/Sources/Core/Camera/CameraSessionManager.swift +1 -0
- package/dist/native/iosnativeWebView/Sources/Core/Camera/HoldController.swift +1 -0
- package/dist/native/iosnativeWebView/Sources/Core/Camera/NativeCameraManager.swift +6 -5
- package/dist/native/iosnativeWebView/Sources/Core/Camera/ZoomController.swift +1 -0
- package/dist/native/iosnativeWebView/Sources/Core/Plugins/PluginBridge.swift +1 -0
- package/dist/native/iosnativeWebView/Sources/Core/Utils/CacheManager.swift +31 -30
- package/dist/native/iosnativeWebView/Sources/Core/Utils/CameraTransportUtils.swift +2 -1
- package/dist/native/iosnativeWebView/Sources/Core/Utils/DeviceInfoUtils.swift +1 -1
- package/dist/native/iosnativeWebView/Sources/Core/Utils/FilePickerHandler.swift +22 -19
- package/dist/native/iosnativeWebView/Sources/Core/Utils/ImageHandler.swift +40 -39
- package/dist/native/iosnativeWebView/Sources/Core/Utils/PerfEventBuffer.swift +1 -0
- package/dist/native/iosnativeWebView/Sources/Core/Utils/ResourceURLProtocol.swift +15 -15
- package/dist/native/iosnativeWebView/Sources/Core/Utils/WebKitConfig.swift +4 -3
- package/dist/native/iosnativeWebView/Sources/Core/WebView/BridgeCommandHandler.swift +6 -1
- package/dist/native/iosnativeWebView/Sources/Core/WebView/BridgeDelegateHandler.swift +1 -0
- package/dist/native/iosnativeWebView/Sources/Core/WebView/BridgeFileHandler.swift +2 -1
- package/dist/native/iosnativeWebView/Sources/Core/WebView/BridgeJavaScriptInterface.swift +2 -1
- package/dist/native/iosnativeWebView/Sources/Core/WebView/BridgeMessageValidator.swift +3 -5
- package/dist/native/iosnativeWebView/Sources/Core/WebView/NativeBridge.swift +20 -13
- package/dist/native/iosnativeWebView/Sources/Core/WebView/SplashView.swift +6 -5
- package/dist/native/iosnativeWebView/Sources/Core/WebView/SplashViewModel.swift +14 -13
- package/dist/native/iosnativeWebView/Sources/Core/WebView/TransitionManager.swift +3 -3
- package/dist/native/iosnativeWebView/Sources/Core/WebView/WebView.swift +9 -8
- package/dist/native/iosnativeWebView/Sources/Core/WebView/WebViewModel.swift +7 -6
- package/dist/native/iosnativeWebView/Sources/Core/WebView/WebViewNavigationDelegate.swift +24 -25
- package/dist/native/iosnativeWebView/iosnativeWebView/AppDelegate.swift +6 -1
- package/dist/native/iosnativeWebView/iosnativeWebView/ContentView.swift +1 -0
- package/dist/native/iosnativeWebView/iosnativeWebView/iosnativeWebViewApp.swift +4 -0
- package/dist/native/iosnativeWebView/iosnativeWebView.xcodeproj/project.pbxproj +2 -22
- package/dist/native/iosnativeWebView/iosnativeWebViewTests/BridgeMessageValidatorTests.swift +1 -0
- package/dist/native/iosnativeWebView/iosnativeWebViewTests/CacheManagerTests.swift +1 -0
- package/dist/native/iosnativeWebView/iosnativeWebViewTests/FilePickerHandlerTests.swift +2 -1
- package/dist/native/iosnativeWebView/iosnativeWebViewTests/NativeBridgeTests.swift +15 -9
- package/dist/native/iosnativeWebView/iosnativeWebViewTests/WebViewTests.swift +1 -0
- package/dist/native/setupEmulatorIos.js +2 -2
- package/dist/native/terminalProgress.js +17 -17
- package/dist/router/ClientRouter.d.ts +8 -0
- package/dist/router/ClientRouter.js +13 -11
- package/dist/router/ServerRouter.d.ts +13 -0
- package/dist/router/ServerRouter.js +19 -7
- package/dist/scripts/build.js +14 -2
- package/dist/scripts/loadEnvironmentVariables.js +3 -2
- package/dist/scripts/plugins.js +1 -1
- package/dist/scripts/preServerInit.js +49 -3
- package/dist/scripts/preflight.js +111 -0
- package/dist/scripts/scriptUtils.js +46 -1
- package/dist/scripts/serve.js +7 -1
- package/dist/scripts/start.js +8 -1
- package/dist/server/expressServer.d.ts +1 -0
- package/dist/server/expressServer.js +247 -271
- package/dist/server/manifestCache.d.ts +2 -0
- package/dist/server/manifestCache.js +25 -33
- package/dist/server/renderer/ChunkExtractor.d.ts +44 -0
- package/dist/server/renderer/ChunkExtractor.js +113 -125
- package/dist/server/renderer/document/Body.d.ts +21 -0
- package/dist/server/renderer/document/Body.jsx +45 -45
- package/dist/server/renderer/document/FastRefresh.d.ts +3 -0
- package/dist/server/renderer/document/FastRefresh.jsx +7 -13
- package/dist/server/renderer/document/Head.d.ts +20 -0
- package/dist/server/renderer/document/Head.jsx +32 -32
- package/dist/server/renderer/document/index.d.ts +2 -0
- package/dist/server/renderer/document/index.jsx +2 -2
- package/dist/server/renderer/extract.d.ts +67 -0
- package/dist/server/renderer/extract.js +92 -89
- package/dist/server/renderer/handler.d.ts +2 -0
- package/dist/server/renderer/handler.jsx +401 -404
- package/dist/server/renderer/index.d.ts +2 -0
- package/dist/server/renderer/index.js +5 -8
- package/dist/server/renderer/render.d.ts +35 -0
- package/dist/server/renderer/render.js +33 -32
- package/dist/server/utils/botDetectionMiddleware.d.ts +1 -0
- package/dist/server/utils/botDetectionMiddleware.js +33 -23
- package/dist/server/utils/cjsRequire.d.ts +8 -0
- package/dist/server/utils/cjsRequire.js +2 -2
- package/dist/server/utils/userAgentUtil.d.ts +7 -0
- package/dist/server/utils/userAgentUtil.js +68 -71
- package/dist/server/utils/validator.d.ts +31 -0
- package/dist/server/utils/validator.js +133 -158
- package/dist/vite/inject-cache-key-plugin.js +3 -27
- package/dist/vite/moduleAliases.js +36 -0
- package/dist/vite/node-loader.mjs +2 -29
- package/dist/vite/resolveDevServerConfig.js +4 -1
- package/dist/vite/vite.config.js +13 -31
- package/dist/web-router/components/MetaTag.d.ts +4 -0
- package/dist/web-router/components/MetaTag.jsx +26 -28
- package/dist/web-router/components/MetaTag.test.jsx +100 -0
- package/dist/web-router/components/RouterDataProvider.d.ts +96 -0
- package/dist/web-router/components/RouterDataProvider.jsx +260 -259
- package/dist/web-router/components/RouterDataProvider.server.test.jsx +98 -0
- package/dist/web-router/components/RouterDataProvider.test.jsx +310 -0
- package/dist/web-router/components/Split.d.ts +74 -0
- package/dist/web-router/components/Split.jsx +147 -156
- package/dist/web-router/components/Split.server.test.jsx +52 -0
- package/dist/web-router/components/Split.test.jsx +167 -0
- package/dist/web-router/components/SplitInview.d.ts +22 -0
- package/dist/web-router/components/SplitInview.jsx +78 -89
- package/dist/web-router/components/SplitInview.test.jsx +112 -0
- package/dist/web-router/components/SsrRequestContext.d.ts +20 -0
- package/dist/web-router/components/SsrRequestContext.jsx +17 -7
- package/dist/web-router/components/SsrRequestContext.test.jsx +53 -0
- package/dist/web-router/context.d.ts +15 -0
- package/dist/web-router/context.jsx +5 -5
- package/dist/web-router/context.test.jsx +10 -0
- package/dist/web-router/utils/metaDataUtils.d.ts +24 -0
- package/dist/web-router/utils/metaDataUtils.jsx +86 -86
- package/dist/web-router/utils/metaDataUtils.test.jsx +188 -0
- package/dist/web-router/vitest.setup.js +12 -0
- package/mcp_v2/knowledge-base.json +52 -8
- package/mcp_v2/mcp.js +140 -3
- package/mcp_v2/package-lock.json +2031 -0
- package/mcp_v2/package.json +13 -2
- package/mcp_v2/scripts/copyErrorsIndex.cjs +34 -0
- package/mcp_v2/test/errors.test.ts +123 -0
- package/mcp_v2/test/github.test.ts +177 -0
- package/mcp_v2/tools/errors.d.ts +20 -0
- package/mcp_v2/tools/errors.js +63 -0
- package/mcp_v2/tools/github.d.ts +41 -0
- package/mcp_v2/tools/github.js +231 -0
- package/mcp_v2/vitest.config.mjs +22 -0
- package/package.json +60 -11
- package/test/errors/docsDrift.test.ts +113 -0
- package/test/errors/index.test.ts +200 -0
- package/test/errors/registry.test.ts +108 -0
- package/test/scripts/preflight.test.ts +121 -0
- package/test/server/ChunkExtractor.test.ts +97 -0
- package/test/server/extract.test.ts +128 -0
- package/test/server/fixtures/template/server/document.jsx +19 -0
- package/test/server/fixtures/template/server/index.js +10 -0
- package/test/server/fixtures/template/src/js/containers/App/index.jsx +33 -0
- package/test/server/fixtures/template/src/js/routes/index.jsx +72 -0
- package/test/server/fixtures/template/src/js/routes/utils.jsx +39 -0
- package/test/server/fixtures/template/src/js/store/index.js +19 -0
- package/test/server/handler.assets.test.ts +331 -0
- package/test/server/handler.test.ts +210 -0
- package/test/server/manifestCache.test.ts +71 -0
- package/test/server/render.test.ts +90 -0
- package/test/server/scriptUtils.test.ts +103 -0
- package/test/server/userAgentUtil.test.ts +48 -0
- package/test/server/validator.test.ts +228 -0
- package/test/vite/resolveDevServerConfig.test.js +4 -1
- package/tsconfig.test.json +23 -0
- package/vitest.config.ts +93 -0
- package/dist/caching.js +0 -1
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/DeviceInfoUtilsTest.kt +0 -187
- package/dist/native/bridge/standardizedHooks.js +0 -611
- package/dist/router.js +0 -1
- package/dist/scripts/validator.js +0 -149
- package/dist/web-router/hooks.jsx +0 -72
- package/dist/web-router/types/components/MetaTag.d.ts +0 -2
- package/dist/web-router/types/components/RouterDataProvider.d.ts +0 -95
- package/dist/web-router/types/context.d.ts +0 -14
- package/dist/web-router/types/hooks.d.ts +0 -1
- package/dist/web-router/types/index.d.ts +0 -3
- package/dist/web-router/types/utils/metaDataUtils.d.ts +0 -24
- /package/dist/native/iosnativeWebView/{Sources/Core → CoreLogic/Sources/CatalystCoreLogic}/Constants/CatalystConstants.swift +0 -0
- /package/dist/native/iosnativeWebView/{Sources/Core → CoreLogic/Sources/CatalystCoreLogic}/Constants/ConfigConstants.swift +0 -0
- /package/dist/native/iosnativeWebView/{Sources/Core → CoreLogic/Sources/CatalystCoreLogic}/Notifications/NotificationModels.swift +0 -0
- /package/dist/native/iosnativeWebView/{Sources/Core → CoreLogic/Sources/CatalystCoreLogic}/Protocols/NotificationHandlerProtocol.swift +0 -0
- /package/dist/native/iosnativeWebView/{Sources/Core → CoreLogic/Sources/CatalystCoreLogic}/Utils/NullNotificationHandler.swift +0 -0
|
@@ -0,0 +1,471 @@
|
|
|
1
|
+
package io.yourname.androidproject
|
|
2
|
+
|
|
3
|
+
import android.app.Activity
|
|
4
|
+
import android.content.ContentResolver
|
|
5
|
+
import android.net.Uri
|
|
6
|
+
import android.util.Base64
|
|
7
|
+
import android.webkit.MimeTypeMap
|
|
8
|
+
import android.webkit.WebView
|
|
9
|
+
import io.yourname.androidproject.utils.FileSizeRouterUtils
|
|
10
|
+
import io.yourname.androidproject.utils.FrameworkServerUtils
|
|
11
|
+
import org.junit.After
|
|
12
|
+
import org.junit.Assert.*
|
|
13
|
+
import org.junit.Before
|
|
14
|
+
import org.junit.Test
|
|
15
|
+
import org.mockito.MockedStatic
|
|
16
|
+
import org.mockito.Mockito.mockStatic
|
|
17
|
+
import org.mockito.kotlin.any
|
|
18
|
+
import org.mockito.kotlin.doReturn
|
|
19
|
+
import org.mockito.kotlin.doThrow
|
|
20
|
+
import org.mockito.kotlin.mock
|
|
21
|
+
import kotlin.io.path.createTempDirectory
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Unit tests for FileSizeRouterUtils, previously entirely untested (0%).
|
|
25
|
+
*
|
|
26
|
+
* determineTransport/getMimeType/formatFileSize operate on plain
|
|
27
|
+
* java.io.File and don't need a Context, so they're exercised directly
|
|
28
|
+
* against real temp files.
|
|
29
|
+
*
|
|
30
|
+
* processFile's three transport branches (added in a later pass):
|
|
31
|
+
*
|
|
32
|
+
* IMPORTANT, confirmed empirically: Mockito.mockStatic only intercepts
|
|
33
|
+
* genuine JVM static methods (Java classes like android.jar's Uri/
|
|
34
|
+
* Base64/MimeTypeMap). FileUtils/FrameworkServerUtils/IntentUtils are
|
|
35
|
+
* Kotlin `object`s — their "static-looking" members compile to instance
|
|
36
|
+
* methods on a singleton INSTANCE field, which mockStatic cannot
|
|
37
|
+
* intercept (attempting it throws MissingMethodInvocationException,
|
|
38
|
+
* since the real method runs instead of a mock). The PluginBridge
|
|
39
|
+
* coverage pass hit the identical wall with GeneratedPluginIndex. Real
|
|
40
|
+
* objects are used below instead, matching FrameworkServerUtilsTest's
|
|
41
|
+
* own established pattern (a real embedded server, not a mock):
|
|
42
|
+
* - processViaBridge: real FileUtils.convertUriToBase64 with a mocked
|
|
43
|
+
* Context/ContentResolver — Uri.fromFile and Base64.encodeToString are
|
|
44
|
+
* genuine android.jar statics, mockStatic'd normally.
|
|
45
|
+
* - processViaFrameworkServer: the real FrameworkServerUtils object,
|
|
46
|
+
* started/stopped exactly as FrameworkServerUtilsTest.kt does (shared
|
|
47
|
+
* JVM-wide singleton state — defensive stopServer() in both setUp and
|
|
48
|
+
* tearDown so this class can't leak state into/from that one
|
|
49
|
+
* depending on JVM test-class execution order).
|
|
50
|
+
* - processViaContentProvider: IntentUtils.createFileProviderUri needs
|
|
51
|
+
* real FileProvider manifest metadata to succeed, which isn't
|
|
52
|
+
* available in a JVM unit test — only its failure/exception paths
|
|
53
|
+
* (non-Activity context, and a real call that throws) are covered;
|
|
54
|
+
* the success path is Robolectric/instrumented-test territory.
|
|
55
|
+
*/
|
|
56
|
+
class FileSizeRouterUtilsTest {
|
|
57
|
+
|
|
58
|
+
private lateinit var tempDir: java.io.File
|
|
59
|
+
private lateinit var mimeTypeMapMock: MockedStatic<MimeTypeMap>
|
|
60
|
+
|
|
61
|
+
@Before
|
|
62
|
+
fun setUp() {
|
|
63
|
+
tempDir = createTempDirectory(prefix = "catalyst-router-test").toFile()
|
|
64
|
+
|
|
65
|
+
val mimeTypeMap: MimeTypeMap = mock {
|
|
66
|
+
// Mockito's stub-matching is most-recent-wins for overlapping
|
|
67
|
+
// matchers — the any() catch-all must be stubbed first so the
|
|
68
|
+
// specific "txt"/"jpg" stubs below take precedence for those
|
|
69
|
+
// exact arguments.
|
|
70
|
+
on { getMimeTypeFromExtension(org.mockito.kotlin.any()) } doReturn null
|
|
71
|
+
on { getMimeTypeFromExtension("txt") } doReturn "text/plain"
|
|
72
|
+
on { getMimeTypeFromExtension("jpg") } doReturn "image/jpeg"
|
|
73
|
+
}
|
|
74
|
+
mimeTypeMapMock = mockStatic(MimeTypeMap::class.java)
|
|
75
|
+
mimeTypeMapMock.`when`<MimeTypeMap> { MimeTypeMap.getSingleton() } doReturn mimeTypeMap
|
|
76
|
+
|
|
77
|
+
// FrameworkServerUtils is a JVM-wide singleton object; stop it
|
|
78
|
+
// defensively before each test so this class can't inherit
|
|
79
|
+
// running-server state left by FrameworkServerUtilsTest (or any
|
|
80
|
+
// other test class) depending on JVM test-class execution order.
|
|
81
|
+
FrameworkServerUtils.stopServer()
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
@After
|
|
85
|
+
fun tearDown() {
|
|
86
|
+
mimeTypeMapMock.close()
|
|
87
|
+
FrameworkServerUtils.stopServer()
|
|
88
|
+
tempDir.deleteRecursively()
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
private fun fileOfSize(name: String, bytes: Int): java.io.File {
|
|
92
|
+
val file = java.io.File(tempDir, name)
|
|
93
|
+
file.writeBytes(ByteArray(bytes))
|
|
94
|
+
return file
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// ============================================================
|
|
98
|
+
// determineTransport
|
|
99
|
+
// ============================================================
|
|
100
|
+
|
|
101
|
+
@Test
|
|
102
|
+
fun `determineTransport reports UNSUPPORTED and cannot proceed for a missing file`() {
|
|
103
|
+
val missing = java.io.File(tempDir, "does-not-exist.txt")
|
|
104
|
+
|
|
105
|
+
val decision = FileSizeRouterUtils.determineTransport(missing)
|
|
106
|
+
|
|
107
|
+
assertEquals(FileSizeRouterUtils.TransportType.UNSUPPORTED, decision.transportType)
|
|
108
|
+
assertFalse(decision.canProceed)
|
|
109
|
+
assertEquals("Selected file no longer exists", decision.errorMessage)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
@Test
|
|
113
|
+
fun `determineTransport routes a small file to BRIDGE_BASE64`() {
|
|
114
|
+
val file = fileOfSize("small.txt", 1024) // 1 KB, well under 2MB
|
|
115
|
+
|
|
116
|
+
val decision = FileSizeRouterUtils.determineTransport(file)
|
|
117
|
+
|
|
118
|
+
assertEquals(FileSizeRouterUtils.TransportType.BRIDGE_BASE64, decision.transportType)
|
|
119
|
+
assertTrue(decision.canProceed)
|
|
120
|
+
assertEquals("text/plain", decision.mimeType)
|
|
121
|
+
assertEquals(1024L, decision.fileSize)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
@Test
|
|
125
|
+
fun `determineTransport routes a file just over the bridge threshold to CONTENT_PROVIDER when server is not running`() {
|
|
126
|
+
val file = fileOfSize("medium.jpg", FileSizeRouterUtils.MAX_BRIDGE_SIZE + 1)
|
|
127
|
+
|
|
128
|
+
val decision = FileSizeRouterUtils.determineTransport(file)
|
|
129
|
+
|
|
130
|
+
// FrameworkServerUtils.isRunning() is false by default (no server
|
|
131
|
+
// started anywhere in this test), so the >2MB branch falls back to
|
|
132
|
+
// CONTENT_PROVIDER rather than FRAMEWORK_SERVER.
|
|
133
|
+
assertEquals(FileSizeRouterUtils.TransportType.CONTENT_PROVIDER, decision.transportType)
|
|
134
|
+
assertTrue(decision.canProceed)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
@Test
|
|
138
|
+
fun `MAX_SERVER_SIZE boundary exceeds MAX_BRIDGE_SIZE and a small file still routes to BRIDGE_BASE64`() {
|
|
139
|
+
// Not a real >100MB UNSUPPORTED case (impractical to allocate that
|
|
140
|
+
// much on disk in a unit test) -- this only asserts the threshold
|
|
141
|
+
// ordering the UNSUPPORTED branch depends on, plus that a small
|
|
142
|
+
// file's routing stays correct/unaffected by that boundary's
|
|
143
|
+
// existence. Renamed from a name that claimed to test the
|
|
144
|
+
// >100MB UNSUPPORTED path, which it never actually exercised.
|
|
145
|
+
val file = fileOfSize("huge.bin", 100) // real size doesn't matter, but must exist
|
|
146
|
+
assertTrue(FileSizeRouterUtils.MAX_SERVER_SIZE > FileSizeRouterUtils.MAX_BRIDGE_SIZE)
|
|
147
|
+
|
|
148
|
+
val decision = FileSizeRouterUtils.determineTransport(file)
|
|
149
|
+
assertEquals(FileSizeRouterUtils.TransportType.BRIDGE_BASE64, decision.transportType)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// ============================================================
|
|
153
|
+
// getMimeType
|
|
154
|
+
// ============================================================
|
|
155
|
+
|
|
156
|
+
@Test
|
|
157
|
+
fun `getMimeType resolves via MimeTypeMap when the extension is known`() {
|
|
158
|
+
val file = fileOfSize("photo.jpg", 10)
|
|
159
|
+
assertEquals("image/jpeg", FileSizeRouterUtils.getMimeType(file))
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
@Test
|
|
163
|
+
fun `getMimeType falls back to the office-document table for docx`() {
|
|
164
|
+
val file = fileOfSize("report.docx", 10)
|
|
165
|
+
assertEquals(
|
|
166
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
167
|
+
FileSizeRouterUtils.getMimeType(file)
|
|
168
|
+
)
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
@Test
|
|
172
|
+
fun `getMimeType falls back to octet-stream for a fully unknown extension`() {
|
|
173
|
+
val file = fileOfSize("mystery.xyz123", 10)
|
|
174
|
+
assertEquals("application/octet-stream", FileSizeRouterUtils.getMimeType(file))
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// ============================================================
|
|
178
|
+
// formatFileSize
|
|
179
|
+
// ============================================================
|
|
180
|
+
|
|
181
|
+
@Test
|
|
182
|
+
fun `formatFileSize formats bytes without a decimal point`() {
|
|
183
|
+
assertEquals("512 B", FileSizeRouterUtils.formatFileSize(512))
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
@Test
|
|
187
|
+
fun `formatFileSize formats kilobytes with one decimal place`() {
|
|
188
|
+
assertEquals("2.0 KB", FileSizeRouterUtils.formatFileSize(2048))
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
@Test
|
|
192
|
+
fun `formatFileSize formats megabytes and gigabytes correctly`() {
|
|
193
|
+
assertEquals("5.0 MB", FileSizeRouterUtils.formatFileSize(5L * 1024 * 1024))
|
|
194
|
+
assertEquals("1.0 GB", FileSizeRouterUtils.formatFileSize(1024L * 1024 * 1024))
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// ============================================================
|
|
198
|
+
// processFile — early return when the decision cannot proceed
|
|
199
|
+
// ============================================================
|
|
200
|
+
|
|
201
|
+
@Test
|
|
202
|
+
fun `processFile returns a failure result immediately when the decision cannot proceed`() {
|
|
203
|
+
val decision = FileSizeRouterUtils.determineTransport(java.io.File(tempDir, "does-not-exist.txt"))
|
|
204
|
+
val context: android.content.Context = mock()
|
|
205
|
+
val webView: WebView = mock()
|
|
206
|
+
|
|
207
|
+
val result = FileSizeRouterUtils.processFile(context, webView, decision)
|
|
208
|
+
|
|
209
|
+
assertFalse(result.success)
|
|
210
|
+
assertEquals(decision.errorMessage, result.error)
|
|
211
|
+
assertNull(result.fileSrc)
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// ============================================================
|
|
215
|
+
// processFile — BRIDGE_BASE64 branch (processViaBridge)
|
|
216
|
+
//
|
|
217
|
+
// FileUtils is a real object (Kotlin objects can't be mockStatic'd,
|
|
218
|
+
// see class header) -- convertUriToBase64 is driven for real via a
|
|
219
|
+
// mocked Context.contentResolver. Uri.fromFile and Base64.encodeToString
|
|
220
|
+
// are genuine android.jar statics, mockStatic'd normally.
|
|
221
|
+
// ============================================================
|
|
222
|
+
|
|
223
|
+
@Test
|
|
224
|
+
fun `processFile via bridge succeeds when the content resolver returns real bytes`() {
|
|
225
|
+
val file = fileOfSize("small.txt", 100)
|
|
226
|
+
val decision = FileSizeRouterUtils.determineTransport(file)
|
|
227
|
+
assertEquals(FileSizeRouterUtils.TransportType.BRIDGE_BASE64, decision.transportType)
|
|
228
|
+
|
|
229
|
+
val fakeUri: Uri = mock()
|
|
230
|
+
val resolver: ContentResolver = mock {
|
|
231
|
+
on { openInputStream(fakeUri) } doReturn java.io.ByteArrayInputStream("hello".toByteArray())
|
|
232
|
+
}
|
|
233
|
+
val context: android.content.Context = mock {
|
|
234
|
+
on { getContentResolver() } doReturn resolver
|
|
235
|
+
}
|
|
236
|
+
val webView: WebView = mock()
|
|
237
|
+
|
|
238
|
+
val uriMock = mockStatic(Uri::class.java)
|
|
239
|
+
val base64Mock = mockStatic(Base64::class.java)
|
|
240
|
+
try {
|
|
241
|
+
uriMock.`when`<Uri> { Uri.fromFile(file) }.thenReturn(fakeUri)
|
|
242
|
+
base64Mock.`when`<String> { Base64.encodeToString(any(), any()) }.thenReturn("aGVsbG8=")
|
|
243
|
+
|
|
244
|
+
val result = FileSizeRouterUtils.processFile(context, webView, decision)
|
|
245
|
+
|
|
246
|
+
assertTrue(result.success)
|
|
247
|
+
assertEquals(FileSizeRouterUtils.TransportType.BRIDGE_BASE64, result.transportUsed)
|
|
248
|
+
assertEquals("data:${decision.mimeType};base64,aGVsbG8=", result.fileSrc)
|
|
249
|
+
} finally {
|
|
250
|
+
uriMock.close()
|
|
251
|
+
base64Mock.close()
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
@Test
|
|
256
|
+
fun `processFile via bridge fails when the content resolver cannot open the uri`() {
|
|
257
|
+
val file = fileOfSize("small.txt", 100)
|
|
258
|
+
val decision = FileSizeRouterUtils.determineTransport(file)
|
|
259
|
+
|
|
260
|
+
val fakeUri: Uri = mock()
|
|
261
|
+
val resolver: ContentResolver = mock {
|
|
262
|
+
on { openInputStream(fakeUri) } doReturn null
|
|
263
|
+
}
|
|
264
|
+
val context: android.content.Context = mock {
|
|
265
|
+
on { getContentResolver() } doReturn resolver
|
|
266
|
+
}
|
|
267
|
+
val webView: WebView = mock()
|
|
268
|
+
|
|
269
|
+
val uriMock = mockStatic(Uri::class.java)
|
|
270
|
+
try {
|
|
271
|
+
uriMock.`when`<Uri> { Uri.fromFile(file) }.thenReturn(fakeUri)
|
|
272
|
+
|
|
273
|
+
val result = FileSizeRouterUtils.processFile(context, webView, decision)
|
|
274
|
+
|
|
275
|
+
assertFalse(result.success)
|
|
276
|
+
assertEquals(FileSizeRouterUtils.TransportType.BRIDGE_BASE64, result.transportUsed)
|
|
277
|
+
assertNull(result.fileSrc)
|
|
278
|
+
assertNotNull(result.error)
|
|
279
|
+
} finally {
|
|
280
|
+
uriMock.close()
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
@Test
|
|
285
|
+
fun `processFile via bridge fails gracefully when the content resolver throws`() {
|
|
286
|
+
val file = fileOfSize("small.txt", 100)
|
|
287
|
+
val decision = FileSizeRouterUtils.determineTransport(file)
|
|
288
|
+
|
|
289
|
+
val fakeUri: Uri = mock()
|
|
290
|
+
val resolver: ContentResolver = mock {
|
|
291
|
+
on { openInputStream(fakeUri) } doThrow RuntimeException("permission denied")
|
|
292
|
+
}
|
|
293
|
+
val context: android.content.Context = mock {
|
|
294
|
+
on { getContentResolver() } doReturn resolver
|
|
295
|
+
}
|
|
296
|
+
val webView: WebView = mock()
|
|
297
|
+
|
|
298
|
+
val uriMock = mockStatic(Uri::class.java)
|
|
299
|
+
try {
|
|
300
|
+
uriMock.`when`<Uri> { Uri.fromFile(file) }.thenReturn(fakeUri)
|
|
301
|
+
|
|
302
|
+
val result = FileSizeRouterUtils.processFile(context, webView, decision)
|
|
303
|
+
|
|
304
|
+
assertFalse(result.success)
|
|
305
|
+
assertNotNull(result.error)
|
|
306
|
+
} finally {
|
|
307
|
+
uriMock.close()
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// ============================================================
|
|
312
|
+
// processFile — FRAMEWORK_SERVER branch (processViaFrameworkServer)
|
|
313
|
+
//
|
|
314
|
+
// FrameworkServerUtils is a real, JVM-wide singleton object (can't be
|
|
315
|
+
// mockStatic'd, see class header) -- started/stopped exactly as
|
|
316
|
+
// FrameworkServerUtilsTest.kt does. Defensive stop in both setUp and
|
|
317
|
+
// tearDown so shared server state can't leak across test classes.
|
|
318
|
+
// ============================================================
|
|
319
|
+
|
|
320
|
+
@Test
|
|
321
|
+
fun `processFile via framework server succeeds against a real running server`() {
|
|
322
|
+
FrameworkServerUtils.stopServer()
|
|
323
|
+
try {
|
|
324
|
+
val file = fileOfSize("bigfile.bin", 3 * 1024 * 1024) // 3MB, over bridge threshold
|
|
325
|
+
val serverContext: android.content.Context = mock { on { getCacheDir() } doReturn tempDir }
|
|
326
|
+
val serverWebView: WebView = mock { on { getUrl() } doReturn "http://localhost:8080/index.html" }
|
|
327
|
+
// If the real bind fails in this environment (port contention
|
|
328
|
+
// on a shared CI runner), skip rather than fail confusingly on
|
|
329
|
+
// a downstream assertion -- matches FrameworkServerUtilsTest's
|
|
330
|
+
// own Assume-based tolerance for the same startServer() call.
|
|
331
|
+
org.junit.Assume.assumeTrue(
|
|
332
|
+
"Framework server failed to start in this environment — skipping",
|
|
333
|
+
FrameworkServerUtils.startServer(serverContext, serverWebView)
|
|
334
|
+
)
|
|
335
|
+
|
|
336
|
+
val decision = FileSizeRouterUtils.determineTransport(file)
|
|
337
|
+
assertEquals(FileSizeRouterUtils.TransportType.FRAMEWORK_SERVER, decision.transportType)
|
|
338
|
+
|
|
339
|
+
val context: android.content.Context = mock()
|
|
340
|
+
val webView: WebView = mock()
|
|
341
|
+
val result = FileSizeRouterUtils.processFile(context, webView, decision)
|
|
342
|
+
|
|
343
|
+
assertTrue(result.success)
|
|
344
|
+
assertEquals(FileSizeRouterUtils.TransportType.FRAMEWORK_SERVER, result.transportUsed)
|
|
345
|
+
assertNotNull(result.fileSrc)
|
|
346
|
+
assertTrue(result.fileSrc!!.startsWith("http://"))
|
|
347
|
+
} finally {
|
|
348
|
+
FrameworkServerUtils.stopServer()
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
@Test
|
|
353
|
+
fun `processFile via framework server fails when copyAndServeFile is called while stopped`() {
|
|
354
|
+
// Construct a FRAMEWORK_SERVER decision directly (determineTransport
|
|
355
|
+
// itself would route to CONTENT_PROVIDER once the server is
|
|
356
|
+
// confirmed stopped) to exercise processViaFrameworkServer's own
|
|
357
|
+
// failure branch: copyAndServeFile returns null when
|
|
358
|
+
// !isServerRunning, independent of how the decision was reached.
|
|
359
|
+
FrameworkServerUtils.stopServer()
|
|
360
|
+
try {
|
|
361
|
+
assertFalse(FrameworkServerUtils.isRunning())
|
|
362
|
+
val file = fileOfSize("bigfile.bin", 3 * 1024 * 1024)
|
|
363
|
+
val decision = FileSizeRouterUtils.FileRoutingDecision(
|
|
364
|
+
transportType = FileSizeRouterUtils.TransportType.FRAMEWORK_SERVER,
|
|
365
|
+
file = file,
|
|
366
|
+
fileName = file.name,
|
|
367
|
+
mimeType = "application/octet-stream",
|
|
368
|
+
fileSize = file.length(),
|
|
369
|
+
reason = "forced for test"
|
|
370
|
+
)
|
|
371
|
+
|
|
372
|
+
val context: android.content.Context = mock()
|
|
373
|
+
val webView: WebView = mock()
|
|
374
|
+
val result = FileSizeRouterUtils.processFile(context, webView, decision)
|
|
375
|
+
|
|
376
|
+
assertFalse(result.success)
|
|
377
|
+
assertNull(result.fileSrc)
|
|
378
|
+
assertNotNull(result.error)
|
|
379
|
+
} finally {
|
|
380
|
+
FrameworkServerUtils.stopServer()
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// ============================================================
|
|
385
|
+
// processFile — CONTENT_PROVIDER branch (processViaContentProvider)
|
|
386
|
+
//
|
|
387
|
+
// IntentUtils.createFileProviderUri needs real FileProvider manifest
|
|
388
|
+
// metadata to succeed -- not available in a JVM unit test, so only
|
|
389
|
+
// its failure paths are covered here (non-Activity context, and a
|
|
390
|
+
// real call against a mocked Activity that throws for lack of
|
|
391
|
+
// provider registration). The success path is Robolectric/
|
|
392
|
+
// instrumented-test territory.
|
|
393
|
+
// ============================================================
|
|
394
|
+
|
|
395
|
+
@Test
|
|
396
|
+
fun `processFile via content provider fails when context is not an Activity`() {
|
|
397
|
+
FrameworkServerUtils.stopServer()
|
|
398
|
+
try {
|
|
399
|
+
val file = fileOfSize("bigfile.bin", 3 * 1024 * 1024)
|
|
400
|
+
val decision = FileSizeRouterUtils.determineTransport(file)
|
|
401
|
+
assertEquals(FileSizeRouterUtils.TransportType.CONTENT_PROVIDER, decision.transportType)
|
|
402
|
+
|
|
403
|
+
val nonActivityContext: android.content.Context = mock()
|
|
404
|
+
val webView: WebView = mock()
|
|
405
|
+
|
|
406
|
+
val result = FileSizeRouterUtils.processFile(nonActivityContext, webView, decision)
|
|
407
|
+
|
|
408
|
+
assertFalse(result.success)
|
|
409
|
+
assertTrue(result.error?.contains("Activity context") == true)
|
|
410
|
+
} finally {
|
|
411
|
+
FrameworkServerUtils.stopServer()
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
@Test
|
|
416
|
+
fun `processFile via content provider fails gracefully when the real call throws`() {
|
|
417
|
+
FrameworkServerUtils.stopServer()
|
|
418
|
+
try {
|
|
419
|
+
val file = fileOfSize("bigfile.bin", 3 * 1024 * 1024)
|
|
420
|
+
val decision = FileSizeRouterUtils.determineTransport(file)
|
|
421
|
+
assertEquals(FileSizeRouterUtils.TransportType.CONTENT_PROVIDER, decision.transportType)
|
|
422
|
+
|
|
423
|
+
// A mocked Activity has no real FileProvider manifest entry --
|
|
424
|
+
// IntentUtils.createFileProviderUri's real call against it is
|
|
425
|
+
// expected to throw, exercising the catch branch.
|
|
426
|
+
val activity: Activity = mock()
|
|
427
|
+
val webView: WebView = mock()
|
|
428
|
+
|
|
429
|
+
val result = FileSizeRouterUtils.processFile(activity, webView, decision)
|
|
430
|
+
|
|
431
|
+
assertFalse(result.success)
|
|
432
|
+
assertEquals(FileSizeRouterUtils.TransportType.CONTENT_PROVIDER, result.transportUsed)
|
|
433
|
+
assertNull(result.fileSrc)
|
|
434
|
+
assertNotNull(result.error)
|
|
435
|
+
} finally {
|
|
436
|
+
FrameworkServerUtils.stopServer()
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// ============================================================
|
|
441
|
+
// processFile — UNSUPPORTED branch (the `else` in the when block)
|
|
442
|
+
// ============================================================
|
|
443
|
+
|
|
444
|
+
@Test
|
|
445
|
+
fun `processFile returns not-supported for an UNSUPPORTED decision that still has canProceed true`() {
|
|
446
|
+
// determineTransport never actually produces canProceed=true with
|
|
447
|
+
// UNSUPPORTED (the >100MB case sets canProceed=false, hitting the
|
|
448
|
+
// early-return branch tested above) -- this constructs that
|
|
449
|
+
// otherwise-unreachable combination directly to exercise
|
|
450
|
+
// processFile's own `when` branch for TransportType.UNSUPPORTED,
|
|
451
|
+
// which is defensive dead code from determineTransport's callers
|
|
452
|
+
// but still real code in processFile itself.
|
|
453
|
+
val file = fileOfSize("weird.bin", 10)
|
|
454
|
+
val decision = FileSizeRouterUtils.FileRoutingDecision(
|
|
455
|
+
transportType = FileSizeRouterUtils.TransportType.UNSUPPORTED,
|
|
456
|
+
file = file,
|
|
457
|
+
fileName = file.name,
|
|
458
|
+
mimeType = "application/octet-stream",
|
|
459
|
+
fileSize = 10,
|
|
460
|
+
reason = "forced for test",
|
|
461
|
+
canProceed = true
|
|
462
|
+
)
|
|
463
|
+
|
|
464
|
+
val context: android.content.Context = mock()
|
|
465
|
+
val webView: WebView = mock()
|
|
466
|
+
val result = FileSizeRouterUtils.processFile(context, webView, decision)
|
|
467
|
+
|
|
468
|
+
assertFalse(result.success)
|
|
469
|
+
assertEquals("Transport not supported", result.error)
|
|
470
|
+
}
|
|
471
|
+
}
|