refactor(apps): 重构数据层目录结构并新增启动预热编排器

This commit is contained in:
zl-q
2026-03-29 20:26:30 +08:00
parent 33340de8f9
commit 4db9a13bfe
108 changed files with 1653 additions and 1320 deletions
@@ -4,7 +4,7 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:social_app/app/di/injection.dart';
import 'package:social_app/app/router/app_router.dart';
import 'package:social_app/app/router/app_routes.dart';
import 'package:social_app/core/network/i_api_client.dart';
import 'package:social_app/data/network/i_api_client.dart';
import 'package:social_app/features/chat/presentation/bloc/chat_bloc.dart';
import 'package:social_app/features/auth/presentation/bloc/auth_state.dart';
@@ -0,0 +1,103 @@
import 'dart:async';
import 'package:dio/dio.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:social_app/app/services/app_prewarm_orchestrator.dart';
import 'package:social_app/data/network/i_api_client.dart';
import 'package:social_app/data/cache/cache_store.dart';
import 'package:social_app/features/calendar/data/repositories/calendar_repository.dart';
import 'package:social_app/features/messages/data/repositories/inbox_repository.dart';
import 'package:social_app/features/chat/data/repositories/chat_history_repository.dart';
class _FakeApiClient implements IApiClient {
@override
Future<Response<T>> delete<T>(String path, {data, Options? options}) {
throw UnimplementedError();
}
@override
Future<Response<T>> get<T>(String path, {Options? options}) {
throw UnimplementedError();
}
@override
Future<Stream<String>> getSseLines(
String path, {
Map<String, String>? headers,
}) {
throw UnimplementedError();
}
@override
Future<Response<T>> patch<T>(String path, {data, Options? options}) {
throw UnimplementedError();
}
@override
Future<Response<T>> post<T>(String path, {data, Options? options}) {
throw UnimplementedError();
}
@override
Future<Response<T>> put<T>(String path, {data, Options? options}) {
throw UnimplementedError();
}
}
void main() {
late HybridCacheStore store;
late _FakeApiClient apiClient;
late CalendarRepository calendarRepository;
late InboxRepository inboxRepository;
late ChatHistoryRepository chatHistoryRepository;
setUp(() {
apiClient = _FakeApiClient();
store = HybridCacheStore(
memory: MemoryCacheStore(),
persistent: PersistentCacheStore(),
);
calendarRepository = CalendarRepository(apiClient: apiClient, store: store);
inboxRepository = InboxRepositoryImpl(apiClient: apiClient, store: store);
chatHistoryRepository = ChatHistoryRepository(
apiClient: apiClient,
store: store,
);
});
test('completes prewarm within budget', () async {
final orchestrator = AppPrewarmOrchestrator(
calendarRepository: calendarRepository,
inboxRepository: inboxRepository,
chatHistoryRepository: chatHistoryRepository,
bootBudget: const Duration(milliseconds: 100),
prewarmChatHistory: () async {},
prewarmCalendarToday: () async {},
prewarmUnreadInbox: () async {},
);
await orchestrator.ensureStartedFor('u1');
expect(orchestrator.status, AppPrewarmStatus.completed);
expect(orchestrator.isBootBlocking, isFalse);
});
test('times out when budget exceeded', () async {
final completer = Completer<void>();
final orchestrator = AppPrewarmOrchestrator(
calendarRepository: calendarRepository,
inboxRepository: inboxRepository,
chatHistoryRepository: chatHistoryRepository,
bootBudget: const Duration(milliseconds: 30),
prewarmChatHistory: () => completer.future,
prewarmCalendarToday: () => completer.future,
prewarmUnreadInbox: () => completer.future,
);
await orchestrator.ensureStartedFor('u1');
expect(orchestrator.status, AppPrewarmStatus.timedOut);
expect(orchestrator.isBootBlocking, isFalse);
completer.complete();
});
}