fix(recommend): 延后推荐数据刷新

This commit is contained in:
Zhou Weidong committed 2026-10-27 09:19:18 +08:00
1 parent 6be024f86f
commit 4b97f89c0b
2 files changed
+218 -5

No files matched your search

@@ -0,0 +1,183 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:fruitshorts/core/data/services/category_controller.dart';
import 'package:fruitshorts/core/data/services/home_feed_controller.dart';
import 'package:fruitshorts/l10n/app_localizations.dart';
import 'package:fruitshorts/pages/home/home_feed_channel.dart';
import 'package:fruitshorts/pages/recommend/recommend_page.dart';
import 'package:provider/provider.dart';
import '../support/fake_catalog.dart';
import '../support/fake_category.dart';
void main() {
testWidgets('should_refresh_once_when_parent_rebuilds_repeatedly', (
tester,
) async {
final fixture = await _pumpRecommend(tester, active: true);
expect(fixture.controller.refreshCalls, 1);
for (var index = 0; index < 20; index++) {
fixture.harnessKey.currentState!.rebuildSameInputs();
await tester.pump();
}
expect(tester.takeException(), isNull);
expect(fixture.controller.refreshCalls, 1);
});
testWidgets('should_refresh_once_when_active_turns_on', (tester) async {
final fixture = await _pumpRecommend(tester, active: false);
expect(fixture.controller.refreshCalls, 0);
fixture.harnessKey.currentState!.update(active: true);
await tester.pump();
expect(fixture.controller.refreshCalls, 1);
fixture.harnessKey.currentState!.rebuildSameInputs();
await tester.pump();
expect(fixture.controller.refreshCalls, 1);
});
testWidgets('should_refresh_again_when_data_source_changes', (tester) async {
final fixture = await _pumpRecommend(tester, active: true);
expect(fixture.controller.refreshCalls, 1);
fixture.harnessKey.currentState!.update(active: false);
await tester.pump();
expect(fixture.controller.refreshCalls, 1);
fixture.harnessKey.currentState!.update(active: true);
await tester.pump();
expect(fixture.controller.refreshCalls, 2);
});
testWidgets('should_not_refresh_after_dispose_when_channel_changes', (
tester,
) async {
final fixture = await _pumpRecommend(tester, active: true);
expect(fixture.controller.refreshCalls, 1);
fixture.harnessKey.currentState!.update(active: true);
final selection = fixture.controller.selectChannel(HomeFeedChannel.anime);
await tester.pumpWidget(const MaterialApp(home: SizedBox.shrink()));
await selection;
await tester.pump();
expect(fixture.controller.refreshCalls, 1);
});
}
Future<_RecommendFixture> _pumpRecommend(
WidgetTester tester, {
required bool active,
}) async {
tester.view.physicalSize = const Size(390, 844);
tester.view.devicePixelRatio = 1;
addTearDown(tester.view.resetPhysicalSize);
addTearDown(tester.view.resetDevicePixelRatio);
final catalog = FakeCatalogRepository();
final controller = _RecordingHomeFeedController(catalog);
final categories = CategoryController(
FakeCategoryRepository(catalog: catalog),
);
final harnessKey = GlobalKey<_RecommendHarnessState>();
final fixture = _RecommendFixture(
controller: controller,
categoryController: categories,
harnessKey: harnessKey,
);
addTearDown(controller.dispose);
addTearDown(categories.dispose);
await tester.pumpWidget(fixture.app(active: active));
await tester.pump();
return fixture;
}
class _RecommendFixture {
const _RecommendFixture({
required this.controller,
required this.categoryController,
required this.harnessKey,
});
final _RecordingHomeFeedController controller;
final CategoryController categoryController;
final GlobalKey<_RecommendHarnessState> harnessKey;
Widget app({required bool active}) {
return MaterialApp(
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
home: ChangeNotifierProvider<CategoryController>.value(
value: categoryController,
child: _RecommendHarness(
key: harnessKey,
controller: controller,
active: active,
),
),
);
}
}
class _RecommendHarness extends StatefulWidget {
const _RecommendHarness({
super.key,
required this.controller,
required this.active,
});
final HomeFeedController controller;
final bool active;
@override
State<_RecommendHarness> createState() => _RecommendHarnessState();
}
class _RecommendHarnessState extends State<_RecommendHarness> {
late HomeFeedController _controller;
late bool _active;
@override
void initState() {
super.initState();
_controller = widget.controller;
_active = widget.active;
}
void rebuildSameInputs() {
setState(() {});
}
void update({required bool active}) {
setState(() {
_active = active;
});
}
@override
Widget build(BuildContext context) {
return RecommendPage(
feedController: _controller,
active: _active,
videoOnly: true,
onSearch: () {},
);
}
}
class _RecordingHomeFeedController extends HomeFeedController {
_RecordingHomeFeedController(super.repository);
int refreshCalls = 0;
@override
Future<bool> refreshCurrent() async {
refreshCalls++;
notifyListeners();
return true;
}
}