Tests: Add custom attribute getter tests to the selector module
[jquery.git] / test / data / mock.php
blob105f9867be796ee141257289da66259723cc0bbe
1 <?php
3 /**
4 * Keep in sync with /test/middleware-mockserver.cjs
5 */
6 function cleanCallback( $callback ) {
7 return preg_replace( '/[^a-z0-9_]/i', '', $callback );
10 class MockServer {
11 protected function contentType( $req ) {
12 $type = $req->query['contentType'];
13 header("Content-type: $type");
14 echo $req->query['response'];
17 protected function wait( $req ) {
18 $wait = (int) $req->query['wait'];
19 sleep( $wait );
20 if ( isset( $req->query['script'] ) ) {
21 header( 'Content-type: text/javascript' );
22 } else {
23 header( 'Content-type: text/html' );
24 echo 'ERROR <script>QUnit.assert.ok( true, "mock executed" );</script>';
28 protected function name( $req ) {
29 if ( $req->query['name'] === 'foo' ) {
30 echo 'bar';
31 } elseif ( $_POST['name'] === 'peter' ) {
32 echo 'pan';
33 } else {
34 echo 'ERROR';
38 protected function xml( $req ) {
39 header( 'Content-type: text/xml' );
40 if ( $req->query['cal'] !== '5-2' && $_POST['cal'] !== '5-2' ) {
41 echo '<error>ERROR</error>';
42 return;
44 echo "<math><calculation>5-2</calculation><result>3</result></math>\n";
47 protected function atom( $req ) {
48 header( 'Content-type: atom+xml' );
49 echo '<root><element /></root>';
52 protected function script( $req ) {
53 if ( isset( $req->query['header'] ) ) {
54 if ( $req->query['header'] === 'ecma' ) {
55 header( 'Content-type: application/ecmascript' );
56 } else {
57 header( 'Content-type: text/javascript' );
59 } else {
60 header( 'Content-type: text/html' );
63 if ( !empty( $req->query['cors'] ) ) {
64 header( "Access-Control-Allow-Origin: *" );
67 if ( !empty( $req->query['callback'] ) ) {
68 $headers = array_combine(
69 array_map( 'strtolower', array_keys( $req->headers ) ),
70 array_values( $req->headers )
73 echo cleanCallback( $req->query['callback'] ) .
74 "(" . json_encode( [ 'headers' => $headers ] ) . ")";
75 } else {
76 echo 'QUnit.assert.ok( true, "mock executed" );';
80 // Used to be in test.js, but was renamed to testbar.php
81 // https://github.com/jquery/jquery/commit/d89c278a33#commitcomment-23423165
82 protected function testbar( $req ) {
83 echo 'this.testBar = "bar";
84 jQuery("#ap").html("bar");
85 QUnit.assert.ok( true, "mock executed");';
88 protected function json( $req ) {
89 if ( isset( $req->query['header'] ) ) {
90 header( 'Content-type: application/json' );
93 if ( isset( $req->query['cors'] ) ) {
94 header( 'Access-Control-Allow-Origin: *' );
97 if ( isset( $req->query['array'] ) ) {
98 echo '[ {"name": "John", "age": 21}, {"name": "Peter", "age": 25 } ]';
99 } else {
100 echo '{ "data": {"lang": "en", "length": 25} }';
104 protected function jsonp( $req ) {
105 if ( isset( $req->query['callback'] ) ) {
106 $callback = $req->query['callback'];
107 } elseif ( $req->method === 'GET' ) {
108 // Try REST-like path
109 preg_match( '/\/([^\/?]+)\?.+$/', $req->url, $m );
110 $callback = $m[1];
111 } else {
112 $callback = $_POST['callback'];
114 $json = isset( $req->query['array'] ) ?
115 '[ { "name": "John", "age": 21 }, { "name": "Peter", "age": 25 } ]' :
116 '{ "data": { "lang": "en", "length": 25 } }';
117 echo cleanCallback( $callback ) . '(' . $json . ')';
120 protected function xmlOverJsonp( $req ) {
121 $callback = $_REQUEST['callback'];
122 $cleanCallback = cleanCallback( $callback );
123 $text = json_encode( file_get_contents( __DIR__ . '/with_fries.xml' ) );
124 echo "$cleanCallback($text)\n";
127 protected function formData( $req ) {
128 $prefix = 'multipart/form-data; boundary=--';
129 $contentTypeValue = $req->headers[ 'CONTENT-TYPE' ];
130 if ( substr( $contentTypeValue, 0, strlen( $prefix ) ) === $prefix ) {
131 echo 'key1 -> ' . $_POST[ 'key1' ] . ', key2 -> ' . $_POST[ 'key2' ];
132 } else {
133 echo 'Incorrect Content-Type: ' . $contentTypeValue .
134 "\nExpected prefix: " . $prefix;
138 protected function error( $req ) {
139 header( 'HTTP/1.0 400 Bad Request' );
140 if ( isset( $req->query['json'] ) ) {
141 header( 'Content-Type: application/json' );
142 echo '{ "code": 40, "message": "Bad Request" }';
143 } else {
144 echo 'plain text message';
148 protected function headers( $req ) {
149 header( 'Sample-Header: Hello World' );
150 header( 'Empty-Header: ' );
151 header( 'Sample-Header2: Hello World 2' );
152 header( 'List-Header: Item 1' );
153 header( 'list-header: Item 2', FALSE );
154 header( 'constructor: prototype collision (constructor)' );
156 foreach ( explode( '|' , $req->query[ 'keys' ] ) as $key ) {
157 // Only echo if key exists in the header
158 if ( isset( $req->headers[ strtoupper( $key ) ] ) ) {
159 echo "$key: " . $req->headers[ strtoupper( $key ) ] . "\n";
165 protected function echoData( $req ) {
166 echo file_get_contents('php://input');
169 protected function echoQuery( $req ) {
170 echo $_SERVER['QUERY_STRING'];
173 protected function echoMethod( $req ) {
174 echo $req->method;
177 protected function echoHtml( $req ) {
178 header( 'Content-type: text/html' );
179 echo '<div id="method">' . $req->method . '</div>';
180 echo '<div id="query">' . $_SERVER['QUERY_STRING'] . '</div>';
181 echo '<div id="data">' . file_get_contents('php://input') . '</div>';
184 protected function etag( $req ) {
185 $hash = md5( $req->query['ts'] );
186 $etag = 'W/"' . $hash . '"';
188 $ifNoneMatch = isset( $req->headers['IF-NONE-MATCH'] ) ? $req->headers['IF-NONE-MATCH'] : '';
189 if ($ifNoneMatch === $etag) {
190 header('HTTP/1.0 304 Not Modified');
191 return;
194 header("Etag: $etag");
195 echo "ETag: $etag\n";
196 if ( $ifNoneMatch ) {
197 echo "If-None-Match: $ifNoneMatch\n";
201 protected function ims( $req ) {
202 $ts = $req->query['ts'];
204 $ims = isset( $req->headers['IF-MODIFIED-SINCE'] ) ? $req->headers['IF-MODIFIED-SINCE'] : '';
205 if ($ims === $ts) {
206 header('HTTP/1.0 304 Not Modified');
207 return;
210 header("Last-Modified: $ts");
211 echo "Last-Modified: $ts\n";
212 if ( $ims ) {
213 echo "If-Modified-Since: $ims\n";
217 protected function status( $req ) {
218 header( "HTTP/1.0 {$req->query['code']} {$req->query['text']}" );
221 protected function testHTML( $req ) {
222 header( 'Content-type: text/html' );
223 $html = file_get_contents( __DIR__ . '/test.include.html' );
224 $html = str_replace( '{{baseURL}}', $req->query['baseURL'], $html );
225 echo $html;
228 protected function cspFrame( $req ) {
229 header( "Content-Security-Policy: default-src 'self'; require-trusted-types-for 'script'; report-uri ./mock.php?action=cspLog" );
230 header( 'Content-type: text/html' );
231 echo file_get_contents( __DIR__ . '/csp.include.html' );
234 protected function cspNonce( $req ) {
235 $test = $req->query['test'] ? '-' . $req->query['test'] : '';
236 header( "Content-Security-Policy: script-src 'nonce-jquery+hardcoded+nonce'; report-uri ./mock.php?action=cspLog" );
237 header( 'Content-type: text/html' );
238 echo file_get_contents( __DIR__ . '/csp-nonce' . $test . '.html' );
241 protected function cspAjaxScript( $req ) {
242 header( "Content-Security-Policy: script-src 'self'; report-uri ./mock.php?action=cspLog" );
243 header( 'Content-type: text/html' );
244 echo file_get_contents( __DIR__ . '/csp-ajax-script.html' );
247 protected function cspLog( $req ) {
248 file_put_contents( $this->cspFile, 'error' );
251 protected function cspClean( $req ) {
252 file_put_contents( $this->cspFile, '' );
255 protected function trustedHtml( $req ) {
256 header( "Content-Security-Policy: require-trusted-types-for 'script'; report-uri ./mock.php?action=cspLog" );
257 header( 'Content-type: text/html' );
258 echo file_get_contents( __DIR__ . '/trusted-html.html' );
261 protected function trustedTypesAttributes( $req ) {
262 header( "Content-Security-Policy: require-trusted-types-for 'script'; report-uri ./mock.php?action=cspLog" );
263 header( 'Content-type: text/html' );
264 echo file_get_contents( __DIR__ . '/trusted-types-attributes.html' );
267 protected function errorWithScript( $req ) {
268 header( 'HTTP/1.0 404 Not Found' );
269 if ( isset( $req->query['withScriptContentType'] ) ) {
270 header( 'Content-Type: application/javascript' );
272 if ( isset( $req->query['callback'] ) ) {
273 $callback = $req->query['callback'];
274 echo cleanCallback( $callback ) . '( {"status": 404, "msg": "Not Found"} )';
275 } else {
276 echo 'QUnit.assert.ok( false, "Mock return erroneously executed" );';
280 public function __construct() {
281 $this->cspFile = __DIR__ . '/support/csp.log';
284 public function respond( stdClass $req ) {
285 if ( !isset( $req->query['action'] ) || !method_exists( $this, $req->query['action'] ) ) {
286 header( "HTTP/1.0 400 Bad Request" );
287 echo "Invalid action query.\n";
288 return;
290 $this->{$req->query['action']}( $req );
294 // Don't include PHP errors in http response
295 error_reporting( 0 );
297 // Collect headers
298 $headers = array();
299 foreach ( $_SERVER as $name => $value ) {
300 if ( substr( $name, 0, 5 ) === 'HTTP_' ) {
301 $name = str_replace( '_', '-', substr( $name, 5 ) );
302 $headers[$name] = $value;
303 } elseif ( $name === 'CONTENT_LENGTH' ) {
304 $headers['CONTENT-LENGTH'] = $value;
305 } elseif ( $name === 'CONTENT_TYPE' ) {
306 $headers['CONTENT-TYPE'] = $value;
310 $mock = new MockServer();
311 $req = (object) array(
312 'query' => $_GET,
313 'headers' => $headers,
314 'method' => $_SERVER['REQUEST_METHOD'],
315 'url' => $_SERVER['REQUEST_URI'],
317 $mock->respond( $req );