125 lines
5.1 KiB
Dart
125 lines
5.1 KiB
Dart
import 'package:cloud_firestore/cloud_firestore.dart';
|
|
import 'package:fancake/core/firebase/firebase_boot.dart';
|
|
import 'package:fancake/features/auth/auth.dart';
|
|
import 'package:fancake/features/auth/auth_repository.dart';
|
|
import 'package:firebase_auth/firebase_auth.dart' as fb;
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:integration_test/integration_test.dart';
|
|
|
|
/// 로그인 실동작 실증 — 별첨 2 2주차 확인 항목 「앱 설치·로그인·탭 이동 확인」.
|
|
///
|
|
/// **왜 에뮬레이터로 재는가.** 실 Firebase 프로젝트는 계정 명의가 확정되어야
|
|
/// 열 수 있다(계정·권한 이전 별첨 A-3). 그 사이 로그인 코드가 실제로 도는지
|
|
/// 확인할 방법이 없으면, 설정 파일이 들어오는 날 처음 돌려 보게 된다.
|
|
///
|
|
/// 이 테스트는 **설정 파일 대신 에뮬레이터를 물리고 실제 왕복을 돈다.**
|
|
/// 통과한다는 것은 설정 파일만 들어오면 그대로 동작한다는 뜻이다.
|
|
///
|
|
/// 실행:
|
|
/// firebase emulators:start --only auth,firestore,functions --project demo-fanuzu
|
|
/// flutter drive --driver=test_driver/perf_driver.dart \
|
|
/// --target=integration_test/auth_emulator_test.dart \
|
|
/// --dart-define=FANUZU_EMULATOR_HOST=10.0.2.2 --no-dds -d <device>
|
|
void main() {
|
|
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
|
|
|
setUpAll(() async {
|
|
await FirebaseBoot.init();
|
|
});
|
|
|
|
testWidgets('에뮬레이터를 물면 실 모드로 뜬다', (tester) async {
|
|
expect(FirebaseBoot.useEmulator, isTrue,
|
|
reason: '--dart-define=FANUZU_EMULATOR_HOST 를 주고 실행하십시오');
|
|
expect(FirebaseBoot.isLive, isTrue, reason: FirebaseBoot.reason);
|
|
});
|
|
|
|
testWidgets('이메일로 가입하면 계정이 만들어지고 로그인 상태가 된다', (tester) async {
|
|
final auth = AuthRepository();
|
|
final email = 'fan+${DateTime.now().microsecondsSinceEpoch}@fanuzu.co.kr';
|
|
|
|
final outcome = await auth.signInWithEmail(
|
|
email: email,
|
|
password: 'password12',
|
|
signUp: true,
|
|
);
|
|
|
|
expect(outcome, isA<AuthSucceeded>(),
|
|
reason: outcome is AuthFailed ? '${outcome.code} ${outcome.message}' : '');
|
|
expect(auth.isSignedIn, isTrue);
|
|
expect(auth.account!.email, email);
|
|
expect(fb.FirebaseAuth.instance.currentUser, isNotNull);
|
|
});
|
|
|
|
testWidgets('가입한 계정으로 다시 로그인된다', (tester) async {
|
|
final auth = AuthRepository();
|
|
final email = 'fan+${DateTime.now().microsecondsSinceEpoch}@fanuzu.co.kr';
|
|
await auth.signInWithEmail(
|
|
email: email, password: 'password12', signUp: true,
|
|
);
|
|
await fb.FirebaseAuth.instance.signOut();
|
|
|
|
final again = await auth.signInWithEmail(
|
|
email: email, password: 'password12',
|
|
);
|
|
expect(again, isA<AuthSucceeded>());
|
|
});
|
|
|
|
testWidgets('틀린 비밀번호는 카탈로그 코드로 돌아온다', (tester) async {
|
|
final auth = AuthRepository();
|
|
final email = 'fan+${DateTime.now().microsecondsSinceEpoch}@fanuzu.co.kr';
|
|
await auth.signInWithEmail(
|
|
email: email, password: 'password12', signUp: true,
|
|
);
|
|
|
|
final wrong = await auth.signInWithEmail(
|
|
email: email, password: 'wrong-password',
|
|
);
|
|
expect(wrong, isA<AuthFailed>());
|
|
// 「등록되지 않은 이메일」과 갈라 주지 않는다 — 가입 목록을 훑을 수 있다.
|
|
expect((wrong as AuthFailed).code, startsWith('E-AUTH-'));
|
|
});
|
|
|
|
testWidgets('가입하면 Auth 트리거가 계정·지갑 문서를 만든다', (tester) async {
|
|
final auth = AuthRepository();
|
|
final email = 'fan+${DateTime.now().microsecondsSinceEpoch}@fanuzu.co.kr';
|
|
await auth.signInWithEmail(
|
|
email: email, password: 'password12', signUp: true,
|
|
);
|
|
final uid = auth.account!.uid;
|
|
|
|
// fn-auth-oncreate 는 배경 트리거라 즉시 도착하지 않는다. 몇 초 기다린다.
|
|
Map<String, dynamic>? user;
|
|
for (var i = 0; i < 20 && user == null; i++) {
|
|
await Future<void>.delayed(const Duration(milliseconds: 500));
|
|
final snap = await FirebaseFirestore.instance.doc('users/$uid').get();
|
|
user = snap.data();
|
|
}
|
|
|
|
expect(user, isNotNull, reason: 'fn-auth-oncreate 가 계정 문서를 만들지 않았습니다');
|
|
expect(user!['status'], 'active');
|
|
expect(user['totalContributedPop'], 0);
|
|
|
|
final wallet =
|
|
await FirebaseFirestore.instance.doc('users/$uid/wallet/main').get();
|
|
expect(wallet.exists, isTrue);
|
|
expect(wallet.get('activityBalance'), 0);
|
|
});
|
|
|
|
testWidgets('클라이언트는 지갑을 직접 쓸 수 없다', (tester) async {
|
|
final auth = AuthRepository();
|
|
final email = 'fan+${DateTime.now().microsecondsSinceEpoch}@fanuzu.co.kr';
|
|
await auth.signInWithEmail(
|
|
email: email, password: 'password12', signUp: true,
|
|
);
|
|
final uid = auth.account!.uid;
|
|
|
|
// 별첨 1 ② 「클라이언트 단독 지급 0건」이 규칙 층에서 실제로 막히는지 본다.
|
|
await expectLater(
|
|
FirebaseFirestore.instance
|
|
.doc('users/$uid/wallet/main')
|
|
.set({'activityBalance': 999999}),
|
|
throwsA(isA<FirebaseException>()),
|
|
);
|
|
});
|
|
}
|