using System.Net; using System.Net.Http.Json; using System.Text.Json; using FluentAssertions; using Microsoft.Extensions.DependencyInjection; [Collection("Integration")] public class OrderLifecycleTests : IAsyncLifetime { private readonly ApiFixture _fixture; private readonly HttpClient _client; private Guid _encounterId; public OrderLifecycleTests(ApiFixture fixture) { _fixture = fixture; _client = fixture.CreateClient(); } public async Task InitializeAsync() => await ResetAndSeedAsync(); public Task DisposeAsync() => Task.CompletedTask; private async Task ResetAndSeedAsync() { using var scope = _fixture.Services.CreateScope(); var db = scope.ServiceProvider.GetRequiredService(); await DbResetHelper.ResetAsync(db); var patient = new Patient { Id = Guid.NewGuid(), Mrn = "MRN-ORD-001", FirstName = "Order", LastName = "Test", DateOfBirth = new DateOnly(1988, 2, 10), Gender = "F", CreatedAt = DateTimeOffset.UtcNow }; var encounter = new Encounter { Id = Guid.NewGuid(), PatientId = patient.Id, EncounterType = EncounterType.Inpatient, Status = EncounterStatus.Active, Department = Department.GeneralMedicine, AttendingPhysician = "Dr. Order", AdmittedAt = DateTimeOffset.UtcNow, CreatedAt = DateTimeOffset.UtcNow }; db.Patients.Add(patient); db.Encounters.Add(encounter); await db.SaveChangesAsync(); _encounterId = encounter.Id; } [Fact] public async Task CreateOrder_Returns201() { await ResetAndSeedAsync(); var resp = await _client.PostAsJsonAsync( $"/api/v1/encounters/{_encounterId}/orders", new CreateOrderRequest(OrderType.Lab, "CBC with differential", "Dr. Test")); resp.StatusCode.Should().Be(HttpStatusCode.Created); var body = await resp.Content.ReadFromJsonAsync(); body!.RootElement.GetProperty("data").GetProperty("status").GetString() .Should().Be("Pending"); } [Fact] public async Task ListOrders_ReturnsPaginated() { await ResetAndSeedAsync(); await _client.PostAsJsonAsync( $"/api/v1/encounters/{_encounterId}/orders", new CreateOrderRequest(OrderType.Lab, "BMP", "Dr. A")); await _client.PostAsJsonAsync( $"/api/v1/encounters/{_encounterId}/orders", new CreateOrderRequest(OrderType.Imaging, "Chest X-ray", "Dr. B")); var resp = await _client.GetAsync($"/api/v1/encounters/{_encounterId}/orders"); resp.StatusCode.Should().Be(HttpStatusCode.OK); var body = await resp.Content.ReadFromJsonAsync(); body!.RootElement.GetProperty("data").GetProperty("totalCount").GetInt32() .Should().Be(2); } [Fact] public async Task RecordResult_TransitionsToResulted() { await ResetAndSeedAsync(); var createResp = await _client.PostAsJsonAsync( $"/api/v1/encounters/{_encounterId}/orders", new CreateOrderRequest(OrderType.Lab, "Potassium", "Dr. Test")); var createBody = await createResp.Content.ReadFromJsonAsync(); var orderId = createBody!.RootElement.GetProperty("data").GetProperty("id").GetGuid(); var resultResp = await _client.PatchAsJsonAsync( $"/api/v1/orders/{orderId}/result", new RecordOrderResultRequest("Potassium 4.2 mEq/L — within normal limits")); resultResp.StatusCode.Should().Be(HttpStatusCode.OK); var body = await resultResp.Content.ReadFromJsonAsync(); body!.RootElement.GetProperty("data").GetProperty("status").GetString() .Should().Be("Resulted"); body.RootElement.GetProperty("data").GetProperty("resultSummary").GetString() .Should().Contain("4.2"); } [Fact] public async Task CancelResultedOrder_Returns409() { await ResetAndSeedAsync(); var createResp = await _client.PostAsJsonAsync( $"/api/v1/encounters/{_encounterId}/orders", new CreateOrderRequest(OrderType.Lab, "Glucose", "Dr. Test")); var orderId = (await createResp.Content.ReadFromJsonAsync())! .RootElement.GetProperty("data").GetProperty("id").GetGuid(); await _client.PatchAsJsonAsync( $"/api/v1/orders/{orderId}/result", new RecordOrderResultRequest("Normal")); var resp = await _client.PatchAsJsonAsync( $"/api/v1/orders/{orderId}/status", new TransitionOrderStatusRequest(OrderStatus.Cancelled)); resp.StatusCode.Should().Be(HttpStatusCode.Conflict); } }