diff --git a/.changeset/v6-hide-serialization.md b/.changeset/v6-hide-serialization.md new file mode 100644 index 00000000..9eb46db6 --- /dev/null +++ b/.changeset/v6-hide-serialization.md @@ -0,0 +1,5 @@ +--- +"posthog_flutter": major +--- + +- **Breaking:** remove `toMap()` from the config classes and `PostHogFeatureFlagResult.fromMap()` from the public API — they serialize the internal platform-channel wire format and were never meant for app code diff --git a/api/posthog_flutter.api.json b/api/posthog_flutter.api.json index 459d349e..e0b04b58 100644 --- a/api/posthog_flutter.api.json +++ b/api/posthog_flutter.api.json @@ -2064,18 +2064,6 @@ "posthog_flutter.dart" ], "executableDeclarations": [ - { - "entryPoints": [], - "isDeprecated": false, - "isExperimental": false, - "isStatic": false, - "name": "toMap", - "parameters": [], - "relativePath": "lib/src/posthog_config.dart", - "returnTypeName": "Map", - "type": "method", - "typeParameterNames": [] - }, { "entryPoints": [], "isDeprecated": false, @@ -2421,18 +2409,6 @@ "posthog_flutter.dart" ], "executableDeclarations": [ - { - "entryPoints": [], - "isDeprecated": false, - "isExperimental": false, - "isStatic": false, - "name": "toMap", - "parameters": [], - "relativePath": "lib/src/posthog_config.dart", - "returnTypeName": "Map", - "type": "method", - "typeParameterNames": [] - }, { "entryPoints": [], "isDeprecated": false, @@ -2623,18 +2599,6 @@ "posthog_flutter.dart" ], "executableDeclarations": [ - { - "entryPoints": [], - "isDeprecated": false, - "isExperimental": false, - "isStatic": false, - "name": "toMap", - "parameters": [], - "relativePath": "lib/src/posthog_config.dart", - "returnTypeName": "Map", - "type": "method", - "typeParameterNames": [] - }, { "entryPoints": [], "isDeprecated": false, @@ -2913,18 +2877,6 @@ "posthog_flutter.dart" ], "executableDeclarations": [ - { - "entryPoints": [], - "isDeprecated": false, - "isExperimental": false, - "isStatic": false, - "name": "toMap", - "parameters": [], - "relativePath": "lib/src/posthog_config.dart", - "returnTypeName": "Map", - "type": "method", - "typeParameterNames": [] - }, { "entryPoints": [], "isDeprecated": false, @@ -3066,18 +3018,6 @@ "posthog_flutter.dart" ], "executableDeclarations": [ - { - "entryPoints": [], - "isDeprecated": false, - "isExperimental": false, - "isStatic": false, - "name": "toMap", - "parameters": [], - "relativePath": "lib/src/posthog_config.dart", - "returnTypeName": "Map", - "type": "method", - "typeParameterNames": [] - }, { "entryPoints": [], "isDeprecated": false, @@ -3131,18 +3071,6 @@ "posthog_flutter.dart" ], "executableDeclarations": [ - { - "entryPoints": [], - "isDeprecated": false, - "isExperimental": false, - "isStatic": false, - "name": "toMap", - "parameters": [], - "relativePath": "lib/src/posthog_config.dart", - "returnTypeName": "Map", - "type": "method", - "typeParameterNames": [] - }, { "entryPoints": [], "isDeprecated": false, @@ -3295,18 +3223,6 @@ "posthog_flutter.dart" ], "executableDeclarations": [ - { - "entryPoints": [], - "isDeprecated": false, - "isExperimental": false, - "isStatic": false, - "name": "toMap", - "parameters": [], - "relativePath": "lib/src/posthog_config.dart", - "returnTypeName": "Map", - "type": "method", - "typeParameterNames": [] - }, { "entryPoints": [], "isDeprecated": false, @@ -3515,37 +3431,6 @@ "posthog_flutter.dart" ], "executableDeclarations": [ - { - "entryPoints": [], - "isDeprecated": false, - "isExperimental": false, - "isStatic": true, - "name": "fromMap", - "parameters": [ - { - "isDeprecated": false, - "isExperimental": false, - "isNamed": false, - "isRequired": true, - "name": "result", - "relativePath": "lib/src/feature_flag_result.dart", - "typeName": "Object?" - }, - { - "isDeprecated": false, - "isExperimental": false, - "isNamed": false, - "isRequired": true, - "name": "fallbackKey", - "relativePath": "lib/src/feature_flag_result.dart", - "typeName": "String" - } - ], - "relativePath": "lib/src/feature_flag_result.dart", - "returnTypeName": "PostHogFeatureFlagResult?", - "type": "method", - "typeParameterNames": [] - }, { "entryPoints": [], "isDeprecated": false, diff --git a/posthog_flutter/lib/posthog_flutter_web.dart b/posthog_flutter/lib/posthog_flutter_web.dart index 0c718f0e..25aa4db6 100644 --- a/posthog_flutter/lib/posthog_flutter_web.dart +++ b/posthog_flutter/lib/posthog_flutter_web.dart @@ -7,6 +7,7 @@ import 'package:flutter/services.dart'; import 'package:flutter_web_plugins/flutter_web_plugins.dart'; import 'package:posthog_flutter/src/error_tracking/dart_exception_processor.dart'; import 'package:posthog_flutter/src/util/logging.dart'; +import 'package:posthog_flutter/src/utils/channel_serialization.dart'; import 'package:posthog_flutter/src/utils/property_normalizer.dart'; import 'src/feature_flag_result.dart'; @@ -413,7 +414,7 @@ class PosthogFlutterWeb extends PosthogFlutterPlatformInterface { ); // Web SDK returns: { key, enabled, variant, payload } - return PostHogFeatureFlagResult.fromMap(result, key); + return featureFlagResultFromMap(result, key); } @override diff --git a/posthog_flutter/lib/src/feature_flag_result.dart b/posthog_flutter/lib/src/feature_flag_result.dart index 9a85fef5..14298af1 100644 --- a/posthog_flutter/lib/src/feature_flag_result.dart +++ b/posthog_flutter/lib/src/feature_flag_result.dart @@ -53,23 +53,4 @@ class PostHogFeatureFlagResult { @override int get hashCode => Object.hash(key, enabled, variant); - - /// Creates a [PostHogFeatureFlagResult] from a native SDK response map. - /// - /// The [result] should be a map containing `key`, `enabled`, `variant`, and - /// `payload` entries. Falls back to [fallbackKey] if the map does not include - /// a key. - /// - /// Returns `null` if [result] is `null` or is not a [Map]. - static PostHogFeatureFlagResult? fromMap(Object? result, String fallbackKey) { - if (result == null) return null; - if (result is! Map) return null; - - return PostHogFeatureFlagResult( - key: result['key'] as String? ?? fallbackKey, - enabled: result['enabled'] as bool? ?? false, - variant: result['variant'] as String?, - payload: result['payload'], - ); - } } diff --git a/posthog_flutter/lib/src/posthog_config.dart b/posthog_flutter/lib/src/posthog_config.dart index 78b2c2c8..c501e432 100644 --- a/posthog_flutter/lib/src/posthog_config.dart +++ b/posthog_flutter/lib/src/posthog_config.dart @@ -7,7 +7,6 @@ import 'posthog.dart'; import 'posthog_event.dart'; import 'posthog_flutter_platform_interface.dart'; import 'replay/mask/posthog_text_mask.dart'; -import 'util/logging.dart'; /// Callback to intercept and modify events before they are sent to PostHog. /// @@ -394,42 +393,6 @@ class PostHogConfig { final trimmedHost = host.trim(); return trimmedHost.isEmpty ? _defaultHost : trimmedHost; } - - /// Converts this configuration to a platform-channel map. - /// - /// Returns the values consumed by the Android, Apple, and web implementations. - Map toMap() { - return { - 'projectToken': projectToken, - 'host': host, - 'flushAt': flushAt, - 'maxQueueSize': maxQueueSize, - 'maxBatchSize': maxBatchSize, - 'flushInterval': flushInterval.inSeconds, - 'sendFeatureFlagEvents': sendFeatureFlagEvent, - 'preloadFeatureFlags': preloadFeatureFlags, - 'captureApplicationLifecycleEvents': captureApplicationLifecycleEvents, - 'rageClickConfig': rageClickConfig.toMap(), - 'debug': debug, - 'optOut': optOut, - 'surveys': surveys, - 'personProfiles': personProfiles.name, - 'compression': compression.name, - 'sessionReplay': sessionReplay, - 'dataMode': dataMode.name, - 'sessionReplayConfig': sessionReplayConfig.toMap(), - 'errorTrackingConfig': errorTrackingConfig.toMap(), - 'logs': logsConfig.toMap(), - 'capturePushNotificationSubscriptions': - capturePushNotificationSubscriptions, - 'capturePushNotificationOpened': capturePushNotificationOpened, - // A closure can't cross the channel. This tells native whether to install - // a bridging provider at all — installing one the host didn't ask for - // would change how the native SDK handles a 401 on the subscription call. - 'pushIdentityProviderEnabled': pushIdentityProvider != null, - if (bootstrap != null) 'bootstrap': bootstrap!.toMap(), - }; - } } /// Pre-seeded identity and feature-flag state applied on the very first SDK @@ -486,34 +449,6 @@ class PostHogBootstrapConfig { /// JSON payloads paired with [featureFlags], keyed by flag key. Each value is /// the already-decoded payload (map, list, string, number, `null`, ...). final Map? featureFlagPayloads; - - /// Converts this configuration to a platform-channel map. - /// - /// Only the dimensions that were set are included; [isIdentifiedId] is always - /// sent so the native SDK doesn't have to infer it. - Map toMap() { - final flags = featureFlags; - if (flags != null) { - for (final entry in flags.entries) { - // Only bool/String are served (see [featureFlags]); the native SDKs drop - // anything else silently, so warn instead of leaving no trace. - if (entry.value is! bool && entry.value is! String) { - printIfDebug( - '[PostHog] bootstrap featureFlags["${entry.key}"] is ' - '${entry.value.runtimeType}; only bool and String values are served, ' - 'so this entry will be ignored.', - ); - } - } - } - return { - if (distinctId != null) 'distinctId': distinctId, - 'isIdentifiedId': isIdentifiedId, - if (featureFlags != null) 'featureFlags': featureFlags, - if (featureFlagPayloads != null) - 'featureFlagPayloads': featureFlagPayloads, - }; - } } /// Configuration for the logs subsystem. @@ -615,36 +550,6 @@ class PostHogLogsConfig { /// record. Keep anything sensitive out of those fields; put it in [body] or /// [PostHogLogRecord.attributes], which a callback can scrub or drop. List beforeSend = []; - - /// Converts the identity and tuning options to a platform-channel map. - /// - /// Only fields the user set are included, so unset fields keep the native - /// default. [beforeSend] is intentionally omitted: it runs in Dart and never - /// crosses the platform channel. - Map toMap() { - return { - if (serviceName != null) 'serviceName': serviceName, - if (serviceVersion != null) 'serviceVersion': serviceVersion, - if (environment != null) 'environment': environment, - if (resourceAttributes.isNotEmpty) - 'resourceAttributes': resourceAttributes, - if (flushInterval != null) - 'flushIntervalSeconds': _wholeSeconds(flushInterval!), - if (flushAt != null) 'flushAt': flushAt, - if (maxBatchSize != null) 'maxBatchSize': maxBatchSize, - if (maxBufferSize != null) 'maxBufferSize': maxBufferSize, - if (rateCapMaxLogs != null) 'rateCapMaxLogs': rateCapMaxLogs, - if (rateCapWindow != null) - 'rateCapWindowSeconds': _wholeSeconds(rateCapWindow!), - }; - } - - /// The native flush interval and rate-cap window are whole seconds. A - /// sub-second [Duration] truncates to `0`, which the native SDK treats as - /// "disabled" (rate cap) or continuous flushing — surprising for a caller who - /// set, say, 500ms. Floor at 1s, the smallest value the native API can honor. - static int _wholeSeconds(Duration duration) => - duration.inSeconds < 1 ? 1 : duration.inSeconds; } /// Configuration for rage-click autocapture on iOS and Mac Catalyst. @@ -674,17 +579,6 @@ class PostHogRageClickConfig { /// /// Defaults to `3`. var minimumTapCount = 3; - - /// Converts this rage-click configuration to a platform-channel map. - Map toMap() { - return { - 'enabled': enabled, - 'thresholdPoints': thresholdPoints, - 'timeoutInterval': - timeoutInterval.inMicroseconds / Duration.microsecondsPerSecond, - 'minimumTapCount': minimumTapCount, - }; - } } /// Pixel format for Android native-screen captures in session replay. @@ -966,26 +860,6 @@ class PostHogSessionReplayConfig { /// /// Default: false. var verifyScreenshotMaskAlignment = false; - - /// Converts this session replay configuration to a platform-channel map. - /// - /// Returns values consumed by the Android and Apple session replay - /// implementations. - Map toMap() { - return { - 'captureTouches': captureTouches, - 'maskAllImages': maskAllImages, - 'maskAllTexts': maskAllTexts, - 'throttleDelayMs': throttleDelay.inMilliseconds, - 'maskAllPlatformViews': maskAllPlatformViews, - 'captureNativeScreens': captureNativeScreens, - 'verifyScreenshotMaskAlignment': verifyScreenshotMaskAlignment, - 'screenshotScale': screenshotScale, - 'screenshotCompressionQuality': screenshotCompressionQuality, - 'screenshotColorMode': screenshotColorMode.name, - if (sampleRate != null) 'sampleRate': sampleRate, - }; - } } /// Configuration for PostHog error tracking and exception capture. @@ -1159,25 +1033,6 @@ class PostHogErrorTrackingConfig { /// /// Record steps with `Posthog().addExceptionStep()`. final exceptionSteps = PostHogExceptionStepsConfig(); - - /// Converts this error tracking configuration to a platform-channel map. - /// - /// Returns values consumed by the Android, Apple, and Dart exception capture - /// implementations. - Map toMap() { - return { - 'inAppIncludes': inAppIncludes, - 'inAppExcludes': inAppExcludes, - 'inAppByDefault': inAppByDefault, - 'captureFlutterErrors': captureFlutterErrors, - 'captureSilentFlutterErrors': captureSilentFlutterErrors, - 'capturePlatformDispatcherErrors': capturePlatformDispatcherErrors, - 'captureNativeExceptions': captureNativeExceptions, - 'captureNativeCrashes': captureNativeCrashes, - 'captureIsolateErrors': captureIsolateErrors, - 'exceptionSteps': exceptionSteps.toMap(), - }; - } } /// Configuration for exception steps. @@ -1211,12 +1066,4 @@ class PostHogExceptionStepsConfig { /// until the total fits. A single step larger than the budget is rejected /// outright. Defaults to `32768` (32 KiB). var maxBytes = 32768; - - /// Converts this configuration to a platform-channel map. - Map toMap() { - return { - 'enabled': enabled, - 'maxBytes': maxBytes, - }; - } } diff --git a/posthog_flutter/lib/src/posthog_flutter_io.dart b/posthog_flutter/lib/src/posthog_flutter_io.dart index 50f0ba19..6bf9ad44 100644 --- a/posthog_flutter/lib/src/posthog_flutter_io.dart +++ b/posthog_flutter/lib/src/posthog_flutter_io.dart @@ -12,6 +12,7 @@ import 'surveys/models/survey_callbacks.dart'; import 'error_tracking/dart_exception_processor.dart'; import 'utils/before_send.dart'; import 'utils/capture_utils.dart'; +import 'utils/channel_serialization.dart'; import 'utils/property_normalizer.dart'; import 'feature_flag_result.dart'; @@ -683,7 +684,7 @@ class PosthogFlutterIO extends PosthogFlutterPlatformInterface { }); // Native returns: { key, enabled, variant, payload } - return PostHogFeatureFlagResult.fromMap(result, key); + return featureFlagResultFromMap(result, key); } on PlatformException catch (exception) { printIfDebug('Exception on getFeatureFlagResult: $exception'); return null; diff --git a/posthog_flutter/lib/src/utils/channel_serialization.dart b/posthog_flutter/lib/src/utils/channel_serialization.dart new file mode 100644 index 00000000..25e770c4 --- /dev/null +++ b/posthog_flutter/lib/src/utils/channel_serialization.dart @@ -0,0 +1,171 @@ +import '../feature_flag_result.dart'; +import '../posthog_config.dart'; +import '../util/logging.dart'; + +extension PostHogConfigSerialization on PostHogConfig { + Map toMap() { + return { + 'projectToken': projectToken, + 'host': host, + 'flushAt': flushAt, + 'maxQueueSize': maxQueueSize, + 'maxBatchSize': maxBatchSize, + 'flushInterval': flushInterval.inSeconds, + 'sendFeatureFlagEvents': sendFeatureFlagEvent, + 'preloadFeatureFlags': preloadFeatureFlags, + 'captureApplicationLifecycleEvents': captureApplicationLifecycleEvents, + 'rageClickConfig': rageClickConfig.toMap(), + 'debug': debug, + 'optOut': optOut, + 'surveys': surveys, + 'personProfiles': personProfiles.name, + 'compression': compression.name, + 'sessionReplay': sessionReplay, + 'dataMode': dataMode.name, + 'sessionReplayConfig': sessionReplayConfig.toMap(), + 'errorTrackingConfig': errorTrackingConfig.toMap(), + 'logs': logsConfig.toMap(), + 'capturePushNotificationSubscriptions': + capturePushNotificationSubscriptions, + 'capturePushNotificationOpened': capturePushNotificationOpened, + // A closure can't cross the channel. This tells native whether to install + // a bridging provider at all — installing one the host didn't ask for + // would change how the native SDK handles a 401 on the subscription call. + 'pushIdentityProviderEnabled': pushIdentityProvider != null, + if (bootstrap != null) 'bootstrap': bootstrap!.toMap(), + }; + } +} + +extension PostHogBootstrapConfigSerialization on PostHogBootstrapConfig { + /// Only the dimensions that were set are included; [isIdentifiedId] is always + /// sent so the native SDK doesn't have to infer it. + Map toMap() { + final flags = featureFlags; + if (flags != null) { + for (final entry in flags.entries) { + // Only bool/String are served (see [featureFlags]); the native SDKs drop + // anything else silently, so warn instead of leaving no trace. + if (entry.value is! bool && entry.value is! String) { + printIfDebug( + '[PostHog] bootstrap featureFlags["${entry.key}"] is ' + '${entry.value.runtimeType}; only bool and String values are served, ' + 'so this entry will be ignored.', + ); + } + } + } + return { + if (distinctId != null) 'distinctId': distinctId, + 'isIdentifiedId': isIdentifiedId, + if (featureFlags != null) 'featureFlags': featureFlags, + if (featureFlagPayloads != null) + 'featureFlagPayloads': featureFlagPayloads, + }; + } +} + +extension PostHogLogsConfigSerialization on PostHogLogsConfig { + /// Only fields the user set are included, so unset fields keep the native + /// default. [beforeSend] is intentionally omitted: it runs in Dart and never + /// crosses the platform channel. + Map toMap() { + return { + if (serviceName != null) 'serviceName': serviceName, + if (serviceVersion != null) 'serviceVersion': serviceVersion, + if (environment != null) 'environment': environment, + if (resourceAttributes.isNotEmpty) + 'resourceAttributes': resourceAttributes, + if (flushInterval != null) + 'flushIntervalSeconds': _wholeSeconds(flushInterval!), + if (flushAt != null) 'flushAt': flushAt, + if (maxBatchSize != null) 'maxBatchSize': maxBatchSize, + if (maxBufferSize != null) 'maxBufferSize': maxBufferSize, + if (rateCapMaxLogs != null) 'rateCapMaxLogs': rateCapMaxLogs, + if (rateCapWindow != null) + 'rateCapWindowSeconds': _wholeSeconds(rateCapWindow!), + }; + } + + /// The native flush interval and rate-cap window are whole seconds. A + /// sub-second [Duration] truncates to `0`, which the native SDK treats as + /// "disabled" (rate cap) or continuous flushing — surprising for a caller who + /// set, say, 500ms. Floor at 1s, the smallest value the native API can honor. + static int _wholeSeconds(Duration duration) => + duration.inSeconds < 1 ? 1 : duration.inSeconds; +} + +extension PostHogRageClickConfigSerialization on PostHogRageClickConfig { + Map toMap() { + return { + 'enabled': enabled, + 'thresholdPoints': thresholdPoints, + 'timeoutInterval': + timeoutInterval.inMicroseconds / Duration.microsecondsPerSecond, + 'minimumTapCount': minimumTapCount, + }; + } +} + +extension PostHogSessionReplayConfigSerialization + on PostHogSessionReplayConfig { + Map toMap() { + return { + 'captureTouches': captureTouches, + 'maskAllImages': maskAllImages, + 'maskAllTexts': maskAllTexts, + 'throttleDelayMs': throttleDelay.inMilliseconds, + 'maskAllPlatformViews': maskAllPlatformViews, + 'captureNativeScreens': captureNativeScreens, + 'verifyScreenshotMaskAlignment': verifyScreenshotMaskAlignment, + 'screenshotScale': screenshotScale, + 'screenshotCompressionQuality': screenshotCompressionQuality, + 'screenshotColorMode': screenshotColorMode.name, + if (sampleRate != null) 'sampleRate': sampleRate, + }; + } +} + +extension PostHogErrorTrackingConfigSerialization + on PostHogErrorTrackingConfig { + Map toMap() { + return { + 'inAppIncludes': inAppIncludes, + 'inAppExcludes': inAppExcludes, + 'inAppByDefault': inAppByDefault, + 'captureFlutterErrors': captureFlutterErrors, + 'captureSilentFlutterErrors': captureSilentFlutterErrors, + 'capturePlatformDispatcherErrors': capturePlatformDispatcherErrors, + 'captureNativeExceptions': captureNativeExceptions, + 'captureNativeCrashes': captureNativeCrashes, + 'captureIsolateErrors': captureIsolateErrors, + 'exceptionSteps': exceptionSteps.toMap(), + }; + } +} + +extension PostHogExceptionStepsConfigSerialization + on PostHogExceptionStepsConfig { + Map toMap() { + return { + 'enabled': enabled, + 'maxBytes': maxBytes, + }; + } +} + +/// Returns `null` if [result] is not a [Map]. Falls back to [fallbackKey] when +/// the map has no `key`. +PostHogFeatureFlagResult? featureFlagResultFromMap( + Object? result, + String fallbackKey, +) { + if (result is! Map) return null; + + return PostHogFeatureFlagResult( + key: result['key'] as String? ?? fallbackKey, + enabled: result['enabled'] as bool? ?? false, + variant: result['variant'] as String?, + payload: result['payload'], + ); +} diff --git a/posthog_flutter/test/posthog_logs_test.dart b/posthog_flutter/test/posthog_logs_test.dart index 8d0d46f3..624822a8 100644 --- a/posthog_flutter/test/posthog_logs_test.dart +++ b/posthog_flutter/test/posthog_logs_test.dart @@ -1,6 +1,7 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:posthog_flutter/posthog_flutter.dart'; import 'package:posthog_flutter/src/posthog_flutter_platform_interface.dart'; +import 'package:posthog_flutter/src/utils/channel_serialization.dart'; import 'posthog_flutter_platform_interface_fake.dart'; diff --git a/posthog_flutter/test/posthog_test.dart b/posthog_flutter/test/posthog_test.dart index fcec7dcf..106927ee 100644 --- a/posthog_flutter/test/posthog_test.dart +++ b/posthog_flutter/test/posthog_test.dart @@ -7,6 +7,7 @@ import 'package:posthog_flutter/src/posthog_flutter_platform_interface.dart'; import 'package:posthog_flutter/src/posthog_internal_events.dart'; import 'package:posthog_flutter/src/replay/mask/posthog_mask_controller.dart'; import 'package:posthog_flutter/src/replay/screenshot/screenshot_capturer.dart'; +import 'package:posthog_flutter/src/utils/channel_serialization.dart'; import 'posthog_flutter_platform_interface_fake.dart'; @@ -511,12 +512,12 @@ void main() { }); test('fromMap returns null for null input', () { - final result = PostHogFeatureFlagResult.fromMap(null, 'fallback'); + final result = featureFlagResultFromMap(null, 'fallback'); expect(result, isNull); }); test('fromMap returns null for non-Map input', () { - final result = PostHogFeatureFlagResult.fromMap('not a map', 'fallback'); + final result = featureFlagResultFromMap('not a map', 'fallback'); expect(result, isNull); }); @@ -528,7 +529,7 @@ void main() { 'payload': {'data': 123}, }; - final result = PostHogFeatureFlagResult.fromMap(map, 'fallback'); + final result = featureFlagResultFromMap(map, 'fallback'); expect(result, isNotNull); expect(result!.key, equals('my-flag')); @@ -540,7 +541,7 @@ void main() { test('fromMap uses fallback key when map key is null', () { final map = {'enabled': true, 'variant': null, 'payload': null}; - final result = PostHogFeatureFlagResult.fromMap(map, 'fallback-key'); + final result = featureFlagResultFromMap(map, 'fallback-key'); expect(result, isNotNull); expect(result!.key, equals('fallback-key')); @@ -549,7 +550,7 @@ void main() { test('fromMap defaults enabled to false when not in map', () { final map = {'key': 'my-flag'}; - final result = PostHogFeatureFlagResult.fromMap(map, 'fallback'); + final result = featureFlagResultFromMap(map, 'fallback'); expect(result, isNotNull); expect(result!.enabled, isFalse); diff --git a/posthog_flutter/test/replay_capture_touches_test.dart b/posthog_flutter/test/replay_capture_touches_test.dart index 485c5cb2..1a4f9d1d 100644 --- a/posthog_flutter/test/replay_capture_touches_test.dart +++ b/posthog_flutter/test/replay_capture_touches_test.dart @@ -4,6 +4,7 @@ import 'package:posthog_flutter/posthog_flutter.dart'; import 'package:posthog_flutter/src/posthog_flutter_io.dart'; import 'package:posthog_flutter/src/posthog_flutter_platform_interface.dart'; import 'package:posthog_flutter/src/posthog_internal_events.dart'; +import 'package:posthog_flutter/src/utils/channel_serialization.dart'; void main() { TestWidgetsFlutterBinding.ensureInitialized(); diff --git a/posthog_flutter/test/replay_screenshot_config_test.dart b/posthog_flutter/test/replay_screenshot_config_test.dart index edc745a2..d562fd4f 100644 --- a/posthog_flutter/test/replay_screenshot_config_test.dart +++ b/posthog_flutter/test/replay_screenshot_config_test.dart @@ -1,5 +1,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:posthog_flutter/posthog_flutter.dart'; +import 'package:posthog_flutter/src/utils/channel_serialization.dart'; void main() { test('screenshot controls preserve native defaults', () {