// connection_controller_test.dart — 连接状态机:严格三态、禁乐观显示 import 'package:flutter_test/flutter_test.dart'; import 'package:pangolin_vpn/state/connection_provider.dart'; void main() { // 注入极短握手时长,用真实计时器走完状态流转。 ConnectionController make() => ConnectionController(handshake: const Duration(milliseconds: 20)); test('初始为 off', () { final ctl = make(); expect(ctl.state.phase, VpnPhase.off); ctl.dispose(); }); test('connect: off → connecting → on', () async { final ctl = make(); ctl.connect(); expect(ctl.state.phase, VpnPhase.connecting); await Future.delayed(const Duration(milliseconds: 60)); expect(ctl.state.phase, VpnPhase.on); ctl.dispose(); }); test('握手中再次 toggle 被忽略(禁止乐观回退)', () async { final ctl = make(); ctl.toggle(); // off → connecting expect(ctl.state.phase, VpnPhase.connecting); ctl.toggle(); // connecting 中点击 → 仍 connecting expect(ctl.state.phase, VpnPhase.connecting); await Future.delayed(const Duration(milliseconds: 60)); expect(ctl.state.phase, VpnPhase.on); ctl.dispose(); }); test('on 态 toggle → off', () async { final ctl = make(); ctl.connect(); await Future.delayed(const Duration(milliseconds: 60)); expect(ctl.state.phase, VpnPhase.on); ctl.toggle(); expect(ctl.state.phase, VpnPhase.off); ctl.dispose(); }); test('已连接时切换节点 → 重连(回到 connecting)', () async { final ctl = make(); ctl.connect(); await Future.delayed(const Duration(milliseconds: 60)); expect(ctl.state.phase, VpnPhase.on); ctl.onNodeChanged(); expect(ctl.state.phase, VpnPhase.connecting); ctl.dispose(); }); test('on 态计时累加', () async { final ctl = make(); ctl.connect(); await Future.delayed(const Duration(milliseconds: 60)); expect(ctl.state.elapsed, Duration.zero); await Future.delayed(const Duration(milliseconds: 1100)); expect(ctl.state.elapsed.inSeconds, greaterThanOrEqualTo(1)); ctl.dispose(); }); test('off 态切换节点不会自动连接', () { final ctl = make(); ctl.onNodeChanged(); expect(ctl.state.phase, VpnPhase.off); ctl.dispose(); }); }