generated from ttipo/project-base
feat(flutter): 홈 화면 구현과 반려동물 등록 연결
시안 screen-home 의 흐름을 옮겼다. - 인사말(소셜 프로필 이름, 모르면 "집사") · 알림 아이콘 - 우리 아이: 없으면 등록 안내 카드 → 등록 화면, 있으면 아이 고르기 + 펫 명함 빈 슬롯 - 일정(오늘 일정·오늘 할 일·예약 일정)·다이어리는 해당 기능 전까지 시안의 빈 상태로 표시 - 등록·수정 화면을 탭바 위에 덮는 라우트로 연결, 토스트를 모든 화면 위에 표시 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:tma_app/app.dart';
|
||||
import 'package:tma_app/core/storage/preferences_provider.dart';
|
||||
import 'package:tma_app/features/pet/domain/pet.dart';
|
||||
import 'package:tma_app/features/pet/presentation/pages/pet_register_page.dart';
|
||||
|
||||
/// 로그인·온보딩까지 마친 사용자
|
||||
const Map<String, Object> _signedIn = {
|
||||
'entry.introSeen': true,
|
||||
'entry.onboardingSeen': true,
|
||||
'auth.demoSession': 'kakao',
|
||||
};
|
||||
|
||||
Future<void> _launchHome(WidgetTester tester, {Map<String, Object> extra = const {}}) async {
|
||||
tester.view.physicalSize = const Size(402, 874);
|
||||
tester.view.devicePixelRatio = 1;
|
||||
addTearDown(tester.view.reset);
|
||||
|
||||
SharedPreferences.setMockInitialValues({..._signedIn, ...extra});
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await tester.pumpWidget(
|
||||
ProviderScope(
|
||||
overrides: [sharedPreferencesProvider.overrideWithValue(prefs)],
|
||||
child: const RupApp(),
|
||||
),
|
||||
);
|
||||
// 스플래시 이미지 디코딩 → 2.6초 뒤 홈으로
|
||||
await tester.runAsync(() => Future<void>.delayed(const Duration(milliseconds: 300)));
|
||||
await tester.pump(const Duration(seconds: 4));
|
||||
await _settle(tester);
|
||||
}
|
||||
|
||||
Future<void> _settle(WidgetTester tester) async {
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 600));
|
||||
await tester.pump();
|
||||
}
|
||||
|
||||
void main() {
|
||||
testWidgets('아이가 없으면 홈에 등록 안내가 보이고, 누르면 등록 화면으로 간다', (tester) async {
|
||||
await _launchHome(tester);
|
||||
expect(find.text('안녕하세요, 집사님'), findsOneWidget);
|
||||
expect(find.text('우리 아이를 등록해 주세요'), findsOneWidget);
|
||||
expect(find.text('오늘은 등록된 일정이 없어요'), findsOneWidget);
|
||||
|
||||
await tester.tap(find.text('우리 아이를 등록해 주세요'));
|
||||
await _settle(tester);
|
||||
expect(find.byType(PetRegisterPage), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('기본 정보 없이 등록을 누르면 빠진 칸마다 오류를 보여 준다', (tester) async {
|
||||
await _launchHome(tester);
|
||||
await tester.tap(find.text('우리 아이를 등록해 주세요'));
|
||||
await _settle(tester);
|
||||
|
||||
await tester.ensureVisible(find.text('반려동물 등록').last);
|
||||
await tester.tap(find.text('반려동물 등록').last);
|
||||
await _settle(tester);
|
||||
|
||||
expect(find.text('이름을 입력해주세요.'), findsOneWidget);
|
||||
expect(find.text('종을 선택해주세요.'), findsOneWidget);
|
||||
expect(find.text('생년월일을 선택해주세요.'), findsOneWidget);
|
||||
expect(find.text('몸무게를 입력해주세요.'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('등록된 아이가 있으면 아이 목록과 명함 만들기 안내가 보인다', (tester) async {
|
||||
final pet = Pet.fromInput(
|
||||
'pet-1',
|
||||
PetInput(
|
||||
name: '콩이',
|
||||
species: '강아지',
|
||||
breed: '말티즈',
|
||||
gender: PetGender.male,
|
||||
neutered: true,
|
||||
birthDate: DateTime(2021, 9, 14),
|
||||
weight: 3.2,
|
||||
weightUnit: WeightUnit.kg,
|
||||
),
|
||||
);
|
||||
await _launchHome(tester, extra: {'pets.v1': jsonEncode([pet.toJson()])});
|
||||
|
||||
expect(find.text('우리 아이를 등록해 주세요'), findsNothing);
|
||||
expect(find.text('콩이'), findsWidgets);
|
||||
expect(find.text('명함 만들기'), findsOneWidget);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user