using System.Text.Json; using backend.Tools; using FluentAssertions; using Xunit; namespace backend.tests; public class SetVolumeToolTests { [Fact] public async Task Forwards_call_to_pi_and_returns_its_result() { var fake = new RecordingChannel( JsonDocument.Parse("""{"ok":true}""").RootElement); var tool = new SetVolumeTool(); var ctx = new DeviceContext(Guid.NewGuid(), Guid.NewGuid(), fake); var args = JsonDocument.Parse("""{"level":42}""").RootElement; var res = await tool.ExecuteAsync(new ToolInvocation("c1", args), ctx, default); fake.LastName.Should().Be("set_volume"); fake.LastArgs.GetProperty("level").GetInt32().Should().Be(42); res.Output.GetProperty("ok").GetBoolean().Should().BeTrue(); } [Fact] public async Task Rejects_out_of_range_level_without_calling_pi() { var fake = new RecordingChannel(JsonDocument.Parse("""{"ok":true}""").RootElement); var tool = new SetVolumeTool(); var ctx = new DeviceContext(Guid.NewGuid(), Guid.NewGuid(), fake); var args = JsonDocument.Parse("""{"level":150}""").RootElement; var res = await tool.ExecuteAsync(new ToolInvocation("c1", args), ctx, default); fake.LastName.Should().BeNull(); res.Output.GetProperty("ok").GetBoolean().Should().BeFalse(); res.Output.GetProperty("error").GetString().Should().Contain("0..100"); } private class RecordingChannel(JsonElement reply) : IDeviceChannel { public string? LastName { get; private set; } public JsonElement LastArgs { get; private set; } public Task CallPiToolAsync(string name, JsonElement args, CancellationToken ct) { LastName = name; LastArgs = args; return Task.FromResult(reply); } } }