using System.Net.Http.Json; using System.Text.Json; using FluentAssertions; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; [Collection("Integration")] public class PhiEncryptionTests { private readonly ApiFixture _fixture; public PhiEncryptionTests(ApiFixture fixture) => _fixture = fixture; [Fact] public async Task PatientPhi_StoredEncrypted_ReturnsDecryptedViaApi() { var client = _fixture.CreateClient(); client.ClearAuth(); client.AsAdmin(); var registerResp = await client.PostAsJsonAsync("/api/v1/patients", new { firstName = "Encrypted", lastName = "Patient", dateOfBirth = "1990-05-20", gender = "female" }); registerResp.EnsureSuccessStatusCode(); var body = await registerResp.Content.ReadFromJsonAsync(); var patientId = body.GetProperty("data").GetProperty("id").GetGuid(); // Raw DB check — first_name should NOT equal plaintext using var scope = _fixture.Services.CreateScope(); var db = scope.ServiceProvider.GetRequiredService(); var raw = await db.Database .SqlQuery($"SELECT first_name AS \"Value\" FROM patients WHERE id = {patientId}") .FirstAsync(); raw.Should().NotBe("Encrypted"); // API returns decrypted var getResp = await client.GetAsync($"/api/v1/patients/{patientId}"); getResp.EnsureSuccessStatusCode(); var patient = await getResp.Content.ReadFromJsonAsync(); patient.GetProperty("data").GetProperty("firstName").GetString() .Should().Be("Encrypted"); } [Fact] public async Task PatientView_WritesPhiAccessLog() { var client = _fixture.CreateClient(); client.ClearAuth(); var nurseId = Guid.Parse("11111111-1111-1111-1111-111111111111"); client.AsNurse(nurseId); await client.PostAsJsonAsync("/api/v1/patients", new { firstName = "PhiLog", lastName = "TestPatient", dateOfBirth = "1975-03-15", gender = "male" }); var listResp = await client.GetAsync("/api/v1/patients?pageSize=1"); listResp.EnsureSuccessStatusCode(); var list = await listResp.Content.ReadFromJsonAsync(); var patientId = list.GetProperty("data").GetProperty("items")[0].GetProperty("id").GetGuid(); await client.GetAsync($"/api/v1/patients/{patientId}"); client.ClearAuth(); client.AsAdmin(); var logsResp = await client.GetAsync($"/api/v1/phi-access-logs?patientId={patientId}"); logsResp.EnsureSuccessStatusCode(); var logs = await logsResp.Content.ReadFromJsonAsync(); logs.GetProperty("data").GetProperty("totalCount").GetInt32() .Should().BeGreaterThan(0); } [Fact] public async Task NameSearch_FindsEncryptedPatient() { var client = _fixture.CreateClient(); client.ClearAuth(); client.AsAdmin(); await client.PostAsJsonAsync("/api/v1/patients", new { firstName = "Searchable", lastName = "UniqueName", dateOfBirth = "1985-01-01", gender = "male" }); var resp = await client.GetAsync("/api/v1/patients?q=Searchable+UniqueName"); resp.EnsureSuccessStatusCode(); var body = await resp.Content.ReadFromJsonAsync(); body.GetProperty("data").GetProperty("totalCount").GetInt32() .Should().BeGreaterThan(0); } }