mirror of
https://github.com/GopeedLab/gopeed.git
synced 2026-11-08 09:30:27 +00:00
feat: move native communication to FFI (#1457)
This commit is contained in:
86 files changed
+4558
-886
No files matched your search
@@ -0,0 +1,41 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:gopeed/api/api.dart' as api;
|
||||
import 'package:gopeed/core/network/gopeed/gopeed_transport.dart';
|
||||
import 'package:gopeed/features/auth/application/web_auth_controller.dart';
|
||||
|
||||
void main() {
|
||||
test('successful login relies on the server cookie and unauthorized requires login', () async {
|
||||
api.setTransportForTesting(_LoginTransport());
|
||||
final controller = WebAuthController();
|
||||
addTearDown(controller.dispose);
|
||||
|
||||
final failure = await controller.login(username: 'gopeed', password: 'secret');
|
||||
|
||||
expect(failure, isNull);
|
||||
controller.requireLogin();
|
||||
expect(controller.loginRequired, isTrue);
|
||||
});
|
||||
}
|
||||
|
||||
class _LoginTransport implements GopeedTransport {
|
||||
@override
|
||||
Future<dynamic> request(
|
||||
String path, {
|
||||
String method = 'GET',
|
||||
dynamic data,
|
||||
Map<String, dynamic>? queryParameters,
|
||||
}) async {
|
||||
expect(path, 'api/web/login');
|
||||
expect(method, 'POST');
|
||||
return {'code': 0};
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Response<String>> proxyRequest(String uri, {dynamic data, Options? options}) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
String join(String path) => path;
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import 'package:gopeed/core/capabilities/app_capabilities.dart';
|
||||
import 'package:gopeed/core/capabilities/capability_rpc.dart';
|
||||
import 'package:gopeed/core/capabilities/gopeed_capability.dart';
|
||||
import 'package:gopeed/core/common/start_config.dart';
|
||||
import 'package:gopeed/core/common/api_server_state.dart';
|
||||
import 'package:gopeed/features/settings/application/settings_controller.dart';
|
||||
|
||||
void main() {
|
||||
@@ -36,13 +37,51 @@ void main() {
|
||||
expect((await container.read(settingsControllerProvider.future)).config.downloadDir, 'E:/Created task');
|
||||
expect(getConfigCalls, 2);
|
||||
});
|
||||
|
||||
test('settings save preserves backend-owned client preferences', () async {
|
||||
final backend = DownloaderConfig()
|
||||
..extra.windowState = WindowStateConfig(isMaximized: true, width: 1200, height: 800)
|
||||
..extra.createHistory = ['https://example.com/existing.zip']
|
||||
..extra.analyticsClientId = 'existing-client';
|
||||
DownloaderConfig? saved;
|
||||
final registry = CapabilityRegistry(createAppCapabilityCodecs())
|
||||
..bind(GopeedMethods.getConfig, (_) => DownloaderConfig.fromJson(backend.toJson()))
|
||||
..bind(GopeedMethods.putConfig, (config) {
|
||||
saved = DownloaderConfig.fromJson(config.toJson());
|
||||
return const RpcUnit();
|
||||
});
|
||||
final container = ProviderContainer(
|
||||
overrides: [
|
||||
appCapabilitiesProvider.overrideWithValue(AppCapabilities(LocalCapabilityInvoker(registry))),
|
||||
appRuntimeControllerProvider.overrideWith(_TestRuntimeController.new),
|
||||
],
|
||||
);
|
||||
addTearDown(container.dispose);
|
||||
|
||||
final controller = container.read(settingsControllerProvider.notifier);
|
||||
await container.read(settingsControllerProvider.future);
|
||||
await controller.save(DownloaderConfig(downloadDir: 'E:/New'));
|
||||
|
||||
expect(saved?.downloadDir, 'E:/New');
|
||||
expect(saved?.extra.windowState.isMaximized, isTrue);
|
||||
expect(saved?.extra.createHistory, ['https://example.com/existing.zip']);
|
||||
expect(saved?.extra.analyticsClientId, 'existing-client');
|
||||
});
|
||||
}
|
||||
|
||||
class _TestRuntimeController extends AppRuntimeController {
|
||||
@override
|
||||
Future<AppRuntimeState> build() async => AppRuntimeState(
|
||||
startConfig: StartConfig(),
|
||||
runningPort: 0,
|
||||
apiServerState: const ApiServerState(
|
||||
enabled: false,
|
||||
running: false,
|
||||
network: '',
|
||||
address: '',
|
||||
runningPort: 0,
|
||||
pendingApply: false,
|
||||
lastError: '',
|
||||
),
|
||||
downloaderConfig: DownloaderConfig(downloadDir: 'C:/Stale runtime snapshot'),
|
||||
);
|
||||
}
|
||||
@@ -145,21 +145,30 @@ void main() {
|
||||
final rememberDirectory = find.byKey(const ValueKey('create-task-remember-download-directory-checkbox'));
|
||||
final directDownloadCheckbox = find.byKey(const ValueKey('create-task-direct-download-checkbox'));
|
||||
final rememberDirectoryRow = find.byKey(const ValueKey('create-task-remember-download-directory'));
|
||||
final rememberDirectoryLabel = find.byKey(const ValueKey('create-task-remember-download-directory-label'));
|
||||
final directDownloadLabel = find.descendant(
|
||||
of: find.byKey(const ValueKey('create-task-direct-download-toggle')),
|
||||
matching: find.text('Skip resolving and create tasks immediately'),
|
||||
);
|
||||
final directoryComponent = find.byKey(const ValueKey('create-task-directory-component'));
|
||||
final directoryOptionsRow = find.byKey(const ValueKey('create-task-directory-options-row'));
|
||||
final directoryOptionsLayout = find.byKey(const ValueKey('create-task-directory-options-layout'));
|
||||
final directoryPicker = find.byKey(const ValueKey('create-task-directory-picker'));
|
||||
expect(tester.widget<shad.Checkbox>(rememberDirectory).state, shad.CheckboxState.unchecked);
|
||||
expect(find.text('Save as default download directory'), findsOneWidget);
|
||||
final rememberStyle = tester.widget<Text>(rememberDirectoryLabel).style!;
|
||||
final directStyle = tester.widget<Text>(directDownloadLabel).style!;
|
||||
expect(rememberStyle.color, directStyle.color);
|
||||
expect(rememberStyle.fontSize, directStyle.fontSize);
|
||||
expect(rememberStyle.fontWeight, directStyle.fontWeight);
|
||||
expect(tester.widget<shad.Checkbox>(rememberDirectory).size, isNull);
|
||||
expect(tester.getSize(rememberDirectory), const Size.square(AppDesignTokens.checkboxSize));
|
||||
expect(tester.getCenter(rememberDirectory).dx, closeTo(tester.getCenter(directDownloadCheckbox).dx, 0.5));
|
||||
final rememberDirectoryLabel = tester.widget<Text>(
|
||||
find.byKey(const ValueKey('create-task-remember-download-directory-label')),
|
||||
);
|
||||
final directDownloadLabel = tester.widget<Text>(find.byKey(const ValueKey('create-task-direct-download-label')));
|
||||
expect(rememberDirectoryLabel.style, directDownloadLabel.style);
|
||||
expect(rememberDirectoryLabel.maxLines, directDownloadLabel.maxLines);
|
||||
expect(rememberDirectoryLabel.overflow, directDownloadLabel.overflow);
|
||||
final rememberDirectoryText = tester.widget<Text>(rememberDirectoryLabel);
|
||||
final directDownloadText = tester.widget<Text>(directDownloadLabel);
|
||||
expect(rememberDirectoryText.style, directDownloadText.style);
|
||||
expect(rememberDirectoryText.maxLines, directDownloadText.maxLines);
|
||||
expect(rememberDirectoryText.overflow, directDownloadText.overflow);
|
||||
expect(tester.widget<shad.IconButton>(directoryPicker).variance, same(shad.ButtonVariance.outline));
|
||||
expect(tester.widget<flutter.Row>(directoryOptionsLayout).mainAxisAlignment, MainAxisAlignment.spaceBetween);
|
||||
expect(tester.getCenter(rememberDirectoryRow).dy, closeTo(tester.getCenter(shortcutRow).dy, 0.5));
|
||||
|
||||
Reference in new issue
Block a user