e89f3de748
- selectedNodeCodeProvider 改为持久化 StateNotifier(select() 落盘、启动恢复,默认智能 AUTO); 自动连接复用上次选择:智能就智能、具体就具体。 - 自动连接门控加等「选中节点已恢复」(controller.loaded),避免用到未恢复的默认值。 - 自动连接触发时弹 toast「正在自动连接到 X」(全局 ScaffoldMessenger key)。 - 测试:选中节点 select 落盘 + 重启恢复(具体/智能)。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
51 lines
2.0 KiB
Dart
51 lines
2.0 KiB
Dart
// selected_node_persist_test.dart — 选中节点(智能/具体)跨重启持久化,供自动连接复用上次选择。
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:pangolin_vpn/models/node.dart';
|
|
import 'package:pangolin_vpn/state/nodes_provider.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
void main() {
|
|
TestWidgetsFlutterBinding.ensureInitialized();
|
|
setUp(() => SharedPreferences.setMockInitialValues({}));
|
|
|
|
Future<void> waitSelected(ProviderContainer c, String want) async {
|
|
for (var i = 0; i < 60; i++) {
|
|
if (c.read(selectedNodeCodeProvider) == want) return;
|
|
await Future<void>.delayed(const Duration(milliseconds: 10));
|
|
}
|
|
}
|
|
|
|
test('默认智能选择(AUTO)', () async {
|
|
final c = ProviderContainer();
|
|
addTearDown(c.dispose);
|
|
expect(c.read(selectedNodeCodeProvider), kSmartNodeCode);
|
|
});
|
|
|
|
test('select 具体节点 → 落盘', () async {
|
|
final c = ProviderContainer();
|
|
addTearDown(c.dispose);
|
|
await waitSelected(c, kSmartNodeCode); // 等 _load
|
|
await c.read(selectedNodeCodeProvider.notifier).select('JP');
|
|
expect(c.read(selectedNodeCodeProvider), 'JP');
|
|
final p = await SharedPreferences.getInstance();
|
|
expect(p.getString('selected_node_code'), 'JP', reason: '应持久化');
|
|
});
|
|
|
|
test('重启从持久化恢复具体节点', () async {
|
|
SharedPreferences.setMockInitialValues({'selected_node_code': 'JP'});
|
|
final c = ProviderContainer();
|
|
addTearDown(c.dispose);
|
|
await waitSelected(c, 'JP');
|
|
expect(c.read(selectedNodeCodeProvider), 'JP', reason: '重启应恢复上次选择');
|
|
});
|
|
|
|
test('重启恢复智能选择(AUTO 持久化)', () async {
|
|
SharedPreferences.setMockInitialValues({'selected_node_code': kSmartNodeCode});
|
|
final c = ProviderContainer();
|
|
addTearDown(c.dispose);
|
|
await waitSelected(c, kSmartNodeCode);
|
|
expect(c.read(selectedNodeCodeProvider), kSmartNodeCode);
|
|
});
|
|
}
|