Skip to content

Commit

Permalink
Fix entity bug where the wrong properties of an entity are populated (#…
Browse files Browse the repository at this point in the history
…914)

* Fix entity bug: join on ds_property_field formDefId instead of schema

* Updated test to test removing an entity bind
  • Loading branch information
ktuite authored Jul 3, 2023
1 parent 891edc2 commit ba6ee47
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 1 deletion.
2 changes: 1 addition & 1 deletion lib/model/query/datasets.js
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ JOIN form_defs ON fs.id = form_defs."schemaId"
JOIN dataset_form_defs ON
dataset_form_defs."formDefId" = form_defs."id"
LEFT OUTER JOIN ds_property_fields ON
ds_property_fields."schemaId" = form_fields."schemaId"
ds_property_fields."formDefId" = form_defs."id"
AND ds_property_fields."path" = form_fields."path"
LEFT OUTER JOIN ds_properties ON
ds_properties."id" = ds_property_fields."dsPropertyId"
Expand Down
4 changes: 4 additions & 0 deletions test/data/xml.js
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,7 @@ module.exports = {
</meta>
<name>Alice</name>
<age>88</age>
<hometown>Chicago</hometown>
</data>`,
two: `<data xmlns:jr="http://openrosa.org/javarosa" xmlns:entities="http://www.opendatakit.org/xforms" id="simpleEntity" version="1.0">
<meta>
Expand All @@ -595,6 +596,7 @@ module.exports = {
</meta>
<name>Jane</name>
<age>30</age>
<hometown>Boston</hometown>
</data>`,
three: `<data xmlns:jr="http://openrosa.org/javarosa" xmlns:entities="http://www.opendatakit.org/xforms" id="simpleEntity" version="1.0">
<meta>
Expand All @@ -606,6 +608,7 @@ module.exports = {
</meta>
<name>John</name>
<age>40</age>
<hometown>Toronto</hometown>
</data>`,
four: `<data xmlns:jr="http://openrosa.org/javarosa" xmlns:entities="http://www.opendatakit.org/xforms" id="simpleEntity" version="1.0">
<meta>
Expand All @@ -617,6 +620,7 @@ module.exports = {
</meta>
<name>Robert</name>
<age>18</age>
<hometown>Seattle</hometown>
</data>`
},
multiPropertyEntity: {
Expand Down
89 changes: 89 additions & 0 deletions test/integration/api/datasets.js
Original file line number Diff line number Diff line change
Expand Up @@ -2154,6 +2154,95 @@ describe('datasets and entities', () => {
});
});

describe('form schemas and dataset properties', () => {
it('should populate entity properties based on correct form schema', testService(async (service, container) => {
const asAlice = await service.login('alice');

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

// Submission to old (and only) version of form should have only age filled in
await asAlice.post('/v1/projects/1/forms/simpleEntity/submissions')
.send(testData.instances.simpleEntity.one)
.set('Content-Type', 'application/xml')
.expect(200);

await exhaust(container);

// Upload a new version of the form with saveto added to hometown
await asAlice.post('/v1/projects/1/forms/simpleEntity/draft')
.set('Content-Type', 'application/xml')
.send(testData.forms.simpleEntity
.replace('<bind nodeset="/data/hometown" type="string"/>', '<bind nodeset="/data/hometown" type="string" entities:saveto="hometown"/>'))
.expect(200);

await asAlice.post('/v1/projects/1/forms/simpleEntity/draft/publish?version=2.0')
.expect(200);

// Submission to old version of form should make entity with age filled in
await asAlice.post('/v1/projects/1/forms/simpleEntity/submissions')
.send(testData.instances.simpleEntity.two)
.set('Content-Type', 'application/xml')
.expect(200);

// Submission to new version of form should make entity with hometown filled in
await asAlice.post('/v1/projects/1/forms/simpleEntity/submissions')
.send(testData.instances.simpleEntity.three.replace('version="1.0"', 'version="2.0"'))
.set('Content-Type', 'application/xml')
.expect(200);

await exhaust(container);

// Upload a new version of the form with saveto removed from age
await asAlice.post('/v1/projects/1/forms/simpleEntity/draft')
.set('Content-Type', 'application/xml')
.send(testData.forms.simpleEntity
.replace('<bind nodeset="/data/age" type="int" entities:saveto="age"/>', '<bind nodeset="/data/age" type="int"/>')
.replace('<bind nodeset="/data/hometown" type="string"/>', '<bind nodeset="/data/hometown" type="string" entities:saveto="hometown"/>'))
.expect(200);

await asAlice.post('/v1/projects/1/forms/simpleEntity/draft/publish?version=3.0')
.expect(200);

await asAlice.post('/v1/projects/1/forms/simpleEntity/submissions')
.send(testData.instances.simpleEntity.four.replace('version="1.0"', 'version="3.0"'))
.set('Content-Type', 'application/xml')
.expect(200);

await exhaust(container);

// Submission 1 - should just have name and age
await asAlice.get('/v1/projects/1/datasets/people/entities/12345678-1234-4123-8234-123456789abc')
.expect(200)
.then(({ body: person }) => {
person.currentVersion.should.have.property('data').which.is.eql({ age: '88', first_name: 'Alice' });
});

// Submission 2 - should also just have name and age
await asAlice.get('/v1/projects/1/datasets/people/entities/12345678-1234-4123-8234-123456789aaa')
.expect(200)
.then(({ body: person }) => {
person.currentVersion.should.have.property('data').which.is.eql({ age: '30', first_name: 'Jane' });
});

// Submission 3 - should have name, age and hometown filled in
await asAlice.get('/v1/projects/1/datasets/people/entities/12345678-1234-4123-8234-123456789bbb')
.expect(200)
.then(({ body: person }) => {
person.currentVersion.should.have.property('data').which.is.eql({ age: '40', hometown: 'Toronto', first_name: 'John' });
});

// Submission 4 - should have name and hometown filled in, NO age
await asAlice.get('/v1/projects/1/datasets/people/entities/12345678-1234-4123-8234-123456789ccc')
.expect(200)
.then(({ body: person }) => {
person.currentVersion.should.have.property('data').which.is.eql({ first_name: 'Robert', hometown: 'Seattle' });
});
}));
});

describe('dataset and entities should have isolated lifecycle', () => {
it('should allow a form that has created an entity to be purged', testService(async (service, container) => {
const asAlice = await service.login('alice');
Expand Down

0 comments on commit ba6ee47

Please sign in to comment.