2022-05-11 22:42:14 +03:00
|
|
|
import 'dart:convert';
|
|
|
|
import 'dart:math';
|
|
|
|
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
import 'package:integration_test/integration_test.dart';
|
2022-05-11 23:52:38 +03:00
|
|
|
import 'package:yubico_authenticator/oath/views/account_list.dart';
|
2022-05-11 22:42:14 +03:00
|
|
|
import 'package:yubico_authenticator/oath/views/oath_screen.dart';
|
|
|
|
|
2022-05-12 16:35:14 +03:00
|
|
|
import 'test_util.dart';
|
|
|
|
|
2022-05-11 22:42:14 +03:00
|
|
|
Future<void> addDelay(int ms) async {
|
|
|
|
await Future<void>.delayed(Duration(milliseconds: ms));
|
|
|
|
}
|
|
|
|
|
|
|
|
int randomNum(int max) {
|
|
|
|
var r = Random.secure();
|
|
|
|
return r.nextInt(max);
|
|
|
|
}
|
|
|
|
|
|
|
|
String randomPadded() {
|
|
|
|
return randomNum(999).toString().padLeft(3, '0');
|
|
|
|
}
|
|
|
|
|
|
|
|
String generateRandomIssuer() {
|
2022-07-06 23:50:38 +03:00
|
|
|
return 'i${randomPadded()}';
|
2022-05-11 22:42:14 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
String generateRandomName() {
|
2022-07-06 23:50:38 +03:00
|
|
|
return 'n${randomPadded()}';
|
2022-05-11 22:42:14 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
String generateRandomSecret() {
|
|
|
|
final random = Random.secure();
|
|
|
|
return base64Encode(List.generate(10, (_) => random.nextInt(256)));
|
|
|
|
}
|
|
|
|
|
|
|
|
void main() {
|
|
|
|
final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
|
|
|
binding.framePolicy = LiveTestWidgetsFlutterBindingFramePolicy.fullyLive;
|
|
|
|
|
2022-07-06 23:50:38 +03:00
|
|
|
group('OATH Options', () {
|
|
|
|
/*
|
|
|
|
These tests verify that all oath options are verified to function correctly by:
|
|
|
|
1. setting firsPassword and verifying it
|
|
|
|
2. logging in and changing to secondPassword and verifying it
|
|
|
|
3. changing to thirdPassword
|
|
|
|
4. removing thirdPassword
|
|
|
|
*/
|
|
|
|
testWidgets('OATH: set firstPassword', (WidgetTester tester) async {
|
2022-05-12 16:35:14 +03:00
|
|
|
await tester.pumpWidget(await getAuthenticatorApp());
|
2022-05-11 22:42:14 +03:00
|
|
|
await tester.pump(const Duration(milliseconds: 500));
|
|
|
|
|
2022-07-06 23:50:38 +03:00
|
|
|
var firstPassword = 'aaa111';
|
2022-05-11 22:42:14 +03:00
|
|
|
|
2022-07-06 23:50:38 +03:00
|
|
|
/// expect(find.byType(OathScreen), findsOneWidget); <<< I am not certain if this is needed.
|
|
|
|
|
|
|
|
await tester.tap(find.byIcon(Icons.tune));
|
|
|
|
await tester.pump(const Duration(milliseconds: 100));
|
2022-05-11 22:42:14 +03:00
|
|
|
|
|
|
|
await tester.tap(find.text('Set password'));
|
2022-07-06 23:50:38 +03:00
|
|
|
await tester.pump(const Duration(milliseconds: 100));
|
|
|
|
|
|
|
|
await tester.enterText(find.byKey(const Key('new oath password')), firstPassword);
|
|
|
|
await tester.pump();
|
|
|
|
await tester.enterText(find.byKey(const Key('confirm oath password')), firstPassword);
|
|
|
|
await tester.pump();
|
|
|
|
|
|
|
|
await tester.tap(find.text('Save'));
|
|
|
|
await tester.pump(const Duration(milliseconds: 100));
|
|
|
|
|
|
|
|
await tester.pump(const Duration(milliseconds: 1000));
|
|
|
|
});
|
|
|
|
testWidgets('OATH: verify firstPassword', (WidgetTester tester) async {
|
|
|
|
await tester.pumpWidget(await getAuthenticatorApp());
|
|
|
|
await tester.pump(const Duration(milliseconds: 500));
|
|
|
|
|
|
|
|
var firstPassword = 'aaa111';
|
|
|
|
|
|
|
|
await tester.enterText(find.byKey(const Key('oath password')), firstPassword);
|
|
|
|
await tester.pump();
|
|
|
|
|
|
|
|
/// TODO: verification of state here: see that list of accounts is shown
|
|
|
|
await tester.pump(const Duration(milliseconds: 1000));
|
|
|
|
});
|
|
|
|
testWidgets('OATH: set secondPassword', (WidgetTester tester) async {
|
|
|
|
await tester.pumpWidget(await getAuthenticatorApp());
|
|
|
|
await tester.pump(const Duration(milliseconds: 500));
|
|
|
|
|
|
|
|
var firstPassword = 'aaa111';
|
|
|
|
var secondPassword = 'bbb222';
|
|
|
|
|
|
|
|
await tester.enterText(find.byKey(const Key('oath password')), firstPassword);
|
|
|
|
await tester.pump();
|
|
|
|
await tester.tap(find.byKey(const Key('oath unlock')));
|
2022-05-11 22:42:14 +03:00
|
|
|
|
2022-07-06 23:50:38 +03:00
|
|
|
await tester.tap(find.byIcon(Icons.tune));
|
|
|
|
await tester.pump(const Duration(milliseconds: 100));
|
2022-05-11 22:42:14 +03:00
|
|
|
|
2022-07-06 23:50:38 +03:00
|
|
|
await tester.tap(find.text('Manage password'));
|
|
|
|
await tester.pump(const Duration(milliseconds: 100));
|
|
|
|
|
|
|
|
await tester.enterText(find.byKey(const Key('current oath password')), firstPassword);
|
|
|
|
await tester.pump();
|
|
|
|
await tester.enterText(find.byKey(const Key('new oath password')), secondPassword);
|
|
|
|
|
|
|
|
await tester.pump();
|
|
|
|
await tester.enterText(find.byKey(const Key('confirm oath password')), secondPassword);
|
2022-05-11 22:42:14 +03:00
|
|
|
await tester.pump();
|
|
|
|
|
|
|
|
await tester.tap(find.text('Save'));
|
2022-07-06 23:50:38 +03:00
|
|
|
await tester.pump(const Duration(milliseconds: 100));
|
2022-05-11 22:42:14 +03:00
|
|
|
|
2022-07-06 23:50:38 +03:00
|
|
|
await tester.pump(const Duration(milliseconds: 1000));
|
2022-05-11 22:42:14 +03:00
|
|
|
});
|
2022-07-06 23:50:38 +03:00
|
|
|
testWidgets('OATH: set thirdPassword', (WidgetTester tester) async {
|
2022-05-12 16:35:14 +03:00
|
|
|
await tester.pumpWidget(await getAuthenticatorApp());
|
2022-05-11 22:42:14 +03:00
|
|
|
await tester.pump(const Duration(milliseconds: 500));
|
|
|
|
|
2022-07-06 23:50:38 +03:00
|
|
|
var secondPassword = 'bbb222';
|
|
|
|
var thirdPassword = 'ccc333';
|
2022-05-11 22:42:14 +03:00
|
|
|
|
2022-07-06 23:50:38 +03:00
|
|
|
await tester.tap(find.byIcon(Icons.tune));
|
|
|
|
await tester.pump(const Duration(milliseconds: 100));
|
2022-05-11 22:42:14 +03:00
|
|
|
|
|
|
|
await tester.tap(find.text('Manage password'));
|
2022-07-06 23:50:38 +03:00
|
|
|
await tester.pump(const Duration(milliseconds: 100));
|
|
|
|
|
|
|
|
await tester.enterText(find.byKey(const Key('current oath password')), secondPassword);
|
|
|
|
await tester.pump();
|
|
|
|
await tester.enterText(find.byKey(const Key('new oath password')), thirdPassword);
|
|
|
|
await tester.pump();
|
|
|
|
await tester.enterText(find.byKey(const Key('confirm oath password')), thirdPassword);
|
2022-05-11 22:42:14 +03:00
|
|
|
await tester.pump();
|
|
|
|
|
|
|
|
await tester.tap(find.text('Save'));
|
2022-07-06 23:50:38 +03:00
|
|
|
await tester.pump(const Duration(milliseconds: 100));
|
|
|
|
|
|
|
|
await tester.pump(const Duration(milliseconds: 1000));
|
2022-05-11 22:42:14 +03:00
|
|
|
|
2022-07-06 23:50:38 +03:00
|
|
|
/// TODO: verification of state here: see that list of accounts is shown
|
2022-05-11 22:42:14 +03:00
|
|
|
});
|
2022-07-06 23:50:38 +03:00
|
|
|
|
|
|
|
testWidgets('OATH: remove thirdPassword', (WidgetTester tester) async {
|
2022-05-12 16:35:14 +03:00
|
|
|
await tester.pumpWidget(await getAuthenticatorApp());
|
2022-05-11 22:42:14 +03:00
|
|
|
await tester.pump(const Duration(milliseconds: 500));
|
|
|
|
|
2022-07-06 23:50:38 +03:00
|
|
|
var thirdPassword = 'ccc333';
|
2022-05-11 22:42:14 +03:00
|
|
|
|
2022-07-06 23:50:38 +03:00
|
|
|
await tester.tap(find.byIcon(Icons.tune));
|
|
|
|
await tester.pump(const Duration(milliseconds: 100));
|
2022-05-11 22:42:14 +03:00
|
|
|
|
|
|
|
await tester.tap(find.text('Manage password'));
|
2022-07-06 23:50:38 +03:00
|
|
|
await tester.pump(const Duration(milliseconds: 100));
|
2022-05-11 22:42:14 +03:00
|
|
|
|
2022-07-06 23:50:38 +03:00
|
|
|
await tester.enterText(find.byKey(const Key('current oath password')), thirdPassword);
|
2022-05-11 22:42:14 +03:00
|
|
|
await tester.pump();
|
|
|
|
|
|
|
|
await tester.tap(find.text('Remove password'));
|
|
|
|
|
2022-07-06 23:50:38 +03:00
|
|
|
/// TODO: verification of state here: see that list of accounts is shown
|
|
|
|
await tester.pump(const Duration(milliseconds: 1000));
|
2022-05-11 22:42:14 +03:00
|
|
|
});
|
|
|
|
});
|
|
|
|
group('TOTP tests', () {
|
2022-07-06 23:50:38 +03:00
|
|
|
/*
|
|
|
|
Tests will verify all TOTP functionality, not yet though:
|
|
|
|
1. Add 32 TOTP accounts
|
|
|
|
*/
|
|
|
|
testWidgets('TOTP: Add 32 accounts', (WidgetTester tester) async {
|
2022-05-12 16:35:14 +03:00
|
|
|
await tester.pumpWidget(await getAuthenticatorApp());
|
2022-05-11 22:42:14 +03:00
|
|
|
await tester.pump(const Duration(milliseconds: 500));
|
|
|
|
|
2022-05-11 23:52:38 +03:00
|
|
|
for (var i = 0; i < 32; i += 1) {
|
2022-07-06 23:50:38 +03:00
|
|
|
await tester.tap(find.byKey(const Key('add oath account')));
|
|
|
|
await tester.pump(const Duration(milliseconds: 100));
|
2022-05-11 23:52:38 +03:00
|
|
|
|
|
|
|
var issuer = generateRandomIssuer();
|
|
|
|
var name = generateRandomName();
|
|
|
|
var secret = 'abba';
|
|
|
|
|
|
|
|
/// this random fails: generateRandomSecret();
|
|
|
|
|
|
|
|
await tester.enterText(find.byKey(const Key('issuer')), issuer);
|
2022-07-06 23:50:38 +03:00
|
|
|
await tester.pump(const Duration(milliseconds: 40));
|
2022-05-11 23:52:38 +03:00
|
|
|
await tester.enterText(find.byKey(const Key('name')), name);
|
2022-07-06 23:50:38 +03:00
|
|
|
await tester.pump(const Duration(milliseconds: 40));
|
2022-05-11 23:52:38 +03:00
|
|
|
await tester.enterText(find.byKey(const Key('secret')), secret);
|
|
|
|
|
2022-07-06 23:50:38 +03:00
|
|
|
await tester.pump(const Duration(milliseconds: 100));
|
2022-05-11 23:52:38 +03:00
|
|
|
|
|
|
|
await tester.tap(find.byKey(const Key('save_btn')));
|
|
|
|
|
2022-07-06 23:50:38 +03:00
|
|
|
await tester.pump(const Duration(milliseconds: 100));
|
2022-05-11 23:52:38 +03:00
|
|
|
|
|
|
|
expect(find.byType(OathScreen), findsOneWidget);
|
|
|
|
|
2022-07-06 23:50:38 +03:00
|
|
|
await tester.enterText(find.byKey(const Key('search_accounts')), issuer);
|
2022-05-11 23:52:38 +03:00
|
|
|
|
2022-07-06 23:50:38 +03:00
|
|
|
await tester.pump(const Duration(milliseconds: 100));
|
2022-05-11 23:52:38 +03:00
|
|
|
|
2022-07-06 23:50:38 +03:00
|
|
|
expect(find.descendant(of: find.byType(AccountList), matching: find.textContaining(issuer)), findsOneWidget);
|
2022-05-11 23:52:38 +03:00
|
|
|
|
|
|
|
await tester.pump(const Duration(milliseconds: 50));
|
|
|
|
}
|
2022-07-06 23:50:38 +03:00
|
|
|
await tester.pump(const Duration(milliseconds: 3000));
|
|
|
|
/*
|
2022-05-11 23:52:38 +03:00
|
|
|
await tester.tap(find.byType(FloatingActionButton));
|
2022-07-06 23:50:38 +03:00
|
|
|
await tester.pump(const Duration(milliseconds: 500));
|
2022-05-11 23:52:38 +03:00
|
|
|
|
|
|
|
await tester.tap(find.text('Reset OATH'));
|
2022-07-06 23:50:38 +03:00
|
|
|
await tester.pump(const Duration(milliseconds: 500));
|
2022-05-11 23:52:38 +03:00
|
|
|
|
|
|
|
await tester.tap(find.text('Reset'));
|
2022-07-06 23:50:38 +03:00
|
|
|
await tester.pump(const Duration(milliseconds: 500));
|
2022-05-11 23:52:38 +03:00
|
|
|
|
2022-07-06 23:50:38 +03:00
|
|
|
*/
|
2022-05-11 22:42:14 +03:00
|
|
|
});
|
|
|
|
});
|
2022-07-06 23:50:38 +03:00
|
|
|
/*
|
2022-05-11 22:42:14 +03:00
|
|
|
group('HOTP tests', () {
|
|
|
|
testWidgets('first HOTP test', (WidgetTester tester) async {
|
2022-05-12 16:35:14 +03:00
|
|
|
await tester.pumpWidget(await getAuthenticatorApp());
|
2022-05-11 22:42:14 +03:00
|
|
|
await tester.pump(const Duration(milliseconds: 500));
|
|
|
|
|
|
|
|
expect(find.byType(OathScreen), findsOneWidget);
|
|
|
|
});
|
|
|
|
});
|
2022-07-06 23:50:38 +03:00
|
|
|
|
|
|
|
*/
|
2022-05-11 22:42:14 +03:00
|
|
|
}
|