using IpPbx.CLMgrLib; using SwyxTray.Swyx; using SwyxTray.Web; if (args.Contains("--serve")) { await TransportChecks.Serve(); return; } int checks = 0; void Check(bool condition, string name) { if (!condition) throw new Exception(name); checks++; } void Reject(Action action, string name) { try { action(); } catch (InvalidOperationException) { checks++; return; } throw new Exception(name); } var recordings = new CallRecordingTracker(); int invocations = 0; Action invoke = () => invocations++; Reject(() => recordings.Set(0, 41, 42, true, false, true, invoke), "stale call"); Reject(() => recordings.Set(0, 41, 41, false, false, true, invoke), "ringing"); Reject(() => recordings.Set(0, 41, 41, false, true, true, invoke), "held start"); Check(invocations == 0, "invalid calls do not reach SDK"); recordings.Set(0, 41, 41, true, false, true, invoke); recordings.Set(0, 41, 41, true, false, true, invoke); Check(invocations == 1 && recordings.IsRequested(0, 41), "idempotent start"); recordings.Set(0, 41, 41, false, true, false, invoke); Check(invocations == 2 && !recordings.IsRequested(0, 41), "stop while held"); Reject(() => recordings.Set(0, 41, 41, true, false, true, () => throw new InvalidOperationException()), "SDK error"); Check(!recordings.IsRequested(0, 41), "failed start not reported as success"); recordings.Set(0, 41, 41, true, false, true, invoke); Reject(() => recordings.Set(0, 41, 41, true, false, false, () => throw new InvalidOperationException()), "stop error"); Check(recordings.IsRequested(0, 41), "failed stop retains request state"); recordings.Retain(new[] { (0, 42) }); Check(!recordings.IsRequested(0, 41), "call ended clears request state"); recordings.Set(0, 42, 42, true, false, false, invoke); Check(invocations == 4, "stop external recording reaches SDK too"); SwyxSnapshot Snapshot(CLMgrLineStates state, int id = 41, bool recording = false) => new(true, true, "test", "test", new[] { new SwyxLineInfo(0, state, "123", "Test", true, id, recording) }); var active = Snapshot(CLMgrLineStates.LSActive, recording: true); var end = CallEventMessage.Diff(active, Snapshot(CLMgrLineStates.LSInactive)); Check(end.Count == 1 && end[0].Event == "ended" && end[0].CallId == 41 && end[0].PeerNumber == "123", "end preserves call identity"); Check(CallEventMessage.Diff(active, SwyxSnapshot.Offline).Count == 0, "disconnect is not call end"); Check(CallEventMessage.Diff(active, active with { IsServerUp = false }).Count == 0, "server down is not call end"); Check(CallEventMessage.Diff(active, Snapshot(CLMgrLineStates.LSOnHold)).Count == 0, "holding is not call end"); Check(CallEventMessage.Diff(Snapshot(CLMgrLineStates.LSOnHold), active).Count == 0, "resume is not new call"); var replaced = CallEventMessage.Diff(active, Snapshot(CLMgrLineStates.LSRinging, 42)); Check(replaced.Count == 2 && replaced.Any(e => e.Event == "ended" && e.CallId == 41) && replaced.Any(e => e.Event == "incoming" && e.CallId == 42), "reused line keeps calls distinct"); var json = Protocol.Serialize(SnapshotMessage.From(active)); Check(json.Contains("\"callId\":41") && json.Contains("\"recordingRequested\":true"), "wire fields"); OutboxChecks.Run(Check); await TransportChecks.Run(Check); Console.WriteLine($"{checks} recording/protocol checks passed (no COM calls).");