걸음 수 Health Connect·HealthKit · 위치 퀘스트 사진·QR 인증 · 행성 형태 확정

This commit is contained in:
Sn-Kinos
2026-10-05 23:57:01 +09:00
parent dc9861df38
commit dce2f64362
44 changed files with 930 additions and 66 deletions
+37
View File
@@ -230,6 +230,20 @@ service cloud.firestore {
expect(backend.calls.single.payload['occurredAt'], isA<String>());
});
test('Health 가 있으면 그 날 0시부터의 합계를 센서보다 먼저 쓴다 (B-02)', () async {
final db = await _seed();
final backend = _RecordingBackend(db);
final repo = FirestoreQuestRepository(
backend,
todaySteps: () async => 7_300,
stepCount: () => Stream.fromIterable([40_000]),
);
final card = _card(await repo.load(), 'steps');
expect(await repo.progressStream(card).first, 7_300);
await repo.verify(card);
expect(backend.calls.single.payload['steps'], 7_300);
});
test('앱을 껐다 켜도 오늘치가 0 으로 돌아가지 않는다', () async {
final db = await _seed();
// 첫 실행 — 기준선 40,000 을 잡고 5,000 걷는다.
@@ -300,6 +314,29 @@ service cloud.firestore {
expect(call.payload['mocked'], isTrue);
});
test('위치 Quest 의 인증 방법을 상세에 싣고 QR 은 GPS 와 함께 보낸다 (C-03 · PRD-05)', () async {
final db = await _seed();
final backend = _RecordingBackend(db);
final repo = FirestoreQuestRepository(
backend,
placeFix: () async =>
const PlaceFix(lat: 37.5, lng: 126.9, accuracyM: 5, mocked: false),
);
// 수단을 적지 않은 운영 Quest 는 GPS 하나.
expect((await repo.detail('place')).verifyMethods, ['gps']);
await db.doc('quests/place').update({'verifyMethods': ['gps', 'qr']});
await db.doc('questSecrets/place').set({'authorUid': 'other', 'qrCode': 'secret'});
final detail = await repo.detail('place');
expect(detail.verifyMethods, ['gps', 'qr']);
expect(detail.qrCode, isNull, reason: '참여자에게는 QR 값을 주지 않는다');
await repo.verify(detail.card, proof: const PlaceProof(qr: 'scanned'));
final call = backend.calls.single;
expect(call.payload['qr'], 'scanned');
expect(call.payload['lat'], 37.5);
expect(call.payload.containsKey('photo'), isFalse);
});
test('장소가 등록되지 않은 위치 퀘스트는 서버를 부르지 않는다', () async {
final db = await _seed();
await db.doc('quests/place').set({