Skip to content

Commit

Permalink
Allow property name from deleted form to be used in entity list
Browse files Browse the repository at this point in the history
  • Loading branch information
ktuite committed Aug 29, 2024
1 parent 5b6eb2d commit 5ddb7ad
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 2 deletions.
11 changes: 9 additions & 2 deletions lib/model/query/datasets.js
Original file line number Diff line number Diff line change
Expand Up @@ -179,11 +179,18 @@ createPublishedDataset.audit.withResult = true;
const _createPublishedProperty = (property) => sql`
INSERT INTO ds_properties ("name", "datasetId", "publishedAt")
VALUES (${property.name}, ${property.datasetId}, clock_timestamp())
ON CONFLICT ("name", "datasetId")
DO UPDATE SET "publishedAt" = clock_timestamp()
WHERE ds_properties."publishedAt" IS NULL
RETURNING *`;

// eslint-disable-next-line no-unused-vars
const createPublishedProperty = (property, dataset) => ({ one }) =>
one(_createPublishedProperty(property));
const createPublishedProperty = (property, dataset) => async ({ all }) => {
const result = await all(_createPublishedProperty(property));
if (result.length === 0)
throw Problem.user.uniquenessViolation({ table: 'ds_properties', fields: [ 'name', 'datasetId' ], values: [ property.name, dataset.id ] });
return result[0];
};

createPublishedProperty.audit = (property, dataset) => (log) =>
log('dataset.update', dataset, { properties: [property.name] });
Expand Down
66 changes: 66 additions & 0 deletions test/integration/api/datasets.js
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,34 @@ describe('datasets and entities', () => {
});
}));

it('should reject if creating a dataset property that already exists', testService(async (service) => {
const asAlice = await service.login('alice');

await asAlice.post('/v1/projects/1/datasets')
.send({
name: 'trees'
})
.expect(200);

// Create a property
await asAlice.post('/v1/projects/1/datasets/trees/properties')
.send({
name: 'height'
})
.expect(200);

// Second time should fail
await asAlice.post('/v1/projects/1/datasets/trees/properties')
.send({
name: 'height'
})
.expect(409)
.then(({ body }) => {
body.code.should.equal(409.3);
body.message.should.startWith('A resource already exists with name,datasetId value(s) of height');
});
}));

it('should log an event for creating a new dataset property', testService(async (service) => {
const asAlice = await service.login('alice');

Expand All @@ -434,6 +462,44 @@ describe('datasets and entities', () => {
logs[0].details.properties.should.eql([ 'circumference' ]);
});
}));

it('should allow property name from a deleted draft form be used', testService(async (service) => {
const asAlice = await service.login('alice');

// Create a draft dataset
await asAlice.post('/v1/projects/1/forms')
.send(testData.forms.simpleEntity)
.set('Content-Type', 'application/xml')
.expect(200);

// Delete the draft form
await asAlice.delete('/v1/projects/1/forms/simpleEntity')
.expect(200);

// Create the dataset with the same name as the dataset in the deleted form
await asAlice.post('/v1/projects/1/datasets')
.send({ name: 'people' })
.expect(200);

// Create a property with a name that wasn't originally in the dataset in the form
await asAlice.post('/v1/projects/1/datasets/people/properties')
.send({ name: 'nickname' })
.expect(200);

// Create a property with a name that was in the dataset in the form
await asAlice.post('/v1/projects/1/datasets/people/properties')
.send({ name: 'age' })
.expect(200);

// Re-creating an existing property should result in an error
await asAlice.post('/v1/projects/1/datasets/people/properties')
.send({ name: 'age' })
.expect(409)
.then(({ body }) => {
body.code.should.equal(409.3);
body.message.should.startWith('A resource already exists with name,datasetId value(s) of age');
});
}));
});
});

Expand Down

0 comments on commit 5ddb7ad

Please sign in to comment.