import 'package:flutter_test/flutter_test.dart'; import 'package:twp_softphone/models/call_info.dart'; void main() { group('CallInfo', () { test('default state is idle', () { const info = CallInfo(); expect(info.state, CallState.idle); expect(info.callSid, isNull); expect(info.callerNumber, isNull); expect(info.duration, Duration.zero); expect(info.isMuted, false); expect(info.isSpeakerOn, false); expect(info.isOnHold, false); }); test('isActive returns true for ringing, connecting, connected', () { expect(const CallInfo(state: CallState.ringing).isActive, true); expect(const CallInfo(state: CallState.connecting).isActive, true); expect(const CallInfo(state: CallState.connected).isActive, true); }); test('isActive returns false for idle and disconnected', () { expect(const CallInfo(state: CallState.idle).isActive, false); expect(const CallInfo(state: CallState.disconnected).isActive, false); }); test('copyWith preserves unmodified fields', () { const original = CallInfo( state: CallState.connected, callSid: 'CA123', callerNumber: '+1234567890', isMuted: true, ); final modified = original.copyWith(isSpeakerOn: true); expect(modified.state, CallState.connected); expect(modified.callSid, 'CA123'); expect(modified.callerNumber, '+1234567890'); expect(modified.isMuted, true); expect(modified.isSpeakerOn, true); }); test('copyWith can change state', () { const info = CallInfo(state: CallState.connecting); final updated = info.copyWith(state: CallState.connected); expect(updated.state, CallState.connected); }); test('copyWith with callerNumber preserves it', () { const info = CallInfo(callerNumber: '+19095737372'); final updated = info.copyWith(state: CallState.connected); expect(updated.callerNumber, '+19095737372'); }); test('reset to idle clears all fields', () { // Verify a complex state exists const connected = CallInfo( state: CallState.connected, callSid: 'CA123', callerNumber: '+1234567890', isMuted: true, isSpeakerOn: true, isOnHold: true, duration: Duration(seconds: 30), ); expect(connected.isActive, true); // Simulating what callEnded does const reset = CallInfo(); expect(reset.state, CallState.idle); expect(reset.callSid, isNull); expect(reset.callerNumber, isNull); expect(reset.isActive, false); }); }); group('CallState transitions', () { test('outbound call flow: idle -> connecting -> connected -> idle', () { var info = const CallInfo(); expect(info.state, CallState.idle); // makeCall sets connecting + callerNumber info = info.copyWith(state: CallState.connecting, callerNumber: '+19095737372'); expect(info.state, CallState.connecting); expect(info.callerNumber, '+19095737372'); expect(info.isActive, true); // SDK fires connected info = info.copyWith(state: CallState.connected); expect(info.state, CallState.connected); expect(info.callerNumber, '+19095737372'); // preserved expect(info.isActive, true); // callEnded resets info = const CallInfo(); expect(info.state, CallState.idle); expect(info.isActive, false); }); test('inbound call flow: idle -> ringing -> connected -> idle', () { var info = const CallInfo(); info = info.copyWith(state: CallState.ringing); expect(info.isActive, true); // callerNumber set from active.from info = info.copyWith(callerNumber: '+18005551234'); expect(info.callerNumber, '+18005551234'); info = info.copyWith(state: CallState.connected); expect(info.state, CallState.connected); info = const CallInfo(); expect(info.state, CallState.idle); }); test('outbound callerNumber not overwritten by null copyWith', () { var info = const CallInfo( state: CallState.connecting, callerNumber: '+19095737372', ); // copyWith without callerNumber should preserve it info = info.copyWith(state: CallState.connected); expect(info.callerNumber, '+19095737372'); }); }); }