Skip to content

Commit

Permalink
Warn about <2024.1 entities spec and update tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ktuite committed Nov 6, 2024
1 parent 59defd9 commit 4014ab6
Show file tree
Hide file tree
Showing 9 changed files with 201 additions and 88 deletions.
10 changes: 9 additions & 1 deletion lib/data/dataset.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@ const getDataset = (xml) =>
else if (!semverSatisfies(version.get(), '2022.1.0 - 2024.1.x'))
throw Problem.user.invalidEntityForm({ reason: `Entities specification version [${version.get()}] is not supported.` });

let warnings;
if (semverSatisfies(version.get(), '<2024.1.x'))
warnings = {
type: 'oldEntityVersion',
details: { version: version.get() },
reason: `Entities specification version [${version.get()}] is not compatible with Offline Entities. Please use version 2024.1.0 or later.`
};

const strippedAttrs = Object.create(null);
for (const [name, value] of Object.entries(entityAttrs.get()))
strippedAttrs[stripNamespacesFromPath(name)] = value;
Expand All @@ -101,7 +109,7 @@ const getDataset = (xml) =>
if (actions.length === 0)
throw Problem.user.invalidEntityForm({ reason: 'The form must specify at least one entity action, for example, create or update.' });

return Option.of({ name: datasetName, actions });
return Option.of({ name: datasetName, actions, warnings });
});

module.exports = { getDataset, validateDatasetName, validatePropertyName };
13 changes: 12 additions & 1 deletion lib/model/query/forms.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ const createNew = (partial, project) => async ({ Actees, Datasets, FormAttachmen

// Check for xmlFormId collisions with previously deleted forms
await Forms.checkDeletedForms(partial.xmlFormId, project.id);
await Forms.checkDatasetWarnings(parsedDataset);
await Forms.rejectIfWarnings();

// Provision Actee for form
Expand Down Expand Up @@ -761,6 +762,16 @@ const checkDeletedForms = (xmlFormId, projectId) => ({ maybeOne, context }) => (
}
}));

const checkDatasetWarnings = (dataset) => ({ context }) => {
if (context.query.ignoreWarnings) return resolve();

if (dataset.isDefined() && dataset.get().warnings != null) {
if (!context.transitoryData.has('workflowWarnings')) context.transitoryData.set('workflowWarnings', []);
context.transitoryData.get('workflowWarnings').push(dataset.get().warnings);
}
return resolve();
};

const checkStructuralChange = (existingFields, fields) => ({ context }) => {
if (context.query.ignoreWarnings) return resolve();

Expand Down Expand Up @@ -829,7 +840,7 @@ module.exports = {
getByProjectId, getByProjectAndXmlFormId, getByProjectAndNumericId,
getAllByAuth,
getFields, getBinaryFields, getStructuralFields, getMergedFields,
rejectIfWarnings, checkMeta, checkDeletedForms, checkStructuralChange, checkFieldDowncast,
rejectIfWarnings, checkMeta, checkDeletedForms, checkStructuralChange, checkFieldDowncast, checkDatasetWarnings,
_newSchema,
lockDefs, getAllSubmitters
};
Expand Down
49 changes: 48 additions & 1 deletion test/data/xml.js
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,30 @@ module.exports = {
</h:html>`,

simpleEntity: `<?xml version="1.0"?>
<h:html xmlns="http://www.w3.org/2002/xforms" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:jr="http://openrosa.org/javarosa" xmlns:entities="http://www.opendatakit.org/xforms">
<h:head>
<model entities:entities-version="2024.1.0">
<instance>
<data id="simpleEntity" orx:version="1.0">
<name/>
<age/>
<hometown/>
<meta>
<entity dataset="people" id="" create="">
<label/>
</entity>
</meta>
</data>
</instance>
<bind nodeset="/data/name" type="string" entities:saveto="first_name"/>
<bind nodeset="/data/age" type="int" entities:saveto="age"/>
<bind nodeset="/data/hometown" type="string"/>
</model>
</h:head>
</h:html>`,

// Copy of the above form with the original entities-version
simpleEntity2022: `<?xml version="1.0"?>
<h:html xmlns="http://www.w3.org/2002/xforms" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:jr="http://openrosa.org/javarosa" xmlns:entities="http://www.opendatakit.org/xforms">
<h:head>
<model entities:entities-version="2022.1.0">
Expand All @@ -371,7 +395,7 @@ module.exports = {
multiPropertyEntity: `<?xml version="1.0"?>
<h:html xmlns="http://www.w3.org/2002/xforms" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:jr="http://openrosa.org/javarosa" xmlns:entities="http://www.opendatakit.org/xforms">
<h:head>
<model entities:entities-version="2022.1.0">
<model entities:entities-version="2024.1.0">
<instance>
<data id="multiPropertyEntity" orx:version="1.0">
<q1/>
Expand All @@ -394,6 +418,29 @@ module.exports = {
</h:html>`,

updateEntity: `<?xml version="1.0"?>
<h:html xmlns="http://www.w3.org/2002/xforms" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:jr="http://openrosa.org/javarosa" xmlns:entities="http://www.opendatakit.org/xforms">
<h:head>
<model entities:entities-version="2024.1.0">
<instance>
<data id="updateEntity" orx:version="1.0">
<name/>
<age/>
<hometown/>
<meta>
<entity dataset="people" id="" update="" baseVersion="" branchId="" trunkVersion="">
<label/>
</entity>
</meta>
</data>
</instance>
<bind nodeset="/data/name" type="string" entities:saveto="first_name"/>
<bind nodeset="/data/age" type="int" entities:saveto="age"/>
</model>
</h:head>
</h:html>`,

// Copy of the above form with the original entities-version spec
updateEntity2023: `<?xml version="1.0"?>
<h:html xmlns="http://www.w3.org/2002/xforms" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:jr="http://openrosa.org/javarosa" xmlns:entities="http://www.opendatakit.org/xforms">
<h:head>
<model entities:entities-version="2023.1.0">
Expand Down
95 changes: 71 additions & 24 deletions test/integration/api/datasets.js
Original file line number Diff line number Diff line change
Expand Up @@ -2259,15 +2259,15 @@ describe('datasets and entities', () => {
const updateForm = `<?xml version="1.0"?>
<h:html xmlns="http://www.w3.org/2002/xforms" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:jr="http://openrosa.org/javarosa" xmlns:entities="http://www.opendatakit.org/xforms">
<h:head>
<model entities:entities-version="2023.1.0">
<model entities:entities-version="2024.1.0">
<instance>
<data id="updateEntity" orx:version="1.0">
<person/>
<name/>
<age/>
<hometown/>
<meta>
<entity dataset="people" id="" update="" baseVersion="">
<entity dataset="people" id="" update="" baseVersion="" trunkVersion="" branchId="">
<label/>
</entity>
</meta>
Expand Down Expand Up @@ -2347,15 +2347,15 @@ describe('datasets and entities', () => {
const differentDataset = `<?xml version="1.0"?>
<h:html xmlns="http://www.w3.org/2002/xforms" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:jr="http://openrosa.org/javarosa" xmlns:entities="http://www.opendatakit.org/xforms">
<h:head>
<model entities:entities-version="2023.1.0">
<model entities:entities-version="2024.1.0">
<instance>
<data id="updateEntity" orx:version="1.0">
<person/>
<name/>
<age/>
<hometown/>
<meta>
<entity dataset="students" id="" update="" baseVersion="">
<entity dataset="students" id="" update="" baseVersion="" trunkVersion="" branchId="">
<label/>
</entity>
</meta>
Expand Down Expand Up @@ -2490,7 +2490,7 @@ describe('datasets and entities', () => {
const noDataset = `<?xml version="1.0"?>
<h:html xmlns="http://www.w3.org/2002/xforms" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:jr="http://openrosa.org/javarosa" xmlns:entities="http://www.opendatakit.org/xforms">
<h:head>
<model entities:entities-version="2023.1.0">
<model entities:entities-version="2024.1.0">
<instance>
<data id="updateEntity" orx:version="1.0">
<person/>
Expand Down Expand Up @@ -2533,15 +2533,15 @@ describe('datasets and entities', () => {
const caseChange = `<?xml version="1.0"?>
<h:html xmlns="http://www.w3.org/2002/xforms" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:jr="http://openrosa.org/javarosa" xmlns:entities="http://www.opendatakit.org/xforms">
<h:head>
<model entities:entities-version="2023.1.0">
<model entities:entities-version="2024.1.0">
<instance>
<data id="updateEntity" orx:version="1.0">
<person/>
<name/>
<age/>
<hometown/>
<meta>
<entity dataset="people" id="" update="" baseVersion="">
<entity dataset="people" id="" update="" baseVersion="" trunkVersion="" branchId="">
<label/>
</entity>
</meta>
Expand Down Expand Up @@ -2583,7 +2583,7 @@ describe('datasets and entities', () => {
const caseChange = `<?xml version="1.0"?>
<h:html xmlns="http://www.w3.org/2002/xforms" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:jr="http://openrosa.org/javarosa" xmlns:entities="http://www.opendatakit.org/xforms">
<h:head>
<model entities:entities-version="2023.1.0">
<model entities:entities-version="2024.1.0">
<instance>
<data id="updateEntity" orx:version="1.0">
<person/>
Expand Down Expand Up @@ -3442,10 +3442,57 @@ describe('datasets and entities', () => {

describe('parsing datasets on form upload', () => {
describe('parsing datasets at /projects/:id/forms POST', () => {

describe('warnings about entities-version from before 2024.1.0', () => {
it('should warn if the entities-version is 2022.1.0 (earlier than 2024.1.0)', testService(async (service) => {
const asAlice = await service.login('alice');

await asAlice.post('/v1/projects/1/forms')
.send(testData.forms.simpleEntity2022)
.set('Content-Type', 'application/xml')
.expect(400)
.then(({ body }) => {
body.code.should.be.eql(400.16);
body.details.warnings.workflowWarnings[0].should.be.eql({
type: 'oldEntityVersion',
details: { version: '2022.1.0' },
reason: 'Entities specification version [2022.1.0] is not compatible with Offline Entities. Please use version 2024.1.0 or later.'
});
});

await asAlice.post('/v1/projects/1/forms?ignoreWarnings=true')
.send(testData.forms.simpleEntity2022)
.set('Content-Type', 'application/xml')
.expect(200);
}));

it('should warn if the entities-version is 2023.1.0 (earlier than 2024.1.0)', testService(async (service) => {
const asAlice = await service.login('alice');

await asAlice.post('/v1/projects/1/forms')
.send(testData.forms.updateEntity2023)
.set('Content-Type', 'application/xml')
.expect(400)
.then(({ body }) => {
body.code.should.be.eql(400.16);
body.details.warnings.workflowWarnings[0].should.be.eql({
type: 'oldEntityVersion',
details: { version: '2023.1.0' },
reason: 'Entities specification version [2023.1.0] is not compatible with Offline Entities. Please use version 2024.1.0 or later.'
});
});

await asAlice.post('/v1/projects/1/forms?ignoreWarnings=true')
.send(testData.forms.updateEntity)
.set('Content-Type', 'application/xml')
.expect(200);
}));
});

it('should return a Problem if the entity xml has the wrong version', testService((service) =>
service.login('alice', (asAlice) =>
asAlice.post('/v1/projects/1/forms')
.send(testData.forms.simpleEntity.replace('2022.1.0', 'bad-version'))
.send(testData.forms.simpleEntity.replace('2024.1.0', 'bad-version'))
.set('Content-Type', 'text/xml')
.expect(400)
.then(({ body }) => {
Expand Down Expand Up @@ -3509,7 +3556,7 @@ describe('datasets and entities', () => {
const xml = `<h:html xmlns="http://www.w3.org/2002/xforms" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:jr="http://openrosa.org/javarosa" xmlns:entities="http://www.opendatakit.org/xforms">
<h:head>
<h:title>nobinds</h:title>
<model entities:entities-version='2022.1.0'>
<model entities:entities-version='2024.1.0'>
<instance>
<data id="nobinds">
<name/>
Expand Down Expand Up @@ -3551,7 +3598,7 @@ describe('datasets and entities', () => {
const alice = await service.login('alice');
const xml = `<h:html xmlns="http://www.w3.org/2002/xforms" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:jr="http://openrosa.org/javarosa" xmlns:entities="http://www.opendatakit.org/xforms">
<h:head>
<model entities:entities-version='2022.1.0'>
<model entities:entities-version='2024.1.0'>
<instance>
<data id="validate_structure">
<name/>
Expand Down Expand Up @@ -3603,7 +3650,7 @@ describe('datasets and entities', () => {
<h:html xmlns="http://www.w3.org/2002/xforms" xmlns:entities="http://www.opendatakit.org/xforms/entities" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:jr="http://openrosa.org/javarosa" xmlns:odk="http://www.opendatakit.org/xforms" xmlns:orx="http://openrosa.org/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<h:head>
<h:title>Repeat Children Entities</h:title>
<model entities:entities-version="2022.1.0" odk:xforms-version="1.0.0">
<model entities:entities-version="2024.1.0" odk:xforms-version="1.0.0">
<instance>
<data id="repeat_entity" version="2">
<num_children/>
Expand Down Expand Up @@ -4534,12 +4581,12 @@ describe('datasets and entities', () => {
const form = `<?xml version="1.0"?>
<h:html xmlns="http://www.w3.org/2002/xforms" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:jr="http://openrosa.org/javarosa" xmlns:entities="http://www.opendatakit.org/xforms">
<h:head>
<model entities:entities-version="2023.1.0">
<model entities:entities-version="2024.1.0">
<instance>
<data id="brokenForm" orx:version="1.0">
<age foo="bar"/>
<meta>
<entity dataset="people" id="" create="" update="" baseVersion="" />
<entity dataset="people" id="" create="" update="" baseVersion="" trunkVersion="" branchId=""/>
</meta>
</data>
</instance>
Expand Down Expand Up @@ -4599,12 +4646,12 @@ describe('datasets and entities', () => {
const form = `<?xml version="1.0"?>
<h:html xmlns:entities="http://www.opendatakit.org/xforms">
<h:head>
<model entities:entities-version="2023.1.0">
<model entities:entities-version="2024.1.0">
<instance>
<data id="brokenForm" orx:version="1.0">
<age foo="bar"/>
<meta>
<entity dataset="people" id="" create="" update="" baseVersion="" />
<entity dataset="people" id="" create="" update="" baseVersion="" trunkVersion="" branchId="" />
</meta>
</data>
</instance>
Expand All @@ -4616,12 +4663,12 @@ describe('datasets and entities', () => {
const form2 = `<?xml version="1.0"?>
<h:html xmlns:entities="http://www.opendatakit.org/xforms">
<h:head>
<model entities:entities-version="2023.1.0">
<model entities:entities-version="2024.1.0">
<instance>
<data id="brokenForm" orx:version="2.0">
<age foo="bar"/>
<meta>
<entity dataset="people" id="" create="" update="" baseVersion="">
<entity dataset="people" id="" create="" update="" baseVersion="" trunkVersion="" branchId="">
<label/>
</entity>
</meta>
Expand Down Expand Up @@ -4651,12 +4698,12 @@ describe('datasets and entities', () => {
const form = `<?xml version="1.0"?>
<h:html xmlns:entities="http://www.opendatakit.org/xforms">
<h:head>
<model entities:entities-version="2023.1.0">
<model entities:entities-version="2024.1.0">
<instance>
<data id="updateWithoutLabel" orx:version="1.0">
<age foo="bar"/>
<meta>
<entity dataset="people" id="" update="" baseVersion="" />
<entity dataset="people" id="" update="" baseVersion="" trunkVersion="" branchId=""/>
</meta>
</data>
</instance>
Expand All @@ -4674,12 +4721,12 @@ describe('datasets and entities', () => {
const form2 = `<?xml version="1.0"?>
<h:html xmlns:entities="http://www.opendatakit.org/xforms">
<h:head>
<model entities:entities-version="2023.1.0">
<model entities:entities-version="2024.1.0">
<instance>
<data id="updateWithLabel" orx:version="1.0">
<age foo="bar"/>
<meta>
<entity dataset="people" id="" update="" baseVersion="">
<entity dataset="people" id="" update="" baseVersion="" trunkVersion="" branchId="">
<label/>
</entity>
</meta>
Expand Down Expand Up @@ -4720,12 +4767,12 @@ describe('datasets and entities', () => {
const form = `<?xml version="1.0"?>
<h:html xmlns="http://www.w3.org/2002/xforms" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:jr="http://openrosa.org/javarosa" xmlns:entities="http://www.opendatakit.org/xforms">
<h:head>
<model entities:entities-version="2023.1.0">
<model entities:entities-version="2024.1.0">
<instance>
<data id="brokenForm" orx:version="1.0">
<age foo="bar"/>
<meta>
<entity dataset="people" id="" update="" baseVersion="" />
<entity dataset="people" id="" update="" baseVersion="" trunkVersion="" branchId=""/>
</meta>
</data>
</instance>
Expand Down
2 changes: 1 addition & 1 deletion test/integration/other/empty-entity-structure.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const { testService } = require('../setup');
const emptyEntityForm = `<?xml version="1.0"?>
<h:html xmlns="http://www.w3.org/2002/xforms" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:jr="http://openrosa.org/javarosa" xmlns:entities="http://www.opendatakit.org/xforms">
<h:head>
<model entities:entities-version="2023.1.0">
<model entities:entities-version="2024.1.0">
<instance>
<data id="emptyEntity" orx:version="1.0">
<age/>
Expand Down
Loading

0 comments on commit 4014ab6

Please sign in to comment.