70 lines
3.4 KiB
Dart
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': ''}}), '스트리밍');
|
|
});
|
|
}
|