앱 단위·화면·통합 테스트
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
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);
|
||||
});
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user