using System.Text.Json; using WirelessTextSyncer.Windows.Models; using WirelessTextSyncer.Windows.Services; namespace WirelessTextSyncer.Windows.Tests; [TestClass] public sealed class SyncMessageTests { [TestMethod] public void DeserializeAndroidInsertTextMessage() { var message = JsonSerializer.Deserialize( """{"action":"insertText","text":"hello"}""", new JsonSerializerOptions(JsonSerializerDefaults.Web)); Assert.IsNotNull(message); Assert.AreEqual(SyncAction.InsertText, message.Action); Assert.AreEqual("hello", message.Text); } [TestMethod] public void DeserializeAndroidBackspaceMessage() { var message = JsonSerializer.Deserialize( """{"action":"backspace"}""", new JsonSerializerOptions(JsonSerializerDefaults.Web)); Assert.IsNotNull(message); Assert.AreEqual(SyncAction.Backspace, message.Action); } [TestMethod] public void DeserializeAndroidReplaceAllMessage() { var message = JsonSerializer.Deserialize( """{"action":"replaceAll","text":"final text"}""", new JsonSerializerOptions(JsonSerializerDefaults.Web)); Assert.IsNotNull(message); Assert.AreEqual(SyncAction.ReplaceAll, message.Action); Assert.AreEqual("final text", message.Text); } [TestMethod] public void ReplaceAllAppendsSubmittedText() { var keyboard = new RecordingKeyboardInjectionService(); var handler = new SyncMessageHandler(keyboard, new RecordingAudioControlService()); handler.Handle(new SyncMessage { Action = SyncAction.ReplaceAll, Text = "final text" }); CollectionAssert.AreEqual( new[] { "insert:final text" }, keyboard.Calls); } [TestMethod] public void DeserializeAndroidSetMuteMessage() { var message = JsonSerializer.Deserialize( """{"action":"setMute","muted":true}""", new JsonSerializerOptions(JsonSerializerDefaults.Web)); Assert.IsNotNull(message); Assert.AreEqual(SyncAction.SetMute, message.Action); Assert.AreEqual(true, message.Muted); } [TestMethod] public void SetMuteForwardsToAudioService() { var audio = new RecordingAudioControlService(); var handler = new SyncMessageHandler(new RecordingKeyboardInjectionService(), audio); handler.Handle(new SyncMessage { Action = SyncAction.SetMute, Muted = true }); CollectionAssert.AreEqual(new[] { "mute:True" }, audio.Calls); } [TestMethod] public void DiscoveryResponseContainsServiceEndpoint() { using var discovery = new DiscoveryResponderService(() => "192.168.1.10", () => 8181, "Desktop-WIN11"); using var document = JsonDocument.Parse(discovery.BuildResponseJson()); var root = document.RootElement; Assert.AreEqual("wirelessTextSyncer.service", root.GetProperty("type").GetString()); Assert.AreEqual(1, root.GetProperty("version").GetInt32()); Assert.AreEqual("Desktop-WIN11", root.GetProperty("name").GetString()); Assert.AreEqual("192.168.1.10", root.GetProperty("host").GetString()); Assert.AreEqual(8181, root.GetProperty("port").GetInt32()); } [TestMethod] public void WebSocketServiceInfoContainsDeviceName() { using var server = new WebSocketServerService(new SyncMessageHandler(new RecordingKeyboardInjectionService(), new RecordingAudioControlService()), "Desktop-WIN11"); using var document = JsonDocument.Parse(server.BuildServiceInfoJson()); var root = document.RootElement; Assert.AreEqual("wirelessTextSyncer.service", root.GetProperty("type").GetString()); Assert.AreEqual(1, root.GetProperty("version").GetInt32()); Assert.AreEqual("Desktop-WIN11", root.GetProperty("name").GetString()); Assert.AreEqual(8181, root.GetProperty("port").GetInt32()); } private sealed class RecordingKeyboardInjectionService : IKeyboardInjectionService { public List Calls { get; } = []; public void InsertText(string text) { Calls.Add($"insert:{text}"); } public void ReplaceFocusedText(string text) { Calls.Add($"replace:{text}"); } public void Backspace() { Calls.Add("backspace"); } public void Enter() { Calls.Add("enter"); } } private sealed class RecordingAudioControlService : IAudioControlService { public List Calls { get; } = []; public bool IsMuted => Calls.Count > 0 && Calls[^1] == "mute:True"; public void SetMute(bool muted) { Calls.Add($"mute:{muted}"); } } }