가입 시 약관 동의 단계 추가 — 필수·선택 항목 구분 · 개인정보처리방침 고지 · 동의 기록 저장
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:fancake/app.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:fancake/features/auth/login_screen.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
/// 가입 약관 — 동의 기록이 없는 계정은 HOME 대신 약관으로 가고, 동의를 기록한 뒤에만 HOME 에 들어간다.
|
||||
void main() {
|
||||
setUp(() {
|
||||
FirebaseBoot.debugSetMode(FirebaseMode.mock, reason: '가입 약관 위젯 테스트');
|
||||
});
|
||||
|
||||
const newUser = AuthAccount(
|
||||
uid: 'new-user',
|
||||
provider: AuthProviderKind.kakao,
|
||||
);
|
||||
|
||||
testWidgets('동의 없는 새 계정은 약관 → 필수 동의 → HOME', (tester) async {
|
||||
final signIn = Completer<AuthOutcome>();
|
||||
final provider = _Provider(AuthProviderKind.kakao, () => signIn.future);
|
||||
Set<String>? recorded;
|
||||
final auth = AuthRepository(
|
||||
providers: [provider],
|
||||
releaseMode: false,
|
||||
needsTerms: (_) async => recorded == null,
|
||||
recordTerms: (agreed) async => recorded = agreed,
|
||||
);
|
||||
await tester.pumpWidget(FancakeApp(auth: auth));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.widgetWithText(FilledButton, '로그인'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await tester.tap(find.text(providerButtonLabel(AuthProviderKind.kakao)));
|
||||
await tester.pump();
|
||||
signIn.complete(const AuthSucceeded(newUser));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byType(NavigationBar), findsNothing);
|
||||
expect(find.text('이용 약관'), findsOneWidget);
|
||||
expect(find.text('위치기반 서비스 이용약관 (필수)'), findsNothing);
|
||||
final done = find.widgetWithText(FilledButton, '완료');
|
||||
expect(tester.widget<FilledButton>(done).onPressed, isNull);
|
||||
for (final label in [
|
||||
'서비스 이용약관 (필수)',
|
||||
'개인정보 수집·이용 동의 (필수)',
|
||||
'만 14세 이상입니다. (필수)',
|
||||
]) {
|
||||
await tester.scrollUntilVisible(find.text(label), 100);
|
||||
await tester.tap(find.text(label));
|
||||
await tester.pump();
|
||||
}
|
||||
// 개인정보처리방침은 체크 칸 없는 고지 · 보기 링크.
|
||||
final policy = find.byKey(const ValueKey('privacy-policy-link'));
|
||||
await tester.scrollUntilVisible(policy, 200);
|
||||
await tester.tap(policy);
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('개인정보처리방침'), findsOneWidget);
|
||||
await tester.tap(find.text('확인'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(tester.widget<FilledButton>(done).onPressed, isNotNull);
|
||||
await tester.tap(done);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(recorded, {'service', 'privacy', 'age'});
|
||||
expect(find.byType(NavigationBar), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('이미 동의한 계정은 약관 없이 HOME', (tester) async {
|
||||
final auth = AuthRepository(
|
||||
providers: [
|
||||
_Provider(
|
||||
AuthProviderKind.google,
|
||||
() async => const AuthSucceeded(newUser),
|
||||
),
|
||||
],
|
||||
releaseMode: false,
|
||||
needsTerms: (_) async => false,
|
||||
recordTerms: (_) async => fail('기록하지 않는다'),
|
||||
);
|
||||
await tester.pumpWidget(FancakeApp(auth: auth));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.widgetWithText(FilledButton, '로그인'));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.text(providerButtonLabel(AuthProviderKind.google)));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byType(NavigationBar), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('가입 모드 — 인증 전에 받은 동의를 기록하고 약관을 다시 묻지 않는다', (tester) async {
|
||||
Set<String>? recorded;
|
||||
final auth = AuthRepository(
|
||||
providers: [
|
||||
_Provider(
|
||||
AuthProviderKind.line,
|
||||
() async => const AuthSucceeded(newUser),
|
||||
),
|
||||
],
|
||||
releaseMode: false,
|
||||
needsTerms: (_) async => recorded == null,
|
||||
recordTerms: (agreed) async => recorded = agreed,
|
||||
);
|
||||
await tester.pumpWidget(FancakeApp(auth: auth));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.text('회원가입'));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(
|
||||
find.text(providerButtonLabel(AuthProviderKind.line, signUp: true)),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.text('전체 동의'));
|
||||
await tester.pump();
|
||||
await tester.tap(find.widgetWithText(FilledButton, '완료'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(recorded, {'service', 'privacy', 'age', 'marketing'});
|
||||
expect(find.byType(NavigationBar), findsOneWidget);
|
||||
});
|
||||
}
|
||||
|
||||
final class _Provider implements SocialAuthProvider {
|
||||
_Provider(this.provider, this._signIn);
|
||||
|
||||
@override
|
||||
final AuthProviderKind provider;
|
||||
final Future<AuthOutcome> Function() _signIn;
|
||||
int calls = 0;
|
||||
|
||||
@override
|
||||
bool get isLive => true;
|
||||
|
||||
@override
|
||||
List<String> get missingConfig => const [];
|
||||
|
||||
@override
|
||||
Future<AuthOutcome> signIn() {
|
||||
calls += 1;
|
||||
return _signIn();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> signOut() async {}
|
||||
}
|
||||
Reference in New Issue
Block a user