Skip to content

fix(#10132): update how api handles form updates on change#10171

Closed
nKataraia wants to merge 17 commits intomedic:masterfrom
d-tree-org:10132-api-form-update-changes
Closed

fix(#10132): update how api handles form updates on change#10171
nKataraia wants to merge 17 commits intomedic:masterfrom
d-tree-org:10132-api-form-update-changes

Conversation

@nKataraia
Copy link
Contributor

closes #10132

@nKataraia nKataraia marked this pull request as draft July 22, 2025 08:46
@jkuester
Copy link
Contributor

@dianabarsan Do you have bandwidth to review this PR (you logged the original issue)? If not, I can have a look. 👍

@dianabarsan dianabarsan self-requested a review July 23, 2025 05:29
Copy link
Member

@dianabarsan dianabarsan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice! One request below and please add unit test coverage for this!

@nKataraia nKataraia marked this pull request as ready for review July 30, 2025 13:06
@nKataraia nKataraia requested a review from dianabarsan August 1, 2025 11:03
});
});
const updateAttachments = async (doc) => {
let generated = null;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need to define this variable here, as it's not reused outside of the inner block.

Comment on lines 352 to 354
'xform.xml': { data: Buffer.from(formXml) },
'form.html': { data: Buffer.from(currentForm) },
'model.xml': { data: Buffer.from(currentModel) }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above, the get will only return attachment stubs, not full contents.

const updateAttachment = (doc, updated, name, type) => {
const attachmentData = doc._attachments &&
const updateAttachment = (doc, update, name, type) => {
const attachmentData = doc &&
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function will end up comparing new attachment contents with the existent ones. The problem now is that you're not reading all attachments, because you've changed the get command, and you're only reading the main xml attachment. This means that you never have the data of the model.xml or the form.html attachments, so the app will always think they need to updated, and you end up in an infinite loop. you will need to read the contents of those two attachments too to compare.

@nKataraia nKataraia requested a review from dianabarsan August 11, 2025 16:29
Copy link
Member

@dianabarsan dianabarsan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Great improvements!
I did find one issue which I've detailed in the comments.

const newForm = '<html><title>Hello</title></html>';
const newModel = '<instance><multimedia/></instance>';

sinon.stub(db.medic, 'getAttachment').resolves({ _attachments: {}});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How would getAttachment return a an empty list of attachments?

sinon.stub(db.medic, 'put');

await service.update('form:exists');
expect(db.medic.put.callCount).to.equal(1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test title says that the form should not be updated if the attachment is not xml, but then this assertion contradicts the test name, with the form actually getting updated.
I'm confused.

if (enketoForm) {
const name = formsService.getXFormAttachmentName(doc);
const rawXML = await db.medic.getAttachment(doc._id, name, { rev: doc._rev });
const form = await db.medic.getAttachment(doc._id, 'form.html', { rev: doc._rev });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's possible that any of these two calls fail with a 404 if the form has just been uploaded. This is causing a lot of e2e test failures now.
You will need to wrap this in a try-catch and always create these attachments if they don't yet exist.

@nKataraia nKataraia requested a review from dianabarsan August 12, 2025 09:28
const getAttachment = async (doc, name) => {
try {
return await db.medic.getAttachment(doc._id, name, { rev: doc._rev });
} catch (error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we shouldn't catch all errors, just 404s, and throw all others.

@nKataraia nKataraia changed the title fix(#10132): Update how API handles form updates on change fix(#10132): update how api handles form updates on change Aug 13, 2025
Copy link
Member

@dianabarsan dianabarsan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for all the changes! Awesome work!
I believe this is done and we can proceed to acceptance test this along with the changes to cht-conf to support uploading large attachments.
The focus of this testing is:

  • forms with large attachments get uploaded
  • the model.xml and form.html do not get updated when subsequent attachments are uploaded

},
_rev: '1-rev'
});
// sinon.stub(db.medic, 'getAttachment').resolves(Buffer.from(formXml));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this commented code.

expect(db.medic.getAttachment.callCount).to.equal(3);
expect(service.generate.callCount).to.equal(0);
expect(db.medic.put.callCount).to.equal(0);
// expectAttachments(db.medic.put.args[0][0], newForm, newModel);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this commented code.

@github-actions
Copy link

This PR is now marked "stale" after 30 days without activity. It will be closed automatically in 10 days unless you add a comment, push new changes or remove the "stale" label.

Co-authored-by: Diana Barsan <35681649+dianabarsan@users.noreply.github.com>
@dianabarsan
Copy link
Member

closing in favor of #10248

@dianabarsan dianabarsan closed this Nov 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Update how API handles form updates on change

3 participants