309 lines
8.5 KiB
Dart
309 lines
8.5 KiB
Dart
@Tags(['design'])
|
||
library;
|
||
|
||
import 'package:fancake/core/data/repositories.dart';
|
||
import 'package:fancake/core/router/app_router.dart';
|
||
import 'package:fancake/core/theme/app_theme.dart';
|
||
import 'package:fancake/features/auth/auth_repository.dart';
|
||
import 'package:fancake/features/eclipse/eclipse_data.dart';
|
||
import 'package:fancake/features/galaxy/galaxy_search_screen.dart';
|
||
import 'package:fancake/features/planet/fpi_ranking_screen.dart';
|
||
import 'package:fancake/features/planet/lounge_post_screens.dart';
|
||
import 'package:fancake/features/planet/moderation.dart';
|
||
import 'package:fancake/features/planet/planet_data.dart';
|
||
import 'package:fancake/features/planet/planet_detail_screen.dart';
|
||
import 'package:flutter/material.dart';
|
||
import 'package:flutter_test/flutter_test.dart';
|
||
|
||
import '../eclipse_stubs.dart';
|
||
import 'design_match_test.dart' as base;
|
||
|
||
/// 디자인 일치 2단계 **그룹 B**(F2 갤럭시 · F3 행성/성운 상세) 렌더.
|
||
///
|
||
/// 공유 하네스([base.main])를 그대로 돌리되 shots 만 이 그룹 것으로 바꾼다.
|
||
/// 표본은 Figma 사본 문구와 같게 여기서 만든다(공유 표본 저장소는 건드리지 않는다).
|
||
///
|
||
/// 실행: `DESIGN_MATCH_OUT=<폴더> fvm flutter test --tags design test/design_match/b_test.dart`
|
||
void main() {
|
||
base.shots
|
||
..clear()
|
||
..addAll(_shots);
|
||
base.main();
|
||
}
|
||
|
||
Future<void> _settle(WidgetTester t) async {
|
||
for (var i = 0; i < 6; i++) {
|
||
await t.pump(const Duration(milliseconds: 300));
|
||
}
|
||
}
|
||
|
||
Future<void> _tap(WidgetTester t, Finder f) async {
|
||
await t.tap(f.first, warnIfMissed: false);
|
||
await _settle(t);
|
||
}
|
||
|
||
Future<void> _overlay(
|
||
WidgetTester t,
|
||
void Function(BuildContext c) open,
|
||
) async {
|
||
open(t.element(find.byType(Scaffold).last));
|
||
await _settle(t);
|
||
}
|
||
|
||
final _now = DateTime.now();
|
||
|
||
const _photo = 'assets/figma/lounge-post-sample.png';
|
||
|
||
LoungePost _post(
|
||
String author,
|
||
Duration ago,
|
||
String text, {
|
||
int likes = 8,
|
||
int comments = 24,
|
||
List<String> images = const [],
|
||
String? photo,
|
||
Duration? video,
|
||
}) => LoungePost(
|
||
id: author,
|
||
authorName: author,
|
||
createdAt: _now.subtract(ago),
|
||
title: '',
|
||
body: text,
|
||
likes: likes,
|
||
comments: comments,
|
||
images: images,
|
||
authorPhoto: photo,
|
||
videoDuration: video,
|
||
);
|
||
|
||
/// F3-05 `244:22509` — 첫 댓글 전 글.
|
||
final _hongPost = _post(
|
||
'BTS_Hong',
|
||
Duration.zero,
|
||
'안녕하세요! BTS 팬이에요!',
|
||
likes: 0,
|
||
comments: 0,
|
||
images: const [_photo],
|
||
photo: 'assets/figma/avatar-hong.png',
|
||
video: const Duration(seconds: 36),
|
||
);
|
||
|
||
/// F3-07 `252:163306` — 사진 세 장 글.
|
||
final _ilaPost = _post(
|
||
'ILA_WITH',
|
||
const Duration(days: 3),
|
||
'여러분 지금 미국 컴백 무대 보셨나요?\n사진 공유해드릴게요 모두 온라인 직관하세요',
|
||
likes: 8,
|
||
comments: 5,
|
||
images: const [_photo, _photo, _photo],
|
||
);
|
||
|
||
FpiScore _score(FpiMetric m, int v, int rank, int trend) =>
|
||
FpiScore(metric: m, value: v, rank: rank, trend: trend, myTopPercent: 1);
|
||
|
||
/// 시안 수치 그대로의 행성 · 성운 상세.
|
||
class _FigmaPlanet extends SamplePlanetRepository {
|
||
const _FigmaPlanet();
|
||
|
||
@override
|
||
Future<PlanetDetail> load({required bool nebula}) async => nebula
|
||
? PlanetDetail(
|
||
fandomId: 'bts-rm',
|
||
name: 'BTS_RM',
|
||
isNebula: true,
|
||
stage: 0,
|
||
totalFpi: 0,
|
||
members: 1,
|
||
ownerName: 'BTS_Hong',
|
||
ownerPhoto: 'assets/figma/avatar-hong.png',
|
||
scores: const [],
|
||
posts: const [],
|
||
)
|
||
: PlanetDetail(
|
||
fandomId: 'bts',
|
||
name: 'BTS',
|
||
isNebula: false,
|
||
totalFpi: 1220,
|
||
members: 850,
|
||
ownerName: 'BTS_Maker',
|
||
ownerPhoto: 'assets/figma/avatar-maker.png',
|
||
scores: [
|
||
_score(FpiMetric.bpm, 34200, 2, 1),
|
||
_score(FpiMetric.health, 1180000, 4, -1),
|
||
_score(FpiMetric.referral, 34200, 3, 0),
|
||
_score(FpiMetric.contribution, 450100, 2, 2),
|
||
_score(FpiMetric.community, 1000, 4, -2),
|
||
],
|
||
posts: [
|
||
_post(
|
||
'arrrmy_',
|
||
const Duration(minutes: 3),
|
||
'I love BTS sooooo much 😭😭😭',
|
||
),
|
||
_post(
|
||
'AR_NNJO',
|
||
const Duration(hours: 3),
|
||
'NAMJOON so handsome isn’t it???',
|
||
images: const [_photo],
|
||
),
|
||
_ilaPost,
|
||
],
|
||
);
|
||
|
||
@override
|
||
Future<List<LoungePost>> morePosts({
|
||
required int offset,
|
||
int limit = 5,
|
||
}) async => const [];
|
||
|
||
@override
|
||
Future<FpiRanking> planetRanking({
|
||
required FpiMetric metric,
|
||
int limit = 30,
|
||
}) async => FpiRanking(
|
||
mine: const FpiRankRow(
|
||
rank: 24,
|
||
id: 'bts',
|
||
name: 'BTS',
|
||
value: 34200,
|
||
change: 12,
|
||
isMine: true,
|
||
),
|
||
rows: _rows(const [
|
||
(1, 'Bigbnag', 782200, 1),
|
||
(2, 'NewJeans', 703200, 0),
|
||
(3, 'Blackpink', 689700, 1),
|
||
(5, 'Twice', 531100, -1),
|
||
(6, 'ITZY', 527800, 2),
|
||
(7, 'Aespa', 422400, 3),
|
||
(8, 'Seventeen', 329600, 8),
|
||
(9, 'Eighteen', 311200, -1),
|
||
(10, 'Nineteen', 134500, 1),
|
||
]),
|
||
);
|
||
|
||
@override
|
||
Future<FpiRanking> userRanking({
|
||
required FpiMetric metric,
|
||
required String fandomId,
|
||
int limit = 30,
|
||
}) async => FpiRanking(
|
||
mine: const FpiRankRow(
|
||
rank: 82,
|
||
id: 'me',
|
||
name: 'BTS_Hong',
|
||
value: 3,
|
||
change: 1,
|
||
),
|
||
rows: _rows(const [
|
||
(1, 'GLAS_SMILE', 3000, 0),
|
||
(2, 'Suyom_mo', 2600, 0),
|
||
(3, 'Bool_huuu', 1400, 0),
|
||
(4, 'Wachooo', 1200, 1),
|
||
(5, 'Jeans_Bewn', 1200, 0),
|
||
(6, 'pinkyy', 1100, 1),
|
||
(7, 'T_T', 1000, -1),
|
||
(8, 'Yogi_ITZY', 98, 2),
|
||
]),
|
||
);
|
||
}
|
||
|
||
List<FpiRankRow> _rows(List<(int, String, int, int)> t) => [
|
||
for (final (rank, name, value, change) in t)
|
||
FpiRankRow(rank: rank, id: name, name: name, value: value, change: change),
|
||
];
|
||
|
||
Widget _detail({bool nebula = false}) => PlanetDetailScreen(
|
||
nebula: nebula,
|
||
repository: const _FigmaPlanet(),
|
||
eclipse: const NoEclipseRepository(),
|
||
);
|
||
|
||
const _report = ModerationTarget(
|
||
authorName: 'BTS_Hong',
|
||
title: '공방 신청 꿀팁 공유합니다.',
|
||
);
|
||
|
||
/// 이클립스가 없는 표본 저장소. 탭 화면은 공유 하네스가 저장소를 직접 만들어서
|
||
/// 바꿀 수 없으므로, 탭 셸을 통째로 한 번 더 띄운다(하단 탭까지 그려진다).
|
||
class _NoEclipseRepos extends Repositories {
|
||
_NoEclipseRepos() : super(live: false);
|
||
|
||
@override
|
||
EclipseRepository get eclipse => const NoEclipseRepository();
|
||
}
|
||
|
||
Widget _tab(String path) {
|
||
final router = buildRouter(
|
||
AuthRepository()..signInWithMockSession(),
|
||
repositories: _NoEclipseRepos(),
|
||
)..go(path);
|
||
return MaterialApp.router(
|
||
theme: buildAppTheme(),
|
||
debugShowCheckedModeBanner: false,
|
||
routerConfig: router,
|
||
);
|
||
}
|
||
|
||
final _shots = <base.Shot>[
|
||
// F2 갤럭시
|
||
base.Shot('F2-01', build: (_) async => _tab('/galaxy')),
|
||
base.Shot(
|
||
'F2-02',
|
||
build: (r) async => GalaxySearchScreen(repository: r.galaxy),
|
||
),
|
||
// F3 행성/성운 상세
|
||
base.Shot('F3-01', h: 1042, build: (_) async => _detail(nebula: true)),
|
||
base.Shot(
|
||
'F3-02',
|
||
build: (_) async => const ReportScreen(
|
||
target: ModerationTarget(authorName: 'BTS_Hong', title: 'BTS_RM'),
|
||
),
|
||
),
|
||
base.Shot(
|
||
'F3-03',
|
||
build: (_) async => _detail(nebula: true),
|
||
after: (t) => _overlay(
|
||
t,
|
||
(c) => confirmBlock(c, 'BTS_Hong', message: '이 성운을 차단할까요?'),
|
||
),
|
||
),
|
||
base.Shot('F3-04', h: 1243, build: (_) async => _detail()),
|
||
base.Shot('F3-05', build: (_) async => LoungePostScreen(post: _hongPost)),
|
||
base.Shot('F3-06', build: (_) async => const ReportScreen(target: _report)),
|
||
base.Shot(
|
||
'F3-07',
|
||
build: (_) async => LoungePostScreen(post: _ilaPost),
|
||
after: (t) => _overlay(t, (c) => confirmBlock(c, 'ILA_WITH')),
|
||
),
|
||
base.Shot('F3-09', build: (_) async => const LoungeComposeScreen()),
|
||
base.Shot(
|
||
'F3-10',
|
||
build: (_) async => const FpiRankingScreen(
|
||
metric: FpiMetric.bpm,
|
||
repository: _FigmaPlanet(),
|
||
),
|
||
),
|
||
base.Shot(
|
||
'F3-11',
|
||
build: (_) async => const FpiUserRankingScreen(
|
||
metric: FpiMetric.bpm,
|
||
fandomId: 'bts',
|
||
planetName: 'BTS',
|
||
repository: _FigmaPlanet(),
|
||
),
|
||
),
|
||
base.Shot(
|
||
'F3-12',
|
||
build: (_) async => _detail(),
|
||
after: (t) async {
|
||
await _tap(t, find.text('팬덤 라운지'));
|
||
await _tap(
|
||
t,
|
||
find.image(const AssetImage('assets/figma/icon-post-more.png')),
|
||
);
|
||
},
|
||
),
|
||
base.Shot('F3-13', build: (_) async => const ReportScreen(target: _report)),
|
||
];
|