Implement nested question remediation and review content

This commit is contained in:
hz
2026-07-16 21:46:56 -05:00
parent 0f5a1122d4
commit c8bfc26645
14 changed files with 1339 additions and 245 deletions
+56
View File
@@ -30,6 +30,9 @@ public sealed class ChoicePoolTests
Assert.Equal(9, response.Choices.Count);
Assert.Single(response.References);
Assert.Equal("https://example.org/guideline", response.References[0].Url);
Assert.Equal("Key teaching point", response.KeyTakeaway);
Assert.Equal("Exam pearl", response.UsmlePearl);
Assert.Single(response.ReviewFollowups);
}
[Fact]
@@ -54,6 +57,40 @@ public sealed class ChoicePoolTests
Assert.Contains("every incorrect choice", QuestionValidator.Validate(request));
}
[Fact]
public void OptionalReviewFollowupsRequireValidAuthoredContent()
{
var request = BuildRequest(5);
Assert.Null(QuestionValidator.Validate(request));
request.ReviewFollowups[0].CorrectChoiceId = "missing";
Assert.Contains("reviewFollowups correctChoiceId", QuestionValidator.Validate(request));
request = BuildRequest(5);
request.ReviewFollowups[0].TeachingPoint = "";
Assert.Contains("reviewFollowups teachingPoint", QuestionValidator.Validate(request));
}
[Fact]
public void LegacyQuestionWithoutReviewContentRemainsValid()
{
var request = BuildRequest(5);
request.KeyTakeaway = "";
request.UsmlePearl = "";
request.ReviewFollowups = [];
Assert.Null(QuestionValidator.Validate(request));
}
[Fact]
public void ActiveSimulationQuestionContractDoesNotExposeReviewContent()
{
Assert.Null(typeof(ExamSimulationQuestionResponse).GetProperty(nameof(QuestionResponse.Explanation)));
Assert.Null(typeof(ExamSimulationQuestionResponse).GetProperty(nameof(QuestionResponse.KeyTakeaway)));
Assert.Null(typeof(ExamSimulationQuestionResponse).GetProperty(nameof(QuestionResponse.UsmlePearl)));
Assert.Null(typeof(ExamSimulationQuestionResponse).GetProperty(nameof(QuestionResponse.ReviewFollowups)));
}
[Fact]
public void PublishedQuestionRequiresAtLeastFiveUniqueChoices()
{
@@ -121,6 +158,9 @@ public sealed class ChoicePoolTests
Choices = request.Choices,
CorrectChoiceId = request.CorrectChoiceId,
Explanation = request.Explanation,
KeyTakeaway = request.KeyTakeaway,
UsmlePearl = request.UsmlePearl,
ReviewFollowups = request.ReviewFollowups,
ChoiceExplanations = request.ChoiceExplanations,
WrongAnswerFollowups = request.WrongAnswerFollowups,
ChoiceSelectionPercentages = request.ChoiceSelectionPercentages,
@@ -140,6 +180,22 @@ public sealed class ChoicePoolTests
Choices = choices,
CorrectChoiceId = "A",
Explanation = "Explanation",
KeyTakeaway = "Key teaching point",
UsmlePearl = "Exam pearl",
ReviewFollowups =
[
new QuestionReviewFollowup
{
Prompt = "Which statement best reinforces the concept?",
Choices =
[
new QuestionChoice { Id = "A", Text = "Accurate statement" },
new QuestionChoice { Id = "B", Text = "Inaccurate statement" }
],
CorrectChoiceId = "A",
TeachingPoint = "Review teaching point"
}
],
ChoiceExplanations = ids.ToDictionary(id => id, id => id == "A" ? "Correct." : "Incorrect."),
WrongAnswerFollowups = ids.Where(id => id != "A").ToDictionary(
id => id,