From cef4540456d94708eb4703ee541356ad9f0b3f11 Mon Sep 17 00:00:00 2001 From: cesnimda Date: Wed, 11 Nov 2026 18:32:10 +0100 Subject: [PATCH] test(documents): record canonical profile capture interleavings --- .../PACKAGE_PROFILE_CAPTURE.md | 11 +++++++ .../package-profile/SOURCE_RECEIPTS.json | 27 ++++++++++++++++++ .../package-profile/profile-green.trx.gz | Bin 0 -> 4841 bytes .../package-profile/profile-green.txt | 11 +++++++ .../package-profile/profile-red.trx.gz | Bin 0 -> 1650 bytes .../evidence/package-profile/profile-red.txt | 20 +++++++++++++ 6 files changed, 69 insertions(+) create mode 100644 docs/cv-integration-qa/PACKAGE_PROFILE_CAPTURE.md create mode 100644 docs/cv-integration-qa/evidence/package-profile/SOURCE_RECEIPTS.json create mode 100644 docs/cv-integration-qa/evidence/package-profile/profile-green.trx.gz create mode 100644 docs/cv-integration-qa/evidence/package-profile/profile-green.txt create mode 100644 docs/cv-integration-qa/evidence/package-profile/profile-red.trx.gz create mode 100644 docs/cv-integration-qa/evidence/package-profile/profile-red.txt diff --git a/docs/cv-integration-qa/PACKAGE_PROFILE_CAPTURE.md b/docs/cv-integration-qa/PACKAGE_PROFILE_CAPTURE.md new file mode 100644 index 00000000..16c8575b --- /dev/null +++ b/docs/cv-integration-qa/PACKAGE_PROFILE_CAPTURE.md @@ -0,0 +1,11 @@ +# Canonical profile binding during submitted CV capture + +Follow-up to PACKAGE_REVISION_CAPTURE.md. The CV variant guard alone did not bind the canonical profile metadata to the profile used by rendering. A deterministic test used the real CareerProfileService save and CvVariantService render to change the profile during capture; the resulting HTML contained the new name while capture could still publish the previously selected projection. + +Capture now rechecks the owner's canonical profile revision/projection after rendering and rejects a changed, created or removed row through the existing revision_conflict path. A genuinely absent legacy profile remains capturable. Canonical save/render ownership, null-as-inherit selections, renderer code/styles and historical packages are unchanged. No new profile store, schema, API field or migration. + +RED:one focused test failed with no conflict. GREEN:26 targeted cases passed/no skips across package/controller/export-revision/native SQLite suites;22 overlap the preceding run. Four added cases cover real profile save during render, creation, removal and unchanged absence. Logs and raw/gzip TRX/source receipts are in evidence/package-profile. Build/temp/results used E; no live DB/models/providers, physical PDF or production services were used. + +This guards the canonical row/projection used by ordinary writers. It is not proof of a transactionally atomic snapshot across every source, arbitrary direct database mutations, legacy user-only fallback writes, or filesystem races. AttachmentStorage destination ownership remains a separate source-backed/unreproduced concern. Native/MariaDB/browser, full integrated security/recovery and final milestone gates remain open. + +Rollback reverts only this follow-up source change and reruns affected package tests; no data repair required. Existing accepted PDF metrics remain historical and source-bound, not newly executed. diff --git a/docs/cv-integration-qa/evidence/package-profile/SOURCE_RECEIPTS.json b/docs/cv-integration-qa/evidence/package-profile/SOURCE_RECEIPTS.json new file mode 100644 index 00000000..c022d08b --- /dev/null +++ b/docs/cv-integration-qa/evidence/package-profile/SOURCE_RECEIPTS.json @@ -0,0 +1,27 @@ +{ + "sourceCommit": "b9c0b6186871d31a494c05cabc5e6361dccb851f", + "sourcesLfSha256": { + "JobTrackerApi/Services/SubmittedApplicationPackageService.cs": "75a4aabb02d21cc860cfa05006defaddeb8ef5918eb973e624690b0d8da42e70", + "JobTrackerApi.Tests/SubmittedApplicationPackageTests.cs": "9f737f14852a1bb93e36913407aaed9d2939207a4f0806d1086d8cc456350af3", + "JobTrackerApi/Services/CareerProfileService.cs": "dc91aca78069feff24eecf796c1fac459af9f5564e61d7918822f45b81807fef", + "JobTrackerApi/Services/CvVariantService.cs": "da85153ff2199a4410df91807c6073aa19736676332266a227149d6d089ea841" + }, + "receipts": [ + { + "name": "profile-red", + "total": 1, + "passed": 0, + "failed": 1, + "rawSha256": "b63f144ec7c99a3eb40841ac7e5cc59ae84d71017e388afccb4cf441e3a9fcba", + "gzipSha256": "482b6a8b235ce988134cbaebe52de232b3c469dcd02f535156a05a3bf5a2fa82" + }, + { + "name": "profile-green", + "total": 26, + "passed": 26, + "failed": 0, + "rawSha256": "7eb74ef3e0aca92ae83dd673026cdb1bfc45da3b976732ad6f043ae83f9b6ea9", + "gzipSha256": "eb5251eda46e66feb96d69711757c19aea2bef1da70c9e404321b8827910301a" + } + ] +} diff --git a/docs/cv-integration-qa/evidence/package-profile/profile-green.trx.gz b/docs/cv-integration-qa/evidence/package-profile/profile-green.trx.gz new file mode 100644 index 0000000000000000000000000000000000000000..2227c969df2cc811727cd3e227729922eccc1e21 GIT binary patch literal 4841 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 E:\Storage\Projects\Active\temp docs\jobjakt-local-build\frozen-document-integrity\artifacts\bin\JobTrackerApi\debug\JobTrackerApi.dll + PdfBrowserStub -> E:\Storage\Projects\Active\temp docs\jobjakt-local-build\frozen-document-integrity\artifacts\bin\PdfBrowserStub\debug\PdfBrowserStub.dll + JobTrackerApi.Tests -> E:\Storage\Projects\Active\temp docs\jobjakt-local-build\frozen-document-integrity\artifacts\bin\JobTrackerApi.Tests\debug\JobTrackerApi.Tests.dll +Test run for E:\Storage\Projects\Active\temp docs\jobjakt-local-build\frozen-document-integrity\artifacts\bin\JobTrackerApi.Tests\debug\JobTrackerApi.Tests.dll (.NETCoreApp,Version=v9.0) +VSTest version 17.14.1 (x64) + +Starting test execution, please wait... +A total of 1 test files matched the specified pattern. +Results File: E:\Storage\Projects\Active\temp docs\jobjakt-local-build\frozen-document-integrity\profile-green\profile-green.trx + +Passed! - Failed: 0, Passed: 26, Skipped: 0, Total: 26, Duration: 4 s - JobTrackerApi.Tests.dll (net9.0) diff --git a/docs/cv-integration-qa/evidence/package-profile/profile-red.trx.gz b/docs/cv-integration-qa/evidence/package-profile/profile-red.trx.gz new file mode 100644 index 0000000000000000000000000000000000000000..7ea59748621f5f10e570782bbd522e1490b178d5 GIT binary patch literal 1650 zcmV-&295b2iwFP!000023hh{1Z`(!|elM{9VW0(y1TC-PRkhtJwgP04q(P+Qr3!@M z%%RPM08|)DG;>i2K^=2+&@Oukw2f^*K(I~4lmHLpRXNS{p8tt^^ zMO~I|l%D@)KCZBYZF9CF&0deVi$;|zG7WfpaVzzSF#SXqoqTut3P zW&!uI9tBi(22ClhDyX$Ve7AZngdQWc86&mX8M*P2jUR7Jqz1E`eY^Ut*PzfUHQx26 zE_9bO-8O+Ou-2ge42|Y=I;D_uYf9tP3NoKrDT|oJ!;CY=<2cRnDvhU&bQDmQyFp^{ zIG`5uBhLz>EV9CB>QM+`8dKIwzwGe&m&jI){NU#_lxr<1s_fv^!-3 z-w#JwgU;%zL1AyoI7@kIah_oT=QOZr8gq-MQOH=%A|7NDB3g|Op!idYPV!#C^P&$( z!V)}}2AE{bvjRWJtTc%dD~zengCz8*hbJVI=;%in^5U$Jz_gH8_YD7#N0>>!wi=PV zUgOR}N+F-sx!Bvp?H8aF2J~dEu$O3ibs@#2di0nWA6f}B@={vR7HS_nw-worUR>?@vgDKa@ekoyIKOMbuPufp|-eS zt!WunQENDt2+JCsAiDQreZZmh|8$6{Sy|LTywLAM@i#b!zzKVBEXyK`niG+me!)I; z>VcpM6=@`VEJUkFDSA}|rH`DwyxXfH=kqc;a&8pck#n<)550fC({}^v49s9N_kGs> zhne+l^kjwo2elthV74Bf*LdbV*1cL&X1di{L)8!rq*}ih*?amyTL#P0%G#pjcLW+c zcac-0C@X4nc8EGfe{~mX4q1DC=sz|u%YK^QYt-$cwHSwLcldr&)!7|4D8B%GAviG! z{e&unW-(hY2WVc6(9FLkG>597hvra{bkJZh8yux(fc4|FXA?pqCET`{Y0g_U@Y5Qk z@6>?P3)x=N;2bWgQeRFCMjHFobJ6*%#`c)irv=r83a5}P;JU)bt*ZwTr7vV+4;%jb zG;!bV&T6CTh8t#Mz#Q8?wMvn>Or``_q3Xot-|8$HhM)*T2lz~JweP(QyMfYVO%e+ z4Zt-o6l$tF`qOP(QdxIzKW E:\Storage\Projects\Active\temp docs\jobjakt-local-build\frozen-document-integrity\artifacts\bin\JobTrackerApi\debug\JobTrackerApi.dll + PdfBrowserStub -> E:\Storage\Projects\Active\temp docs\jobjakt-local-build\frozen-document-integrity\artifacts\bin\PdfBrowserStub\debug\PdfBrowserStub.dll + JobTrackerApi.Tests -> E:\Storage\Projects\Active\temp docs\jobjakt-local-build\frozen-document-integrity\artifacts\bin\JobTrackerApi.Tests\debug\JobTrackerApi.Tests.dll +Test run for E:\Storage\Projects\Active\temp docs\jobjakt-local-build\frozen-document-integrity\artifacts\bin\JobTrackerApi.Tests\debug\JobTrackerApi.Tests.dll (.NETCoreApp,Version=v9.0) +VSTest version 17.14.1 (x64) + +Starting test execution, please wait... +A total of 1 test files matched the specified pattern. +[xUnit.net 00:00:03.18] JobTrackerApi.Tests.SubmittedApplicationPackageTests.Profile_changed_during_render_cannot_publish_old_profile_metadata_with_new_html [FAIL] + Failed JobTrackerApi.Tests.SubmittedApplicationPackageTests.Profile_changed_during_render_cannot_publish_old_profile_metadata_with_new_html [2 s] + Error Message: + Assert.Throws() Failure: No exception was thrown +Expected: typeof(Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException) + Stack Trace: + at JobTrackerApi.Tests.SubmittedApplicationPackageTests.Profile_changed_during_render_cannot_publish_old_profile_metadata_with_new_html() in C:\Users\Connor\.codex\worktrees\frozen-document-integrity\Job tracker\JobTrackerApi.Tests\SubmittedApplicationPackageTests.cs:line 152 + at JobTrackerApi.Tests.SubmittedApplicationPackageTests.Profile_changed_during_render_cannot_publish_old_profile_metadata_with_new_html() in C:\Users\Connor\.codex\worktrees\frozen-document-integrity\Job tracker\JobTrackerApi.Tests\SubmittedApplicationPackageTests.cs:line 155 +--- End of stack trace from previous location --- +Results File: E:\Storage\Projects\Active\temp docs\jobjakt-local-build\frozen-document-integrity\profile-red\profile-red.trx + +Failed! - Failed: 1, Passed: 0, Skipped: 0, Total: 1, Duration: 2 s - JobTrackerApi.Tests.dll (net9.0)