Build: Migrate middleware-mockserver to modern JS

The `test/middleware-mockserver.js` file used to have the same ESLint
settings applied as other test files that are directly run in tested
browsers. Now it shares settings of other Node.js files.

The file is now also written using modern JS, leveraging ES2018.

Closes gh-5196

(cherry picked from commit ce90a48450)
This commit is contained in:
Michał Gołębiowski-Owczarek 2023-01-23 23:20:08 +01:00
parent e062f9cbc6
commit 6b2abbdc46
No known key found for this signature in database
2 changed files with 65 additions and 49 deletions

View File

@ -57,6 +57,14 @@
}, },
"overrides": [ "overrides": [
{
"files": [
"middleware-mockserver.js"
],
"extends": "../.eslintrc-node.json"
},
{ {
"files": [ "files": [
"data/core/jquery-iterability-transpiled-es6.js", "data/core/jquery-iterability-transpiled-es6.js",

View File

@ -1,9 +1,11 @@
/* eslint-env node */ "use strict";
var url = require( "url" );
var fs = require( "fs" ); const url = require( "url" );
var getRawBody = require( "raw-body" ); const fs = require( "fs" );
const getRawBody = require( "raw-body" );
let cspLog = "";
var cspLog = "";
/** /**
* Keep in sync with /test/mock.php * Keep in sync with /test/mock.php
*/ */
@ -11,7 +13,7 @@ function cleanCallback( callback ) {
return callback.replace( /[^a-z0-9_]/gi, "" ); return callback.replace( /[^a-z0-9_]/gi, "" );
} }
var mocks = { const mocks = {
contentType: function( req, resp ) { contentType: function( req, resp ) {
resp.writeHead( 200, { resp.writeHead( 200, {
"content-type": req.query.contentType "content-type": req.query.contentType
@ -19,7 +21,7 @@ var mocks = {
resp.end( req.query.response ); resp.end( req.query.response );
}, },
wait: function( req, resp ) { wait: function( req, resp ) {
var wait = Number( req.query.wait ) * 1000; const wait = Number( req.query.wait ) * 1000;
setTimeout( function() { setTimeout( function() {
if ( req.query.script ) { if ( req.query.script ) {
resp.writeHead( 200, { "content-type": "text/javascript" } ); resp.writeHead( 200, { "content-type": "text/javascript" } );
@ -44,7 +46,7 @@ var mocks = {
}, next ); }, next );
}, },
xml: function( req, resp, next ) { xml: function( req, resp, next ) {
var content = "<math><calculation>5-2</calculation><result>3</result></math>"; const content = "<math><calculation>5-2</calculation><result>3</result></math>";
resp.writeHead( 200, { "content-type": "text/xml" } ); resp.writeHead( 200, { "content-type": "text/xml" } );
if ( req.query.cal === "5-2" ) { if ( req.query.cal === "5-2" ) {
@ -59,7 +61,7 @@ var mocks = {
} }
}, next ); }, next );
}, },
atom: function( req, resp, next ) { atom: function( _req, resp ) {
resp.writeHead( 200, { "content-type": "atom+xml" } ); resp.writeHead( 200, { "content-type": "atom+xml" } );
resp.end( "<root><element /></root>" ); resp.end( "<root><element /></root>" );
}, },
@ -73,7 +75,7 @@ var mocks = {
} }
resp.end( "QUnit.assert.ok( true, \"mock executed\" );" ); resp.end( "QUnit.assert.ok( true, \"mock executed\" );" );
}, },
testbar: function( req, resp ) { testbar: function( _req, resp ) {
resp.writeHead( 200 ); resp.writeHead( 200 );
resp.end( resp.end(
"this.testBar = 'bar'; " + "this.testBar = 'bar'; " +
@ -96,7 +98,7 @@ var mocks = {
} }
}, },
jsonp: function( req, resp, next ) { jsonp: function( req, resp, next ) {
var callback; let callback;
if ( Array.isArray( req.query.callback ) ) { if ( Array.isArray( req.query.callback ) ) {
callback = Promise.resolve( req.query.callback[ req.query.callback.length - 1 ] ); callback = Promise.resolve( req.query.callback[ req.query.callback.length - 1 ] );
} else if ( req.query.callback ) { } else if ( req.query.callback ) {
@ -108,7 +110,7 @@ var mocks = {
return body.trim().replace( "callback=", "" ); return body.trim().replace( "callback=", "" );
} ); } );
} }
var json = req.query.array ? const json = req.query.array ?
JSON.stringify( JSON.stringify(
[ { name: "John", age: 21 }, { name: "Peter", age: 25 } ] [ { name: "John", age: 21 }, { name: "Peter", age: 25 } ]
) : ) :
@ -116,14 +118,14 @@ var mocks = {
{ data: { lang: "en", length: 25 } } { data: { lang: "en", length: 25 } }
); );
callback.then( function( cb ) { callback.then( function( cb ) {
resp.end( cleanCallback( cb ) + "(" + json + ")" ); resp.end( `${ cleanCallback( cb ) }(${ json })` );
}, next ); }, next );
}, },
xmlOverJsonp: function( req, resp ) { xmlOverJsonp: function( req, resp ) {
var callback = req.query.callback; const callback = req.query.callback;
var body = fs.readFileSync( __dirname + "/data/with_fries.xml" ).toString(); const body = fs.readFileSync( `${ __dirname }/data/with_fries.xml` ).toString();
resp.writeHead( 200 ); resp.writeHead( 200 );
resp.end( cleanCallback( callback ) + "(" + JSON.stringify( body ) + ")\n" ); resp.end( `${ cleanCallback( callback ) }(${ JSON.stringify( body ) })\n` );
}, },
error: function( req, resp ) { error: function( req, resp ) {
if ( req.query.json ) { if ( req.query.json ) {
@ -144,8 +146,8 @@ var mocks = {
"constructor": "prototype collision (constructor)" "constructor": "prototype collision (constructor)"
} ); } );
req.query.keys.split( "|" ).forEach( function( key ) { req.query.keys.split( "|" ).forEach( function( key ) {
if ( req.headers[ key.toLowerCase() ] ) { if ( key.toLowerCase() in req.headers ) {
resp.write( key + ": " + req.headers[ key.toLowerCase() ] + "\n" ); resp.write( `${ key }: ${ req.headers[ key.toLowerCase() ] }\n` );
} }
} ); } );
resp.end(); resp.end();
@ -163,16 +165,16 @@ var mocks = {
}, },
echoHtml: function( req, resp, next ) { echoHtml: function( req, resp, next ) {
resp.writeHead( 200, { "Content-Type": "text/html" } ); resp.writeHead( 200, { "Content-Type": "text/html" } );
resp.write( "<div id='method'>" + req.method + "</div>" ); resp.write( `<div id='method'>${ req.method }</div>` );
resp.write( "<div id='query'>" + req.parsed.search.slice( 1 ) + "</div>" ); resp.write( `<div id='query'>${ req.parsed.search.slice( 1 ) }</div>` );
getBody( req ).then( function( body ) { getBody( req ).then( function( body ) {
resp.write( "<div id='data'>" + body + "</div>" ); resp.write( `<div id='data'>${ body }</div>` );
resp.end( body ); resp.end( body );
}, next ); }, next );
}, },
etag: function( req, resp ) { etag: function( req, resp ) {
var hash = Number( req.query.ts ).toString( 36 ); const hash = Number( req.query.ts ).toString( 36 );
var etag = "W/\"" + hash + "\""; const etag = `W/"${ hash }"`;
if ( req.headers[ "if-none-match" ] === etag ) { if ( req.headers[ "if-none-match" ] === etag ) {
resp.writeHead( 304 ); resp.writeHead( 304 );
resp.end(); resp.end();
@ -183,8 +185,8 @@ var mocks = {
} ); } );
resp.end(); resp.end();
}, },
ims: function( req, resp, next ) { ims: function( req, resp ) {
var ts = req.query.ts; const ts = req.query.ts;
if ( req.headers[ "if-modified-since" ] === ts ) { if ( req.headers[ "if-modified-since" ] === ts ) {
resp.writeHead( 304 ); resp.writeHead( 304 );
resp.end(); resp.end();
@ -195,40 +197,44 @@ var mocks = {
} ); } );
resp.end(); resp.end();
}, },
status: function( req, resp, next ) { status: function( req, resp ) {
resp.writeHead( Number( req.query.code ) ); resp.writeHead( Number( req.query.code ) );
resp.end(); resp.end();
}, },
testHTML: function( req, resp ) { testHTML: function( req, resp ) {
resp.writeHead( 200, { "Content-Type": "text/html" } ); resp.writeHead( 200, { "Content-Type": "text/html" } );
var body = fs.readFileSync( __dirname + "/data/test.include.html" ).toString(); const body = fs
body = body.replace( /{{baseURL}}/g, req.query.baseURL ); .readFileSync( `${ __dirname }/data/test.include.html` )
.toString()
.replace( /{{baseURL}}/g, req.query.baseURL );
resp.end( body ); resp.end( body );
}, },
cspFrame: function( req, resp ) { cspFrame: function( _req, resp ) {
resp.writeHead( 200, { resp.writeHead( 200, {
"Content-Type": "text/html", "Content-Type": "text/html",
"Content-Security-Policy": "default-src 'self'; report-uri /base/test/data/mock.php?action=cspLog" "Content-Security-Policy": "default-src 'self'; " +
"report-uri /base/test/data/mock.php?action=cspLog"
} ); } );
var body = fs.readFileSync( __dirname + "/data/csp.include.html" ).toString(); const body = fs.readFileSync( `${ __dirname }/data/csp.include.html` ).toString();
resp.end( body ); resp.end( body );
}, },
cspNonce: function( req, resp ) { cspNonce: function( req, resp ) {
var testParam = req.query.test ? "-" + req.query.test : ""; const testParam = req.query.test ? `-${ req.query.test }` : "";
resp.writeHead( 200, { resp.writeHead( 200, {
"Content-Type": "text/html", "Content-Type": "text/html",
"Content-Security-Policy": "script-src 'nonce-jquery+hardcoded+nonce'; report-uri /base/test/data/mock.php?action=cspLog" "Content-Security-Policy": "script-src 'nonce-jquery+hardcoded+nonce'; " +
"report-uri /base/test/data/mock.php?action=cspLog"
} ); } );
var body = fs.readFileSync( const body = fs.readFileSync(
__dirname + "/data/csp-nonce" + testParam + ".html" ).toString(); `${ __dirname }/data/csp-nonce${ testParam }.html` ).toString();
resp.end( body ); resp.end( body );
}, },
cspLog: function( req, resp ) { cspLog: function( _req, resp ) {
cspLog = "error"; cspLog = "error";
resp.writeHead( 200 ); resp.writeHead( 200 );
resp.end(); resp.end();
}, },
cspClean: function( req, resp ) { cspClean: function( _req, resp ) {
cspLog = ""; cspLog = "";
resp.writeHead( 200 ); resp.writeHead( 200 );
resp.end(); resp.end();
@ -240,14 +246,14 @@ var mocks = {
resp.writeHead( 404, { "Content-Type": "text/html; charset=UTF-8" } ); resp.writeHead( 404, { "Content-Type": "text/html; charset=UTF-8" } );
} }
if ( req.query.callback ) { if ( req.query.callback ) {
resp.end( cleanCallback( req.query.callback ) + resp.end( `${ cleanCallback( req.query.callback )
"( {\"status\": 404, \"msg\": \"Not Found\"} )" ); }( {"status": 404, "msg": "Not Found"} )` );
} else { } else {
resp.end( "QUnit.assert.ok( false, \"Mock return erroneously executed\" );" ); resp.end( "QUnit.assert.ok( false, \"Mock return erroneously executed\" );" );
} }
} }
}; };
var handlers = { const handlers = {
"test/data/mock.php": function( req, resp, next ) { "test/data/mock.php": function( req, resp, next ) {
if ( !mocks[ req.query.action ] ) { if ( !mocks[ req.query.action ] ) {
resp.writeHead( 400 ); resp.writeHead( 400 );
@ -257,11 +263,11 @@ var handlers = {
} }
mocks[ req.query.action ]( req, resp, next ); mocks[ req.query.action ]( req, resp, next );
}, },
"test/data/support/csp.log": function( req, resp ) { "test/data/support/csp.log": function( _req, resp ) {
resp.writeHead( 200 ); resp.writeHead( 200 );
resp.end( cspLog ); resp.end( cspLog );
}, },
"test/data/404.txt": function( req, resp ) { "test/data/404.txt": function( _req, resp ) {
resp.writeHead( 404 ); resp.writeHead( 404 );
resp.end( "" ); resp.end( "" );
} }
@ -276,21 +282,23 @@ var handlers = {
* Express versions of these (e.g. no req.path, req.query, resp.set). * Express versions of these (e.g. no req.path, req.query, resp.set).
*/ */
function MockserverMiddlewareFactory() { function MockserverMiddlewareFactory() {
/** /**
* @param {http.IncomingMessage} req * @param {http.IncomingMessage} req
* @param {http.ServerResponse} resp * @param {http.ServerResponse} resp
* @param {Function} next Continue request handling * @param {Function} next Continue request handling
*/ */
return function( req, resp, next ) { return function( req, resp, next ) {
var parsed = url.parse( req.url, /* parseQuery */ true ), const parsed = url.parse( req.url, /* parseQuery */ true );
path = parsed.pathname.replace( /^\/base\//, "" ), let path = parsed.pathname.replace( /^\/base\//, "" );
query = parsed.query, const query = parsed.query;
subReq = Object.assign( Object.create( req ), { const subReq = Object.assign( Object.create( req ), {
query: query, query: query,
parsed: parsed parsed: parsed
} ); } );
if ( /^test\/data\/mock.php\//.test( path ) ) { if ( /^test\/data\/mock.php\//.test( path ) ) {
// Support REST-like Apache PathInfo // Support REST-like Apache PathInfo
path = "test\/data\/mock.php"; path = "test\/data\/mock.php";
} }