import 'package:cloudreve4_flutter/data/models/user_model.dart'; import 'package:cloudreve4_flutter/services/custom_line_service.dart'; import 'package:cloudreve4_flutter/services/server_service.dart'; import 'package:cloudreve4_flutter/services/storage_service.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:shared_preferences/shared_preferences.dart'; void main() { test('selected node json round trip preserves rewrite fields', () { const node = SelectedCustomLineNode( id: 'node-1', name: 'HK 01', ip: '203.0.113.10', host: 'node.example.com', protocol: 'https', port: 443, ); final restored = SelectedCustomLineNode.fromJson(node.toJson()); expect(restored.id, 'node-1'); expect(restored.name, 'HK 01'); expect(restored.ip, '203.0.113.10'); expect(restored.host, 'node.example.com'); expect(restored.protocol, 'https'); expect(restored.port, 443); expect(restored.canRewriteDownloadUrl, isTrue); }); test('download route defaults to unchanged', () { const route = CustomLineDownloadRoute(url: 'https://pan.example.com/file'); expect(route.changed, isFalse); expect(route.headers, isEmpty); }); test( 'routeDownloadUrl keeps url unchanged and enables host mapping proxy', () async { SharedPreferences.setMockInitialValues({}); await ServerService.instance.init(); await ServerService.instance.updateCurrentServerLogin( user: UserModel( id: 'user-1', nickname: 'VIP', createdAt: DateTime(2026, 1), group: GroupModel(id: 'vip', name: 'VIP'), ), ); await CustomLineService.instance.setSelectedNode( const SelectedCustomLineNode( id: 'node-1', name: 'HK 01', ip: '203.0.113.10', host: 'node.example.com', ), ); final route = await CustomLineService.instance.routeDownloadUrl( 'https://storage.example.com:8443/download/file.txt?token=abc', ); expect( route.url, 'https://storage.example.com:8443/download/file.txt?token=abc', ); expect(route.headers, isEmpty); expect(route.changed, isTrue); expect(route.originalHost, 'storage.example.com'); expect(route.proxy, isNotNull); expect(route.proxy!.host, '127.0.0.1'); expect(route.proxy!.port, greaterThan(0)); await CustomLineService.instance.clearSelectedNode(); await StorageService.instance.clear(); }, ); test('routeDownloadUrl stays unchanged for User group', () async { SharedPreferences.setMockInitialValues({}); await ServerService.instance.init(); await ServerService.instance.updateCurrentServerLogin( user: UserModel( id: 'user-2', nickname: 'Normal', createdAt: DateTime(2026, 1), group: GroupModel(id: 'user', name: 'User'), ), ); await CustomLineService.instance.setSelectedNode( const SelectedCustomLineNode( id: 'node-1', name: 'HK 01', ip: '203.0.113.10', host: 'node.example.com', ), ); final route = await CustomLineService.instance.routeDownloadUrl( 'https://storage.example.com/download/file.txt', ); expect(route.url, 'https://storage.example.com/download/file.txt'); expect(route.headers, isEmpty); expect(route.changed, isFalse); await CustomLineService.instance.clearSelectedNode(); await StorageService.instance.clear(); }); test('routeDownloadUrl stays unchanged after login is cleared', () async { SharedPreferences.setMockInitialValues({}); await ServerService.instance.init(); await ServerService.instance.updateCurrentServerLogin( user: UserModel( id: 'user-3', nickname: 'VIP', createdAt: DateTime(2026, 1), group: GroupModel(id: 'vip', name: 'VIP'), ), ); await CustomLineService.instance.setSelectedNode( const SelectedCustomLineNode( id: 'node-1', name: 'HK 01', ip: '203.0.113.10', host: 'node.example.com', ), ); await ServerService.instance.clearCurrentServerLogin(); final route = await CustomLineService.instance.routeDownloadUrl( 'https://storage.example.com/download/file.txt', ); expect(route.url, 'https://storage.example.com/download/file.txt'); expect(route.headers, isEmpty); expect(route.changed, isFalse); await CustomLineService.instance.clearSelectedNode(); await StorageService.instance.clear(); }); }