fix(flutter): 로그인 전에는 앱을 열 때마다 시작하기 화면을 보여 줌

"시작하기"를 한 번 누르면 기기에 저장해 이후 실행에서 인트로를 건너뛰었다.
그래서 시작하기를 누른 뒤 로그인하지 않고 앱을 다시 열면 스플래시 다음
바로 로그인 화면이 나왔다. 시작하기 여부는 이번 실행 동안만 기억한다.

- 로그아웃은 시안대로 곧바로 로그인 화면으로 간다
- 예전 버전이 저장한 entry.introSeen 값은 더 이상 읽지 않는다

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-28 21:51:06 +09:00
parent 1dba0c80ab
commit 3e6206630f
7 changed files with 51 additions and 30 deletions
+3 -3
View File
@@ -3,16 +3,16 @@ import 'package:tma_app/core/router/app_routes.dart';
import 'package:tma_app/features/entry/domain/entry_state.dart';
EntryState _state({bool intro = false, bool signedIn = false, bool onboarding = false}) {
return EntryState(introSeen: intro, signedIn: signedIn, onboardingSeen: onboarding);
return EntryState(introPassed: intro, signedIn: signedIn, onboardingSeen: onboarding);
}
void main() {
group('EntryState.stage', () {
test('처음 설치하면 인트로 단계다', () {
test('로그인 전에 앱을 열면 인트로 단계다', () {
expect(_state().stage, EntryStage.intro);
});
test('인트로를 봤지만 로그인 전이면 로그인 단계다', () {
test('인트로에서 시작하기를 눌렀고 로그인 전이면 로그인 단계다', () {
expect(_state(intro: true).stage, EntryStage.login);
});
-1
View File
@@ -8,7 +8,6 @@ import 'package:tma_app/features/pet/domain/pet.dart';
/// 로그인·온보딩까지 마친 사용자 (카카오 데모 로그인)
const Map<String, Object> kSignedInPrefs = {
'entry.introSeen': true,
'entry.onboardingSeen': true,
'auth.demoSession': 'kakao',
};
+30 -3
View File
@@ -79,8 +79,10 @@ void main() {
});
testWidgets('로그인 화면의 뒤로가기는 인트로로 돌아간다', (tester) async {
await _pumpApp(tester, {'entry.introSeen': true});
await _pumpApp(tester, {});
await _passSplash(tester);
await tester.tap(find.text('시작하기'));
await _settle(tester);
expect(find.byType(LoginPage), findsOneWidget);
await tester.tap(find.bySemanticsLabel('뒤로'));
@@ -88,9 +90,35 @@ void main() {
expect(find.byType(IntroPage), findsOneWidget);
});
testWidgets('시작하기를 눌렀어도 로그인 전에 앱을 다시 열면 인트로부터 보여 준다', (tester) async {
await _pumpApp(tester, {});
await _passSplash(tester);
await tester.tap(find.text('시작하기'));
await _settle(tester);
expect(find.byType(LoginPage), findsOneWidget);
// 앱을 닫았다가 다시 연다 — 기기 저장소는 그대로, 메모리 상태만 새로 만든다
final prefs = await SharedPreferences.getInstance();
await tester.pumpWidget(const SizedBox.shrink());
await tester.pumpWidget(
ProviderScope(
overrides: [sharedPreferencesProvider.overrideWithValue(prefs)],
child: const RupApp(),
),
);
expect(find.byType(SplashPage), findsOneWidget);
await _passSplash(tester);
expect(find.byType(IntroPage), findsOneWidget);
});
testWidgets('예전 버전이 저장한 인트로 확인 값이 있어도 로그인 전이면 인트로를 보여 준다', (tester) async {
await _pumpApp(tester, {'entry.introSeen': true});
await _passSplash(tester);
expect(find.byType(IntroPage), findsOneWidget);
});
testWidgets('로그인·온보딩을 마친 사용자는 스플래시 다음 바로 홈으로 간다', (tester) async {
await _pumpApp(tester, {
'entry.introSeen': true,
'entry.onboardingSeen': true,
'auth.demoSession': 'kakao',
});
@@ -101,7 +129,6 @@ void main() {
testWidgets('하단 탭을 누르면 해당 탭 화면으로 바뀐다', (tester) async {
await _pumpApp(tester, {
'entry.introSeen': true,
'entry.onboardingSeen': true,
'auth.demoSession': 'kakao',
});