Implement html/rest.js gateway which handles HTML Restbase responses

Refactor existing Restbase gateway and extract shared logic into
shared Restbase provider. Also introduced new createNullModel()
which defines an empty preview model.

Additionally improve naming in new gateways/formatter so function
names are more explicity.
 * Htmlize() became formatPlainTextExtract() as it should be used
   only with plain text extracts
 * removeEllipsis() became  removeTrailingEllipsis() as it removes
   only trailing ellipsis.
 * src/gateway/index.js defines gateways by configuration name stored
   in extension.json

Bug: T165018
Change-Id: Ibe54dddfc1080e94814d1562d41e85cb6b43bfc1
Depends-On: I4f42c61b155a37c5dd42bc40034583865abd5d7a
This commit is contained in:
Piotr Miazga 2017-06-08 15:29:57 +02:00
parent 9c2a4b143f
commit f2fbef6ec7
16 changed files with 165 additions and 79 deletions

View file

@ -55,8 +55,8 @@
"PopupsOptInDefaultState": "0", "PopupsOptInDefaultState": "0",
"@PopupsConflictingNavPopupsGadgetName": "@var string: Navigation popups gadget name", "@PopupsConflictingNavPopupsGadgetName": "@var string: Navigation popups gadget name",
"PopupsConflictingNavPopupsGadgetName": "Navigation_popups", "PopupsConflictingNavPopupsGadgetName": "Navigation_popups",
"@PopupsAPIUseRESTBase": "Whether to use RESTBase rather than the MediaWiki API for fetching Popups data.", "@PopupsGateway": "Which gateway to use for fetching Popups data. Available options: [mwApiPlain|restbasePlain|restbaseHTML]. Full and always up to date list is available in src/gateway/index.js",
"PopupsAPIUseRESTBase": false, "PopupsGateway": "mwApiPlain",
"@PopupsAnonsEnabledSamplingRate": "Sampling rate for showing popups to anonymous users.", "@PopupsAnonsEnabledSamplingRate": "Sampling rate for showing popups to anonymous users.",
"PopupsAnonsEnabledSamplingRate": 0.9, "PopupsAnonsEnabledSamplingRate": 0.9,
"@PopupsStatsvSamplingRate": "Sampling rate for logging performance data to statsv.", "@PopupsStatsvSamplingRate": "Sampling rate for logging performance data to statsv.",

View file

@ -120,7 +120,7 @@ class PopupsHooks {
$conf = PopupsContext::getInstance()->getConfig(); $conf = PopupsContext::getInstance()->getConfig();
$vars['wgPopupsSchemaSamplingRate'] = $conf->get( 'PopupsSchemaSamplingRate' ); $vars['wgPopupsSchemaSamplingRate'] = $conf->get( 'PopupsSchemaSamplingRate' );
$vars['wgPopupsBetaFeature'] = $conf->get( 'PopupsBetaFeature' ); $vars['wgPopupsBetaFeature'] = $conf->get( 'PopupsBetaFeature' );
$vars['wgPopupsAPIUseRESTBase'] = $conf->get( 'PopupsAPIUseRESTBase' ); $vars['wgPopupsGateway'] = $conf->get( 'PopupsGateway' );
$vars['wgPopupsAnonsEnabledSamplingRate'] = $conf->get( 'PopupsAnonsEnabledSamplingRate' ); $vars['wgPopupsAnonsEnabledSamplingRate'] = $conf->get( 'PopupsAnonsEnabledSamplingRate' );
$vars['wgPopupsStatsvSamplingRate'] = $conf->get( 'PopupsStatsvSamplingRate' ); $vars['wgPopupsStatsvSamplingRate'] = $conf->get( 'PopupsStatsvSamplingRate' );
} }

Binary file not shown.

Binary file not shown.

View file

@ -7,14 +7,14 @@ var $ = jQuery,
* @param {String} title * @param {String} title
* @returns {Array} * @returns {Array}
*/ */
function htmlize( plainTextExtract, title ) { function formatPlainTextExtract( plainTextExtract, title ) {
var extract = plainTextExtract; var extract = plainTextExtract;
if ( plainTextExtract === undefined ) { if ( plainTextExtract === undefined ) {
return []; return [];
} }
extract = removeParentheticals( extract ); extract = removeParentheticals( extract );
extract = removeEllipsis( extract ); extract = removeTrailingEllipsis( extract );
// After cleaning the extract it may have been blanked // After cleaning the extract it may have been blanked
if ( extract.length === 0 ) { if ( extract.length === 0 ) {
@ -78,7 +78,7 @@ function makeTitleInExtractBold( extract, title ) {
* @param {String} extract * @param {String} extract
* @return {String} * @return {String}
*/ */
function removeEllipsis( extract ) { function removeTrailingEllipsis( extract ) {
return extract.replace( /\.\.\.$/, '' ); return extract.replace( /\.\.\.$/, '' );
} }
@ -127,5 +127,7 @@ function removeParentheticals( extract ) {
} }
module.exports = { module.exports = {
htmlize: htmlize formatPlainTextExtract: formatPlainTextExtract,
removeTrailingEllipsis: removeTrailingEllipsis,
removeParentheticals: removeParentheticals
}; };

35
src/gateway/html/rest.js Normal file
View file

@ -0,0 +1,35 @@
var formatter = require( '../../formatter' ),
restbaseProvider = require( '../restProvider' ),
$ = jQuery;
/**
* Creates an instance of the RESTBase gateway.
*
* This gateway differs from the {@link MediaWikiGateway MediaWiki gateway} in
* that it fetches page data from [the RESTBase page summary endpoint][0].
*
* [0]: https://en.wikipedia.org/api/rest_v1/#!/Page_content/get_page_summary_title
*
* @param {Function} ajax A function with the same signature as `jQuery.ajax`
* @param {Object} config Configuration that affects the major behavior of the
* gateway.
* @param {Number} config.THUMBNAIL_SIZE The length of the major dimension of
* the thumbnail.
* @returns {RESTBaseGateway}
*/
module.exports = function createRESTHTMLBaseGateway( ajax, config ) {
return restbaseProvider( ajax, config, parseHTMLResponse );
};
/**
* Prepare extract
* @param {Object} page Rest response
* @returns {Array} An array of DOM Elements
*/
function parseHTMLResponse( page ) {
var extract = page.extract_html;
extract = formatter.removeTrailingEllipsis( extract );
extract = formatter.removeParentheticals( extract );
return extract.length === 0 ? [] : $.parseHTML( extract );
}

View file

@ -18,6 +18,7 @@
*/ */
module.exports = { module.exports = {
createMediaWikiApiGateway: require( './mediawiki' ), mwApiPlain: require( './plain/mediawiki' ),
createRESTBaseGateway: require( './rest' ) restbasePlain: require( './plain/rest' ),
restbaseHTML: require( './html/rest' )
}; };

View file

@ -13,8 +13,8 @@
// //
// FIXME: Move this to src/constants.js. // FIXME: Move this to src/constants.js.
var CACHE_LIFETIME = 300, var CACHE_LIFETIME = 300,
createModel = require( '../preview/model' ).createModel, modelBuilder = require( '../../preview/model' ),
plainTextHTMLizer = require( '../formatter' ).htmlize, formatter = require( '../../formatter' ),
$ = jQuery; $ = jQuery;
/** /**
@ -71,7 +71,7 @@ module.exports = function createMediaWikiApiGateway( api, config ) {
function getPageSummary( title ) { function getPageSummary( title ) {
return fetch( title ) return fetch( title )
.then( extractPageFromResponse ) .then( extractPageFromResponse )
.then( htmlize ) .then( formatPlainTextExtract )
.then( convertPageToModel ); .then( convertPageToModel );
} }
@ -80,7 +80,7 @@ module.exports = function createMediaWikiApiGateway( api, config ) {
extractPageFromResponse: extractPageFromResponse, extractPageFromResponse: extractPageFromResponse,
convertPageToModel: convertPageToModel, convertPageToModel: convertPageToModel,
getPageSummary: getPageSummary, getPageSummary: getPageSummary,
htmlize: htmlize formatPlainTextExtract: formatPlainTextExtract
}; };
}; };
@ -107,16 +107,16 @@ function extractPageFromResponse( data ) {
} }
/** /**
* HTMLize plain text response * Make plain text nicer by applying formatter.
* *
* @function * @function
* @name MediaWikiGateway#htmlize * @name MediaWikiGateway#formatPlainTextExtract
* @param {Object} data The response * @param {Object} data The response
* @returns {Object} * @returns {Object}
*/ */
function htmlize( data ) { function formatPlainTextExtract( data ) {
var result = $.extend( {}, data ); var result = $.extend( {}, data );
result.extract = plainTextHTMLizer( data.extract, data.title ); result.extract = formatter.formatPlainTextExtract( data.extract, data.title );
return result; return result;
} }
@ -129,7 +129,7 @@ function htmlize( data ) {
* @returns {PreviewModel} * @returns {PreviewModel}
*/ */
function convertPageToModel( page ) { function convertPageToModel( page ) {
return createModel( return modelBuilder.createModel(
page.title, page.title,
page.canonicalurl, page.canonicalurl,
page.pagelanguagehtmlcode, page.pagelanguagehtmlcode,

30
src/gateway/plain/rest.js Normal file
View file

@ -0,0 +1,30 @@
var formatter = require( '../../formatter' ),
restbaseProvider = require( '../restProvider' );
/**
* Creates an instance of the RESTBase gateway that returns plain text
*
* This gateway differs from the {@link MediaWikiGateway MediaWiki gateway} in
* that it fetches page data from [the RESTBase page summary endpoint][0].
*
* [0]: https://en.wikipedia.org/api/rest_v1/#!/Page_content/get_page_summary_title
*
* @param {Function} ajax A function with the same signature as `jQuery.ajax`
* @param {Object} config Configuration that affects the major behavior of the
* gateway.
* @param {Number} config.THUMBNAIL_SIZE The length of the major dimension of
* the thumbnail.
* @returns {RESTBaseGateway}
*/
module.exports = function createRESTBaseGateway( ajax, config ) {
return restbaseProvider( ajax, config, parsePlainTextResponse );
};
/**
* Prepare extract
* @param {Object} page Rest response
* @returns {Array} An array of DOM Elements
*/
function parsePlainTextResponse( page ) {
return formatter.formatPlainTextExtract( page.extract, page.title );
}

View file

@ -4,11 +4,9 @@
var RESTBASE_ENDPOINT = '/api/rest_v1/page/summary/', var RESTBASE_ENDPOINT = '/api/rest_v1/page/summary/',
RESTBASE_PROFILE = 'https://www.mediawiki.org/wiki/Specs/Summary/1.2.0', RESTBASE_PROFILE = 'https://www.mediawiki.org/wiki/Specs/Summary/1.2.0',
createModel = require( '../preview/model' ).createModel, modelBuilder = require( '../preview/model' ),
plainTextHTMLizer = require( '../formatter' ).htmlize,
mw = window.mediaWiki, mw = window.mediaWiki,
$ = jQuery; $ = jQuery;
/** /**
* @interface RESTBaseGateway * @interface RESTBaseGateway
* @extends Gateway * @extends Gateway
@ -29,9 +27,10 @@ var RESTBASE_ENDPOINT = '/api/rest_v1/page/summary/',
* gateway. * gateway.
* @param {Number} config.THUMBNAIL_SIZE The length of the major dimension of * @param {Number} config.THUMBNAIL_SIZE The length of the major dimension of
* the thumbnail. * the thumbnail.
* @param {Function} extractParser A function that takes response and returns parsed extract
* @returns {RESTBaseGateway} * @returns {RESTBaseGateway}
*/ */
module.exports = function createRESTBaseGateway( ajax, config ) { module.exports = function createRESTBaseGateway( ajax, config, extractParser ) {
/** /**
* Fetches page data from [the RESTBase page summary endpoint][0]. * Fetches page data from [the RESTBase page summary endpoint][0].
@ -60,17 +59,13 @@ module.exports = function createRESTBaseGateway( ajax, config ) {
.then( .then(
function ( page ) { function ( page ) {
result.resolve( result.resolve(
convertPageToModel( page, config.THUMBNAIL_SIZE ) ); convertPageToModel( page, config.THUMBNAIL_SIZE, extractParser ) );
}, },
function ( jqXHR ) { function ( jqXHR ) {
if ( jqXHR.status === 404 ) { if ( jqXHR.status === 404 ) {
result.resolve( result.resolve(
convertPageToModel( { modelBuilder.createNullModel( title )
title: title,
lang: '',
dir: '',
extract: ''
}, 0 )
); );
} else { } else {
result.reject(); result.reject();
@ -148,15 +143,16 @@ function generateThumbnailData( thumbnail, original, thumbSize ) {
* @name RESTBaseGateway#convertPageToModel * @name RESTBaseGateway#convertPageToModel
* @param {Object} page * @param {Object} page
* @param {Number} thumbSize * @param {Number} thumbSize
* @param {Function} extractParser
* @returns {PreviewModel} * @returns {PreviewModel}
*/ */
function convertPageToModel( page, thumbSize ) { function convertPageToModel( page, thumbSize, extractParser ) {
return createModel( return modelBuilder.createModel(
page.title, page.title,
new mw.Title( page.title ).getUrl(), new mw.Title( page.title ).getUrl(),
page.lang, page.lang,
page.dir, page.dir,
plainTextHTMLizer( page.extract, page.title ), extractParser( page ),
page.thumbnail ? generateThumbnailData( page.thumbnail, page.originalimage, thumbSize ) : undefined page.thumbnail ? generateThumbnailData( page.thumbnail, page.originalimage, thumbSize ) : undefined
); );
} }

View file

@ -8,8 +8,7 @@ var mw = mediaWiki,
ReduxThunk = require( 'redux-thunk' ), ReduxThunk = require( 'redux-thunk' ),
constants = require( './constants' ), constants = require( './constants' ),
createRESTBaseGateway = require( './gateway/rest' ), gatewayBuilder = require( './gateway/index' ),
createMediaWikiApiGateway = require( './gateway/mediawiki' ),
createUserSettings = require( './userSettings' ), createUserSettings = require( './userSettings' ),
createPreviewBehavior = require( './previewBehavior' ), createPreviewBehavior = require( './previewBehavior' ),
createSchema = require( './schema' ), createSchema = require( './schema' ),
@ -47,10 +46,16 @@ var mw = mediaWiki,
* @return {ext.popups.Gateway} * @return {ext.popups.Gateway}
*/ */
function createGateway( config ) { function createGateway( config ) {
if ( config.get( 'wgPopupsAPIUseRESTBase' ) ) { switch ( config.get( 'wgPopupsGateway' ) ) {
return createRESTBaseGateway( $.ajax, constants ); case 'mwApiPlain':
return gatewayBuilder.mwApiPlain( new mw.Api(), constants );
case 'restbasePlain':
return gatewayBuilder.restbasePlain( $.ajax, constants );
case 'restbaseHTML':
return gatewayBuilder.restbaseHTML( $.ajax, constants );
default:
throw new Error( 'Unknown gateway' );
} }
return createMediaWikiApiGateway( new mw.Api(), constants );
} }
/** /**

View file

@ -2,19 +2,15 @@
* @module preview/model * @module preview/model
*/ */
/**
* @constant {String}
*/
var TYPE_GENERIC = 'generic', var TYPE_GENERIC = 'generic',
/**
* @constant {String}
*/
TYPE_PAGE = 'page'; TYPE_PAGE = 'page';
/**
* @constant {String}
*/
exports.TYPE_GENERIC = TYPE_GENERIC;
/**
* @constant {String}
*/
exports.TYPE_PAGE = TYPE_PAGE;
/** /**
* @typedef {Object} PreviewModel * @typedef {Object} PreviewModel
* @property {String} title * @property {String} title
@ -24,11 +20,17 @@ exports.TYPE_PAGE = TYPE_PAGE;
* @property {?Array} extract `undefined` if the extract isn't * @property {?Array} extract `undefined` if the extract isn't
* viable, e.g. if it's empty after having ellipsis and parentheticals * viable, e.g. if it's empty after having ellipsis and parentheticals
* removed * removed
* @property {String} type Either "EXTRACT" or "GENERIC" * @property {String} type Either "extract" or "generic"
* @property {?Object} thumbnail * @property {?Object} thumbnail
* *
* @global * @global
*/ */
module.exports = {
TYPE_GENERIC: TYPE_GENERIC,
TYPE_PAGE: TYPE_PAGE,
createModel: createModel,
createNullModel: createNullModel
};
/** /**
* Creates a preview model. * Creates a preview model.
@ -41,7 +43,7 @@ exports.TYPE_PAGE = TYPE_PAGE;
* @param {?Object} thumbnail * @param {?Object} thumbnail
* @return {PreviewModel} * @return {PreviewModel}
*/ */
exports.createModel = function createModel( function createModel(
title, title,
url, url,
languageCode, languageCode,
@ -60,7 +62,17 @@ exports.createModel = function createModel(
type: processedExtract === undefined ? TYPE_GENERIC : TYPE_PAGE, type: processedExtract === undefined ? TYPE_GENERIC : TYPE_PAGE,
thumbnail: thumbnail thumbnail: thumbnail
}; };
}; }
/**
* Creates an empty preview model.
*
* @param {String} title
* @return {PreviewModel}
*/
function createNullModel( title ) {
return createModel( title, '', '', '', [], '' );
}
/** /**
* Processes the extract returned by the TextExtracts MediaWiki API query * Processes the extract returned by the TextExtracts MediaWiki API query
@ -69,11 +81,11 @@ exports.createModel = function createModel(
* If the extract is `undefined`, `null`, or empty, then `undefined` is * If the extract is `undefined`, `null`, or empty, then `undefined` is
* returned. * returned.
* *
* @param {?Array} extract * @param {Array|undefined|null} extract
* @return {?String} * @return {Array|undefined} Array when extract is an not empty array, undefined otherwise
*/ */
function processExtract( extract ) { function processExtract( extract ) {
if ( extract === undefined || extract.length === 0 ) { if ( extract === undefined || extract === null || extract.length === 0 ) {
return undefined; return undefined;
} }
return extract; return extract;

View file

@ -55,7 +55,7 @@ QUnit.test( 'Title is bold', function ( assert ) {
function test( extract, title, expected, msg ) { function test( extract, title, expected, msg ) {
var $div = $( '<div>' ).append( var $div = $( '<div>' ).append(
formatter.htmlize( extract, title ) formatter.formatPlainTextExtract( extract, title )
); );
assert.equal( $div.html(), expected, msg ); assert.equal( $div.html(), expected, msg );
} }
@ -86,7 +86,7 @@ QUnit.test( 'it strips ellipsis and parentheticals', function ( assert ) {
testCase = cases[ i ]; testCase = cases[ i ];
$div = $( '<div>' ).append( $div = $( '<div>' ).append(
formatter.htmlize( testCase[ 0 ], 'Test' ) formatter.formatPlainTextExtract( testCase[ 0 ], 'Test' )
); );
assert.equal( $div.html(), testCase[ 1 ] ); assert.equal( $div.html(), testCase[ 1 ] );

View file

@ -1,5 +1,5 @@
var createModel = require( '../../../src/preview/model' ).createModel, var createModel = require( '../../../src/preview/model' ).createModel,
createMediaWikiApiGateway = require( '../../../src/gateway/mediawiki' ), createMediaWikiApiGateway = require( '../../../src/gateway/plain/mediawiki' ),
DEFAULT_CONSTANTS = { DEFAULT_CONSTANTS = {
THUMBNAIL_SIZE: 300, THUMBNAIL_SIZE: 300,
EXTRACT_LENGTH: 525 EXTRACT_LENGTH: 525
@ -146,7 +146,7 @@ QUnit.test( 'MediaWiki API gateway is correctly converting the page data to a mo
page = gateway.extractPageFromResponse( MEDIAWIKI_API_RESPONSE ); page = gateway.extractPageFromResponse( MEDIAWIKI_API_RESPONSE );
assert.deepEqual( assert.deepEqual(
gateway.convertPageToModel( gateway.htmlize( page ) ), gateway.convertPageToModel( gateway.formatPlainTextExtract( page ) ),
MEDIAWIKI_API_RESPONSE_PREVIEW_MODEL MEDIAWIKI_API_RESPONSE_PREVIEW_MODEL
); );
} ); } );

View file

@ -1,5 +1,5 @@
var createModel = require( '../../../src/preview/model' ).createModel, var createModel = require( '../../../src/preview/model' ).createModel,
createRESTBaseGateway = require( '../../../src/gateway/rest' ), createRESTBaseGateway = require( '../../../src/gateway/restProvider' ),
DEFAULT_CONSTANTS = { DEFAULT_CONSTANTS = {
THUMBNAIL_SIZE: 512 THUMBNAIL_SIZE: 512
}, },
@ -97,7 +97,7 @@ var createModel = require( '../../../src/preview/model' ).createModel,
'url/Barack Obama', // Generated in the stub below 'url/Barack Obama', // Generated in the stub below
'en', 'en',
'ltr', 'ltr',
[ document.createTextNode( 'Barack Hussein Obama II born August 4, 1961) ' ) ], '!Barack Hussein Obama II born August 4, 1961) ...!',
{ {
source: 'https://upload.wikimedia.org/wikipedia/commons/thumb/8/8d/President_Barack_Obama.jpg/409px-President_Barack_Obama.jpg', source: 'https://upload.wikimedia.org/wikipedia/commons/thumb/8/8d/President_Barack_Obama.jpg/409px-President_Barack_Obama.jpg',
width: 409, width: 409,
@ -105,19 +105,17 @@ var createModel = require( '../../../src/preview/model' ).createModel,
} }
); );
function provideParsedExtract( page ) {
return '!' + page.extract + '!';
}
QUnit.module( 'gateway/rest', { QUnit.module( 'gateway/rest', {
beforeEach: function () { beforeEach: function () {
window.mediaWiki.RegExp = {
escape: this.sandbox.spy( function ( str ) {
return str.replace( /([\\{}()|.?*+\-\^$\[\]])/g, '\\$1' );
} )
};
window.mediaWiki.Title = function ( title ) { window.mediaWiki.Title = function ( title ) {
this.getUrl = function () { return 'url/' + title; }; this.getUrl = function () { return 'url/' + title; };
}; };
}, },
afterEach: function () { afterEach: function () {
window.mediaWiki.RegExp = null;
window.mediaWiki.Title = null; window.mediaWiki.Title = null;
} }
} ); } );
@ -134,15 +132,22 @@ QUnit.test( 'RESTBase gateway is called with correct arguments', function ( asse
}; };
gateway.fetch( 'Test Title' ); gateway.fetch( 'Test Title' );
assert.deepEqual( getSpy.getCall( 0 ).args[ 0 ], expectedOptions, 'options' ); assert.deepEqual( getSpy.getCall( 0 ).args[ 0 ], expectedOptions, 'options' );
} ); } );
QUnit.test( 'RESTBase provider uses extract parser', function ( assert ) {
var getSpy = this.sandbox.spy(),
gateway = createRESTBaseGateway();
gateway.convertPageToModel( RESTBASE_RESPONSE, 512, getSpy );
assert.deepEqual( getSpy.getCall( 0 ).args[ 0 ], RESTBASE_RESPONSE );
} );
QUnit.test( 'RESTBase gateway is correctly converting the page data to a model ', function ( assert ) { QUnit.test( 'RESTBase gateway is correctly converting the page data to a model ', function ( assert ) {
var gateway = createRESTBaseGateway(); var gateway = createRESTBaseGateway();
assert.deepEqual( assert.deepEqual(
gateway.convertPageToModel( RESTBASE_RESPONSE, 512 ), gateway.convertPageToModel( RESTBASE_RESPONSE, 512, provideParsedExtract ),
RESTBASE_RESPONSE_PREVIEW_MODEL RESTBASE_RESPONSE_PREVIEW_MODEL
); );
} ); } );
@ -151,7 +156,7 @@ QUnit.test( 'RESTBase gateway doesn\'t stretch thumbnails', function ( assert )
var model, var model,
gateway = createRESTBaseGateway(); gateway = createRESTBaseGateway();
model = gateway.convertPageToModel( RESTBASE_RESPONSE, 2000 ); model = gateway.convertPageToModel( RESTBASE_RESPONSE, 2000, provideParsedExtract );
assert.deepEqual( assert.deepEqual(
model.thumbnail, model.thumbnail,
@ -160,7 +165,7 @@ QUnit.test( 'RESTBase gateway doesn\'t stretch thumbnails', function ( assert )
); );
// --- // ---
model = gateway.convertPageToModel( RESTBASE_RESPONSE, RESTBASE_RESPONSE.originalimage.height ); model = gateway.convertPageToModel( RESTBASE_RESPONSE, RESTBASE_RESPONSE.originalimage.height, provideParsedExtract );
assert.deepEqual( assert.deepEqual(
model.thumbnail, model.thumbnail,
@ -169,7 +174,7 @@ QUnit.test( 'RESTBase gateway doesn\'t stretch thumbnails', function ( assert )
); );
// --- // ---
model = gateway.convertPageToModel( RESTBASE_RESPONSE_WITH_SMALL_IMAGE, 320 ); model = gateway.convertPageToModel( RESTBASE_RESPONSE_WITH_SMALL_IMAGE, 320, provideParsedExtract );
assert.deepEqual( assert.deepEqual(
model.thumbnail, model.thumbnail,
@ -178,7 +183,7 @@ QUnit.test( 'RESTBase gateway doesn\'t stretch thumbnails', function ( assert )
); );
// --- // ---
model = gateway.convertPageToModel( RESTBASE_RESPONSE_WITH_LANDSCAPE_IMAGE, 640 ); model = gateway.convertPageToModel( RESTBASE_RESPONSE_WITH_LANDSCAPE_IMAGE, 640, provideParsedExtract );
assert.deepEqual( assert.deepEqual(
model.thumbnail, model.thumbnail,
@ -200,7 +205,7 @@ QUnit.test( 'RESTBase gateway handles awkwardly thumbnails', function ( assert )
response.thumbnail = Object.assign( {}, RESTBASE_RESPONSE.thumbnail ); response.thumbnail = Object.assign( {}, RESTBASE_RESPONSE.thumbnail );
response.thumbnail.source = 'http://foo.bar/baz/Qux-320px-Quux.png/800px-Qux-320px-Quux.png'; response.thumbnail.source = 'http://foo.bar/baz/Qux-320px-Quux.png/800px-Qux-320px-Quux.png';
model = gateway.convertPageToModel( response, 500 ); model = gateway.convertPageToModel( response, 500, provideParsedExtract );
assert.deepEqual( assert.deepEqual(
model.thumbnail.source, model.thumbnail.source,
@ -213,7 +218,7 @@ QUnit.test( 'RESTBase gateway stretches SVGs', function ( assert ) {
var model, var model,
gateway = createRESTBaseGateway(); gateway = createRESTBaseGateway();
model = gateway.convertPageToModel( SVG_RESTBASE_RESPONSE, 2000 ); model = gateway.convertPageToModel( SVG_RESTBASE_RESPONSE, 2000, provideParsedExtract );
assert.equal( assert.equal(
model.thumbnail.source, model.thumbnail.source,
@ -238,7 +243,7 @@ QUnit.test( 'RESTBase gateway handles the API failure', function ( assert ) {
QUnit.test( 'RESTBase gateway does not treat a 404 as a failure', function ( assert ) { QUnit.test( 'RESTBase gateway does not treat a 404 as a failure', function ( assert ) {
var deferred = $.Deferred(), var deferred = $.Deferred(),
api = this.sandbox.stub().returns( deferred.reject( { status: 404 } ).promise() ), api = this.sandbox.stub().returns( deferred.reject( { status: 404 } ).promise() ),
gateway = createRESTBaseGateway( api ), gateway = createRESTBaseGateway( api, { THUMBNAIL_SIZE: 200 }, provideParsedExtract ),
done = assert.async( 1 ); done = assert.async( 1 );
gateway.getPageSummary( 'Test Title' ).done( function () { gateway.getPageSummary( 'Test Title' ).done( function () {
@ -251,7 +256,7 @@ QUnit.test( 'RESTBase gateway returns the correct data ', function ( assert ) {
var api = this.sandbox.stub().returns( var api = this.sandbox.stub().returns(
$.Deferred().resolve( RESTBASE_RESPONSE ).promise() $.Deferred().resolve( RESTBASE_RESPONSE ).promise()
), ),
gateway = createRESTBaseGateway( api, DEFAULT_CONSTANTS ), gateway = createRESTBaseGateway( api, DEFAULT_CONSTANTS, provideParsedExtract ),
done = assert.async( 1 ); done = assert.async( 1 );
gateway.getPageSummary( 'Test Title' ).done( function ( result ) { gateway.getPageSummary( 'Test Title' ).done( function ( result ) {
@ -263,7 +268,7 @@ QUnit.test( 'RESTBase gateway returns the correct data ', function ( assert ) {
QUnit.test( 'RESTBase gateway handles missing images ', function ( assert ) { QUnit.test( 'RESTBase gateway handles missing images ', function ( assert ) {
var model, var model,
gateway = createRESTBaseGateway(); gateway = createRESTBaseGateway();
model = gateway.convertPageToModel( RESTBASE_RESPONSE_WITHOUT_IMAGE, 300 ); model = gateway.convertPageToModel( RESTBASE_RESPONSE_WITHOUT_IMAGE, 300, provideParsedExtract );
assert.equal( assert.equal(
model.originalimage, model.originalimage,
@ -283,7 +288,7 @@ QUnit.test( 'RESTBase gateway handles missing pages ', function ( assert ) {
api = this.sandbox.stub().returns( api = this.sandbox.stub().returns(
$.Deferred().reject( response ).promise() $.Deferred().reject( response ).promise()
), ),
gateway = createRESTBaseGateway( api, DEFAULT_CONSTANTS ), gateway = createRESTBaseGateway( api, DEFAULT_CONSTANTS, provideParsedExtract ),
done = assert.async( 1 ); done = assert.async( 1 );
gateway.getPageSummary( 'Missing Page' ).fail( function () { gateway.getPageSummary( 'Missing Page' ).fail( function () {

View file

@ -178,7 +178,7 @@ class PopupsHooksTest extends MediaWikiTestCase {
$config = [ $config = [
'wgPopupsSchemaSamplingRate' => 10, 'wgPopupsSchemaSamplingRate' => 10,
'wgPopupsBetaFeature' => true, 'wgPopupsBetaFeature' => true,
'wgPopupsAPIUseRESTBase' => false, 'wgPopupsGateway' => 'mwApiPlain',
'wgPopupsAnonsEnabledSamplingRate' => 0.9, 'wgPopupsAnonsEnabledSamplingRate' => 0.9,
'wgPopupsStatsvSamplingRate' => 0 'wgPopupsStatsvSamplingRate' => 0
]; ];