refactor: 重构聊天数据层至core并简化首页UI

This commit is contained in:
zl-q
2026-03-29 21:46:26 +08:00
parent 4db9a13bfe
commit f126d7a547
18 changed files with 568 additions and 328 deletions
@@ -1,10 +1,11 @@
import 'package:dio/dio.dart';
import 'dart:typed_data';
import 'package:flutter_bloc/flutter_bloc.dart';
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/data/network/i_api_client.dart';
import 'package:social_app/core/chat/chat_api.dart';
import 'package:social_app/features/chat/presentation/bloc/chat_bloc.dart';
import 'package:social_app/features/auth/presentation/bloc/auth_state.dart';
@@ -13,7 +14,7 @@ void main() {
if (sl.isRegistered<ChatBloc>()) {
await sl.unregister<ChatBloc>();
}
sl.registerSingleton<ChatBloc>(ChatBloc(apiClient: _FakeApiClient()));
sl.registerSingleton<ChatBloc>(ChatBloc(chatApi: _FakeChatApi()));
});
tearDown(() async {
@@ -43,6 +44,17 @@ void main() {
expect(result, AppRoutes.homeMain);
});
test('keeps authenticated home access on home route', () {
final result = resolveAuthRedirect(
authState: const AuthAuthenticated(
user: AuthUser(id: 'u1', phone: '13800138000'),
),
matchedLocation: AppRoutes.homeMain,
);
expect(result, isNull);
});
test('redirects auth checking state to boot route', () {
final result = resolveAuthRedirect(
authState: AuthLoading(),
@@ -69,37 +81,50 @@ void main() {
});
}
class _FakeApiClient implements IApiClient {
class _FakeChatApi implements ChatApi {
@override
Future<Response<T>> delete<T>(String path, {data, Options? options}) {
Future<void> cancelRun({required String threadId, required String runId}) {
throw UnimplementedError();
}
@override
Future<Response<T>> get<T>(String path, {Options? options}) {
Future<Map<String, dynamic>> createRun(Map<String, dynamic> runInput) {
throw UnimplementedError();
}
@override
Future<Stream<String>> getSseLines(
String path, {
Map<String, String>? headers,
Future<Map<String, dynamic>> fetchHistory({
String? threadId,
DateTime? beforeDate,
}) {
throw UnimplementedError();
}
@override
Future<Response<T>> patch<T>(String path, {data, Options? options}) {
Future<Uint8List> fetchAttachmentPreview(String previewPath) {
throw UnimplementedError();
}
@override
Future<Response<T>> post<T>(String path, {data, Options? options}) {
Future<Stream<String>> streamRunEvents(
String threadId, {
String? lastEventId,
}) {
throw UnimplementedError();
}
@override
Future<Response<T>> put<T>(String path, {data, Options? options}) {
Future<String> transcribeAudio(String filePath) {
throw UnimplementedError();
}
@override
Future<Map<String, dynamic>> uploadAttachment({
required String threadId,
required String filename,
required String mimeType,
required Uint8List bytes,
}) {
throw UnimplementedError();
}
}
@@ -1,13 +1,15 @@
import 'dart:async';
import 'dart:typed_data';
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/core/chat/chat_api.dart';
import 'package:social_app/core/chat/chat_history_repository.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
@@ -44,15 +46,65 @@ class _FakeApiClient implements IApiClient {
}
}
class _FakeChatApi implements ChatApi {
@override
Future<void> cancelRun({required String threadId, required String runId}) {
throw UnimplementedError();
}
@override
Future<Map<String, dynamic>> createRun(Map<String, dynamic> runInput) {
throw UnimplementedError();
}
@override
Future<Map<String, dynamic>> fetchHistory({
String? threadId,
DateTime? beforeDate,
}) {
throw UnimplementedError();
}
@override
Future<Uint8List> fetchAttachmentPreview(String previewPath) {
throw UnimplementedError();
}
@override
Future<Stream<String>> streamRunEvents(
String threadId, {
String? lastEventId,
}) {
throw UnimplementedError();
}
@override
Future<String> transcribeAudio(String filePath) {
throw UnimplementedError();
}
@override
Future<Map<String, dynamic>> uploadAttachment({
required String threadId,
required String filename,
required String mimeType,
required Uint8List bytes,
}) {
throw UnimplementedError();
}
}
void main() {
late HybridCacheStore store;
late _FakeApiClient apiClient;
late _FakeChatApi chatApi;
late CalendarRepository calendarRepository;
late InboxRepository inboxRepository;
late ChatHistoryRepository chatHistoryRepository;
setUp(() {
apiClient = _FakeApiClient();
chatApi = _FakeChatApi();
store = HybridCacheStore(
memory: MemoryCacheStore(),
persistent: PersistentCacheStore(),
@@ -60,7 +112,7 @@ void main() {
calendarRepository = CalendarRepository(apiClient: apiClient, store: store);
inboxRepository = InboxRepositoryImpl(apiClient: apiClient, store: store);
chatHistoryRepository = ChatHistoryRepository(
apiClient: apiClient,
chatApi: chatApi,
store: store,
);
});