diff --git a/src/server/quote/ProgramQuoteCleaner.js b/src/server/quote/ProgramQuoteCleaner.js
index 5d5819f..10ce70f 100644
--- a/src/server/quote/ProgramQuoteCleaner.js
+++ b/src/server/quote/ProgramQuoteCleaner.js
@@ -19,7 +19,9 @@
* along with this program. If not, see .
*/
-var Class = require( 'easejs' ).Class;
+'use strict';
+
+const { Class } = require( 'easejs' );
module.exports = Class( 'ProgramQuoteCleaner',
@@ -51,10 +53,16 @@ module.exports = Class( 'ProgramQuoteCleaner',
}
// fix any problems with linked groups
- this._fixLinkedGroups( quote, function( err )
+ this._fixLinkedGroups( quote, err =>
{
- // done
- callback( err );
+ if ( err )
+ {
+ callback( err );
+ return;
+ }
+
+ this._fixMeta( quote );
+ callback( null );
} );
},
@@ -149,6 +157,34 @@ module.exports = Class( 'ProgramQuoteCleaner',
}
return len;
- }
+ },
+
+
+ /**
+ * Initialize missing metadata
+ *
+ * This is similar to bucket initialization, except there are no leaders
+ * or default values---just empty arrays. That may change in the future.
+ *
+ * @param {ServerSideQuote} quote quote containing metabucket
+ *
+ * @return {undefined}
+ */
+ 'private _fixMeta'( quote )
+ {
+ const { fields } = this._program.meta;
+ const metabucket = quote.getMetabucket();
+ const metadata = metabucket.getData();
+
+ Object.keys( fields ).forEach( field_name =>
+ {
+ if ( Array.isArray( metadata[ field_name ] ) )
+ {
+ return;
+ }
+
+ metabucket.setValues( { [field_name]: [] } );
+ } );
+ },
} );
diff --git a/test/server/quote/ProgramQuoteCleanerTest.js b/test/server/quote/ProgramQuoteCleanerTest.js
new file mode 100644
index 0000000..6b7e42f
--- /dev/null
+++ b/test/server/quote/ProgramQuoteCleanerTest.js
@@ -0,0 +1,90 @@
+/**
+ * Tests ProgramQuoteCleaner
+ *
+ * Copyright (C) 2017 R-T Specialty, LLC.
+ *
+ * This file is part of the Liza Data Collection Framework.
+ *
+ * liza is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+'use strict';
+
+const { expect } = require( 'chai' );
+const Sut = require( '../../../' ).server.quote.ProgramQuoteCleaner;
+
+
+describe( 'ProgramQuoteCleaner', () =>
+{
+ describe( "metadata cleaning", () =>
+ {
+ [
+ {
+ label: "populates all fields when empty",
+ existing: {},
+ fields: { foo: {}, bar: {} },
+ expected: { foo: [], bar: [] },
+ },
+ {
+ label: "populates only missing fields when non-empty",
+ existing: { foo: [ 1 ], baz: [ 2 ] },
+ fields: { foo: {}, bar: {} },
+ expected: { foo: [ 1 ], bar: [], baz: [ 2 ] },
+ },
+ ].forEach( ( { label, existing, fields, expected } ) =>
+ it( label, done =>
+ {
+ const quote = createStubQuote( existing );
+ const program = createStubProgram( fields );
+
+ Sut( program ).clean( quote, err =>
+ {
+ expect( err ).to.equal( null );
+ expect( quote.getMetabucket().getData() )
+ .to.deep.equal( expected );
+
+ done();
+ } );
+ } )
+ );
+ } );
+} );
+
+
+function createStubQuote( metadata )
+{
+ return {
+ getProgramId: () => 'foo',
+ setData: () => {},
+ getMetabucket: () => ( {
+ getDataByName: name => metadata[ name ],
+ getData: () => metadata,
+ setValues: data =>
+ {
+ Object.keys( data ).forEach( field_name =>
+ metadata[ field_name ] = data[ field_name ]
+ );
+ },
+ } ),
+ };
+}
+
+
+function createStubProgram( meta_fields )
+{
+ return {
+ getId: () => 'foo',
+ meta: { fields: meta_fields },
+ };
+}