1<?php 2namespace CorsSlim\Tests; 3 4class CorsSlimRouteTest extends \PHPUnit_Framework_TestCase { 5 public function setUp() { 6 ob_start(); 7 } 8 public function tearDown() { 9 ob_end_clean(); 10 } 11 12 private function runApp($action, $actionName, $mwOptions = NULL, $headers = array()) { 13 \Slim\Environment::mock(array( 14 'REQUEST_METHOD' => 'GET', 15 'SERVER_NAME' => 'localhost', 16 'SERVER_PORT' => 80, 17 'ACCEPT' => 'application/json', 18 'SCRIPT_NAME' => '/index.php', 19 'PATH_INFO' => '/'. $actionName 20 )); 21 $app = new \Slim\Slim(); 22 $app->setName($actionName); 23 24 $mw = function() { 25 // Do nothing 26 }; 27 if (isset($mwOptions)) { 28 if (is_callable($mwOptions)) { 29 $mw = $mwOptions; 30 } 31 else { 32 $mwOptions['appName'] = $actionName; 33 $mw = \CorsSlim\CorsSlim::routeMiddleware($mwOptions); 34 } 35 } 36 37 $app->get('/:name', $mw, function ($name) use ($app, $action) { 38 if ($app->request->isHead()) { 39 $app->status(204); 40 return; 41 } 42 43 $app->contentType('application/json'); 44 $app->response->write(json_encode(array( 45 "action" => $action, 46 "method" => "GET", 47 "name" => $name 48 ) 49 ) 50 ); 51 }); 52 53 foreach ($headers as $key => $value) { 54 $app->request->headers()->set($key, $value); 55 } 56 57 $app->run(); 58 59 $this->validate($app, 'GET', $action, $actionName); 60 61 return $app; 62 } 63 64 private function runAppHead($action, $actionName, $mwOptions = NULL, $headers = array()) { 65 \Slim\Environment::mock(array( 66 'REQUEST_METHOD' => 'HEAD', 67 'SERVER_NAME' => 'localhost', 68 'SERVER_PORT' => 80, 69 'ACCEPT' => 'application/json', 70 'SCRIPT_NAME' => '/index.php', 71 'PATH_INFO' => '/'. $actionName 72 )); 73 $app = new \Slim\Slim(); 74 $app->setName($actionName); 75 76 $mw = function() { 77 // Do nothing 78 }; 79 if (isset($mwOptions)) { 80 if (is_callable($mwOptions)) { 81 $mw = $mwOptions; 82 } 83 else { 84 $mwOptions['appName'] = $actionName; 85 $mw = \CorsSlim\CorsSlim::routeMiddleware($mwOptions); 86 } 87 } 88 89 $app->get('/:name', $mw, function ($name) use ($app, $action) { 90 if ($app->request->isHead()) { 91 $app->status(204); 92 return; 93 } 94 95 $app->contentType('application/json'); 96 $app->response->write(json_encode(array( 97 "action" => $action, 98 "method" => "GET", 99 "name" => $name 100 ) 101 ) 102 ); 103 }); 104 105 foreach ($headers as $key => $value) { 106 $app->request->headers()->set($key, $value); 107 } 108 109 $app->run(); 110 111 $this->assertEquals(204, $app->response()->status()); 112 113 return $app; 114 } 115 116 private function runAppPost($action, $actionName, $mwOptions = NULL, $headers = array()) { 117 \Slim\Environment::mock(array( 118 'REQUEST_METHOD' => 'POST', 119 'SERVER_NAME' => 'localhost', 120 'SERVER_PORT' => 80, 121 'ACCEPT' => 'application/json', 122 'SCRIPT_NAME' => '/index.php', 123 'PATH_INFO' => '/'. $actionName 124 )); 125 $app = new \Slim\Slim(); 126 $app->setName($actionName); 127 128 $mw = function() { 129 // Do nothing 130 }; 131 if (isset($mwOptions)) { 132 if (is_callable($mwOptions)) { 133 $mw = $mwOptions; 134 } 135 else { 136 $mwOptions['appName'] = $actionName; 137 $mw = \CorsSlim\CorsSlim::routeMiddleware($mwOptions); 138 } 139 } 140 141 $app->post('/:name', $mw, function ($name) use ($app, $action) { 142 if ($app->request->isHead()) { 143 $app->status(204); 144 return; 145 } 146 147 $app->contentType('application/json'); 148 $app->response->write(json_encode(array( 149 "action" => $action, 150 "method" => "POST", 151 "name" => $name 152 ) 153 ) 154 ); 155 }); 156 157 foreach ($headers as $key => $value) { 158 $app->request->headers()->set($key, $value); 159 } 160 161 $app->run(); 162 163 $this->validate($app, 'POST', $action, $actionName); 164 165 return $app; 166 } 167 168 private function runAppPreFlight($action, $actionName, $mwOptions = NULL, $headers = array()) { 169 \Slim\Environment::mock(array( 170 'REQUEST_METHOD' => 'OPTIONS', 171 'SERVER_NAME' => 'localhost', 172 'SERVER_PORT' => 80, 173 'ACCEPT' => 'application/json', 174 'SCRIPT_NAME' => '/index.php', 175 'PATH_INFO' => '/'. $actionName 176 )); 177 $app = new \Slim\Slim(); 178 $app->setName($actionName); 179 180 $mw = function() { 181 // Do nothing 182 }; 183 if (isset($mwOptions)) { 184 if (is_callable($mwOptions)) { 185 $mw = $mwOptions; 186 } 187 else { 188 $mwOptions['appName'] = $actionName; 189 $mw = \CorsSlim\CorsSlim::routeMiddleware($mwOptions); 190 } 191 } 192 193 $app->options('/:name', $mw, function ($name) use ($app, $action) { 194 }); 195 196 $app->delete('/:name', $mw, function ($name) use ($app, $action) { 197 if ($app->request->isHead()) { 198 $app->status(204); 199 return; 200 } 201 202 203 $app->contentType('application/json'); 204 $app->response->write(json_encode(array( 205 "action" => $action, 206 "method" => "DELETE", 207 "name" => $name 208 ) 209 ) 210 ); 211 }); 212 213 foreach ($headers as $key => $value) { 214 $app->request->headers()->set($key, $value); 215 } 216 217 $app->run(); 218 219 return $app; 220 } 221 222 private function validate($app, $method, $action, $name) { 223 $this->assertEquals(200, $app->response()->status()); 224 $this->assertEquals("application/json", $app->response()->header("Content-Type")); 225 226 $content = json_decode($app->response()->body()); 227 $this->assertEquals($action, $content->action); 228 $this->assertEquals($method, $content->method); 229 $this->assertEquals($name, $content->name); 230 } 231 232 public function testDefaultCors() { 233 $app = $this->runApp('cors', 'DefaultCors', array()); 234 $this->assertEquals("*", $app->response()->header("Access-Control-Allow-Origin")); 235 } 236 237 public function testCorsOrigin() { 238 $app = $this->runApp('cors-origin', 'CorsOrigin', array("origin" => "*")); 239 $this->assertEquals("*", $app->response()->header("Access-Control-Allow-Origin")); 240 } 241 242 public function testCorsOriginSingle() { 243 $app = $this->runApp('cors-origin-single', 'CorsOriginSingle', array("origin" => "http://github.com", "appName" => "CorsOriginSingle")); 244 $this->assertEquals("http://github.com", $app->response()->header("Access-Control-Allow-Origin")); 245 } 246 247 public function testCorsOriginArray() { 248 $app = $this->runApp('cors-origin-array', 'CorsOriginArray', array("origin" => array("http://mozilla.com", "http://php.net", "http://github.com"))); 249 $this->assertEquals("http://mozilla.com", $app->response()->header("Access-Control-Allow-Origin")); 250 } 251 252 public function testCorsOriginArraySpecific() { 253 $mwOptions = array("origin" => array("http://mozilla.com", "http://php.net", "http://github.com")); 254 $headers = array('origin' => 'http://php.net'); 255 $app = $this->runApp('cors-origin-array-specific', 'CorsOriginArraySpecific', $mwOptions, $headers); 256 $this->assertEquals("http://php.net", $app->response()->header("Access-Control-Allow-Origin")); 257 } 258 259 public function testCorsOriginCallable() { 260 $mwOptions = array("origin" => function($reqOrigin) { return $reqOrigin;}); 261 $headers = array('origin' => 'http://www.slimframework.com/'); 262 $app = $this->runApp('cors-origin-callable', 'CorsOriginCallable', $mwOptions, $headers); 263 $this->assertEquals("http://www.slimframework.com/", $app->response()->header("Access-Control-Allow-Origin")); 264 } 265 266 // Simple Requests 267 public function testSimpleCorsRequestFail() { 268 $app = $this->runApp('cors', 'SimpleCorsRequestFail'); 269 $this->assertNull($app->response()->header("Access-Control-Allow-Origin")); 270 } 271 272 public function testSimpleCorsRequest() { 273 $app = $this->runApp('cors', 'SimpleCorsRequest', array()); 274 $this->assertEquals("*", $app->response()->header("Access-Control-Allow-Origin")); 275 } 276 277 public function testSimpleCorsRequestHeadFail() { 278 $app = $this->runAppHead('cors', 'SimpleCorsRequestHeadFail'); 279 $this->assertNull($app->response()->header("Access-Control-Allow-Origin")); 280 } 281 282 public function testSimpleCorsRequestHead() { 283 $app = $this->runAppHead('cors', 'SimpleCorsRequestHead', array()); 284 $this->assertEquals("*", $app->response()->header("Access-Control-Allow-Origin")); 285 } 286 287 public function testSimpleCorsRequestPostFail() { 288 $app = $this->runAppPost('cors', 'SimpleCorsRequestPostFail'); 289 $this->assertNull($app->response()->header("Access-Control-Allow-Origin")); 290 } 291 292 public function testSimpleCorsRequestPost() { 293 $app = $this->runAppPost('cors', 'SimpleCorsRequestPost', array()); 294 $this->assertEquals("*", $app->response()->header("Access-Control-Allow-Origin")); 295 } 296 297 // Complex Requests (With Pre-Flight) 298 public function testComplexCorsRequestPreFlightFail() { 299 $app = $this->runAppPreFlight('cors', 'ComplexCorsRequestPreFlightFail'); 300 $this->assertEquals(200, $app->response()->status()); 301 $this->assertNull($app->response()->header("Access-Control-Allow-Origin")); 302 } 303 304 public function testComplexCorsRequestPreFlight() { 305 $app = $this->runAppPreFlight('cors', 'ComplexCorsRequestPreFlight', array()); 306 $this->assertEquals(200, $app->response()->status()); 307 $this->assertEquals("*", $app->response()->header("Access-Control-Allow-Origin")); 308 } 309 310 // Access-Control-Expose-Headers 311 public function testAccessControlExposeHeaders() { 312 $app = $this->runApp('cors', 'SimpleCorsRequestAccessControlExposeHeaders', array('exposeHeaders' => 'X-My-Custom-Header')); 313 $this->assertEquals("X-My-Custom-Header", $app->response()->header("Access-Control-Expose-Headers")); 314 } 315 316 public function testAccessControlExposeHeadersArray() { 317 $app = $this->runApp('cors', 'SimpleCorsRequesAccessControlExposeHeadersArrayt', array('exposeHeaders' => array("X-My-Custom-Header", "X-Another-Custom-Header"))); 318 $this->assertEquals("X-My-Custom-Header, X-Another-Custom-Header", $app->response()->header("Access-Control-Expose-Headers")); 319 } 320 321 // Access-Control-Max-Age 322 public function testAccessControlMaxAge() { 323 $app = $this->runAppPreFlight('cors', 'SimpleCorsRequestAccessControlMaxAge', array('maxAge' => 1728000)); 324 $this->assertEquals(200, $app->response()->status()); 325 $this->assertEquals(1728000, $app->response()->header("Access-Control-Max-Age")); 326 } 327 328 // Access-Control-Allow-Credentials 329 public function testAccessControlAllowCredentials() { 330 $app = $this->runApp('cors', 'SimpleCorsRequestAccessControlAllowCredentials', array('allowCredentials' => True)); 331 $this->assertEquals("true", $app->response()->header("Access-Control-Allow-Credentials")); 332 } 333 334 // Access-Control-Allow-Methods 335 public function testAccessControlAllowMethods() { 336 $app = $this->runAppPreFlight('cors', 'SimpleCorsRequestAccessControlAllowMethods', array('allowMethods' => array('GET', 'POST'))); 337 $this->assertEquals(200, $app->response()->status()); 338 $this->assertEquals('GET, POST', $app->response()->header("Access-Control-Allow-Methods")); 339 } 340 341 // Access-Control-Allow-Headers 342 public function testAccessControlAllowHeaders() { 343 $app = $this->runAppPreFlight('cors', 'SimpleCorsRequestAccessControlAllowHeaders', array("allowHeaders" => array("X-PINGOTHER"))); 344 $this->assertEquals(200, $app->response()->status()); 345 $this->assertEquals('X-PINGOTHER', $app->response()->header("Access-Control-Allow-Headers")); 346 } 347}