Files
Evergreen-Health/Admin.NET.Test/Health/HomeAssistantTemperatureUnitTests.cs
2026-10-09 16:46:30 +08:00

73 lines
3.5 KiB
C#

using Evergreen.Health.Application.Health.Integrations.HomeAssistant;
using Microsoft.Extensions.Options;
using System.Net;
using System.Text;
using Xunit;
namespace Admin.NET.Test.Health;
public sealed class HomeAssistantTemperatureUnitTests
{
[Theory]
[InlineData("°C")]
[InlineData("°F")]
public async Task NativeClimateWithoutUnitUsesHaUnitSystemWithoutGuessing(string unit)
{
var handler = new UnitHandler("""[{"entity_id":"climate.room","state":"off","attributes":{"temperature":23,"min_temp":5,"max_temp":35,"target_temp_step":0.5,"supported_features":393}}]""",
unit);
var states = await Client(handler).GetStatesAsync();
var state = Assert.Single(states);
Assert.Equal(unit, state.GetStringAttribute("temperature_unit"));
Assert.Equal(23d, state.GetDoubleAttribute("temperature"));
Assert.Equal(393d, state.GetDoubleAttribute("supported_features"));
Assert.Equal(new[] { "/api/states", "/api/config" }, handler.Paths);
}
[Fact]
public async Task ExplicitDeviceUnitIsNotOverwritten()
{
var handler = new UnitHandler("""[{"entity_id":"climate.room","state":"off","attributes":{"temperature_unit":"°F","temperature":73}}]""", "°C");
var state = Assert.Single(await Client(handler).GetStatesAsync());
Assert.Equal("°F", state.GetStringAttribute("temperature_unit"));
Assert.Equal(new[] { "/api/states" }, handler.Paths);
}
[Fact]
public async Task MissingConfigKeepsUnitUnknownAndDoesNotHideOtherDevices()
{
var handler = new UnitHandler("""[{"entity_id":"climate.room","state":"off","attributes":{"temperature":23}},{"entity_id":"switch.room","state":"on","attributes":{}}]""",
"°C", HttpStatusCode.ServiceUnavailable);
var states = await Client(handler).GetStatesAsync();
Assert.Equal(2, states.Count);
Assert.Null(states[0].GetStringAttribute("temperature_unit"));
Assert.Equal("on", states[1].State);
Assert.Equal(23d, states[0].GetDoubleAttribute("temperature"));
}
[Fact]
public async Task OtherDevicesDoNotRequireUnitProbe()
{
var handler = new UnitHandler("""[{"entity_id":"cover.room","state":"unavailable","attributes":{"supported_features":15}}]""", "°C");
Assert.Single(await Client(handler).GetStatesAsync());
Assert.Equal(new[] { "/api/states" }, handler.Paths);
}
private static HomeAssistantClient Client(UnitHandler handler) => new(new HttpClient(handler),
Options.Create(new HomeAssistantOptions { BaseUrl = "https://ha.example.invalid", AccessToken = "fake-test-token" }));
private sealed class UnitHandler(string states, string unit, HttpStatusCode configStatus = HttpStatusCode.OK) : HttpMessageHandler
{
public List<string> Paths { get; } = [];
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
Assert.Equal(HttpMethod.Get, request.Method);
var path = request.RequestUri!.AbsolutePath;
Paths.Add(path);
var content = path == "/api/states" ? states : System.Text.Json.JsonSerializer.Serialize(new { unit_system = new { temperature = unit } });
return Task.FromResult(new HttpResponseMessage(path == "/api/states" ? HttpStatusCode.OK : configStatus)
{ Content = new StringContent(content, Encoding.UTF8, "application/json") });
}
}
}