using LogiBoardToolBox.Core.HidPlusPlus;
using LogiBoardToolBox.Core.Onboard;
using XFEExtension.NetCore.XUnit.Assertions;
using XFEExtension.NetCore.XUnit.Attributes;
namespace LogiBoardToolBox.Test;
[TestFixture]
public class OnboardHandoffTests
{
[Test]
public async Task ReturningFromExternalHostStopsSpyBeforeEnteringOnboardWithoutWritingFlash()
{
var snapshot = Fixture.Create(10);
using var mouse = new FakeMouse(snapshot) { SpySupported = true, SpyActive = true };
using var client = new HidPlusPlusClient(mouse, 1);
var memory = new OnboardMemory(client, snapshot.DeviceIdentity, snapshot.DeviceName);
var map = mouse.SpyMap.ToArray();
await memory.SetModeAsync(true);
Assert.Equal(false, mouse.SpyActive); Assert.Equal((byte)1, mouse.Mode);
Assert.Equal(0, mouse.WriteStarts); Assert.Equal(true, map.SequenceEqual(mouse.SpyMap));
Assert.Equal(true, mouse.Requests.FindIndex(StopSpy) < mouse.Requests.FindIndex(EnterOnboard));
Assert.Equal(true, snapshot.Sectors.All(p => p.Value.SequenceEqual(mouse.Sectors[p.Key])));
}
[Test]
public async Task ReselectingAnActiveOnboardProfileAlsoStopsStaleSpy()
{
var snapshot = Fixture.Create(10);
using var mouse = new FakeMouse(snapshot) { SpySupported = true };
using var client = new HidPlusPlusClient(mouse, 1);
await client.FeatureAsync(0x8100, 1, [1]); mouse.SpyActive = true; mouse.Requests.Clear();
var memory = new OnboardMemory(client, snapshot.DeviceIdentity, snapshot.DeviceName);
await memory.ActivateProfileAsync(1);
Assert.Equal(false, mouse.SpyActive); Assert.Equal((ushort)1, mouse.Active);
Assert.Equal(true, mouse.Requests.Any(StopSpy)); Assert.Equal(0, mouse.WriteStarts);
}
[Test]
public async Task ImmediateSaveCompletesTheHostHandoffBeforeWritingTheEditedProfile()
{
var snapshot = Fixture.Create(10); var draft = snapshot.GetProfiles()[0].Copy(); draft.Dpis = [400, 800, 1600, 3200, 6400];
using var mouse = new FakeMouse(snapshot) { SpySupported = true, SpyActive = true };
using var client = new HidPlusPlusClient(mouse, 1);
var memory = new OnboardMemory(client, snapshot.DeviceIdentity, snapshot.DeviceName);
using var scratch = new ScratchDirectory();
await memory.CommitAsync(MemoryWritePlan.Create(snapshot, draft, [], true), scratch.Path);
var stop = mouse.Requests.FindIndex(StopSpy); var mode = mouse.Requests.FindIndex(EnterOnboard);
var write = mouse.Requests.FindIndex(r => r[2] == 2 && r[3] >> 4 == 6);
Assert.Equal(true, stop >= 0 && stop < mode && mode < write); Assert.Equal(false, mouse.SpyActive);
}
[Test]
public async Task FailedSpyStopPreventsFlashWritesAndDevicesWithoutSpyRemainSupported()
{
var snapshot = Fixture.Create(10); var draft = snapshot.GetProfiles()[0].Copy(); draft.Dpis = [800, 1600, 3200, 6400, 12800];
using var mouse = new FakeMouse(snapshot) { SpySupported = true, SpyActive = true, FailSpyStop = true };
using var client = new HidPlusPlusClient(mouse, 1);
var memory = new OnboardMemory(client, snapshot.DeviceIdentity, snapshot.DeviceName);
using var scratch = new ScratchDirectory(); var rejected = false;
try { await memory.CommitAsync(MemoryWritePlan.Create(snapshot, draft, [], true), scratch.Path); }
catch (IOException) { rejected = true; }
Assert.Equal(true, rejected); Assert.Equal(0, mouse.WriteStarts); Assert.Equal((byte)2, mouse.Mode);
Assert.Equal(true, snapshot.Sectors.All(p => p.Value.SequenceEqual(mouse.Sectors[p.Key])));
using var older = new FakeMouse(snapshot); using var olderClient = new HidPlusPlusClient(older, 1);
await new OnboardMemory(olderClient, snapshot.DeviceIdentity, snapshot.DeviceName).SetModeAsync(true);
Assert.Equal((byte)1, older.Mode); Assert.Equal(0, older.WriteStarts);
}
private static bool StopSpy(byte[] r) => r[2] == 3 && r[3] >> 4 == 2;
private static bool EnterOnboard(byte[] r) => r[2] == 2 && r[3] >> 4 == 1 && r[4] == 1;
}
using LogiBoardToolBox.Core.HidPlusPlus;
using LogiBoardToolBox.Core.Onboard;
using XFEExtension.NetCore.XUnit.Assertions;
using XFEExtension.NetCore.XUnit.Attributes;
namespace LogiBoardToolBox.Test;
[TestFixture]
public class OnboardHandoffTests
{
[Test]
public async Task ReturningFromExternalHostStopsSpyBeforeEnteringOnboardWithoutWritingFlash()
{
var snapshot = Fixture.Create(10);
using var mouse = new FakeMouse(snapshot) { SpySupported = true, SpyActive = true };
using var client = new HidPlusPlusClient(mouse, 1);
var memory = new OnboardMemory(client, snapshot.DeviceIdentity, snapshot.DeviceName);
var map = mouse.SpyMap.ToArray();
await memory.SetModeAsync(true);
Assert.Equal(false, mouse.SpyActive); Assert.Equal((byte)1, mouse.Mode);
Assert.Equal(0, mouse.WriteStarts); Assert.Equal(true, map.SequenceEqual(mouse.SpyMap));
Assert.Equal(true, mouse.Requests.FindIndex(StopSpy) < mouse.Requests.FindIndex(EnterOnboard));
Assert.Equal(true, snapshot.Sectors.All(p => p.Value.SequenceEqual(mouse.Sectors[p.Key])));
}
[Test]
public async Task ReselectingAnActiveOnboardProfileAlsoStopsStaleSpy()
{
var snapshot = Fixture.Create(10);
using var mouse = new FakeMouse(snapshot) { SpySupported = true };
using var client = new HidPlusPlusClient(mouse, 1);
await client.FeatureAsync(0x8100, 1, [1]); mouse.SpyActive = true; mouse.Requests.Clear();
var memory = new OnboardMemory(client, snapshot.DeviceIdentity, snapshot.DeviceName);
await memory.ActivateProfileAsync(1);
Assert.Equal(false, mouse.SpyActive); Assert.Equal((ushort)1, mouse.Active);
Assert.Equal(true, mouse.Requests.Any(StopSpy)); Assert.Equal(0, mouse.WriteStarts);
}
[Test]
public async Task ImmediateSaveCompletesTheHostHandoffBeforeWritingTheEditedProfile()
{
var snapshot = Fixture.Create(10); var draft = snapshot.GetProfiles()[0].Copy(); draft.Dpis = [400, 800, 1600, 3200, 6400];
using var mouse = new FakeMouse(snapshot) { SpySupported = true, SpyActive = true };
using var client = new HidPlusPlusClient(mouse, 1);
var memory = new OnboardMemory(client, snapshot.DeviceIdentity, snapshot.DeviceName);
using var scratch = new ScratchDirectory();
await memory.CommitAsync(MemoryWritePlan.Create(snapshot, draft, [], true), scratch.Path);
var stop = mouse.Requests.FindIndex(StopSpy); var mode = mouse.Requests.FindIndex(EnterOnboard);
var write = mouse.Requests.FindIndex(r => r[2] == 2 && r[3] >> 4 == 6);
Assert.Equal(true, stop >= 0 && stop < mode && mode < write); Assert.Equal(false, mouse.SpyActive);
}
[Test]
public async Task FailedSpyStopPreventsFlashWritesAndDevicesWithoutSpyRemainSupported()
{
var snapshot = Fixture.Create(10); var draft = snapshot.GetProfiles()[0].Copy(); draft.Dpis = [800, 1600, 3200, 6400, 12800];
using var mouse = new FakeMouse(snapshot) { SpySupported = true, SpyActive = true, FailSpyStop = true };
using var client = new HidPlusPlusClient(mouse, 1);
var memory = new OnboardMemory(client, snapshot.DeviceIdentity, snapshot.DeviceName);
using var scratch = new ScratchDirectory(); var rejected = false;
try { await memory.CommitAsync(MemoryWritePlan.Create(snapshot, draft, [], true), scratch.Path); }
catch (IOException) { rejected = true; }
Assert.Equal(true, rejected); Assert.Equal(0, mouse.WriteStarts); Assert.Equal((byte)2, mouse.Mode);
Assert.Equal(true, snapshot.Sectors.All(p => p.Value.SequenceEqual(mouse.Sectors[p.Key])));
using var older = new FakeMouse(snapshot); using var olderClient = new HidPlusPlusClient(older, 1);
await new OnboardMemory(olderClient, snapshot.DeviceIdentity, snapshot.DeviceName).SetModeAsync(true);
Assert.Equal((byte)1, older.Mode); Assert.Equal(0, older.WriteStarts);
}
private static bool StopSpy(byte[] r) => r[2] == 3 && r[3] >> 4 == 2;
private static bool EnterOnboard(byte[] r) => r[2] == 2 && r[3] >> 4 == 1 && r[4] == 1;
}