blob: 5f9f3c456d3f113df5b68f7d2670da03d5a1a10a [file] [log] [blame]
// Copyright (c) 2019 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/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:provider/provider.dart';
import 'package:cocoon_service/protos.dart' show Agent;
import 'package:app_flutter/agent_dashboard_page.dart';
import 'package:app_flutter/agent_tile.dart';
import 'package:app_flutter/service/cocoon.dart';
import 'package:app_flutter/service/google_authentication.dart';
import 'package:app_flutter/sign_in_button.dart';
import 'package:app_flutter/state/agent.dart';
void main() {
testWidgets('shows sign in button', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: ChangeNotifierProvider<AgentState>(
create: (_) => FakeAgentState(),
child: const AgentDashboard(),
),
),
),
);
expect(find.byType(SignInButton), findsOneWidget);
});
testWidgets('create agent FAB opens dialog', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
home: AgentDashboardPage(),
),
);
expect(find.byType(AlertDialog), findsNothing);
expect(find.text('Create Agent'), findsOneWidget);
await tester.tap(find.text('Create Agent'));
await tester.pumpAndSettle();
expect(find.byType(AlertDialog), findsOneWidget);
expect(find.text('Create Agent'), findsNWidgets(2));
});
testWidgets('create agent dialog calls create agent',
(WidgetTester tester) async {
final MockCocoonService mockCocoonService = MockCocoonService();
final AgentState agentState = AgentState(
cocoonServiceValue: mockCocoonService,
authServiceValue: MockSignInService(),
);
await tester.pumpWidget(
MaterialApp(
home: ChangeNotifierProvider<AgentState>(
create: (_) => agentState,
child: AgentDashboard(
agentState: agentState,
),
),
),
);
when(mockCocoonService.createAgent(any, any, any))
.thenAnswer((_) async => CocoonResponse<String>()..data = 'abc123');
verifyNever(mockCocoonService.createAgent(any, any, any));
await tester.tap(find.text('Create Agent'));
await tester.pump();
await tester.tap(find.text('Create'));
await tester.pump();
verify(mockCocoonService.createAgent(any, any, any)).called(1);
});
testWidgets('show error snackbar when error occurs',
(WidgetTester tester) async {
final FakeAgentState agentState = FakeAgentState();
final AgentDashboardPage buildDashboardPage =
AgentDashboardPage(agentState: agentState);
await tester.pumpWidget(
MaterialApp(
home: Scaffold(body: buildDashboardPage),
),
);
expect(find.text(agentState.errors.message), findsNothing);
// propagate the error message
agentState.errors.message = 'ERROR';
agentState.errors.notifyListeners();
await tester.pump();
await tester
.pump(const Duration(milliseconds: 750)); // open animation for snackbar
expect(find.text(agentState.errors.message), findsOneWidget);
// Snackbar message should go away after its duration
await tester
.pump(AgentDashboardPage.errorSnackbarDuration); // wait the duration
await tester.pump(); // schedule animation
await tester.pump(const Duration(milliseconds: 1500)); // close animation
expect(find.text(agentState.errors.message), findsNothing);
});
testWidgets('agent filter is passed to agent list',
(WidgetTester tester) async {
final AgentState agentState = AgentState();
await tester.pumpWidget(
MaterialApp(
home: AgentDashboardPage(
agentState: agentState,
agentFilter: 'dash-test-3',
),
),
);
agentState.notifyListeners();
await tester.pump();
expect(find.byType(AgentTile), findsOneWidget);
// agent id shows in the search bar and the agent tile
expect(find.text('dash-test-3'), findsNWidgets(2));
});
}
class FakeAgentState extends ChangeNotifier implements AgentState {
@override
GoogleSignInService authService = MockSignInService();
@override
AgentStateErrors errors = AgentStateErrors();
@override
Duration get refreshRate => null;
@override
Future<void> signIn() => null;
@override
Future<void> signOut() => null;
@override
List<Agent> agents = <Agent>[];
@override
Future<String> authorizeAgent(Agent agent) async => 'abc123';
@override
Future<String> createAgent(String agentId, List<String> capabilities) async =>
'def456';
@override
Future<void> reserveTask(Agent agent) => null;
@override
Future<void> startFetchingStateUpdates() => null;
@override
Timer refreshTimer;
}
class MockCocoonService extends Mock implements CocoonService {}
class MockSignInService extends Mock implements GoogleSignInService {}