Files
ReelShort/test/notice/notices_controller_test.dart
T

96 lines
3.0 KiB
Dart

// Author: fruit.com.cn
import 'package:flutter_test/flutter_test.dart';
import 'package:fruitshorts/core/data/models/notice.dart';
import 'package:fruitshorts/core/data/remote/api_client.dart';
import 'package:fruitshorts/core/data/repositories/notice_repository.dart';
import 'package:fruitshorts/core/data/services/notices_controller.dart';
void main() {
test('should_append_next_page_until_loaded_count_reaches_total', () async {
final repository = ScriptedNoticeRepository([
NoticePage(total: 3, notices: [_notice('1'), _notice('2')]),
NoticePage(total: 3, notices: [_notice('3')]),
]);
final controller = NoticesController(repository);
await controller.load();
expect(controller.notices.map((item) => item.id), ['1', '2']);
expect(controller.hasMore, isTrue);
await controller.loadMore();
expect(controller.notices.map((item) => item.id), ['1', '2', '3']);
expect(controller.hasMore, isFalse);
expect(repository.calls.map((call) => call.pageIndex), [1, 2]);
});
test('should_show_empty_state_when_total_is_zero', () async {
final controller = NoticesController(
ScriptedNoticeRepository([const NoticePage(total: 0)]),
);
await controller.load();
expect(controller.loading, isFalse);
expect(controller.notices, isEmpty);
expect(controller.hasMore, isFalse);
expect(controller.error, isNull);
});
test('should_preserve_backend_message_when_page_load_fails', () async {
final repository = ScriptedNoticeRepository([])
..error = const ApiException(500, '公告服务暂不可用');
final controller = NoticesController(repository);
await controller.load();
expect(controller.error, '公告服务暂不可用');
expect(controller.notices, isEmpty);
});
test('should_replace_list_when_refreshed', () async {
final repository = ScriptedNoticeRepository([
NoticePage(total: 2, notices: [_notice('1'), _notice('2')]),
NoticePage(total: 1, notices: [_notice('9')]),
]);
final controller = NoticesController(repository);
await controller.load();
await controller.refresh();
expect(controller.notices.map((item) => item.id), ['9']);
expect(controller.hasMore, isFalse);
});
}
AppNotice _notice(String id) => AppNotice(
id: id,
title: 'Notice $id',
content: 'Content $id',
type: 'SYSTEM',
publishAt: DateTime(2026, 10, 17, 12),
);
class ScriptedNoticeRepository implements NoticeRepository {
ScriptedNoticeRepository(this.pages);
final List<NoticePage> pages;
final List<NoticePageCall> calls = [];
Object? error;
@override
Future<NoticePage> page({required int pageIndex, int pageSize = 20}) async {
calls.add(NoticePageCall(pageIndex: pageIndex, pageSize: pageSize));
if (error != null) throw error!;
if (pages.isEmpty) return const NoticePage(total: 0);
return pages.removeAt(0);
}
}
class NoticePageCall {
const NoticePageCall({required this.pageIndex, required this.pageSize});
final int pageIndex;
final int pageSize;
}