196 lines
8.8 KiB
Dart
196 lines
8.8 KiB
Dart
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:friendly_map/modules/app/app.dart';
|
|
import 'package:friendly_map/modules/events/events.dart';
|
|
import 'package:friendly_map/modules/kinship/kinship.dart';
|
|
import 'package:friendly_map/modules/platform/platform.dart';
|
|
import 'package:friendly_map/modules/transport/transport.dart';
|
|
|
|
import 'support/app_device.dart';
|
|
|
|
class FakeLog implements CallLogProvider {
|
|
FakeLog(this.entries);
|
|
final List<CallLogEntry> entries;
|
|
@override
|
|
Future<List<CallLogEntry>> forNumber(String number, {int limit = 200}) async => entries;
|
|
}
|
|
|
|
class FakePhone implements PhoneActions {
|
|
final dialed = <String>[];
|
|
final texted = <String>[];
|
|
@override
|
|
Future<bool> dial(String number) async {
|
|
dialed.add(number);
|
|
return true;
|
|
}
|
|
@override
|
|
Future<bool> sms(String number) async {
|
|
texted.add(number);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
class FakeNotifier implements Notifier {
|
|
List<ScheduledNotice> last = [];
|
|
@override
|
|
Future<void> replaceAll(List<ScheduledNotice> notices) async => last = notices;
|
|
}
|
|
|
|
void main() {
|
|
late AppDevice me;
|
|
late FakeNotifier notifier;
|
|
late FakePhone phone;
|
|
|
|
setUp(() async {
|
|
notifier = FakeNotifier();
|
|
phone = FakePhone();
|
|
me = await AppDevice.create(MemoryHub(), '010-1111-2222', '+821011112222', '나',
|
|
notifier: notifier,
|
|
phone: phone,
|
|
callLog: FakeLog([
|
|
CallLogEntry('+821033334444', DateTime(2026, 10, 1, 19, 10), 600, CallKind.outgoing),
|
|
CallLogEntry('+821033334444', DateTime(2026, 10, 9, 19, 30), 120, CallKind.incoming),
|
|
CallLogEntry('+821033334444', DateTime(2026, 10, 12, 9, 0), 0, CallKind.missed),
|
|
]));
|
|
});
|
|
|
|
group('촌수 알려주기', () {
|
|
test('번호 없는 친척도 가계도에 넣고, 나와 내 자식 눈으로 본 관계를 알려 준다', () async {
|
|
final k = me.app.kin;
|
|
await k.setMe(gender: Gender.male, birthYear: 1990);
|
|
final father = (await k.addRelative('아버지', gender: Gender.male, birthYear: 1960))!;
|
|
final uncle = (await k.addRelative('큰아버지', gender: Gender.male, birthYear: 1955))!;
|
|
final cousin = (await k.addRelative('사촌형', gender: Gender.male, birthYear: 1985))!;
|
|
final gf = (await k.addRelative('할아버지', gender: Gender.male, birthYear: 1930))!;
|
|
final son = (await k.addRelative('철수', gender: Gender.male, birthYear: 2020))!;
|
|
expect(await k.setParent('me', father.id), true);
|
|
expect(await k.setParent(father.id, gf.id), true);
|
|
expect(await k.setParent(uncle.id, gf.id), true);
|
|
expect(await k.setParent(cousin.id, uncle.id), true);
|
|
expect(await k.setParent(son.id, 'me'), true);
|
|
|
|
final r = await k.relationOf(cousin.id);
|
|
expect(r.title, '친사촌 형');
|
|
expect(r.chon, 4);
|
|
|
|
final views = await k.explain(cousin.id);
|
|
expect(views.map((v) => v.whose).toList(), ['나', '철수']);
|
|
expect(views[1].relation.title, '당숙');
|
|
expect(views[1].relation.chon, 5);
|
|
|
|
final list = await k.everyone();
|
|
final chons = list.map((e) => e.relation.chon ?? 99).toList();
|
|
expect(chons.first, 1); // 가까운 촌수가 맨 앞
|
|
expect(chons, [...chons]..sort());
|
|
});
|
|
|
|
test('잘못된 번호는 거절, 같은 번호는 한 번만', () async {
|
|
expect(await me.app.kin.addRelative('x', phone: '12'), isNull);
|
|
expect(await me.app.kin.addRelative(' '), isNull);
|
|
expect(await me.app.kin.addRelative('고모', phone: '010-5555-6666'), isNotNull);
|
|
expect(await me.app.kin.addRelative('고모2', phone: '01055556666'), isNull);
|
|
});
|
|
|
|
test('다시 열어도 가계도가 남아 있다', () async {
|
|
final f = (await me.app.kin.addRelative('엄마', gender: Gender.female))!;
|
|
await me.app.kin.setParent('me', f.id);
|
|
expect((await me.app.kin.relationOf(f.id)).title, '어머니');
|
|
expect(await me.app.kin.inTree(f.id), true);
|
|
await me.app.kin.exclude(f.id);
|
|
expect((await me.app.kin.relationOf(f.id)).related, false);
|
|
});
|
|
});
|
|
|
|
group('사람 정보와 통화', () {
|
|
test('통화 요약: 횟수·시간·자주 받는 시간대, 바로 전화·문자', () async {
|
|
final p = (await me.app.friends.add('+821033334444', '삼촌'))!;
|
|
final s = await me.app.calls.summary(p.id);
|
|
expect(s.total, 3);
|
|
expect(s.missed, 1);
|
|
expect(s.totalSeconds, 720);
|
|
expect(s.windows.first.fromHour, 19);
|
|
expect(await me.app.calls.call(p.id), true);
|
|
expect(await me.app.calls.sms(p.id), true);
|
|
expect(phone.dialed, ['+821033334444']);
|
|
expect(phone.texted, ['+821033334444']);
|
|
});
|
|
|
|
test('번호 없는 친척은 걸 수 없고 요약도 비어 있다', () async {
|
|
final r = (await me.app.kin.addRelative('먼 친척'))!;
|
|
expect(await me.app.calls.reachable(r.id), false);
|
|
expect(await me.app.calls.call(r.id), false);
|
|
expect((await me.app.calls.summary(r.id)).total, 0);
|
|
});
|
|
|
|
test('생일·돌아가신 날 기록, 주제·메모', () async {
|
|
final r = (await me.app.kin.addRelative('할머니'))!;
|
|
await me.app.facts.save(r.id, const PersonFacts(birthMonth: 5, birthDay: 3, topics: ['안부', '제사'], memo: '저녁에 편함'));
|
|
var f = await me.app.facts.get(r.id);
|
|
expect(f.hasBirthday, true);
|
|
expect(f.deceased, false);
|
|
expect(f.topics, ['안부', '제사']);
|
|
await me.app.facts.setDeceased(r.id, year: 2020, month: 2, day: 14);
|
|
f = await me.app.facts.get(r.id);
|
|
expect(f.deceased, true);
|
|
expect(f.deceasedText, '2020.2.14');
|
|
expect(f.topics, ['안부', '제사']); // 다른 값은 그대로
|
|
await me.app.facts.setDeceased(r.id); // 해제
|
|
expect((await me.app.facts.get(r.id)).deceased, false);
|
|
expect(() => me.app.facts.save(r.id, const PersonFacts(birthMonth: 2, birthDay: 30)), throwsArgumentError);
|
|
expect(() => me.app.facts.save(r.id, const PersonFacts(birthMonth: 2)), throwsArgumentError);
|
|
});
|
|
});
|
|
|
|
group('일정 알림', () {
|
|
test('기본은 하루 전과 당일, 설정에 적은 날짜대로 예약이 바뀐다', () async {
|
|
final r = (await me.app.kin.addRelative('엄마'))!;
|
|
final soon = DateTime.now().add(const Duration(days: 10));
|
|
await me.app.facts.save(r.id, PersonFacts(birthMonth: soon.month, birthDay: soon.day));
|
|
expect(await me.app.events.leadDays(), [1, 0]);
|
|
expect(await me.app.events.reschedule(), 2);
|
|
expect(notifier.last.length, 2);
|
|
expect(notifier.last.first.text, '내일 엄마 생일입니다');
|
|
|
|
await me.app.events.setLeadDays('1일 전, 2일 전, 7일 전');
|
|
expect(await me.app.events.leadDays(), [7, 2, 1]);
|
|
expect(notifier.last.map((n) => n.text).toList(),
|
|
['7일 뒤 엄마 생일입니다', '2일 뒤 엄마 생일입니다', '내일 엄마 생일입니다']);
|
|
});
|
|
|
|
test('돌아가신 분은 생일 대신 기일, 표시 설정', () async {
|
|
final r = (await me.app.kin.addRelative('할아버지'))!;
|
|
final soon = DateTime.now().add(const Duration(days: 3));
|
|
await me.app.facts.save(
|
|
r.id, PersonFacts(birthMonth: 1, birthDay: 1, deceasedYear: 2015, deceasedMonth: soon.month, deceasedDay: soon.day));
|
|
final list = await me.app.events.forPerson(r.id);
|
|
expect(list.length, 1);
|
|
expect(list.first.upcoming.event.kind, EventKind.memorial);
|
|
expect(list.first.text, '할아버지 기일');
|
|
expect(list.first.upcoming.years, soon.year - 2015);
|
|
expect((await me.app.events.soon(withinDays: 5)).length, 1);
|
|
expect(await me.app.events.showDeceased(), true);
|
|
await me.app.events.setShowDeceased(false);
|
|
expect(await me.app.events.showDeceased(), false);
|
|
});
|
|
|
|
test('음력 기일: 음력 날짜가 양력으로 바뀌어 알림이 잡힌다', () async {
|
|
final r = (await me.app.kin.addRelative('할아버지'))!;
|
|
final target = DateTime.now().add(const Duration(days: 20));
|
|
final l = solarToLunar(target)!;
|
|
await me.app.facts.setDeceased(r.id, year: 2015, month: l.month, day: l.day, lunar: true);
|
|
final list = await me.app.events.forPerson(r.id, withinDays: 40);
|
|
expect(list.length, 1);
|
|
final d = list.first.upcoming.date;
|
|
expect(DateTime(d.year, d.month, d.day).difference(DateTime(target.year, target.month, target.day)).inDays.abs() <= 1, true);
|
|
expect(list.first.text, '할아버지 기일(음력)');
|
|
expect((await me.app.facts.get(r.id)).deceasedText.startsWith('음력 2015.'), true);
|
|
expect(() => me.app.facts.save(r.id, const PersonFacts(birthMonth: 13, birthDay: 1, birthLunar: true)), throwsArgumentError);
|
|
});
|
|
|
|
test('알림 부품이 없으면 예약 0건', () async {
|
|
final bare = await AppDevice.create(MemoryHub(), '010-7777-8888', '+821077778888', '무');
|
|
expect(bare.app.events.canNotify, false);
|
|
expect(await bare.app.events.reschedule(), 0);
|
|
});
|
|
});
|
|
}
|