using System.Net; using System.Net.Http.Json; using FluentAssertions; using Xunit; namespace backend.tests; public class DevicesEndpointsTests { private static async Task<(HttpClient signedIn, string code)> SetupWithPairCode(ApiFactory factory, string email = "owner@example.com") { var client = factory.CreateClient(); await client.PostAsJsonAsync("/api/auth/register", new { email, password = "Passw0rd!" }); await client.PostAsJsonAsync("/api/auth/login", new { email, password = "Passw0rd!" }); var codeRes = await client.PostAsJsonAsync("/api/pair-code", new { name = "kitchen" }); var body = await codeRes.Content.ReadFromJsonAsync>(); return (client, body!["code"].ToString()!); } [Fact] public async Task User_sees_only_their_own_devices() { using var factory = new ApiFactory(); var (alice, codeA) = await SetupWithPairCode(factory, "alice@example.com"); await factory.CreateClient().PostAsJsonAsync("/api/pair", new { code = codeA, hostname = "rpi", client_version = "0.1" }); var (bob, codeB) = await SetupWithPairCode(factory, "bob@example.com"); await factory.CreateClient().PostAsJsonAsync("/api/pair", new { code = codeB, hostname = "rpi", client_version = "0.1" }); var aliceList = await alice.GetStringAsync("/api/devices"); var bobList = await bob.GetStringAsync("/api/devices"); aliceList.Should().Contain("kitchen"); bobList.Should().Contain("kitchen"); aliceList.Should().NotBe(bobList); } [Fact] public async Task Rename_device_updates_name() { using var factory = new ApiFactory(); var (client, code) = await SetupWithPairCode(factory); await factory.CreateClient().PostAsJsonAsync("/api/pair", new { code, hostname = "rpi", client_version = "0.1" }); var listJson = await client.GetFromJsonAsync>>("/api/devices"); var id = listJson![0]["id"].ToString(); var patchRes = await client.PatchAsJsonAsync($"/api/devices/{id}", new { name = "living-room" }); patchRes.StatusCode.Should().Be(HttpStatusCode.OK); var after = await client.GetStringAsync($"/api/devices/{id}"); after.Should().Contain("living-room"); } [Fact] public async Task Revoke_device_sets_is_revoked_true() { using var factory = new ApiFactory(); var (client, code) = await SetupWithPairCode(factory); await factory.CreateClient().PostAsJsonAsync("/api/pair", new { code, hostname = "rpi", client_version = "0.1" }); var listJson = await client.GetFromJsonAsync>>("/api/devices"); var id = listJson![0]["id"].ToString(); var del = await client.DeleteAsync($"/api/devices/{id}"); del.StatusCode.Should().Be(HttpStatusCode.OK); var after = await client.GetStringAsync($"/api/devices/{id}"); after.Should().Contain("\"isRevoked\":true"); } }