jenkins-bot has submitted this change and it was merged. ( https://gerrit.wikimedia.org/r/325926 )
Change subject: LINK_DWELL starts an interaction ...................................................................... LINK_DWELL starts an interaction Action changes: * Mix in timing information into actions that are likely to need it: LINK_DWELL, {LINK,PREVIEW}_ABANDON_START, LINK_CLICK, and PREVIEW_CLICK. * Generate and include an unique token in the LINK_CLICK action. Reducer changes: * Make the eventLogging reducer: * Handle the LINK_CLICK action's new shape. * Start (create) and maintain a model of the user interacting with a link. Bug: T152225 Change-Id: I671b12432ba2f7a93bf81043adb57ac30a4c38c3 --- M resources/ext.popups/actions.js M resources/ext.popups/boot.js M resources/ext.popups/reducers.js M tests/qunit/ext.popups/actions.test.js M tests/qunit/ext.popups/reducers.eventLogging.test.js M tests/qunit/ext.popups/reducers.test.js 6 files changed, 92 insertions(+), 25 deletions(-) Approvals: jenkins-bot: Verified Phuedx: Looks good to me, approved diff --git a/resources/ext.popups/actions.js b/resources/ext.popups/actions.js index 2afa447..6265f44 100644 --- a/resources/ext.popups/actions.js +++ b/resources/ext.popups/actions.js @@ -26,6 +26,20 @@ ABANDON_END_DELAY = 300; // ms. /** + * Mixes in timing information to an action. + * + * Warning: the `baseAction` parameter is modified and returned. + * + * @param {Object} baseAction + * @return {Object} + */ + function timedAction( baseAction ) { + baseAction.timestamp = mw.now(); + + return baseAction; + } + + /** * Represents Page Previews booting. * * When a Redux store is created, the `@@INIT` action is immediately @@ -114,16 +128,19 @@ * @param {Element} el * @param {Event} event * @param {ext.popups.Gateway} gateway + * @param {Function} generateToken * @return {Redux.Thunk} */ - actions.linkDwell = function ( el, event, gateway ) { + actions.linkDwell = function ( el, event, gateway, generateToken ) { + var interactionToken = generateToken(); + return function ( dispatch, getState ) { - dispatch( { + dispatch( timedAction( { type: types.LINK_DWELL, el: el, event: event, - interactionStarted: mw.now() - } ); + interactionToken: interactionToken + } ) ); mw.popups.wait( FETCH_START_DELAY ) .then( function () { @@ -146,10 +163,10 @@ */ actions.linkAbandon = function ( el ) { return function ( dispatch ) { - dispatch( { + dispatch( timedAction( { type: types.LINK_ABANDON_START, el: el - } ); + } ) ); mw.popups.wait( ABANDON_END_DELAY ) .then( function () { @@ -169,10 +186,10 @@ * @return {Object} */ actions.linkClick = function ( el ) { - return { + return timedAction( { type: 'LINK_CLICK', el: el - }; + } ); }; /** @@ -200,9 +217,9 @@ mw.popups.wait( ABANDON_END_DELAY ) .then( function () { - dispatch( { + dispatch( timedAction( { type: types.PREVIEW_ABANDON_END - } ); + } ) ); } ); }; }; @@ -216,9 +233,9 @@ * @return {Object} */ actions.previewShow = function () { - return { + return timedAction( { type: types.PREVIEW_SHOW - }; + } ); }; /** diff --git a/resources/ext.popups/boot.js b/resources/ext.popups/boot.js index 895b463..4ed9463 100644 --- a/resources/ext.popups/boot.js +++ b/resources/ext.popups/boot.js @@ -126,7 +126,7 @@ previewLinks .on( 'mouseover focus', function ( event ) { - actions.linkDwell( this, event, gateway ); + actions.linkDwell( this, event, gateway, generateToken ); } ) .on( 'mouseout blur', function () { actions.linkAbandon( this ); diff --git a/resources/ext.popups/reducers.js b/resources/ext.popups/reducers.js index 7fae9c1..b435a9f 100644 --- a/resources/ext.popups/reducers.js +++ b/resources/ext.popups/reducers.js @@ -151,6 +151,7 @@ state = { previewCount: undefined, baseData: {}, + interaction: undefined, event: undefined }; } @@ -190,6 +191,14 @@ } ) } ); + case mw.popups.actionTypes.LINK_DWELL: + return nextState( state, { + interaction: { + token: action.interactionToken, + started: action.timestamp + } + } ); + default: return state; } diff --git a/tests/qunit/ext.popups/actions.test.js b/tests/qunit/ext.popups/actions.test.js index ff4cc1f..6e2591e 100644 --- a/tests/qunit/ext.popups/actions.test.js +++ b/tests/qunit/ext.popups/actions.test.js @@ -1,13 +1,14 @@ ( function ( mw, $ ) { + function generateToken() { + return '9876543210'; + } + QUnit.module( 'ext.popups/actions' ); QUnit.test( '#boot', function ( assert ) { var isUserInCondition = function () { return false; - }, - generateToken = function () { - return '9876543210'; }, config = new mw.Map(), stubUser = mw.popups.tests.stubs.createStubUser( /* isAnon = */ true ), @@ -104,14 +105,18 @@ this.sandbox.stub( mw, 'now' ).returns( new Date() ); - mw.popups.actions.linkDwell( el, event, gateway )( dispatch, this.getState ); + mw.popups.actions.linkDwell( el, event, gateway, generateToken )( + dispatch, + this.getState + ); - assert.ok( dispatch.calledWith( { + assert.deepEqual( dispatch.getCall( 0 ).args[0], { type: 'LINK_DWELL', el: el, event: event, - interactionStarted: mw.now() - } ) ); + interactionToken: '9876543210', + timestamp: mw.now() + } ); // Stub the state tree being updated. this.state.preview = { @@ -157,7 +162,8 @@ QUnit.test( '#linkDwell doesn\'t dispatch under certain conditions', function ( assert ) { var cases, done, - that = this; + that = this, + event = {}; cases = [ { @@ -174,7 +180,10 @@ $.each( cases, function ( testCase ) { var dispatch = that.sandbox.spy(); - mw.popups.actions.linkDwell( this.el /*, gateway */ )( dispatch, that.getState ); + mw.popups.actions.linkDwell( that.el, event, /* gateway = */ null, generateToken )( + dispatch, + that.getState + ); that.state.preview = testCase; @@ -200,11 +209,14 @@ dispatch = that.sandbox.spy(), done = assert.async(); + this.sandbox.stub( mw, 'now' ).returns( new Date() ); + mw.popups.actions.linkAbandon( that.el )( dispatch ); assert.ok( dispatch.calledWith( { type: 'LINK_ABANDON_START', - el: that.el + el: that.el, + timestamp: mw.now() } ) ); // --- diff --git a/tests/qunit/ext.popups/reducers.eventLogging.test.js b/tests/qunit/ext.popups/reducers.eventLogging.test.js index 6e2c176..6280684 100644 --- a/tests/qunit/ext.popups/reducers.eventLogging.test.js +++ b/tests/qunit/ext.popups/reducers.eventLogging.test.js @@ -50,7 +50,8 @@ }, event: { action: 'pageLoaded' - } + }, + interaction: undefined } ); } ); @@ -107,4 +108,31 @@ ); } ); + QUnit.module( 'ext.popups/reducers#eventLogging @integration' ); + + QUnit.test( 'LINK_DWELL starts an interaction', function ( assert ) { + var state, + action; + + state = { + interaction: {} + }; + + action = { + type: 'LINK_DWELL', + interactionToken: '0987654321', + timestamp: mw.now() + }; + + assert.deepEqual( + mw.popups.reducers.eventLogging( state, action ), + { + interaction: { + token: action.interactionToken, + started: action.timestamp + } + } + ); + } ); + }( mediaWiki ) ); diff --git a/tests/qunit/ext.popups/reducers.test.js b/tests/qunit/ext.popups/reducers.test.js index 9751c2a..507df6a 100644 --- a/tests/qunit/ext.popups/reducers.test.js +++ b/tests/qunit/ext.popups/reducers.test.js @@ -24,7 +24,8 @@ eventLogging: { previewCount: undefined, baseData: {}, - event: undefined + event: undefined, + interaction: undefined }, renderer: { isAnimating: false, -- To view, visit https://gerrit.wikimedia.org/r/325926 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: I671b12432ba2f7a93bf81043adb57ac30a4c38c3 Gerrit-PatchSet: 4 Gerrit-Project: mediawiki/extensions/Popups Gerrit-Branch: mpga Gerrit-Owner: Phuedx <samsm...@wikimedia.org> Gerrit-Reviewer: Jhernandez <jhernan...@wikimedia.org> Gerrit-Reviewer: Phuedx <samsm...@wikimedia.org> Gerrit-Reviewer: jenkins-bot <> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits