feat(#10904): route file attachments to correct sub-docs in report forms#10922
Conversation
|
@YASHSHARMAOFFICIALLY let's use the branch |
8928897 to
bfb5ec2
Compare
|
Done, updated the base branch to |
benkags
left a comment
There was a problem hiding this comment.
Thank you @YASHSHARMAOFFICIALLY. I've left a few review comments.
| private findBinaryNodeByFilename($record, filename: string) { | ||
| let match = null; | ||
| $record | ||
| .find('[type=binary]') |
There was a problem hiding this comment.
You want to ensure the you check for type=file. When testing #10923, I realized Enketo sets type to file; so uploads would fail silently. Did
There was a problem hiding this comment.
Good catch — updated the selector from [type=binary] to [type=file] in 900c9550a. Enketo's Nodeset.setVal rewrites file-widget nodes to type="file" after upload, so this is the correct selector for FileManager files. Inline-binary blobs (draw/signature widgets) still use type="binary" and are handled via the separate xpath-based path.
| const attachLegacyFile = (elem, file, type, alreadyEncoded) => { | ||
| const ownerDoc = resolveOwnerDoc(elem); | ||
| const xpath = Xpath.getElementXPath(elem); | ||
| const formId = ownerDoc === doc ? doc.form : ownerDoc.type; |
There was a problem hiding this comment.
doc.form and doc.type are two different types. And type is not always unique. Let's just use doc.form. What's the rationale for using type here if may ask?
There was a problem hiding this comment.
You're right — switched to doc.form for the xpath root segment in 900c9550a. Using doc.type was incorrect since it's not guaranteed to be unique and serves a different purpose. The xpath-based filename is now always rooted at the main form's internalId regardless of which sub-doc owns the attachment.
| expect(actual.length).to.equal(1); | ||
| expect(AddAttachment.callCount).to.equal(1); | ||
| expect(AddAttachment.args[0][0]._id).to.equal(actual[0]._id); | ||
| }); |
There was a problem hiding this comment.
We should add 2 more unit tests: 1) test repeats 2) test for clean up of attachments removed during edit
There was a problem hiding this comment.
Added both in 5da5cc194:
- Repeats — unit test verifies files inside
db-docblocks nested in repeat sections route to the corresponding sub-docs, with no files landing on the main doc. - Attachment cleanup on edit — unit test verifies that when a file field is cleared during edit, no attachment is created on the sub-doc.
|
@YASHSHARMAOFFICIALLY take a look at YASHSHARMAOFFICIALLY#1 |
|
@YASHSHARMAOFFICIALLY let me know if you are still working on this |
|
@benkags will raised a pr by today night working on these |
|
@YASHSHARMAOFFICIALLY I added the fixes in the linked PR, please take a look, add an e2e test so that it is ready for review. |
…rt forms When a report form contains [db-doc="true"] sub-documents with binary/file fields, attachments are now routed to the owning sub-document instead of always attaching to the main report doc. - Add resolveOwnerDoc() to walk up XML tree to nearest db-doc ancestor - Route FileManager file uploads to correct owner doc - Route inline binary blobs to correct owner doc - Fall back to main report doc when element is not inside a sub-doc
…oc attachments - findFileNodeByFilename now selects [type=file], matching Enketo's runtime XML state - use doc.form for the xpath-rooted filename - additional tests: orphan file fallback, db-doc nested in repeats, and filename shape for sub-doc binaries.
… sub-documents Verifies that when a form has a db-doc sub-document with a file upload field, the uploaded file is attached to the sub-doc and not the main report document.
bfb5ec2 to
cb6c753
Compare
|
@benkags Do check and let me know if any improvment needed further |
…removed during edit Verify that when a file is cleared from a sub-doc during editing, no attachment lands on the sub-doc while the main doc still receives its own file correctly.
|
@benkags @dianabarsan @andrablaj Thank you for the fixes and the review guidance. Addressed the remaining items: Unit tests added:
Both use dedicated XML fixtures to isolate the scenario. The e2e test ( Ready for re-review. |
dianabarsan
left a comment
There was a problem hiding this comment.
Code looks solid, and makes sense on a quick read. Appreciate that.
I need to request that we add an e2e test for this feature, that involves having a form with multiple sub-docs and test that attachments are saved correctly. We should also cover sub-docs in repeats.
Appreciate this contribution!
…-docs with file attachments Cover the two scenarios requested in review: a form with multiple sub-documents each owning separate file attachments, and sub-documents created inside repeat groups with per-instance file routing.
|
@dianabarsan @andrablaj Thank you for the review. I've added the requested e2e coverage in
Happy to contribute more |
|
@dianabarsan please take another look and let us know if there is additional changes needed. Thanks. |
dianabarsan
left a comment
There was a problem hiding this comment.
Thanks for the followup!
Edge case worth covering: if two sub-docs end up with files of the same name (e.g., default-named camera captures, or any form where the user picks files with overlapping names from disk), findFileNodeByFilename returns the first match and both files route to the same sub-doc — the other sub-doc gets no attachment, and the user-file-<name>
FileManager attachment key collides on top of that.
The e2e tests use distinct filenames (icon.png, layers.png, photo-for-upload-form.png), so this isn't exercised. Could you add a case with two sub-docs whose files have the same name and decide what the desired behavior is? At minimum I think we want to detect and warn rather than silently drop one file.
Could we also get an e2e test covering a draw/signature widget inside a db-doc="true" sub-doc? In production the draw widget puts its value in FileManager with a generated filename (drawing-HH_MM_SS.png — webapp/src/js/enketo/widgets/draw.js:674), so it goes through the same findFileNodeByFilename routing the PR
rewires. That path is only tested with upload widgets right now.
Can we also have an e2e test covering binary uploads in subdocs?
While you're there: those generated filenames are second-resolution, so a user signing two sub-doc sections within the same second produces colliding filenames — which is the same routing/collision concern I raised on the upload path, just more likely to hit because the user doesn't choose the filename.
| // actual[0] = main doc, actual[1] = first repeat doc, actual[2] = second repeat doc | ||
| expect(actual.length).to.equal(3); | ||
|
|
||
| const file1Call = AddAttachment.args.find( |
There was a problem hiding this comment.
I think this test asserts that the files were attached to repeat document, but not to which document.
|
Some of the work done here has leaked into #10923 when trying to handle the binary type input - should we track one PR instead? I know you have done a lot of work here already @YASHSHARMAOFFICIALLY but at this point it is hard to separate out the reports logic in #10923's review. I suggest you you target my branch here benkags:10903-sub-contact-routing so that we track all the work you have already done here from there cc @dianabarsan @jkuester. |
The <group> element wrapping the repeat caused Enketo to render it as a separate page. The test never navigated to that page, so the "Repeat photo" labels were not found. Removing the group keeps everything on a single page, matching the other test forms.
|
@dianabarsan @benkags Pushed a fix for the failing e2e test Root cause: The Fix: Removed the |
cc34e08
into
medic:10700-photo-capture-in-sub-contacts-and-reports
|
@YASHSHARMAOFFICIALLY thank you for the changes here! @dianabarsan, sorry for hijacking the PR and merging prematurely! 😬 🥷 I was on a call with @benkags and we were trying to find the most simple way to sync all of this with #10923 and get it shipped. The current plan is that @benkags is going to update his branch with the latest from https://github.com/medic/cht-core/tree/10700-photo-capture-in-sub-contacts-and-reports and then target So, the complete unified changes will be available to review in that PR. 👍 |
…rt forms (medic#10922) Co-authored-by: Bernard K. <kagondubernard81@gmail.com>
…rt forms (medic#10922) Co-authored-by: Bernard K. <kagondubernard81@gmail.com>
…rt forms (medic#10922) Co-authored-by: Bernard K. <kagondubernard81@gmail.com>
Summary
Closes #10904
When a report form contains
[db-doc="true"]sub-documents with binary/file fields, attachments are now routed to the owning sub-document instead of always attaching to the main report doc.Changes
resolveOwnerDoc()— walks up the XML tree from a binary node to find the nearest[db-doc="true"]ancestor, returning the corresponding prepared sub-doc (or the main report doc as fallback)findBinaryNodeByFilename()— locates the[type=binary]XML node matching a FileManager filename so its position in the tree can determine the ownerTest plan
[db-doc="true"]attaches to that sub-doc