RatingServiceSubmitNotify: Notify only once
* src/server/db/MongoServerDao.js (getDocumentField,setDocumentField): New methods. * src/server/service/RatingServiceSubmitNotify.js (postProcessRaterData): Only notify when notification flag is not set. (_getNotifyState, _setNotified): New methods. * test/server/service/RatingServiceSubmitNotifyTest.js: Modify accordingly.master
parent
d8338b50e0
commit
2d1582059f
|
@ -783,5 +783,70 @@ module.exports = Class( 'MongoServerDao' )
|
|||
}
|
||||
);
|
||||
},
|
||||
} );
|
||||
|
||||
|
||||
/**
|
||||
* Set arbitrary data on a document
|
||||
*
|
||||
* @param {number} qid quote/document id
|
||||
* @param {string} key field key
|
||||
* @param {*} value field value
|
||||
* @param {function(?Error)} callback completion callback
|
||||
*
|
||||
* @return {undefined}
|
||||
*/
|
||||
'public setDocumentField'( qid, key, value, callback )
|
||||
{
|
||||
this._collection.update(
|
||||
{ id: qid },
|
||||
{ '$set': { [key]: value } },
|
||||
|
||||
// create record if it does not yet exist
|
||||
{ upsert: true },
|
||||
|
||||
// on complete
|
||||
function( err )
|
||||
{
|
||||
callback && callback( err );
|
||||
return;
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve arbitrary data on a document
|
||||
*
|
||||
* @param {number} qid quote/document id
|
||||
* @param {string} key field key
|
||||
* @param {function(?Error)} callback completion callback
|
||||
*
|
||||
* @return {undefined}
|
||||
*/
|
||||
'public getDocumentField'( qid, key, callback )
|
||||
{
|
||||
this._collection.find(
|
||||
{ id: qid },
|
||||
{ limit: 1 },
|
||||
function( err, cursor )
|
||||
{
|
||||
if ( err !== null )
|
||||
{
|
||||
callback( err, null );
|
||||
return;
|
||||
}
|
||||
|
||||
cursor.toArray( function( err, data )
|
||||
{
|
||||
if ( err !== null )
|
||||
{
|
||||
callback( err, null );
|
||||
return;
|
||||
}
|
||||
|
||||
callback( null, data[ key ] );
|
||||
} );
|
||||
}
|
||||
);
|
||||
},
|
||||
} );
|
||||
|
|
|
@ -32,6 +32,10 @@ const RatingService = require( './RatingService' );
|
|||
* This information is currently stored in `__prem_avail_count`. In the
|
||||
* future, it may be worth accepting a parameter to configure this at
|
||||
* runtime.
|
||||
*
|
||||
* Notification status will persist using the provided DAO. The next time
|
||||
* such a notification is requested, it will only occur if the flag is not
|
||||
* set.
|
||||
*/
|
||||
module.exports = Trait( 'RatingServiceSubmitNotify' )
|
||||
.extend( RatingService,
|
||||
|
@ -42,15 +46,23 @@ module.exports = Trait( 'RatingServiceSubmitNotify' )
|
|||
*/
|
||||
'private _dapi': null,
|
||||
|
||||
/**
|
||||
* Data store for notification flag
|
||||
* @type {ServerDao}
|
||||
*/
|
||||
'private _notifyDao': null,
|
||||
|
||||
|
||||
/**
|
||||
* Initialize mixin with DataApi to trigger
|
||||
*
|
||||
* @param {DataApi} dapi DataApi to trigger
|
||||
* @param {DataApi} dapi DataApi to trigger
|
||||
* @param {ServerDao} dao data store for notification flag
|
||||
*/
|
||||
__mixin( dapi )
|
||||
__mixin( dapi, dao )
|
||||
{
|
||||
this._dapi = dapi;
|
||||
this._dapi = dapi;
|
||||
this._notifyDao = dao;
|
||||
},
|
||||
|
||||
|
||||
|
@ -73,9 +85,51 @@ module.exports = Trait( 'RatingServiceSubmitNotify' )
|
|||
|
||||
if ( avail === 0 )
|
||||
{
|
||||
this._dapi.request( { quote_id: quote_id }, () => {} );
|
||||
this._getNotifyState( quote_id, notified =>
|
||||
{
|
||||
if ( notified === true )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this._dapi.request( { quote_id: quote_id }, () => {} );
|
||||
this._setNotified( quote_id );
|
||||
} );
|
||||
}
|
||||
|
||||
this.__super( data, actions, program, quote );
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Get value of notification flag
|
||||
*
|
||||
* @param {number} quote_id id of quote
|
||||
* @param {function(boolean)} callback callback to call when complete
|
||||
*
|
||||
* @return {undefined}
|
||||
*/
|
||||
'private _getNotifyState'( quote_id, callback )
|
||||
{
|
||||
this._notifyDao.getDocumentField(
|
||||
quote_id,
|
||||
'submitNotified',
|
||||
( err, value ) => callback( value )
|
||||
);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Set notification flag
|
||||
*
|
||||
* @param {number} quote_id id of quote
|
||||
*
|
||||
* @return {undefined}
|
||||
*/
|
||||
'private _setNotified'( quote_id )
|
||||
{
|
||||
this._notifyDao.setDocumentField(
|
||||
quote_id, 'submitNotified', true
|
||||
);
|
||||
},
|
||||
} );
|
||||
|
|
|
@ -50,18 +50,39 @@ describe( 'RatingServiceSubmitNotify', () =>
|
|||
[
|
||||
{
|
||||
prem_avail_count: [ 0 ],
|
||||
prev_called: false,
|
||||
expected_request: true,
|
||||
},
|
||||
{
|
||||
prem_avail_count: [ 2 ],
|
||||
prev_called: false,
|
||||
expected_request: false,
|
||||
},
|
||||
{
|
||||
// this shouldn't happen; ignore all but first index
|
||||
prem_avail_count: [ 2, 2 ],
|
||||
prev_called: false,
|
||||
expected_request: false,
|
||||
},
|
||||
].forEach( ( { prem_avail_count, expected_request }, i ) =>
|
||||
|
||||
// save as above, but already saved
|
||||
{
|
||||
prem_avail_count: [ 0 ],
|
||||
prev_called: true,
|
||||
expected_request: false,
|
||||
},
|
||||
{
|
||||
prem_avail_count: [ 2 ],
|
||||
prev_called: true,
|
||||
expected_request: false,
|
||||
},
|
||||
{
|
||||
// this shouldn't happen; ignore all but first index
|
||||
prem_avail_count: [ 2, 2 ],
|
||||
prev_called: true,
|
||||
expected_request: false,
|
||||
},
|
||||
].forEach( ( { prem_avail_count, expected_request, prev_called }, i ) =>
|
||||
it( `sends request on post process if no premiums (#${i})`, done =>
|
||||
{
|
||||
const {
|
||||
|
@ -91,7 +112,7 @@ describe( 'RatingServiceSubmitNotify', () =>
|
|||
},
|
||||
} )();
|
||||
|
||||
const sut = RatingService.use( Sut( dapi ) )(
|
||||
const sut = RatingService.use( Sut( dapi, dao ) )(
|
||||
logger, dao, server, raters
|
||||
);
|
||||
|
||||
|
@ -101,6 +122,27 @@ describe( 'RatingServiceSubmitNotify', () =>
|
|||
let save_called = false;
|
||||
dao.setWorksheets = () => save_called = true;
|
||||
|
||||
// whether the notify flag is actually set
|
||||
let notify_saved = false;
|
||||
|
||||
// request for notification status
|
||||
dao.getDocumentField = ( qid, key, callback ) =>
|
||||
{
|
||||
expect( qid ).to.equal( quote_id );
|
||||
expect( key ).to.equal( 'submitNotified' );
|
||||
|
||||
callback( null, prev_called );
|
||||
};
|
||||
|
||||
dao.setDocumentField = ( qid, key, value, callback ) =>
|
||||
{
|
||||
expect( qid ).to.equal( quote_id );
|
||||
expect( key ).to.equal( 'submitNotified' );
|
||||
expect( value ).to.equal( true );
|
||||
|
||||
notify_saved = true;
|
||||
};
|
||||
|
||||
stub_rate_data.__prem_avail_count = prem_avail_count;
|
||||
|
||||
sut.request( request, response, quote, 'something', () =>
|
||||
|
@ -108,6 +150,11 @@ describe( 'RatingServiceSubmitNotify', () =>
|
|||
expect( requested ).to.equal( expected_request );
|
||||
expect( save_called ).to.be.true;
|
||||
|
||||
// only save notification status if we're notifying
|
||||
expect( notify_saved ).to.equal(
|
||||
!prev_called && expected_request
|
||||
);
|
||||
|
||||
done();
|
||||
} );
|
||||
} )
|
||||
|
|
Loading…
Reference in New Issue