frindlymap/test/widget_test.dart

127 lines
5.7 KiB
Dart
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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);
});
}