Move REST search client out of WVUI into Vector
Bug: T288686 Depends-on: I4afc8c38dc9c51d55b46b766a1417b1266963482 Change-Id: Iac6023bb6edca5c8dddc3bfd362db727b2534946
This commit is contained in:
parent
7084f9a9df
commit
3e92800bd6
|
@ -2,3 +2,4 @@
|
|||
// @ts-nocheck
|
||||
var mockMediaWiki = require( '@wikimedia/mw-node-qunit/src/mockMediaWiki.js' );
|
||||
global.mw = mockMediaWiki();
|
||||
global.$ = require('jquery');
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
"linkMap": {
|
||||
"\"addEventListener\"": "https://developer.mozilla.org/docs/Web/API/EventTarget/addEventListener",
|
||||
"jQuery": "https://api.jquery.com",
|
||||
"AbortSignal": "https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal",
|
||||
"Document": "https://developer.mozilla.org/docs/Web/API/Document",
|
||||
"Element": "https://developer.mozilla.org/docs/Web/API/Element",
|
||||
"Event": "https://developer.mozilla.org/docs/Web/API/Event",
|
||||
|
@ -31,11 +32,11 @@
|
|||
"HTMLInputElement": "https://developer.mozilla.org/docs/Web/API/HTMLInputElement",
|
||||
"\"removeEventListener\"": "https://developer.mozilla.org/docs/Web/API/EventTarget/removeEventListener",
|
||||
"Window": "https://developer.mozilla.org/docs/Web/API/Window",
|
||||
|
||||
"CheckboxHack": "https://doc.wikimedia.org/mediawiki-core/master/js",
|
||||
|
||||
"MW": "https://doc.wikimedia.org/mediawiki-core/master/js/#!/api/mw",
|
||||
"MediaWikiPageReadyModule": "https://doc.wikimedia.org/mediawiki-core/master/js/#!/api/mw.plugin.page.ready",
|
||||
"MW": "https://doc.wikimedia.org/mediawiki-core/master/js/#!/api/mw",
|
||||
"MwMap": "https://doc.wikimedia.org/mediawiki-core/master/js/#!/api/mw.Map",
|
||||
"RequestInit": "https://developer.mozilla.org/en-US/docs/Web/API/Request/Request",
|
||||
"JQueryStatic": "https://api.jquery.com",
|
||||
"VectorResourceLoaderVirtualConfig": "#",
|
||||
"void": "#",
|
||||
|
|
|
@ -19,8 +19,9 @@
|
|||
"eslint-config-wikimedia": "0.20.0",
|
||||
"grunt-banana-checker": "0.9.0",
|
||||
"jest": "26.4.2",
|
||||
"jest-fetch-mock": "3.0.3",
|
||||
"jsdoc": "3.6.7",
|
||||
"jsdoc-wmf-theme": "0.0.3",
|
||||
"jsdoc-wmf-theme": "0.0.5",
|
||||
"less": "3.8.1",
|
||||
"less-loader": "4.1.0",
|
||||
"mustache": "3.0.1",
|
||||
|
@ -7607,6 +7608,57 @@
|
|||
"react": "^0.14.0 || ^15.0.0 || ^16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/cross-fetch": {
|
||||
"version": "3.1.5",
|
||||
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz",
|
||||
"integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"node-fetch": "2.6.7"
|
||||
}
|
||||
},
|
||||
"node_modules/cross-fetch/node_modules/node-fetch": {
|
||||
"version": "2.6.7",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
||||
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "4.x || >=6.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"encoding": "^0.1.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"encoding": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/cross-fetch/node_modules/tr46": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/cross-fetch/node_modules/webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/cross-fetch/node_modules/whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
"integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"tr46": "~0.0.3",
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
|
||||
|
@ -14172,6 +14224,16 @@
|
|||
"node": ">= 10.14.2"
|
||||
}
|
||||
},
|
||||
"node_modules/jest-fetch-mock": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/jest-fetch-mock/-/jest-fetch-mock-3.0.3.tgz",
|
||||
"integrity": "sha512-Ux1nWprtLrdrH4XwE7O7InRY6psIi3GOsqNESJgMJ+M5cv4A8Lh7SN9d2V2kKRZ8ebAfcd1LNyZguAOb6JiDqw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"cross-fetch": "^3.0.4",
|
||||
"promise-polyfill": "^8.1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/jest-get-type": {
|
||||
"version": "26.3.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz",
|
||||
|
@ -15793,9 +15855,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/jsdoc-wmf-theme": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/jsdoc-wmf-theme/-/jsdoc-wmf-theme-0.0.3.tgz",
|
||||
"integrity": "sha512-jpszk0hcjY7bD1sCd8JrBdtcoudG0h9FbJTjdq8WOSEtUBNWgtIc7s1ccDoYnK/bp4OEuA7xH0xtpqe0SVutsw==",
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/jsdoc-wmf-theme/-/jsdoc-wmf-theme-0.0.5.tgz",
|
||||
"integrity": "sha512-YRVucO3yiKF6a54oIR+gQLDynO60o2m0lOiCBCws0vIORJOn9T++tGJrOCVy5TSaSAmJTX1cnTbUCH7L+c1JCw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"domino": "^2.0.1",
|
||||
|
@ -18861,6 +18923,12 @@
|
|||
"integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/promise-polyfill": {
|
||||
"version": "8.2.1",
|
||||
"resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-8.2.1.tgz",
|
||||
"integrity": "sha512-3p9zj0cEHbp7NVUxEYUWjQlffXqnXaZIMPkAO7HhFh8u5636xLRDHOUo2vpWSK0T2mqm6fKLXYn1KP6PAZ2gKg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/promise.allsettled": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/promise.allsettled/-/promise.allsettled-1.0.4.tgz",
|
||||
|
@ -30772,6 +30840,48 @@
|
|||
"warning": "^4.0.3"
|
||||
}
|
||||
},
|
||||
"cross-fetch": {
|
||||
"version": "3.1.5",
|
||||
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz",
|
||||
"integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"node-fetch": "2.6.7"
|
||||
},
|
||||
"dependencies": {
|
||||
"node-fetch": {
|
||||
"version": "2.6.7",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
||||
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"tr46": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=",
|
||||
"dev": true
|
||||
},
|
||||
"webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=",
|
||||
"dev": true
|
||||
},
|
||||
"whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
"integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"tr46": "~0.0.3",
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"cross-spawn": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
|
||||
|
@ -35892,6 +36002,16 @@
|
|||
"jest-util": "^26.6.2"
|
||||
}
|
||||
},
|
||||
"jest-fetch-mock": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/jest-fetch-mock/-/jest-fetch-mock-3.0.3.tgz",
|
||||
"integrity": "sha512-Ux1nWprtLrdrH4XwE7O7InRY6psIi3GOsqNESJgMJ+M5cv4A8Lh7SN9d2V2kKRZ8ebAfcd1LNyZguAOb6JiDqw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cross-fetch": "^3.0.4",
|
||||
"promise-polyfill": "^8.1.3"
|
||||
}
|
||||
},
|
||||
"jest-get-type": {
|
||||
"version": "26.3.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz",
|
||||
|
@ -37144,9 +37264,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"jsdoc-wmf-theme": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/jsdoc-wmf-theme/-/jsdoc-wmf-theme-0.0.3.tgz",
|
||||
"integrity": "sha512-jpszk0hcjY7bD1sCd8JrBdtcoudG0h9FbJTjdq8WOSEtUBNWgtIc7s1ccDoYnK/bp4OEuA7xH0xtpqe0SVutsw==",
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/jsdoc-wmf-theme/-/jsdoc-wmf-theme-0.0.5.tgz",
|
||||
"integrity": "sha512-YRVucO3yiKF6a54oIR+gQLDynO60o2m0lOiCBCws0vIORJOn9T++tGJrOCVy5TSaSAmJTX1cnTbUCH7L+c1JCw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"domino": "^2.0.1",
|
||||
|
@ -39569,6 +39689,12 @@
|
|||
"integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=",
|
||||
"dev": true
|
||||
},
|
||||
"promise-polyfill": {
|
||||
"version": "8.2.1",
|
||||
"resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-8.2.1.tgz",
|
||||
"integrity": "sha512-3p9zj0cEHbp7NVUxEYUWjQlffXqnXaZIMPkAO7HhFh8u5636xLRDHOUo2vpWSK0T2mqm6fKLXYn1KP6PAZ2gKg==",
|
||||
"dev": true
|
||||
},
|
||||
"promise.allsettled": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/promise.allsettled/-/promise.allsettled-1.0.4.tgz",
|
||||
|
|
|
@ -31,8 +31,9 @@
|
|||
"eslint-config-wikimedia": "0.20.0",
|
||||
"grunt-banana-checker": "0.9.0",
|
||||
"jest": "26.4.2",
|
||||
"jest-fetch-mock": "3.0.3",
|
||||
"jsdoc": "3.6.7",
|
||||
"jsdoc-wmf-theme": "0.0.3",
|
||||
"jsdoc-wmf-theme": "0.0.5",
|
||||
"less": "3.8.1",
|
||||
"less-loader": "4.1.0",
|
||||
"mustache": "3.0.1",
|
||||
|
|
|
@ -1,5 +1,16 @@
|
|||
{
|
||||
"extends": [
|
||||
"../../.eslintrcEs6.json"
|
||||
]
|
||||
],
|
||||
"rules": {
|
||||
"jsdoc/no-undefined-types": [
|
||||
"error",
|
||||
{
|
||||
"definedTypes": [
|
||||
"RequestInit",
|
||||
"MwMap"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
<script>
|
||||
/* global SubmitEvent */
|
||||
const wvui = require( 'wvui-search' ),
|
||||
client = require( './restSearchClient.js' ),
|
||||
instrumentation = require( './instrumentation.js' );
|
||||
|
||||
module.exports = {
|
||||
|
@ -62,10 +63,10 @@ module.exports = {
|
|||
/**
|
||||
* Allow wikis eg. Hebrew Wikipedia to replace the default search API client
|
||||
*
|
||||
* @return {void|Object}
|
||||
* @return {module:restSearchClient~SearchClient}
|
||||
*/
|
||||
getClient: () => {
|
||||
return mw.config.get( 'wgVectorSearchClient', undefined );
|
||||
return client( mw.config );
|
||||
},
|
||||
language: () => {
|
||||
return mw.config.get( 'wgUserLanguage' );
|
||||
|
|
|
@ -0,0 +1,184 @@
|
|||
/** @module restSearchClient */
|
||||
|
||||
/**
|
||||
* @typedef {Object} AbortableFetch
|
||||
* @property {Promise<any>} fetch
|
||||
* @property {Function} abort
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} NullableAbortController
|
||||
* @property {AbortSignal | undefined} signal
|
||||
* @property {Function} abort
|
||||
*/
|
||||
const nullAbortController = {
|
||||
signal: undefined,
|
||||
abort: () => {} // Do nothing (no-op)
|
||||
};
|
||||
|
||||
/**
|
||||
* A wrapper which combines native fetch() in browsers and the following json() call.
|
||||
*
|
||||
* @param {string} resource
|
||||
* @param {RequestInit} [init]
|
||||
* @return {AbortableFetch}
|
||||
*/
|
||||
function fetchJson( resource, init ) {
|
||||
// As of 2020, browser support for AbortController is limited:
|
||||
// https://caniuse.com/abortcontroller
|
||||
// so replacing it with no-op if it doesn't exist.
|
||||
/* eslint-disable compat/compat */
|
||||
const controller = window.AbortController ?
|
||||
new AbortController() :
|
||||
nullAbortController;
|
||||
/* eslint-enable compat/compat */
|
||||
|
||||
const getJson = fetch( resource, $.extend( init, {
|
||||
signal: controller.signal
|
||||
} ) ).then( ( response ) => {
|
||||
if ( !response.ok ) {
|
||||
return Promise.reject(
|
||||
'Network request failed with HTTP code ' + response.status
|
||||
);
|
||||
}
|
||||
return response.json();
|
||||
} );
|
||||
|
||||
return {
|
||||
fetch: getJson,
|
||||
abort: () => {
|
||||
controller.abort();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} RestResponse
|
||||
* @property {RestResult[]} pages
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} RestResult
|
||||
* @property {number} id
|
||||
* @property {string} key
|
||||
* @property {string} title
|
||||
* @property {string} [description]
|
||||
* @property {RestThumbnail | null} [thumbnail]
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} RestThumbnail
|
||||
* @property {string} url
|
||||
* @property {number | null} [width]
|
||||
* @property {number | null} [height]
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} SearchResponse
|
||||
* @property {string} query
|
||||
* @property {SearchResult[]} results
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} SearchResult
|
||||
* @property {number} id
|
||||
* @property {string} key
|
||||
* @property {string} title
|
||||
* @property {string} [description]
|
||||
* @property {SearchResultThumbnail} [thumbnail]
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} SearchResultThumbnail
|
||||
* @property {string} url
|
||||
* @property {number} [width]
|
||||
* @property {number} [height]
|
||||
*/
|
||||
|
||||
/**
|
||||
* Nullish coalescing operator (??) helper
|
||||
*
|
||||
* @param {any} a
|
||||
* @param {any} b
|
||||
* @return {any}
|
||||
*/
|
||||
function nullish( a, b ) {
|
||||
return ( a !== null && a !== undefined ) ? a : b;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} query
|
||||
* @param {RestResponse} restResponse
|
||||
* @return {SearchResponse}
|
||||
*/
|
||||
function adaptApiResponse( query, restResponse ) {
|
||||
return {
|
||||
query,
|
||||
results: restResponse.pages.map( ( page ) => {
|
||||
const thumbnail = page.thumbnail;
|
||||
return {
|
||||
id: page.id,
|
||||
key: page.key,
|
||||
title: page.title,
|
||||
description: page.description,
|
||||
thumbnail: thumbnail ? {
|
||||
url: thumbnail.url,
|
||||
width: nullish( thumbnail.width, undefined ),
|
||||
height: nullish( thumbnail.height, undefined )
|
||||
} : undefined
|
||||
};
|
||||
} )
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} AbortableSearchFetch
|
||||
* @property {Promise<SearchResponse>} fetch
|
||||
* @property {Function} abort
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback fetchByTitle
|
||||
* @param {string} query The search term.
|
||||
* @param {string} domain The base URL for the wiki without protocol. Example: 'sr.wikipedia.org'.
|
||||
* @param {number} [limit] Maximum number of results.
|
||||
* @return {AbortableSearchFetch}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} SearchClient
|
||||
* @property {fetchByTitle} fetchByTitle
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {MwMap} config
|
||||
* @return {SearchClient}
|
||||
*/
|
||||
function restSearchClient( config ) {
|
||||
const customClient = config.get( 'wgVectorSearchClient' );
|
||||
return customClient || {
|
||||
/**
|
||||
* @type {fetchByTitle}
|
||||
*/
|
||||
fetchByTitle: ( q, domain, limit = 10 ) => {
|
||||
const params = { q, limit };
|
||||
const url = '//' + domain + config.get( 'wgScriptPath' ) + '/rest.php/v1/search/title?' + $.param( params );
|
||||
const result = fetchJson( url, {
|
||||
headers: {
|
||||
accept: 'application/json'
|
||||
}
|
||||
} );
|
||||
const searchResponsePromise = result.fetch
|
||||
.then( ( /** @type {RestResponse} */ res ) => {
|
||||
return adaptApiResponse( q, res );
|
||||
} );
|
||||
return {
|
||||
abort: result.abort,
|
||||
fetch: searchResponsePromise
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = restSearchClient;
|
|
@ -145,6 +145,7 @@
|
|||
"packageFiles": [
|
||||
"resources/skins.vector.search/skins.vector.search.js",
|
||||
"resources/skins.vector.search/instrumentation.js",
|
||||
"resources/skins.vector.search/restSearchClient.js",
|
||||
"resources/skins.vector.search/App.vue",
|
||||
{
|
||||
"name": "resources/skins.vector.search/config.json",
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
/* global fetchMock */
|
||||
const restSearchClient = require( '../../resources/skins.vector.search/restSearchClient.js' );
|
||||
const jestFetchMock = require( 'jest-fetch-mock' );
|
||||
|
||||
const mockedRequests = !process.env.TEST_LIVE_REQUESTS;
|
||||
const configMock = {
|
||||
get: jest.fn().mockImplementation( key => {
|
||||
if ( key === 'wgScriptPath' ) {
|
||||
return '/w';
|
||||
}
|
||||
return null;
|
||||
} ),
|
||||
set: jest.fn()
|
||||
};
|
||||
|
||||
describe( 'restApiSearchClient', () => {
|
||||
beforeAll( () => {
|
||||
jestFetchMock.enableFetchMocks();
|
||||
} );
|
||||
|
||||
afterAll( () => {
|
||||
jestFetchMock.disableFetchMocks();
|
||||
} );
|
||||
|
||||
beforeEach( () => {
|
||||
fetchMock.resetMocks();
|
||||
if ( !mockedRequests ) {
|
||||
fetchMock.disableMocks();
|
||||
}
|
||||
} );
|
||||
|
||||
test( '2 results', async () => {
|
||||
const thumbUrl = '//upload.wikimedia.org/wikipedia/commons/0/01/MediaWiki-smaller-logo.png';
|
||||
const restResponse = {
|
||||
pages: [
|
||||
{
|
||||
id: 37298,
|
||||
key: 'Media',
|
||||
title: 'Media',
|
||||
description: 'Wikimedia disambiguation page',
|
||||
thumbnail: null
|
||||
},
|
||||
{
|
||||
id: 323710,
|
||||
key: 'MediaWiki',
|
||||
title: 'MediaWiki',
|
||||
description: 'wiki software',
|
||||
thumbnail: {
|
||||
width: 200,
|
||||
height: 189,
|
||||
url: thumbUrl
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
fetchMock.mockOnce( JSON.stringify( restResponse ) );
|
||||
|
||||
const searchResult = await restSearchClient( configMock ).fetchByTitle(
|
||||
'media',
|
||||
'en.wikipedia.org',
|
||||
2
|
||||
).fetch;
|
||||
|
||||
/* eslint-disable-next-line compat/compat */
|
||||
const controller = new AbortController();
|
||||
|
||||
expect( searchResult.query ).toStrictEqual( 'media' );
|
||||
expect( searchResult.results ).toBeTruthy();
|
||||
expect( searchResult.results.length ).toBe( 2 );
|
||||
|
||||
expect( searchResult.results[ 0 ] ).toStrictEqual(
|
||||
Object.assign( {}, restResponse.pages[ 0 ], {
|
||||
// thumbnail: null -> thumbnail: undefined
|
||||
thumbnail: undefined
|
||||
} ) );
|
||||
expect( searchResult.results[ 1 ] ).toStrictEqual( restResponse.pages[ 1 ] );
|
||||
|
||||
if ( mockedRequests ) {
|
||||
expect( fetchMock ).toHaveBeenCalledTimes( 1 );
|
||||
expect( fetchMock ).toHaveBeenCalledWith(
|
||||
'//en.wikipedia.org/w/rest.php/v1/search/title?q=media&limit=2',
|
||||
{ headers: { accept: 'application/json' }, signal: controller.signal }
|
||||
);
|
||||
}
|
||||
} );
|
||||
|
||||
test( '0 results', async () => {
|
||||
const restResponse = { pages: [] };
|
||||
fetchMock.mockOnce( JSON.stringify( restResponse ) );
|
||||
|
||||
const searchResult = await restSearchClient( configMock ).fetchByTitle(
|
||||
'thereIsNothingLikeThis',
|
||||
'en.wikipedia.org'
|
||||
).fetch;
|
||||
|
||||
/* eslint-disable-next-line compat/compat */
|
||||
const controller = new AbortController();
|
||||
expect( searchResult.query ).toStrictEqual( 'thereIsNothingLikeThis' );
|
||||
expect( searchResult.results ).toBeTruthy();
|
||||
expect( searchResult.results.length ).toBe( 0 );
|
||||
|
||||
if ( mockedRequests ) {
|
||||
expect( fetchMock ).toHaveBeenCalledTimes( 1 );
|
||||
expect( fetchMock ).toHaveBeenCalledWith(
|
||||
'//en.wikipedia.org/w/rest.php/v1/search/title?q=thereIsNothingLikeThis&limit=10',
|
||||
{ headers: { accept: 'application/json' }, signal: controller.signal }
|
||||
);
|
||||
}
|
||||
} );
|
||||
|
||||
if ( mockedRequests ) {
|
||||
test( 'network error', async () => {
|
||||
fetchMock.mockRejectOnce( new Error( 'failed' ) );
|
||||
|
||||
await expect( restSearchClient( configMock ).fetchByTitle(
|
||||
'anything',
|
||||
'en.wikipedia.org'
|
||||
).fetch ).rejects.toThrow( 'failed' );
|
||||
} );
|
||||
}
|
||||
} );
|
Loading…
Reference in New Issue