fix(cv-qa): preserve reviewed mapping order and verify merge journeys
This commit is contained in:
@@ -15,6 +15,36 @@ namespace JobTrackerApi.Tests;
|
||||
|
||||
public class CvImportMappingControllerTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task Mapping_order_is_part_of_replay_identity_while_exact_legacy_receipts_still_work()
|
||||
{
|
||||
await using var db = TestHostFactory.CreateInMemoryDb("user-1");
|
||||
var user = new ApplicationUser { Id = "user-1", UserName = "mapping-order" };
|
||||
db.Users.Add(user);
|
||||
var blocks = new[] { new CvImportBlock("b1", "Engineer First", "paragraph", 1), new CvImportBlock("b2", "Lead Second", "paragraph", 1) };
|
||||
var document = new CvImportDocument("Engineer First Lead Second", false, "application/pdf", 1, 26, "synthetic.pdf", blocks, Array.Empty<string>(), "synthetic");
|
||||
var run = new CvExtractionRun { OwnerUserId = user.Id, ParserVersion = ProfileCvController.DocumentParserVersion, Status = "pending_review", DocumentJson = JsonSerializer.Serialize(document), StructuredProfileJson = StructuredCvProfileJson.SerializePersisted(new()) };
|
||||
db.CvExtractionRuns.Add(run);
|
||||
await db.SaveChangesAsync();
|
||||
var users = TestHostFactory.CreateUserManager();
|
||||
users.Setup(u => u.GetUserAsync(It.IsAny<ClaimsPrincipal>())).ReturnsAsync(user);
|
||||
users.Setup(u => u.UpdateAsync(user)).ReturnsAsync(IdentityResult.Success);
|
||||
var controller = new ProfileCvController(users.Object, Mock.Of<ISummarizerService>(), db, null!) { ControllerContext = new() { HttpContext = new DefaultHttpContext() } };
|
||||
var mappings = new[]
|
||||
{
|
||||
new CvImportRecordMapping("z-first", "jobs", null, new[] { new CvImportMappedField("title", "Engineer", "b1"), new CvImportMappedField("company", "First", "b1") }),
|
||||
new CvImportRecordMapping("a-second", "jobs", null, new[] { new CvImportMappedField("title", "Lead", "b2"), new CvImportMappedField("company", "Second", "b2") }),
|
||||
};
|
||||
var request = new ProfileCvController.ApplyReviewedRequest(0, Array.Empty<CvImportDecision>(), mappings);
|
||||
Assert.IsType<OkObjectResult>(await controller.ApplyReviewed(run.Id, request));
|
||||
var receipt = System.Text.Json.Nodes.JsonNode.Parse(run.ReviewJson!)!;
|
||||
receipt["Hash"] = Convert.ToHexString(System.Security.Cryptography.SHA256.HashData(JsonSerializer.SerializeToUtf8Bytes(new { request.ExpectedVersion, Decisions = request.Decisions!.OrderBy(d => d.Id, StringComparer.Ordinal), Mappings = mappings.OrderBy(m => m.ClientId, StringComparer.Ordinal) })));
|
||||
run.ReviewJson = receipt.ToJsonString();
|
||||
await db.SaveChangesAsync();
|
||||
Assert.IsType<OkObjectResult>(await controller.ApplyReviewed(run.Id, request));
|
||||
Assert.IsType<ConflictObjectResult>(await controller.ApplyReviewed(run.Id, request with { Mappings = mappings.Reverse().ToArray() }));
|
||||
Assert.Single(await db.CareerProfileVersions.ToListAsync());
|
||||
}
|
||||
[Fact]
|
||||
public async Task Mapping_only_apply_is_revision_bound_audited_and_idempotent()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user