diff --git a/pkgs/unified_analytics/CHANGELOG.md b/pkgs/unified_analytics/CHANGELOG.md index 347a36a5d..2c3451fad 100644 --- a/pkgs/unified_analytics/CHANGELOG.md +++ b/pkgs/unified_analytics/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.2 + +- Implemented fake Google Analytics Client for `Analytics.test(...)` constructor; marked with visible for testing annotation + ## 0.1.1 - Bumping intl package to 0.18.0 to fix version solving issue with flutter_tools diff --git a/pkgs/unified_analytics/USAGE_GUIDE.md b/pkgs/unified_analytics/USAGE_GUIDE.md index ae1fca1bf..e8107ea63 100644 --- a/pkgs/unified_analytics/USAGE_GUIDE.md +++ b/pkgs/unified_analytics/USAGE_GUIDE.md @@ -6,6 +6,12 @@ It provides APIs to send events to Google Analytics using the Measurement Protoc To get started using this package, import at the entrypoint dart file and initialize with the required parameters +**IMPORTANT**: It is best practice to close the http client connection when finished +sending events, otherwise, you may notice that the dart process hangs on exit. The example below +shows how to handle closing the connection via `analytics.close()` method + +[Link to documentation for http client's close method](https://pub.dev/documentation/http/latest/http/Client-class.html) + ```dart import 'unified_analytics/unified_analytics.dart'; diff --git a/pkgs/unified_analytics/lib/src/analytics.dart b/pkgs/unified_analytics/lib/src/analytics.dart index fa1f5102f..855cc99e8 100644 --- a/pkgs/unified_analytics/lib/src/analytics.dart +++ b/pkgs/unified_analytics/lib/src/analytics.dart @@ -8,6 +8,7 @@ import 'package:file/file.dart'; import 'package:file/local.dart'; import 'package:file/memory.dart'; import 'package:http/http.dart'; +import 'package:meta/meta.dart'; import 'package:path/path.dart' as p; import 'config_handler.dart'; @@ -43,6 +44,13 @@ abstract class Analytics { platform = DevicePlatform.windows; } + // Create the instance of the GA Client which will create + // an [http.Client] to send requests + final GAClient gaClient = GAClient( + measurementId: kGoogleAnalyticsMeasurementId, + apiSecret: kGoogleAnalyticsApiSecret, + ); + return AnalyticsImpl( tool: tool.label, homeDirectory: getHomeDirectory(fs), @@ -55,11 +63,13 @@ abstract class Analytics { toolsMessage: kToolsMessage, toolsMessageVersion: kToolsMessageVersion, fs: fs, + gaClient: gaClient, ); } /// Factory constructor to return the [AnalyticsImpl] class with a /// [MemoryFileSystem] to use for testing + @visibleForTesting factory Analytics.test({ required String tool, required Directory homeDirectory, @@ -90,6 +100,7 @@ abstract class Analytics { ? FileSystemStyle.windows : FileSystemStyle.posix, ), + gaClient: FakeGAClient(), ); /// Returns a map object with all of the tools that have been parsed @@ -140,7 +151,7 @@ class AnalyticsImpl implements Analytics { final FileSystem fs; late final ConfigHandler _configHandler; late bool _showMessage; - late final GAClient _gaClient; + final GAClient _gaClient; late final String _clientId; late final UserProperty userProperty; late final LogHandler _logHandler; @@ -160,7 +171,8 @@ class AnalyticsImpl implements Analytics { required this.toolsMessage, required int toolsMessageVersion, required this.fs, - }) { + required gaClient, + }) : _gaClient = gaClient { // This initializer class will let the instance know // if it was the first run; if it is, nothing will be sent // on the first run @@ -198,13 +210,6 @@ class AnalyticsImpl implements Analytics { homeDirectory.path, kDartToolDirectoryName, kClientIdFileName)) .readAsStringSync(); - // Create the instance of the GA Client which will create - // an [http.Client] to send requests - _gaClient = GAClient( - measurementId: measurementId, - apiSecret: apiSecret, - ); - // Initialize the user property class that will be attached to // each event that is sent to Google Analytics -- it will be responsible // for getting the session id or rolling the session if the duration @@ -311,6 +316,7 @@ class TestAnalytics extends AnalyticsImpl { required super.toolsMessage, required super.toolsMessageVersion, required super.fs, + required super.gaClient, }); @override diff --git a/pkgs/unified_analytics/lib/src/constants.dart b/pkgs/unified_analytics/lib/src/constants.dart index 51155d00c..7fd1b710a 100644 --- a/pkgs/unified_analytics/lib/src/constants.dart +++ b/pkgs/unified_analytics/lib/src/constants.dart @@ -70,7 +70,7 @@ const int kLogFileLength = 2500; const String kLogFileName = 'dash-analytics.log'; /// The current version of the package, should be in line with pubspec version. -const String kPackageVersion = '0.1.1'; +const String kPackageVersion = '0.1.2'; /// The minimum length for a session const int kSessionDurationMinutes = 30; diff --git a/pkgs/unified_analytics/lib/src/ga_client.dart b/pkgs/unified_analytics/lib/src/ga_client.dart index ad4cfd741..0fc8f1d64 100644 --- a/pkgs/unified_analytics/lib/src/ga_client.dart +++ b/pkgs/unified_analytics/lib/src/ga_client.dart @@ -8,6 +8,27 @@ import 'package:http/http.dart' as http; import 'constants.dart'; +class FakeGAClient implements GAClient { + @override + String get apiSecret => throw UnimplementedError(); + + @override + String get measurementId => throw UnimplementedError(); + + @override + String get postUrl => throw UnimplementedError(); + + @override + http.Client get _client => throw UnimplementedError(); + + @override + void close() {} + + @override + Future sendData(Map body) => + Future.value(http.Response('', 200)); +} + class GAClient { final String measurementId; final String apiSecret; diff --git a/pkgs/unified_analytics/pubspec.yaml b/pkgs/unified_analytics/pubspec.yaml index 7f1490268..bec623248 100644 --- a/pkgs/unified_analytics/pubspec.yaml +++ b/pkgs/unified_analytics/pubspec.yaml @@ -4,7 +4,7 @@ description: >- to Google Analytics. # When updating this, keep the version consistent with the changelog and the # value in lib/src/constants.dart. -version: 0.1.1 +version: 0.1.2 repository: https://github.com/dart-lang/tools/tree/main/pkgs/unified_analytics environment: @@ -15,6 +15,7 @@ dependencies: file: ^6.1.4 http: ^0.13.5 intl: ^0.18.0 + meta: ^1.9.0 path: ^1.8.0 dev_dependencies: