100 lines
4.2 KiB
Dart
100 lines
4.2 KiB
Dart
import 'package:cloud_firestore/cloud_firestore.dart';
|
|
import 'package:fake_cloud_firestore/fake_cloud_firestore.dart';
|
|
import 'package:firebase_auth_mocks/firebase_auth_mocks.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:fancake/core/data/backend.dart';
|
|
import 'package:fancake/features/eclipse/eclipse_data.dart';
|
|
import 'package:fancake/features/eclipse/eclipse_repository_firestore.dart';
|
|
|
|
void main() {
|
|
test('추가 스냅샷 없이 마감시각에 위험 상태가 끝난다', () async {
|
|
final db = FakeFirebaseFirestore();
|
|
final repo = FirestoreEclipseRepository(
|
|
Backend(firestore: db, auth: MockFirebaseAuth()),
|
|
);
|
|
await db.doc('fandoms/bts/eclipseRounds/one').set({
|
|
'status': 'active',
|
|
'startAt': Timestamp.now(),
|
|
'endsAt': Timestamp.fromDate(
|
|
DateTime.now().add(const Duration(milliseconds: 150)),
|
|
),
|
|
});
|
|
final states = <EclipseState?>[];
|
|
final sub = repo.watch(fandomId: 'bts').listen(states.add);
|
|
addTearDown(sub.cancel);
|
|
await Future<void>.delayed(const Duration(milliseconds: 20));
|
|
expect(states.last?.eclipseId, 'one');
|
|
await Future<void>.delayed(const Duration(milliseconds: 200));
|
|
expect(states.last, isNull);
|
|
});
|
|
test('활성 회차의 성공·종료·새 회차를 샤드 구독 중에도 반영한다', () async {
|
|
final db = FakeFirebaseFirestore();
|
|
final repo = FirestoreEclipseRepository(
|
|
Backend(firestore: db, auth: MockFirebaseAuth()),
|
|
);
|
|
final doc = db.doc('fandoms/bts/eclipseRounds/one');
|
|
final data = {
|
|
'status': 'active',
|
|
'startAt': Timestamp.now(),
|
|
'endsAt': Timestamp.fromDate(
|
|
DateTime.now().add(const Duration(hours: 1)),
|
|
),
|
|
'targetPop': 60, // 옛 필드는 목표 인원으로 재해석하지 않는다.
|
|
'target': 2,
|
|
'defended': false,
|
|
};
|
|
await doc.set(data);
|
|
await doc.collection('shards').doc('0').set({'defense': 600, 'defenseCount': 25, 'qualifiedParticipants': 1});
|
|
final states = <EclipseState?>[];
|
|
final sub = repo.watch(fandomId: 'bts').listen(states.add);
|
|
addTearDown(sub.cancel);
|
|
Future<void> flush() =>
|
|
Future<void>.delayed(const Duration(milliseconds: 20));
|
|
await flush();
|
|
expect(states.last?.defense, 1);
|
|
expect(states.last?.targetDefense, 2);
|
|
expect(states.last?.progress, 0.5);
|
|
await doc.update({'defended': true});
|
|
await flush();
|
|
expect(states.last?.defended, true);
|
|
await doc.update({'status': 'ended'});
|
|
await flush();
|
|
expect(states.last, isNull);
|
|
await db.doc('fandoms/bts/eclipseRounds/two').set(data);
|
|
await flush();
|
|
expect(states.last?.eclipseId, 'two');
|
|
await doc.collection('shards').doc('0').update({'defense': 99});
|
|
await flush();
|
|
expect(states.last?.eclipseId, 'two');
|
|
});
|
|
test('방어 화면 구독은 마감 뒤에도 같은 회차의 서버 결과를 받는다', () async {
|
|
final db = FakeFirebaseFirestore();
|
|
final repo = FirestoreEclipseRepository(Backend(firestore: db, auth: MockFirebaseAuth()));
|
|
final ref = db.doc('fandoms/bts/eclipseRounds/final');
|
|
await ref.set({
|
|
'status': 'active', 'startAt': Timestamp.now(),
|
|
'endsAt': Timestamp.fromDate(DateTime.now().add(const Duration(milliseconds: 150))),
|
|
'target': 2, 'qualifiedParticipants': 1,
|
|
});
|
|
final results = <EclipseState?>[];
|
|
final banner = <EclipseState?>[];
|
|
final sub = repo.watch(fandomId: 'bts', includeResults: true).listen(results.add);
|
|
final active = repo.watch(fandomId: 'bts').listen(banner.add);
|
|
addTearDown(sub.cancel);
|
|
addTearDown(active.cancel);
|
|
await Future<void>.delayed(const Duration(milliseconds: 200));
|
|
expect(banner.last, isNull);
|
|
expect(results.last?.eclipseId, 'final');
|
|
expect(results.last?.canDefend, isFalse);
|
|
expect(results.last?.result, isNull);
|
|
await ref.update({'status': 'ended', 'result': 'failed'});
|
|
await Future<void>.delayed(const Duration(milliseconds: 20));
|
|
expect(results.last?.result, EclipseResult.failure);
|
|
expect(banner.last, isNull);
|
|
await ref.update({'status': 'cancelled', 'result': 'cancelled_error'});
|
|
await Future<void>.delayed(const Duration(milliseconds: 20));
|
|
expect(results.last?.result, EclipseResult.cancelled);
|
|
});
|
|
|
|
}
|