From ba6ee474f431b48e885fb035c9266792f06d0ad7 Mon Sep 17 00:00:00 2001 From: Kathleen Tuite Date: Mon, 3 Jul 2023 11:42:57 -0700 Subject: [PATCH] Fix entity bug where the wrong properties of an entity are populated (#914) * Fix entity bug: join on ds_property_field formDefId instead of schema * Updated test to test removing an entity bind --- lib/model/query/datasets.js | 2 +- test/data/xml.js | 4 ++ test/integration/api/datasets.js | 89 ++++++++++++++++++++++++++++++++ 3 files changed, 94 insertions(+), 1 deletion(-) diff --git a/lib/model/query/datasets.js b/lib/model/query/datasets.js index 42d5cc8a3..cc051bf31 100644 --- a/lib/model/query/datasets.js +++ b/lib/model/query/datasets.js @@ -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" diff --git a/test/data/xml.js b/test/data/xml.js index 24332cefb..1803eca42 100644 --- a/test/data/xml.js +++ b/test/data/xml.js @@ -584,6 +584,7 @@ module.exports = { Alice 88 + Chicago `, two: ` @@ -595,6 +596,7 @@ module.exports = { Jane 30 + Boston `, three: ` @@ -606,6 +608,7 @@ module.exports = { John 40 + Toronto `, four: ` @@ -617,6 +620,7 @@ module.exports = { Robert 18 + Seattle ` }, multiPropertyEntity: { diff --git a/test/integration/api/datasets.js b/test/integration/api/datasets.js index bb0f5fb5a..6bc765630 100644 --- a/test/integration/api/datasets.js +++ b/test/integration/api/datasets.js @@ -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('', '')) + .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('', '') + .replace('', '')) + .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');