From b47deedf9c85b24d748a653cd4eda02245e5a0df Mon Sep 17 00:00:00 2001 From: Mike Gerwitz Date: Fri, 10 Aug 2018 13:30:39 -0400 Subject: [PATCH] [DEV-3257] DataApiMediator: Set bucket data after stack clear Allowing the stack to clear ensures that (in practice) DelayedStagingBucket is given a chance to do necessary processing before data are requested from it by bucket hooks as a result of _this_ invocation, which in turn results (in some cases) in infinite recursion. * src/client/dapi/DataApiMediator.js (_updateFieldData): Allow stack to clear before invoking `quote.setData'. * test/client/dapi/DataApiMediatorTest.js: Test respectively. DEV-3257 --- src/client/dapi/DataApiMediator.js | 6 +++++- test/client/dapi/DataApiMediatorTest.js | 11 ++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/client/dapi/DataApiMediator.js b/src/client/dapi/DataApiMediator.js index bdca195..89b600b 100644 --- a/src/client/dapi/DataApiMediator.js +++ b/src/client/dapi/DataApiMediator.js @@ -177,7 +177,11 @@ module.exports = Class( 'DataApiMediator', update[ name ] = field_update; - quote.setData( update ); + // allow the stack to clear before setting data to allow any + // existing bucket processing to complete before hooks are kicked + // off yet again (which, in practice, could otherwise result in + // infinite recursion depending on what the hooks are doing) + setTimeout( () => quote.setData( update ) ); }, diff --git a/test/client/dapi/DataApiMediatorTest.js b/test/client/dapi/DataApiMediatorTest.js index fee5f56..62e12b1 100644 --- a/test/client/dapi/DataApiMediatorTest.js +++ b/test/client/dapi/DataApiMediatorTest.js @@ -319,7 +319,8 @@ describe( "DataApiMediator", () => { it( label, done => { - let set_options = false; + let set_options = false; + let stack_cleared = false; const quote = { getDataByName( given_name ) @@ -329,6 +330,9 @@ describe( "DataApiMediator", () => setData( given_data ) { + // we should have allowed the stack to clear first + expect( stack_cleared ).to.be.true; + expect( given_data ).to.deep.equal( expected ); // should have called setOptions by now @@ -382,6 +386,11 @@ describe( "DataApiMediator", () => dapi_manager.emit( 'updateFieldData', name, index, val_label, results ); + + // #setData should be triggered after the stack clears to + // #mitigate issues with hooks causing too much / infinite + // #recursion on the bucket on the same stack + stack_cleared = true; } ); } );