127 lines
5.7 KiB
Dart
127 lines
5.7 KiB
Dart
import 'package:flutter/material.dart';
|
||
import 'package:flutter_test/flutter_test.dart';
|
||
import 'package:friendly_map/modules/app/app.dart';
|
||
import 'package:friendly_map/modules/storage/storage.dart';
|
||
import 'package:friendly_map/modules/transport/transport.dart';
|
||
import 'package:friendly_map/modules/ui/src/screens/person_screen.dart';
|
||
import 'package:friendly_map/modules/ui/ui.dart';
|
||
|
||
import 'support/app_device.dart';
|
||
import 'support/fake_cipher.dart';
|
||
import 'support/storage_contract.dart' show FakeProbe;
|
||
|
||
/// 키·저장소를 어떻게 여는지는 화면이 모른다. 시험에서는 메모리 기기로 대신한다.
|
||
class FakeBootstrap implements Bootstrap {
|
||
FakeBootstrap({this.keys = false, this.app});
|
||
|
||
bool keys;
|
||
final FriendlyApp? app;
|
||
|
||
@override
|
||
Future<bool> hasKeys() async => keys;
|
||
@override
|
||
Future<String> createKeys() async {
|
||
keys = true;
|
||
return 'one two three four five six seven eight nine ten eleven twelve';
|
||
}
|
||
|
||
@override
|
||
Future<bool> restoreKeys(String phrase) async => false;
|
||
@override
|
||
Future<List<String>> splitRecovery(int n, int k) async => [for (var i = 1; i <= n; i++) 'fmr1.$k.0000.$i:00'];
|
||
@override
|
||
Future<FriendlyApp> openApp() async => app!;
|
||
@override
|
||
Future<String?> recoveryPhrase() async => null;
|
||
}
|
||
|
||
void main() {
|
||
Future<FriendlyApp> openWithFriend(WidgetTester tester) async {
|
||
final device = await tester.runAsync(() => AppDevice.create(MemoryHub(), '010-1111-2222', '+821011112222', '이미영', start: false));
|
||
await tester.pumpWidget(FriendlyMapApp(bootstrap: FakeBootstrap(keys: true, app: device!.app)));
|
||
await tester.pumpAndSettle();
|
||
return device.app;
|
||
}
|
||
|
||
Future<void> tab(WidgetTester tester, String label) async {
|
||
await tester.tap(find.descendant(of: find.byType(NavigationBar), matching: find.text(label)));
|
||
await tester.pumpAndSettle();
|
||
}
|
||
|
||
testWidgets('처음 시작: 복구 코드 없이 이름·번호만 넣으면 바로 채팅 화면', (tester) async {
|
||
final app = FriendlyApp(AppDeps(
|
||
storage: Storage.memory(),
|
||
transport: MemoryTransport('+821011112222', MemoryHub()),
|
||
cipher: FakeCipher('K'),
|
||
identity: FakeIdentity('K'),
|
||
probe: FakeProbe(10),
|
||
));
|
||
final boot = FakeBootstrap(app: app);
|
||
await tester.pumpWidget(FriendlyMapApp(bootstrap: boot));
|
||
await tester.pumpAndSettle();
|
||
expect(find.text('시작하기'), findsOneWidget);
|
||
expect(find.textContaining('복구'), findsNothing);
|
||
await tester.enterText(find.byType(TextField).at(0), '이미영');
|
||
await tester.enterText(find.byType(TextField).at(1), '010-1111-2222');
|
||
await tester.pump();
|
||
await tester.tap(find.text('시작하기'));
|
||
await tester.runAsync(() => Future<void>.delayed(const Duration(milliseconds: 50)));
|
||
await tester.pumpAndSettle();
|
||
expect(boot.keys, isTrue, reason: '키는 조용히 만들어진다');
|
||
expect(find.byType(NavigationBar), findsOneWidget);
|
||
expect(find.text('아직 대화가 없어요'), findsOneWidget);
|
||
});
|
||
|
||
testWidgets('아래 메뉴: 채팅 · 관계 · 업무 · 명함 · 나', (tester) async {
|
||
await openWithFriend(tester);
|
||
for (final l in ['채팅', '관계', '업무', '명함', '나']) {
|
||
expect(find.descendant(of: find.byType(NavigationBar), matching: find.text(l)), findsOneWidget);
|
||
}
|
||
await tab(tester, '명함');
|
||
expect(find.text('내 명함'), findsWidgets);
|
||
await tab(tester, '나');
|
||
expect(find.text('010-1111-2222'), findsOneWidget, reason: '번호는 010 형식으로');
|
||
});
|
||
|
||
testWidgets('관계 탭: 그룹 네 개, 새 그룹 더하기, 학교 안에 하위 그룹', (tester) async {
|
||
await openWithFriend(tester);
|
||
await tab(tester, '관계');
|
||
for (final n in ['가족', '학교', '회사', '그룹·여행']) {
|
||
expect(find.text(n), findsOneWidget);
|
||
}
|
||
await tester.tap(find.text('새 그룹'));
|
||
await tester.pumpAndSettle();
|
||
await tester.enterText(find.byType(TextField).last, '등산 모임');
|
||
await tester.tap(find.text('확인'));
|
||
await tester.runAsync(() => Future<void>.delayed(const Duration(milliseconds: 50)));
|
||
await tester.pumpAndSettle();
|
||
await tester.scrollUntilVisible(find.text('등산 모임'), 200, scrollable: find.byType(Scrollable).first);
|
||
expect(find.text('등산 모임'), findsOneWidget);
|
||
await tester.scrollUntilVisible(find.text('학교'), -200, scrollable: find.byType(Scrollable).first);
|
||
await tester.tap(find.text('학교'));
|
||
await tester.pumpAndSettle();
|
||
expect(find.text('고등학교'), findsOneWidget);
|
||
expect(find.text('대학원'), findsOneWidget);
|
||
});
|
||
|
||
testWidgets('사람 화면의 관계 버튼으로 학교 › 고등학교에 넣으면 들어간 그룹이 보인다', (tester) async {
|
||
final device = await tester.runAsync(() => AppDevice.create(MemoryHub(), '010-1111-2222', '+821011112222', '이미영', start: false));
|
||
final app = device!.app;
|
||
final friend = await tester.runAsync(() => app.friends.add('+821033334444', '김민수'));
|
||
await tester.pumpWidget(FriendlyMapApp(bootstrap: FakeBootstrap(keys: true, app: app)));
|
||
await tester.pumpAndSettle();
|
||
tester.state<NavigatorState>(find.byType(Navigator).first).push(MaterialPageRoute<void>(builder: (_) => PersonScreen(personId: friend!.id)));
|
||
await tester.pumpAndSettle();
|
||
expect(find.text('010-3333-4444'), findsOneWidget);
|
||
expect(find.textContaining('관계 정하기 —'), findsOneWidget);
|
||
await tester.tap(find.text('관계'));
|
||
await tester.pumpAndSettle();
|
||
await tester.tap(find.textContaining('학교 동문'));
|
||
await tester.pumpAndSettle();
|
||
await tester.tap(find.text('고등학교'));
|
||
await tester.runAsync(() => Future<void>.delayed(const Duration(milliseconds: 50)));
|
||
await tester.pumpAndSettle();
|
||
expect(find.text('학교 › 고등학교'), findsOneWidget);
|
||
});
|
||
}
|