blob: e91d0786c7c6c7503a6c2b99f91783043890c798 [file] [log] [blame]
// Copyright 2017 The Chromium Authors. 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:async';
import 'package:flutter/services.dart';
import 'package:mockito/mockito.dart';
import 'package:test/test.dart';
import 'package:flutter/widgets.dart';
import 'package:firebase_analytics/firebase_analytics.dart';
import 'package:firebase_analytics/observer.dart';
void main() {
group('FirebaseAnalyticsObserver', () {
FirebaseAnalytics analytics;
FirebaseAnalyticsObserver observer;
final List<String> printLog = <String>[];
void overridePrint(void Function() func) {
final ZoneSpecification spec =
ZoneSpecification(print: (_, __, ___, String msg) {
// Add to log instead of printing to stdout
printLog.add(msg);
});
return Zone.current.fork(specification: spec).run(func);
}
setUp(() {
printLog.clear();
analytics = MockFirebaseAnalytics();
observer = FirebaseAnalyticsObserver(analytics: analytics);
when(analytics.setCurrentScreen(screenName: anyNamed('screenName')))
.thenAnswer((Invocation invocation) => Future<void>.value());
});
test('setCurrentScreen on route pop', () {
final PageRoute<dynamic> route = MockPageRoute();
final PageRoute<dynamic> previousRoute = MockPageRoute();
when(previousRoute.settings)
.thenReturn(const RouteSettings(name: 'previousRoute'));
observer.didPop(route, previousRoute);
verify(analytics.setCurrentScreen(screenName: 'previousRoute')).called(1);
});
test('setCurrentScreen on route push', () {
final PageRoute<dynamic> route = MockPageRoute();
final PageRoute<dynamic> previousRoute = MockPageRoute();
when(route.settings).thenReturn(const RouteSettings(name: 'route'));
observer.didPush(route, previousRoute);
verify(analytics.setCurrentScreen(screenName: 'route')).called(1);
});
test('uses nameExtractor', () {
observer = FirebaseAnalyticsObserver(
analytics: analytics,
nameExtractor: (RouteSettings settings) => 'foo',
);
final PageRoute<dynamic> route = MockPageRoute();
final PageRoute<dynamic> previousRoute = MockPageRoute();
observer.didPush(route, previousRoute);
verify(analytics.setCurrentScreen(screenName: 'foo')).called(1);
});
test('handles only ${PlatformException}s', () async {
observer = FirebaseAnalyticsObserver(
analytics: analytics,
nameExtractor: (RouteSettings settings) => 'foo',
);
final PageRoute<dynamic> route = MockPageRoute();
final PageRoute<dynamic> previousRoute = MockPageRoute();
// Throws non-PlatformExceptions
when(analytics.setCurrentScreen(screenName: anyNamed('screenName')))
.thenThrow(ArgumentError());
expect(() => observer.didPush(route, previousRoute), throwsArgumentError);
// Print PlatformExceptions
Future<void> throwPlatformException() async =>
throw PlatformException(code: 'a');
when(analytics.setCurrentScreen(screenName: anyNamed('screenName')))
.thenAnswer((Invocation invocation) => throwPlatformException());
overridePrint(() => observer.didPush(route, previousRoute));
await pumpEventQueue();
expect(
printLog,
<String>['$FirebaseAnalyticsObserver: ${PlatformException(code: 'a')}'],
);
});
test('runs onError', () async {
PlatformException passedException;
final void Function(PlatformException error) handleError =
(PlatformException error) {
passedException = error;
};
observer = FirebaseAnalyticsObserver(
analytics: analytics,
nameExtractor: (RouteSettings settings) => 'foo',
onError: handleError,
);
final PageRoute<dynamic> route = MockPageRoute();
final PageRoute<dynamic> previousRoute = MockPageRoute();
final PlatformException thrownException = PlatformException(code: 'b');
Future<void> throwPlatformException() async => throw thrownException;
when(analytics.setCurrentScreen(screenName: anyNamed('screenName')))
.thenAnswer((Invocation invocation) => throwPlatformException());
observer.didPush(route, previousRoute);
await pumpEventQueue();
expect(passedException, thrownException);
});
});
}
class MockFirebaseAnalytics extends Mock implements FirebaseAnalytics {}
class MockPageRoute extends Mock implements PageRoute<dynamic> {}