feat(client/notices): 通知页真实化+铃铛红点接 provider+进页清读+三类型标签六语
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P9G7E3wmAYL9KeYCVZVsqu
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:pangolin_vpn/l10n/strings_en.dart';
|
||||
import 'package:pangolin_vpn/screens/notifications_page.dart';
|
||||
import 'package:pangolin_vpn/services/notices_api.dart';
|
||||
import 'package:pangolin_vpn/state/notices_provider.dart';
|
||||
|
||||
import '../helpers/harness.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('通知页真实数据渲染:type pill + 未读红点 + version 去更新按钮 + 进页清读',
|
||||
(tester) async {
|
||||
final now = DateTime.now();
|
||||
final data = NoticesData(items: [
|
||||
NoticeItem(
|
||||
id: 1,
|
||||
type: 'reward',
|
||||
titleZh: '测试到账',
|
||||
titleEn: 'Reward credited',
|
||||
bodyZh: '你获得了 7 天会员',
|
||||
bodyEn: 'You earned 7 days membership',
|
||||
link: '',
|
||||
publishedAt: now,
|
||||
unread: true,
|
||||
),
|
||||
NoticeItem(
|
||||
id: 2,
|
||||
type: 'version',
|
||||
titleZh: '新版本发布',
|
||||
titleEn: 'New version available',
|
||||
bodyZh: '',
|
||||
bodyEn: '',
|
||||
link: '',
|
||||
publishedAt: now,
|
||||
unread: false,
|
||||
),
|
||||
NoticeItem(
|
||||
id: 3,
|
||||
type: 'news',
|
||||
titleZh: '产品新闻',
|
||||
titleEn: 'Product news',
|
||||
bodyZh: '',
|
||||
bodyEn: '',
|
||||
link: '',
|
||||
publishedAt: now,
|
||||
unread: false,
|
||||
),
|
||||
], unreadCount: 1);
|
||||
|
||||
final fake = _FakeNotifier(data);
|
||||
|
||||
await tester.binding.setSurfaceSize(const Size(420, 900));
|
||||
addTearDown(() => tester.binding.setSurfaceSize(null));
|
||||
|
||||
await tester.pumpWidget(wrapThemed(
|
||||
NotificationsScreen(t: StringsEn()),
|
||||
overrides: [noticesProvider.overrideWith(() => fake)],
|
||||
));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// reward 行 type pill 文案(StringsEn 的 'Credited')在。
|
||||
expect(find.text('Credited'), findsOneWidget);
|
||||
// reward 行未读红点在(fake.markAllRead 不改写数据,仅记录调用)。
|
||||
expect(find.byKey(const ValueKey('notif-unread-1')), findsOneWidget);
|
||||
// version 行「去更新」按钮在(t.lang.updateNow == 'Update now')。
|
||||
expect(find.text('Update now'), findsOneWidget);
|
||||
// 首帧后调用了 markAllRead()。
|
||||
expect(fake.markAllReadCalled, isTrue);
|
||||
});
|
||||
}
|
||||
|
||||
/// 照 invite_page_test.dart 的 `_FakeNotifier extends InviteNotifier` 模式:override
|
||||
/// build() 直接返回固定数据;markAllRead 只记录调用、不改写数据(便于断言未读态渲染
|
||||
/// 与「已调用清读」两件事互不干扰)。
|
||||
class _FakeNotifier extends NoticesNotifier {
|
||||
_FakeNotifier(this._v);
|
||||
final NoticesData _v;
|
||||
bool markAllReadCalled = false;
|
||||
|
||||
@override
|
||||
Future<NoticesData?> build() async => _v;
|
||||
|
||||
@override
|
||||
Future<void> markAllRead() async {
|
||||
markAllReadCalled = true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user