diff --git a/lib/model/frames/form.js b/lib/model/frames/form.js index a7aa285ca..a2b5bcb64 100644 --- a/lib/model/frames/form.js +++ b/lib/model/frames/form.js @@ -26,7 +26,7 @@ // API. This is partly for legacy reasons: Forms and FormsDef did not used to const { Frame, table, readable, writable, into, embedded, fieldTypes } = require('../frame'); -const { injectPublicKey, addVersionSuffix } = require('../../data/schema'); +const { injectPublicKey, addVersionSuffix, updateEntityForm } = require('../../data/schema'); const { Key } = require('./key'); const { md5sum, shasum, sha256sum, digestWith, generateVersionSuffix } = require('../../util/crypto'); const { resolve } = require('../../util/promise'); @@ -76,6 +76,10 @@ class Form extends Frame.define( .then((partial) => partial.with({ key: Option.of(key) })); } + withUpgradeEntityVersion() { + return updateEntityForm(this.xml, '2023.1.0', '2024.1.0', '_upgrade').then(Form.fromXml); + } + _enketoIdForApi() { if (this.def == null) return null; if (this.def.id === this.draftDefId) return this.def.enketoId; diff --git a/lib/worker/form.js b/lib/worker/form.js index c08372f7c..6afc23d27 100644 --- a/lib/worker/form.js +++ b/lib/worker/form.js @@ -42,5 +42,12 @@ const create = pushDraftToEnketo; const updateDraftSet = pushDraftToEnketo; const updatePublish = pushFormToEnketo; -module.exports = { create, updateDraftSet, updatePublish }; +const updateEntitiesVersion = async ({ Forms }, event) => { + const { projectId, xmlFormId } = await Forms.getByActeeIdForUpdate(event.acteeId).then(o => o.get()); + const form = await Forms.getByProjectAndXmlFormId(projectId, xmlFormId, true).then(o => o.get()); + const partial = await form.withUpgradeEntityVersion(); + return Forms.createVersion(partial, form, true, true); +}; + +module.exports = { create, updateDraftSet, updatePublish, updateEntitiesVersion }; diff --git a/lib/worker/jobs.js b/lib/worker/jobs.js index 2efbf5536..906ad6d91 100644 --- a/lib/worker/jobs.js +++ b/lib/worker/jobs.js @@ -27,6 +27,8 @@ const jobs = { 'upgrade.process.form.draft': [ require('./form').updateDraftSet ], 'upgrade.process.form': [ require('./form').updatePublish ], + 'upgrade.process.form.entities_version': [ require('./form').updateEntitiesVersion ], + 'dataset.update': [ require('./dataset').createEntitiesFromPendingSubmissions ] }; diff --git a/test/integration/other/form-entities-version.js b/test/integration/other/form-entities-version.js new file mode 100644 index 000000000..292d1a9b6 --- /dev/null +++ b/test/integration/other/form-entities-version.js @@ -0,0 +1,55 @@ +const appRoot = require('app-root-path'); +const { testService } = require('../setup'); +const testData = require('../../data/xml'); + +const { exhaust } = require(appRoot + '/lib/worker/worker'); + +describe('Update / migrate entities-version within form', () => { + it('should upgrade a 2023.1.0 update form', testService(async (service, container) => { + const { Forms, Audits } = container; + const asAlice = await service.login('alice'); + + // Publish a form that will set up the dataset with properties + await asAlice.post('/v1/projects/1/forms?publish=true') + .send(testData.forms.updateEntity) + .set('Content-Type', 'application/xml') + .expect(200); + + const { acteeId } = await Forms.getByProjectAndXmlFormId(1, 'updateEntity').then(o => o.get()); + await Audits.log(null, 'upgrade.process.form.entities_version', { acteeId }); + + // Run form upgrade + await exhaust(container); + + await asAlice.get('/v1/projects/1/forms/updateEntity/versions') + .then(({ body }) => { + body.length.should.equal(2); + body[0].version.should.equal('1.0_upgrade'); + }); + + await asAlice.get('/v1/projects/1/forms/updateEntity.xml') + .then(({ text }) => { + text.should.equal(` + + + + + + + + + + + + + + + + + + +`); + }); + })); +});