Files
fanuzu/app/test/quest_today_test.dart
T

70 lines
3.4 KiB
Dart

import 'package:fancake/features/quest/quest_data.dart';
import 'package:cloud_firestore/cloud_firestore.dart' show Timestamp;
import 'package:fancake/features/quest/quest_repository_firestore.dart' show questTitle, questToday;
import 'package:fancake/features/quest/widgets/quest_card_tile.dart' show questImage;
import 'package:flutter_test/flutter_test.dart';
/// HOME 과 퀘스트 목록 · 상세가 같이 쓰는 오늘 판정(2026-10-04 실기기 4-1 · 4-9).
void main() {
// 2026-10-04 09:00 KST.
final now = DateTime.utc(2026, 10, 4);
const quest = {'dailyLimit': 1};
const policy = <String, dynamic>{};
test('지난 날의 진행 행은 오늘 0 회다 — 9/21 출석이 10/4 에 「보상 완료」로 남지 않는다', () {
final r = questToday(QuestType.attend, quest, {'dayKey': '2026-09-21', 'count': 1}, policy, now);
expect(r.count, 0);
expect(r.done, isFalse);
});
test('오늘(KST) 행이면 완료다', () {
final r = questToday(QuestType.attend, quest, {'dayKey': '2026-10-04', 'count': 1}, policy, now);
expect(r.done, isTrue);
});
test('날짜 경계는 KST — UTC 10/3 15:00 은 KST 10/4 0 시다', () {
final r = questToday(QuestType.attend, quest, {'dayKey': '2026-10-04', 'count': 1}, policy,
DateTime.utc(2026, 10, 3, 15));
expect(r.done, isTrue);
final before = questToday(QuestType.attend, quest, {'dayKey': '2026-10-04', 'count': 1}, policy,
DateTime.utc(2026, 10, 3, 14, 59));
expect(before.done, isFalse);
});
test('타임어택은 1인 1회라 날짜로 끊지 않는다', () {
final r = questToday(QuestType.timeAttack, quest, {'dayKey': '2026-09-21', 'count': 1}, policy, now);
expect(r.done, isTrue);
});
test('걸음은 구간을 다 받아야 완료다(B-26)', () {
const tiers = {'stepTiers': [{'steps': 1000}, {'steps': 5000}]};
final one = questToday(QuestType.steps, quest, {'dayKey': '2026-10-04', 'count': 1}, tiers, now);
expect(one.done, isFalse);
final two = questToday(QuestType.steps, quest, {'dayKey': '2026-10-04', 'count': 2}, tiers, now);
expect(two.done, isTrue);
});
test('유형 · 제목으로 못 고르는 퀘스트도 아이콘 칸이 비지 않는다', () {
const card = QuestCard(
id: 'daily-heart', title: '심박 기록 남기기', categoryName: 'c', author: QuestAuthor.admin,
stage: QuestStage.notStarted, goal: 1, progress: 0, rewardPop: 80, participants: 0,
);
expect(questImage(card), 'assets/figma/quest-img-bolt.png');
});
// 10/6 실기기 — 운영 Quest 제목은 언어별 지도라 HOME 카드 제목이 비었다. 타임어택은 회차 제목이 먼저다.
test('Quest 제목 — 문자열 · 언어별 지도(앱 언어 → ko) · 열린 타임어택 회차 제목', () {
expect(questTitle({'title': '만보기'}), '만보기');
expect(questTitle({'title': {'en': 'Stream', 'ko': '스트리밍'}}), '스트리밍');
expect(questTitle({'title': {'en': 'Stream'}}), 'Stream');
final round = {
'roundId': 'r1',
'title': '긴급 돌발',
'activeFrom': Timestamp.fromDate(DateTime.now().subtract(const Duration(minutes: 5))),
'activeTo': Timestamp.fromDate(DateTime.now().add(const Duration(minutes: 5))),
};
expect(questTitle({'title': {'ko': '스트리밍'}, 'timeAttack': round}), '긴급 돌발');
expect(questTitle({'title': {'ko': '스트리밍'}, 'timeAttack': {...round, 'title': ''}}), '스트리밍');
});
}