frindlymap/test/location_test.dart

115 lines
4.6 KiB
Dart

import 'package:flutter_test/flutter_test.dart';
import 'package:friendly_map/modules/app/app.dart';
import 'package:friendly_map/modules/platform/platform.dart';
import 'package:friendly_map/modules/transport/transport.dart';
import 'package:friendly_map/modules/visibility/visibility.dart';
import 'support/app_device.dart';
const pa = '+821011112222';
const pb = '+821022223333';
class FakeLocation implements LocationProvider {
GeoPoint? point = const GeoPoint(37.566536, 126.977966); // 서울시청
@override
Future<GeoPoint?> current() async => point;
}
Future<(AppDevice, AppDevice, FakeLocation)> scenario({String? relation}) async {
final hub = MemoryHub();
final loc = FakeLocation();
final a = await AppDevice.create(hub, '010-1111-2222', pa, '가', location: loc);
final b = await AppDevice.create(hub, '010-2222-3333', pb, '나');
final person = (await a.app.friends.add(b.phone, b.name))!;
if (relation != null) await a.app.network.addLink(person.id, relation, '시험');
await AppDevice.settleAll();
await b.app.friends.accept(a.phone);
await AppDevice.settleAll();
return (a, b, loc);
}
void main() {
group('거리 계산', () {
test('서울시청 → 부산시청은 약 325km', () {
const seoul = GeoPoint(37.566536, 126.977966), busan = GeoPoint(35.179800, 129.075000);
final d = distanceMeters(seoul, busan);
expect(d > 320000 && d < 330000, true);
});
test('같은 지점은 0, 방위는 북쪽 0도·동쪽 90도', () {
const p = GeoPoint(37, 127);
expect(distanceMeters(p, p), 0);
expect(bearingDegrees(p, const GeoPoint(38, 127)).round(), 0);
expect(bearingDegrees(p, const GeoPoint(37, 128)).round(), 90);
});
test('읽기 쉬운 글자', () {
expect(distanceLabel(350), '350 m');
expect(distanceLabel(2400), '2.4 km');
});
});
group('위치 공유', () {
test('기본은 꺼짐: 켜기 전에는 아무도에게 보내지 않는다', () async {
final (a, _, _) = await scenario(relation: '가족:동생');
expect(await a.app.location.sharingOn(), false);
expect(await a.app.location.shareNow(), 0);
});
test('가족에게는 정확한 위치가, 친구가 받은 목록에 들어간다', () async {
final (a, b, loc) = await scenario(relation: '가족:동생');
await a.app.location.setSharing(true);
expect(await a.app.location.shareNow(), 1);
await AppDevice.settleAll();
final got = await b.app.location.friends();
expect(got.length, 1);
expect(got.single.person.phone, pa);
expect(got.single.point, loc.point);
});
test('관계를 모르는 친구에게는 보내지 않는다', () async {
final (a, b, _) = await scenario();
await a.app.location.setSharing(true);
expect(await a.app.location.shareNow(), 0);
await AppDevice.settleAll();
expect(await b.app.location.friends(), isEmpty);
});
test('표에서 숨김인 관계(회사)에게는 보내지 않는다, 일부로 바꾸면 약 1km 단위로 뭉개서 보낸다', () async {
final (a, b, _) = await scenario(relation: '전 직장 동료');
await a.app.location.setSharing(true);
expect(await a.app.location.shareNow(), 0);
var m = await a.app.visibility.cycle(VCategory.location, VAudience.company); // 숨김 → 공개
m = await a.app.visibility.cycle(VCategory.location, VAudience.company); // 공개 → 일부
expect(m.get(VCategory.location, VAudience.company), VLevel.partial);
expect(await a.app.location.shareNow(), 1);
await AppDevice.settleAll();
final p = (await b.app.location.friends()).single.point;
expect(p, const GeoPoint(37.57, 126.98));
});
test('위치를 못 얻으면(권한 없음 등) 0명', () async {
final (a, _, loc) = await scenario(relation: '가족:동생');
await a.app.location.setSharing(true);
loc.point = null;
expect(await a.app.location.shareNow(), 0);
});
test('더 오래된 위치는 새 위치를 덮지 못한다', () async {
final (a, b, loc) = await scenario(relation: '가족:동생');
await a.app.location.setSharing(true);
await a.app.location.shareNow();
loc.point = const GeoPoint(35.1798, 129.075);
await Future<void>.delayed(const Duration(milliseconds: 30));
await a.app.location.shareNow();
await AppDevice.settleAll();
expect((await b.app.location.friends()).single.point, const GeoPoint(35.1798, 129.075));
});
test('위치 부품이 없는 기기는 available 이 false', () async {
final (_, b, _) = await scenario();
expect(b.app.location.available, false);
});
});
}