Skip to content

Commit

Permalink
updated comment, added tests around submissionXmlToFieldStream
Browse files Browse the repository at this point in the history
  • Loading branch information
ktuite committed Nov 2, 2023
1 parent e3a7124 commit 304c8aa
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 10 deletions.
21 changes: 12 additions & 9 deletions lib/data/submission.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,22 @@ const { union, last, pluck } = require('ramda');
// field in the submission. does no processing at all to localize repeat groups,
// etc. it's just a stream of found data values.
//
// !!! !!! WARNING WARNING:
// right now this facility is used only by generateExpectedAttachments, which wants
// the original place this facility is used is by generateExpectedAttachments, which wants
// to navigate the schema stack ignoring gaps so it can just deal w binary fields.
//
// the second place this is used is by parseSubmissionXml for parsing entity data from
// submissions. this scenario is similar to the one above in that we want to navigate to
// specific entity-property fields and the SchemaStack allowEmptyNavigation is true.
// includeStructuralAttrs and includeEmptyNodes are two flags specifically for reaching and
// returning data needed for entities including the <entity> element with attributes
// and empty elements like `<prop></prop>` meant to blank out certain entity properties.
//
// leaving this old comment here (the second use of this for entities didn't need to do this,
// but the 3rd use might!) ---
// !!! !!! WARNING WARNING:
// if you are reading this thinking to use it elsewhere, you'll almost certainly
// need to work out a sensible way to flag the SchemaStack allowEmptyNavigation boolean
// to false for whatever you are doing.
//
// actually this is also used to parse entity data out of submissions, a scenario
// in which we want to capture potentially empty nodes like <age></age> that might
// mean the property should be set to blank. includeEmptyNodes allows that instead
// of skipping over outputting empty nodes. i think this is different from what the
// note above is talking about...
// allowEmptyNavigation and includeStructuralAttrs are already true.
const submissionXmlToFieldStream = (fields, xml, includeStructuralAttrs = false, includeEmptyNodes = false) => {
const outStream = new Readable({ objectMode: true, read: noop });

Expand Down
67 changes: 66 additions & 1 deletion test/unit/data/submission.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
require('should');
const should = require('should');
const appRoot = require('app-root-path');
const { filter } = require('ramda');
const { toObjects } = require('streamtest').v2;
Expand Down Expand Up @@ -57,6 +57,71 @@ describe('submission field streamer', () => {
stream.on('end', done); // not hanging/timing out is the assertion here
});
});

describe('entity flags includeStructuralAttrs and includeEmptyNodes', () => {
beforeEach(() => {
should.config.checkProtoEql = false;
});
afterEach(() => {
should.config.checkProtoEql = true;
});

it('should include structural fields', (done) => {
fieldsFor(testData.forms.simpleEntity).then((fields) =>
submissionXmlToFieldStream(fields, testData.instances.simpleEntity.one, true).pipe(toObjects((error, result) => {
result.should.eql([
{ field: new MockField({ order: 4, name: 'entity', path: '/meta/entity', type: 'structure', attrs: {
create: '1',
dataset: 'people',
id: 'uuid:12345678-1234-4123-8234-123456789abc'
} }), text: null },
{ field: new MockField({ order: 5, name: 'label', path: '/meta/entity/label', type: 'unknown' }), text: 'Alice (88)' },
{ field: new MockField({ order: 0, name: 'name', path: '/name', type: 'string', propertyName: 'first_name' }), text: 'Alice' },
{ field: new MockField({ order: 1, name: 'age', path: '/age', type: 'int', propertyName: 'age' }), text: '88' },
{ field: new MockField({ order: 2, name: 'hometown', path: '/hometown', type: 'string' }), text: 'Chicago' }
]);
done();
})));
});

it('should not include structural fields', (done) => {
fieldsFor(testData.forms.simpleEntity).then((fields) =>
submissionXmlToFieldStream(fields, testData.instances.simpleEntity.one, false).pipe(toObjects((error, result) => {
result.should.eql([
{ field: new MockField({ order: 5, name: 'label', path: '/meta/entity/label', type: 'unknown' }), text: 'Alice (88)' },
{ field: new MockField({ order: 0, name: 'name', path: '/name', type: 'string', propertyName: 'first_name' }), text: 'Alice' },
{ field: new MockField({ order: 1, name: 'age', path: '/age', type: 'int', propertyName: 'age' }), text: '88' },
{ field: new MockField({ order: 2, name: 'hometown', path: '/hometown', type: 'string' }), text: 'Chicago' }
]);
done();
})));
});

it('should include empty nodes if specified in fields', (done) => {
fieldsFor(testData.forms.simpleEntity).then((fields) =>
submissionXmlToFieldStream(fields, testData.instances.simpleEntity.one.replace('<age>88</age>', '<age></age>'), false, true).pipe(toObjects((error, result) => {
result.should.eql([
{ field: new MockField({ order: 5, name: 'label', path: '/meta/entity/label', type: 'unknown' }), text: 'Alice (88)' },
{ field: new MockField({ order: 0, name: 'name', path: '/name', type: 'string', propertyName: 'first_name' }), text: 'Alice' },
{ field: new MockField({ order: 1, name: 'age', path: '/age', type: 'int', propertyName: 'age' }), text: '' },
{ field: new MockField({ order: 2, name: 'hometown', path: '/hometown', type: 'string' }), text: 'Chicago' }
]);
done();
})));
});

it('should not include empty nodes', (done) => {
fieldsFor(testData.forms.simpleEntity).then((fields) =>
submissionXmlToFieldStream(fields, testData.instances.simpleEntity.one.replace('<age>88</age>', '<age></age>'), false, false).pipe(toObjects((error, result) => {
result.should.eql([
{ field: new MockField({ order: 5, name: 'label', path: '/meta/entity/label', type: 'unknown' }), text: 'Alice (88)' },
{ field: new MockField({ order: 0, name: 'name', path: '/name', type: 'string', propertyName: 'first_name' }), text: 'Alice' },
{ field: new MockField({ order: 2, name: 'hometown', path: '/hometown', type: 'string' }), text: 'Chicago' }
]);
done();
})));
});
});
});

describe('getSelectMultipleResponses', () => {
Expand Down

0 comments on commit 304c8aa

Please sign in to comment.