Add interactive CCS case practice
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
using QuestionsApi.Models;
|
||||
using QuestionsApi.Services;
|
||||
using System.Text.Json;
|
||||
using Xunit;
|
||||
|
||||
namespace QuestionsApi.Tests;
|
||||
|
||||
public sealed class CcsCaseTests
|
||||
{
|
||||
[Fact]
|
||||
public void DkaImportArtifactMatchesTheCaseSchema()
|
||||
{
|
||||
var path = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "../../../../../content/ccs/dka-emergency-001.json"));
|
||||
var request = JsonSerializer.Deserialize<CcsImportRequest>(File.ReadAllText(path), new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
|
||||
|
||||
Assert.NotNull(request);
|
||||
Assert.Empty(CcsCaseValidator.ValidateImport(request!, new HashSet<string>()));
|
||||
Assert.True(request!.Cases.Single().ScoringCriteria.Count >= 12);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PublishedCaseRequiresReferencesAndKnownOrders()
|
||||
{
|
||||
var request = ValidImport();
|
||||
request.Cases[0].References = [];
|
||||
request.Cases[0].OrderResponses.Add(new CcsCaseOrderDefinition { OrderCode = "unknown" });
|
||||
|
||||
var errors = CcsCaseValidator.ValidateImport(request, new HashSet<string>());
|
||||
|
||||
Assert.Contains(errors, value => value.Contains("reference", StringComparison.OrdinalIgnoreCase));
|
||||
Assert.Contains(errors, value => value.Contains("unknown order code unknown"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ScoringCreditsTimelySequencedCareAndPenalizesHarm()
|
||||
{
|
||||
var definition = ValidImport().Cases[0];
|
||||
definition.ScoringCriteria =
|
||||
[
|
||||
new() { Id = "lab", ActionType = "order", TargetCode = "bmp", Points = 5, LatestMinute = 10, Rationale = "Check potassium." },
|
||||
new() { Id = "insulin", ActionType = "order", TargetCode = "insulin", AfterTargetCode = "bmp", Points = 10, Rationale = "Start after potassium assessment." },
|
||||
new() { Id = "bicarb", ActionType = "order", TargetCode = "bicarb", Points = -4, Rationale = "Avoid routine bicarbonate." }
|
||||
];
|
||||
var attempt = new CcsAttempt { Actions =
|
||||
[
|
||||
new() { Type = "order", Code = "bmp", SimulatedMinute = 2 },
|
||||
new() { Type = "order", Code = "insulin", SimulatedMinute = 4 },
|
||||
new() { Type = "order", Code = "bicarb", SimulatedMinute = 5 }
|
||||
]};
|
||||
|
||||
var score = CcsStore.CalculateScore(attempt, definition);
|
||||
|
||||
Assert.Equal(11, score.EarnedPoints);
|
||||
Assert.Equal(15, score.PossiblePoints);
|
||||
Assert.Equal(73.3, score.Percent);
|
||||
Assert.Contains(score.Criteria, value => value.CriterionId == "bicarb" && value.Status == "harmful");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ValidVersionedCasePassesValidation()
|
||||
{
|
||||
Assert.Empty(CcsCaseValidator.ValidateImport(ValidImport(), new HashSet<string>()));
|
||||
}
|
||||
|
||||
private static CcsImportRequest ValidImport() => new()
|
||||
{
|
||||
Orders =
|
||||
[
|
||||
new() { Code = "bmp", CanonicalName = "Basic metabolic panel", Category = "laboratory" },
|
||||
new() { Code = "insulin", CanonicalName = "Insulin infusion", Category = "medication" },
|
||||
new() { Code = "bicarb", CanonicalName = "Sodium bicarbonate", Category = "medication" }
|
||||
],
|
||||
Cases =
|
||||
[
|
||||
new()
|
||||
{
|
||||
ExternalId = "ccs-test-dka-001", Title = "Diabetic ketoacidosis", System = "Endocrine System",
|
||||
PresentingLocation = "emergency_department", AllowedLocations = ["emergency_department", "icu"],
|
||||
IsPublished = true, RealTimeMinutes = 20, Difficulty = 2,
|
||||
InitialChart = new() { PatientSummary = "Adult with diabetes", ReasonForEncounter = "Vomiting" },
|
||||
OrderResponses = [new() { OrderCode = "bmp", Result = "Potassium 4.9 mEq/L" }],
|
||||
ScoringCriteria = [new() { Id = "lab", ActionType = "order", TargetCode = "bmp", Points = 5 }],
|
||||
References = [new() { Title = "Consensus report", Publisher = "Example Society", Url = "https://example.org/consensus", Supports = "Case management and scoring", AccessedOn = "2026-07-15", Reviewer = "Question bank editorial review" }]
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user