blob: 9aa3360e06addccae5f19fc6d477772f456688aa [file] [log] [blame]
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:io' as io;
import 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:test/test.dart';
import 'package:unified_analytics/src/config_handler.dart';
import 'package:unified_analytics/src/constants.dart';
import 'package:unified_analytics/unified_analytics.dart';
void main() {
late FileSystem fs;
late Directory home;
late Directory dartToolDirectory;
late File clientIdFile;
late File sessionFile;
late File configFile;
late File logFile;
const String homeDirName = 'home';
const DashTool initialTool = DashTool.flutterTool;
const DashTool secondTool = DashTool.dartTool;
const String measurementId = 'measurementId';
const String apiSecret = 'apiSecret';
const int toolsMessageVersion = 1;
const String toolsMessage = 'toolsMessage';
const String flutterChannel = 'flutterChannel';
const String flutterVersion = 'flutterVersion';
const String dartVersion = 'dartVersion';
const DevicePlatform platform = DevicePlatform.macos;
setUp(() {
// Setup the filesystem with the home directory
final FileSystemStyle fsStyle =
io.Platform.isWindows ? FileSystemStyle.windows : FileSystemStyle.posix;
fs = MemoryFileSystem.test(style: fsStyle);
home = fs.directory(homeDirName);
dartToolDirectory = home.childDirectory(kDartToolDirectoryName);
// The 3 files that should have been generated
clientIdFile = home
.childDirectory(kDartToolDirectoryName)
.childFile(kClientIdFileName);
sessionFile =
home.childDirectory(kDartToolDirectoryName).childFile(kSessionFileName);
configFile =
home.childDirectory(kDartToolDirectoryName).childFile(kConfigFileName);
logFile =
home.childDirectory(kDartToolDirectoryName).childFile(kLogFileName);
});
test('Confirm workflow for checking tools into the config file', () {
final Analytics firstAnalytics = Analytics.test(
tool: initialTool,
homeDirectory: home,
measurementId: measurementId,
apiSecret: apiSecret,
flutterChannel: flutterChannel,
toolsMessageVersion: toolsMessageVersion,
toolsMessage: toolsMessage,
flutterVersion: flutterVersion,
dartVersion: dartVersion,
fs: fs,
platform: platform,
);
// Host of assertions to ensure all required artifacts
// are created
expect(dartToolDirectory.existsSync(), true,
reason: 'The directory should have been created');
expect(clientIdFile.existsSync(), true,
reason: 'The $kClientIdFileName file was not found');
expect(sessionFile.existsSync(), true,
reason: 'The $kSessionFileName file was not found');
expect(configFile.existsSync(), true,
reason: 'The $kConfigFileName was not found');
expect(logFile.existsSync(), true,
reason: 'The $kLogFileName file was not found');
expect(dartToolDirectory.listSync().length, equals(4),
reason:
'There should only be 4 files in the $kDartToolDirectoryName directory');
expect(configFile.readAsStringSync(), kConfigString);
expect(firstAnalytics.shouldShowMessage, true);
// Attempting to send a message with this instance should be
// blocked because it has not invoked `clientShowedMessage()`
// and it is the first run
//
// Even after invoking the method, it should be prevented from
// sending a message because it is the first time the tool was
// run in this instance
firstAnalytics.sendEvent(
eventName: DashEvent.hotReloadTime, eventData: <String, dynamic>{});
expect(logFile.readAsLinesSync().length, 0);
firstAnalytics.clientShowedMessage();
// Attempt to send two events, both should be blocked because it is
// part of the first instance
firstAnalytics.sendEvent(
eventName: DashEvent.hotReloadTime, eventData: <String, dynamic>{});
firstAnalytics.sendEvent(
eventName: DashEvent.hotReloadTime, eventData: <String, dynamic>{});
expect(logFile.readAsLinesSync().length, 0);
// Creating a second analytics instance from the same tool now should
// allow for events to be sent
final Analytics secondAnalytics = Analytics.test(
tool: initialTool,
homeDirectory: home,
measurementId: measurementId,
apiSecret: apiSecret,
flutterChannel: flutterChannel,
toolsMessageVersion: toolsMessageVersion,
toolsMessage: toolsMessage,
flutterVersion: flutterVersion,
dartVersion: dartVersion,
fs: fs,
platform: platform,
);
expect(secondAnalytics.shouldShowMessage, false);
secondAnalytics.sendEvent(
eventName: DashEvent.hotReloadTime, eventData: <String, dynamic>{});
expect(logFile.readAsLinesSync().length, 1,
reason: 'Events will be blocked until invoking method '
'ensuring client has seen message');
secondAnalytics.sendEvent(
eventName: DashEvent.hotReloadTime, eventData: <String, dynamic>{});
secondAnalytics.sendEvent(
eventName: DashEvent.hotReloadTime, eventData: <String, dynamic>{});
expect(logFile.readAsLinesSync().length, 3);
// Next, we will want to confirm that the message should be showing when
// a new analytics instance has been created with a newer version for
// message that should be shown
//
// In this case, it should be treated as a new tool being added for the first
// time and all events should be blocked
// Delete the log file to reset the counter of events sent
logFile.deleteSync();
final Analytics thirdAnalytics = Analytics.test(
tool: initialTool,
homeDirectory: home,
measurementId: measurementId,
apiSecret: apiSecret,
flutterChannel: flutterChannel,
toolsMessageVersion: toolsMessageVersion + 1, // Incrementing version
toolsMessage: toolsMessage,
flutterVersion: flutterVersion,
dartVersion: dartVersion,
fs: fs,
platform: platform,
);
expect(logFile.existsSync(), true,
reason: 'The $kLogFileName file was not found');
expect(thirdAnalytics.shouldShowMessage, true,
reason: 'New version number should require showing message');
thirdAnalytics.sendEvent(
eventName: DashEvent.hotReloadTime, eventData: <String, dynamic>{});
expect(logFile.readAsLinesSync().length, 0);
thirdAnalytics.clientShowedMessage();
// Attempt to send two events, both should be blocked because it is
// part of the third instance which has a new version for the consent
// message which will be treated as a new tool being onboarded
thirdAnalytics.sendEvent(
eventName: DashEvent.hotReloadTime, eventData: <String, dynamic>{});
thirdAnalytics.sendEvent(
eventName: DashEvent.hotReloadTime, eventData: <String, dynamic>{});
expect(logFile.readAsLinesSync().length, 0);
// The fourth instance of the analytics class with the consent message
// version incremented should now be able to send messages
final Analytics fourthAnalytics = Analytics.test(
tool: initialTool,
homeDirectory: home,
measurementId: measurementId,
apiSecret: apiSecret,
flutterChannel: flutterChannel,
toolsMessageVersion: toolsMessageVersion + 1, // Incrementing version
toolsMessage: toolsMessage,
flutterVersion: flutterVersion,
dartVersion: dartVersion,
fs: fs,
platform: platform,
);
expect(fourthAnalytics.shouldShowMessage, false);
fourthAnalytics.sendEvent(
eventName: DashEvent.hotReloadTime, eventData: <String, dynamic>{});
expect(logFile.readAsLinesSync().length, 1,
reason: 'Events will be blocked until invoking method '
'ensuring client has seen message');
fourthAnalytics.sendEvent(
eventName: DashEvent.hotReloadTime, eventData: <String, dynamic>{});
fourthAnalytics.sendEvent(
eventName: DashEvent.hotReloadTime, eventData: <String, dynamic>{});
expect(logFile.readAsLinesSync().length, 3);
});
test('Disable second instance if first one did not show message', () {
final Analytics firstAnalytics = Analytics.test(
tool: initialTool,
homeDirectory: home,
measurementId: measurementId,
apiSecret: apiSecret,
flutterChannel: flutterChannel,
toolsMessageVersion: toolsMessageVersion,
toolsMessage: toolsMessage,
flutterVersion: flutterVersion,
dartVersion: dartVersion,
fs: fs,
platform: platform,
);
expect(firstAnalytics.shouldShowMessage, true);
final Analytics secondAnalytics = Analytics.test(
tool: initialTool,
homeDirectory: home,
measurementId: measurementId,
apiSecret: apiSecret,
flutterChannel: flutterChannel,
toolsMessageVersion: toolsMessageVersion,
toolsMessage: toolsMessage,
flutterVersion: flutterVersion,
dartVersion: dartVersion,
fs: fs,
platform: platform,
);
expect(secondAnalytics.shouldShowMessage, true);
secondAnalytics.clientShowedMessage();
final Analytics thirdAnalytics = Analytics.test(
tool: initialTool,
homeDirectory: home,
measurementId: measurementId,
apiSecret: apiSecret,
flutterChannel: flutterChannel,
toolsMessageVersion: toolsMessageVersion,
toolsMessage: toolsMessage,
flutterVersion: flutterVersion,
dartVersion: dartVersion,
fs: fs,
platform: platform,
);
expect(thirdAnalytics.shouldShowMessage, false);
});
test('Passing large version number gets logged in config', () {
final int firstVersion = toolsMessageVersion + 3;
final Analytics secondAnalytics = Analytics.test(
tool: secondTool,
homeDirectory: home,
measurementId: 'measurementId',
apiSecret: 'apiSecret',
flutterChannel: flutterChannel,
toolsMessageVersion: firstVersion,
toolsMessage: toolsMessage,
flutterVersion: 'Flutter 3.6.0-7.0.pre.47',
dartVersion: 'Dart 2.19.0',
fs: fs,
platform: platform,
);
secondAnalytics.clientShowedMessage();
expect(
configFile.readAsStringSync().endsWith(
'${secondTool.label}=${ConfigHandler.dateStamp},$firstVersion\n'),
true);
// Create a new instane of the secondTool with an even
// bigger version
final int secondVersion = firstVersion + 3;
final Analytics thirdAnalytics = Analytics.test(
tool: secondTool,
homeDirectory: home,
measurementId: 'measurementId',
apiSecret: 'apiSecret',
flutterChannel: flutterChannel,
toolsMessageVersion: secondVersion,
toolsMessage: toolsMessage,
flutterVersion: 'Flutter 3.6.0-7.0.pre.47',
dartVersion: 'Dart 2.19.0',
fs: fs,
platform: platform,
);
expect(
configFile.readAsStringSync().endsWith(
'${secondTool.label}=${ConfigHandler.dateStamp},$firstVersion\n'),
true);
// After invoking this method, it will get updated
// in the config with the next version
thirdAnalytics.clientShowedMessage();
expect(
configFile.readAsStringSync().endsWith(
'${secondTool.label}=${ConfigHandler.dateStamp},$secondVersion\n'),
true);
});
}