import 'package:fancake/features/home/home_data.dart'; import 'package:fancake/features/home/home_repository_firestore.dart' show kstWeekStart; import 'package:fancake/features/quest/quest_evidence.dart' show kstMidnight; import 'package:flutter_test/flutter_test.dart'; /// HOME 주간 정보(A-37 · HOME 정보위계 v1.0 §2 · §3). void main() { Map snap(int rank, {num? growthPop, num? sfpi}) => { 'planets': [ {'fandomId': 'other', 'rank': 1}, { 'fandomId': 'f', 'rank': rank, 'growthPop': ?growthPop, 'sfpi': ?sfpi, }, ], }; test('순위는 주간 Snapshot · 변동은 직전 대비 · 성장은 두 축 증분 · 비율은 행성 주간 총량 대비', () { final w = HomeWeekly.from( fandomId: 'f', snapshots: [snap(3, growthPop: 1000, sfpi: 40), snap(5)], fandom: {'growthPop': 1500, 'sfpi': 52}, myWeekPop: 125, wallet: {'activityBalance': 700, 'supportBalance': 30}, ); expect(w.rank, 3); expect(w.rankChange, 2, reason: '5위 → 3위 = 두 계단 오름'); expect(w.weekGrowthPop, 500); expect(w.weekSfpi, 12); expect(w.myShare, 0.25); expect((w.generalPop, w.supportPop), (700, 30)); }); test('기준선 · 직전 Snapshot · 내 기여를 모르면 0 으로 채우지 않는다', () { final w = HomeWeekly.from( fandomId: 'f', snapshots: [snap(4)], fandom: {'growthPop': 1500}, myWeekPop: null, wallet: const {}, ); expect(w.rank, 4); expect(w.rankChange, isNull); expect(w.weekGrowthPop, isNull); expect(w.myShare, isNull); final none = HomeWeekly.from( fandomId: 'f', snapshots: const [], fandom: const {}, myWeekPop: 0, wallet: const {}, ); expect(none.rank, isNull); }); test('만보기 Health 집계 시작은 그 날 0시(KST) — 서버 dayKey 와 같은 경계 (B-02)', () { // 10-07 00:30 KST(= 10-06 15:30 UTC) → 10-07 00:00 KST = 10-06 15:00 UTC. expect( kstMidnight(DateTime.parse('2026-10-06T15:30:00Z')), DateTime.parse('2026-10-06T15:00:00Z'), ); }); test('이번 주 시작은 KST 월요일 00:00', () { // 2026-10-07(수) 15:00 KST → 2026-10-05(월) 00:00 KST = 10-04 15:00 UTC. expect( kstWeekStart(DateTime.parse('2026-10-07T06:00:00Z')), DateTime.parse('2026-10-04T15:00:00Z'), ); // 월요일 08:59 KST(= 일요일 23:59 UTC)도 그 주다. expect( kstWeekStart(DateTime.parse('2026-10-04T23:59:00Z')), DateTime.parse('2026-10-04T15:00:00Z'), ); }); }