RequestHandlerComponentTest.php 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918
  1. <?php
  2. /**
  3. * RequestHandlerComponentTest file
  4. *
  5. * PHP 5
  6. *
  7. * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
  8. * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
  9. *
  10. * Licensed under The MIT License
  11. * Redistributions of files must retain the above copyright notice
  12. *
  13. * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
  14. * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
  15. * @package Cake.Test.Case.Controller.Component
  16. * @since CakePHP(tm) v 1.2.0.5435
  17. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  18. */
  19. App::uses('Controller', 'Controller');
  20. App::uses('RequestHandlerComponent', 'Controller/Component');
  21. App::uses('CakeRequest', 'Network');
  22. App::uses('CakeResponse', 'Network');
  23. App::uses('Router', 'Routing');
  24. App::uses('JsonView', 'View');
  25. /**
  26. * RequestHandlerTestController class
  27. *
  28. * @package Cake.Test.Case.Controller.Component
  29. */
  30. class RequestHandlerTestController extends Controller {
  31. /**
  32. * uses property
  33. *
  34. * @var mixed null
  35. */
  36. public $uses = null;
  37. /**
  38. * test method for ajax redirection
  39. *
  40. * @return void
  41. */
  42. public function destination() {
  43. $this->viewPath = 'Posts';
  44. $this->render('index');
  45. }
  46. /**
  47. * test method for ajax redirection + parameter parsing
  48. *
  49. * @return void
  50. */
  51. public function param_method($one = null, $two = null) {
  52. echo "one: $one two: $two";
  53. $this->autoRender = false;
  54. }
  55. /**
  56. * test method for testing layout rendering when isAjax()
  57. *
  58. * @return void
  59. */
  60. public function ajax2_layout() {
  61. if ($this->autoLayout) {
  62. $this->layout = 'ajax2';
  63. }
  64. $this->destination();
  65. }
  66. }
  67. class CustomJsonView extends JsonView {
  68. /**
  69. * Test method for viewClassMap and overriding _serialize()
  70. */
  71. protected function _serialize($serialize) {
  72. return json_encode(array('return' => 'ok'));
  73. }
  74. }
  75. /**
  76. * RequestHandlerComponentTest class
  77. *
  78. * @package Cake.Test.Case.Controller.Component
  79. */
  80. class RequestHandlerComponentTest extends CakeTestCase {
  81. /**
  82. * Controller property
  83. *
  84. * @var RequestHandlerTestController
  85. */
  86. public $Controller;
  87. /**
  88. * RequestHandler property
  89. *
  90. * @var RequestHandlerComponent
  91. */
  92. public $RequestHandler;
  93. /**
  94. * setUp method
  95. *
  96. * @return void
  97. */
  98. public function setUp() {
  99. parent::setUp();
  100. $this->_init();
  101. }
  102. /**
  103. * init method
  104. *
  105. * @return void
  106. */
  107. protected function _init() {
  108. $request = new CakeRequest('controller_posts/index');
  109. $response = new CakeResponse();
  110. $this->Controller = new RequestHandlerTestController($request, $response);
  111. $this->Controller->constructClasses();
  112. $this->RequestHandler = new RequestHandlerComponent($this->Controller->Components);
  113. $this->_extensions = Router::extensions();
  114. }
  115. /**
  116. * tearDown method
  117. *
  118. * @return void
  119. */
  120. public function tearDown() {
  121. parent::tearDown();
  122. unset($this->RequestHandler, $this->Controller);
  123. if (!headers_sent()) {
  124. header('Content-type: text/html'); //reset content type.
  125. }
  126. call_user_func_array('Router::parseExtensions', $this->_extensions);
  127. }
  128. /**
  129. * Test that the constructor sets the settings.
  130. *
  131. * @return void
  132. */
  133. public function testConstructorSettings() {
  134. $settings = array(
  135. 'ajaxLayout' => 'test_ajax',
  136. 'viewClassMap' => array('json' => 'MyPlugin.MyJson')
  137. );
  138. $Collection = new ComponentCollection();
  139. $Collection->init($this->Controller);
  140. $RequestHandler = new RequestHandlerComponent($Collection, $settings);
  141. $this->assertEquals('test_ajax', $RequestHandler->ajaxLayout);
  142. $this->assertEquals(array('json' => 'MyPlugin.MyJson'), $RequestHandler->settings['viewClassMap']);
  143. }
  144. /**
  145. * testInitializeCallback method
  146. *
  147. * @return void
  148. */
  149. public function testInitializeCallback() {
  150. $this->assertNull($this->RequestHandler->ext);
  151. $this->Controller->request->params['ext'] = 'rss';
  152. $this->RequestHandler->initialize($this->Controller);
  153. $this->assertEquals('rss', $this->RequestHandler->ext);
  154. }
  155. /**
  156. * test that a mapped Accept-type header will set $this->ext correctly.
  157. *
  158. * @return void
  159. */
  160. public function testInitializeContentTypeSettingExt() {
  161. $this->assertNull($this->RequestHandler->ext);
  162. $_SERVER['HTTP_ACCEPT'] = 'application/json';
  163. Router::parseExtensions('json');
  164. $this->RequestHandler->initialize($this->Controller);
  165. $this->assertEquals('json', $this->RequestHandler->ext);
  166. }
  167. /**
  168. * Test that RequestHandler sets $this->ext when jQuery sends its wonky-ish headers.
  169. *
  170. * @return void
  171. */
  172. public function testInitializeContentTypeWithjQueryAccept() {
  173. $_SERVER['HTTP_ACCEPT'] = 'application/json, application/javascript, */*; q=0.01';
  174. $this->assertNull($this->RequestHandler->ext);
  175. Router::parseExtensions('json');
  176. $this->RequestHandler->initialize($this->Controller);
  177. $this->assertEquals('json', $this->RequestHandler->ext);
  178. }
  179. /**
  180. * Test that RequestHandler sets $this->ext when jQuery sends its wonky-ish headers
  181. * and the application is configured to handle multiple extensions
  182. *
  183. * @return void
  184. */
  185. public function testInitializeContentTypeWithjQueryAcceptAndMultiplesExtensions() {
  186. $_SERVER['HTTP_ACCEPT'] = 'application/json, application/javascript, */*; q=0.01';
  187. $this->assertNull($this->RequestHandler->ext);
  188. Router::parseExtensions('rss', 'json');
  189. $this->RequestHandler->initialize($this->Controller);
  190. $this->assertEquals('json', $this->RequestHandler->ext);
  191. }
  192. /**
  193. * Test that RequestHandler does not set $this->ext when multiple accepts are sent.
  194. *
  195. * @return void
  196. */
  197. public function testInitializeNoContentTypeWithSingleAccept() {
  198. $_SERVER['HTTP_ACCEPT'] = 'application/json, text/html, */*; q=0.01';
  199. $this->assertNull($this->RequestHandler->ext);
  200. Router::parseExtensions('json');
  201. $this->RequestHandler->initialize($this->Controller);
  202. $this->assertNull($this->RequestHandler->ext);
  203. }
  204. /**
  205. * Test that ext is not set with multiple accepted content types.
  206. *
  207. * @return void
  208. */
  209. public function testInitializeNoContentTypeWithMultipleAcceptedTypes() {
  210. $_SERVER['HTTP_ACCEPT'] = 'application/json, application/javascript, application/xml, */*; q=0.01';
  211. $this->assertNull($this->RequestHandler->ext);
  212. Router::parseExtensions('xml', 'json');
  213. $this->RequestHandler->initialize($this->Controller);
  214. $this->assertNull($this->RequestHandler->ext);
  215. }
  216. /**
  217. * Test that ext is not set with confusing android accepts headers.
  218. *
  219. * @return void
  220. */
  221. public function testInitializeAmbiguousAndroidAccepts() {
  222. $_SERVER['HTTP_ACCEPT'] = 'application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5';
  223. $this->assertNull($this->RequestHandler->ext);
  224. Router::parseExtensions('html', 'xml');
  225. $this->RequestHandler->initialize($this->Controller);
  226. $this->assertNull($this->RequestHandler->ext);
  227. }
  228. /**
  229. * Test that a type mismatch doesn't incorrectly set the ext
  230. *
  231. * @return void
  232. */
  233. public function testInitializeContentTypeAndExtensionMismatch() {
  234. $this->assertNull($this->RequestHandler->ext);
  235. $extensions = Router::extensions();
  236. Router::parseExtensions('xml');
  237. $this->Controller->request = $this->getMock('CakeRequest');
  238. $this->Controller->request->expects($this->any())
  239. ->method('accepts')
  240. ->will($this->returnValue(array('application/json')));
  241. $this->RequestHandler->initialize($this->Controller);
  242. $this->assertNull($this->RequestHandler->ext);
  243. call_user_func_array(array('Router', 'parseExtensions'), $extensions);
  244. }
  245. /**
  246. * testViewClassMap method
  247. *
  248. * @return void
  249. */
  250. public function testViewClassMap() {
  251. $settings = array('viewClassMap' => array('json' => 'CustomJson'));
  252. $this->RequestHandler->initialize($this->Controller, $settings);
  253. $result = $this->RequestHandler->viewClassMap();
  254. $expected = array(
  255. 'json' => 'CustomJson',
  256. 'xml' => 'Xml'
  257. );
  258. $this->assertEquals($expected, $result);
  259. $result = $this->RequestHandler->viewClassMap('xls', 'Excel.Excel');
  260. $expected = array(
  261. 'json' => 'CustomJson',
  262. 'xml' => 'Xml',
  263. 'xls' => 'Excel.Excel'
  264. );
  265. $this->assertEquals($expected, $result);
  266. $this->RequestHandler->renderAs($this->Controller, 'json');
  267. $this->assertEquals('CustomJson', $this->Controller->viewClass);
  268. }
  269. /**
  270. * testDisabling method
  271. *
  272. * @return void
  273. */
  274. public function testDisabling() {
  275. $_SERVER['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest';
  276. $this->_init();
  277. $this->RequestHandler->initialize($this->Controller);
  278. $this->Controller->beforeFilter();
  279. $this->RequestHandler->startup($this->Controller);
  280. $this->assertEquals(true, $this->Controller->params['isAjax']);
  281. }
  282. /**
  283. * testAutoResponseType method
  284. *
  285. * @return void
  286. */
  287. public function testAutoResponseType() {
  288. $this->Controller->ext = '.thtml';
  289. $this->Controller->request->params['ext'] = 'rss';
  290. $this->RequestHandler->initialize($this->Controller);
  291. $this->RequestHandler->startup($this->Controller);
  292. $this->assertEquals('.ctp', $this->Controller->ext);
  293. }
  294. /**
  295. * testAutoAjaxLayout method
  296. *
  297. * @return void
  298. */
  299. public function testAutoAjaxLayout() {
  300. $_SERVER['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest';
  301. $this->RequestHandler->startup($this->Controller);
  302. $this->assertEquals($this->Controller->layout, $this->RequestHandler->ajaxLayout);
  303. $this->_init();
  304. $this->Controller->request->params['ext'] = 'js';
  305. $this->RequestHandler->initialize($this->Controller);
  306. $this->RequestHandler->startup($this->Controller);
  307. $this->assertNotEquals('ajax', $this->Controller->layout);
  308. unset($_SERVER['HTTP_X_REQUESTED_WITH']);
  309. }
  310. /**
  311. * testStartupCallback method
  312. *
  313. * @return void
  314. */
  315. public function testStartupCallback() {
  316. $_SERVER['REQUEST_METHOD'] = 'PUT';
  317. $_SERVER['CONTENT_TYPE'] = 'application/xml';
  318. $this->Controller->request = $this->getMock('CakeRequest', array('_readInput'));
  319. $this->RequestHandler->startup($this->Controller);
  320. $this->assertTrue(is_array($this->Controller->data));
  321. $this->assertFalse(is_object($this->Controller->data));
  322. }
  323. /**
  324. * testStartupCallback with charset.
  325. *
  326. * @return void
  327. */
  328. public function testStartupCallbackCharset() {
  329. $_SERVER['REQUEST_METHOD'] = 'PUT';
  330. $_SERVER['CONTENT_TYPE'] = 'application/xml; charset=UTF-8';
  331. $this->Controller->request = $this->getMock('CakeRequest', array('_readInput'));
  332. $this->RequestHandler->startup($this->Controller);
  333. $this->assertTrue(is_array($this->Controller->data));
  334. $this->assertFalse(is_object($this->Controller->data));
  335. }
  336. /**
  337. * Test mapping a new type and having startup process it.
  338. *
  339. * @return void
  340. */
  341. public function testStartupCustomTypeProcess() {
  342. if (!function_exists('str_getcsv')) {
  343. $this->markTestSkipped('Need "str_getcsv" for this test.');
  344. }
  345. $_SERVER['REQUEST_METHOD'] = 'POST';
  346. $_SERVER['CONTENT_TYPE'] = 'text/csv';
  347. $this->Controller->request = $this->getMock('CakeRequest', array('_readInput'));
  348. $this->Controller->request->expects($this->once())
  349. ->method('_readInput')
  350. ->will($this->returnValue('"A","csv","string"'));
  351. $this->RequestHandler->addInputType('csv', array('str_getcsv'));
  352. $this->RequestHandler->startup($this->Controller);
  353. $expected = array(
  354. 'A', 'csv', 'string'
  355. );
  356. $this->assertEquals($expected, $this->Controller->request->data);
  357. }
  358. /**
  359. * testNonAjaxRedirect method
  360. *
  361. * @return void
  362. */
  363. public function testNonAjaxRedirect() {
  364. $this->RequestHandler->initialize($this->Controller);
  365. $this->RequestHandler->startup($this->Controller);
  366. $this->assertNull($this->RequestHandler->beforeRedirect($this->Controller, '/'));
  367. }
  368. /**
  369. * testRenderAs method
  370. *
  371. * @return void
  372. */
  373. public function testRenderAs() {
  374. $this->assertFalse(in_array('Rss', $this->Controller->helpers));
  375. $this->RequestHandler->renderAs($this->Controller, 'rss');
  376. $this->assertTrue(in_array('Rss', $this->Controller->helpers));
  377. $this->Controller->viewPath = 'request_handler_test\\rss';
  378. $this->RequestHandler->renderAs($this->Controller, 'js');
  379. $this->assertEquals('request_handler_test' . DS . 'js', $this->Controller->viewPath);
  380. }
  381. /**
  382. * test that attachment headers work with renderAs
  383. *
  384. * @return void
  385. */
  386. public function testRenderAsWithAttachment() {
  387. $this->RequestHandler->request = $this->getMock('CakeRequest');
  388. $this->RequestHandler->request->expects($this->any())
  389. ->method('parseAccept')
  390. ->will($this->returnValue(array('1.0' => array('application/xml'))));
  391. $this->RequestHandler->response = $this->getMock('CakeResponse', array('type', 'download', 'charset'));
  392. $this->RequestHandler->response->expects($this->at(0))
  393. ->method('type')
  394. ->with('application/xml');
  395. $this->RequestHandler->response->expects($this->at(1))
  396. ->method('charset')
  397. ->with('UTF-8');
  398. $this->RequestHandler->response->expects($this->at(2))
  399. ->method('download')
  400. ->with('myfile.xml');
  401. $this->RequestHandler->renderAs($this->Controller, 'xml', array('attachment' => 'myfile.xml'));
  402. $this->assertEquals('Xml', $this->Controller->viewClass);
  403. }
  404. /**
  405. * test that respondAs works as expected.
  406. *
  407. * @return void
  408. */
  409. public function testRespondAs() {
  410. $this->RequestHandler->response = $this->getMock('CakeResponse', array('type'));
  411. $this->RequestHandler->response->expects($this->at(0))->method('type')
  412. ->with('application/json');
  413. $this->RequestHandler->response->expects($this->at(1))->method('type')
  414. ->with('text/xml');
  415. $result = $this->RequestHandler->respondAs('json');
  416. $this->assertTrue($result);
  417. $result = $this->RequestHandler->respondAs('text/xml');
  418. $this->assertTrue($result);
  419. }
  420. /**
  421. * test that attachment headers work with respondAs
  422. *
  423. * @return void
  424. */
  425. public function testRespondAsWithAttachment() {
  426. $this->RequestHandler = $this->getMock(
  427. 'RequestHandlerComponent',
  428. array('_header'),
  429. array(&$this->Controller->Components)
  430. );
  431. $this->RequestHandler->response = $this->getMock('CakeResponse', array('type', 'download'));
  432. $this->RequestHandler->request = $this->getMock('CakeRequest');
  433. $this->RequestHandler->request->expects($this->once())
  434. ->method('parseAccept')
  435. ->will($this->returnValue(array('1.0' => array('application/xml'))));
  436. $this->RequestHandler->response->expects($this->once())->method('download')
  437. ->with('myfile.xml');
  438. $this->RequestHandler->response->expects($this->once())->method('type')
  439. ->with('application/xml');
  440. $result = $this->RequestHandler->respondAs('xml', array('attachment' => 'myfile.xml'));
  441. $this->assertTrue($result);
  442. }
  443. /**
  444. * test that calling renderAs() more than once continues to work.
  445. *
  446. * @link #6466
  447. * @return void
  448. */
  449. public function testRenderAsCalledTwice() {
  450. $this->RequestHandler->renderAs($this->Controller, 'print');
  451. $this->assertEquals('RequestHandlerTest' . DS . 'print', $this->Controller->viewPath);
  452. $this->assertEquals('print', $this->Controller->layoutPath);
  453. $this->RequestHandler->renderAs($this->Controller, 'js');
  454. $this->assertEquals('RequestHandlerTest' . DS . 'js', $this->Controller->viewPath);
  455. $this->assertEquals('js', $this->Controller->layoutPath);
  456. $this->assertTrue(in_array('Js', $this->Controller->helpers));
  457. }
  458. /**
  459. * testRequestClientTypes method
  460. *
  461. * @return void
  462. */
  463. public function testRequestClientTypes() {
  464. $_SERVER['HTTP_X_PROTOTYPE_VERSION'] = '1.5';
  465. $this->assertEquals('1.5', $this->RequestHandler->getAjaxVersion());
  466. unset($_SERVER['HTTP_X_REQUESTED_WITH'], $_SERVER['HTTP_X_PROTOTYPE_VERSION']);
  467. $this->assertFalse($this->RequestHandler->getAjaxVersion());
  468. }
  469. /**
  470. * Tests the detection of various Flash versions
  471. *
  472. * @return void
  473. */
  474. public function testFlashDetection() {
  475. $request = $this->getMock('CakeRequest');
  476. $request->expects($this->once())->method('is')
  477. ->with('flash')
  478. ->will($this->returnValue(true));
  479. $this->RequestHandler->request = $request;
  480. $this->assertTrue($this->RequestHandler->isFlash());
  481. }
  482. /**
  483. * testRequestContentTypes method
  484. *
  485. * @return void
  486. */
  487. public function testRequestContentTypes() {
  488. $_SERVER['REQUEST_METHOD'] = 'GET';
  489. $this->assertNull($this->RequestHandler->requestedWith());
  490. $_SERVER['REQUEST_METHOD'] = 'POST';
  491. $_SERVER['CONTENT_TYPE'] = 'application/json';
  492. $this->assertEquals('json', $this->RequestHandler->requestedWith());
  493. $result = $this->RequestHandler->requestedWith(array('json', 'xml'));
  494. $this->assertEquals('json', $result);
  495. $result = $this->RequestHandler->requestedWith(array('rss', 'atom'));
  496. $this->assertFalse($result);
  497. $_SERVER['HTTP_ACCEPT'] = 'text/xml,application/xml,application/xhtml+xml,text/html,text/plain,image/png,*/*';
  498. $this->assertTrue($this->RequestHandler->isXml());
  499. $this->assertFalse($this->RequestHandler->isAtom());
  500. $this->assertFalse($this->RequestHandler->isRSS());
  501. $_SERVER['HTTP_ACCEPT'] = 'application/atom+xml,text/xml,application/xml,application/xhtml+xml,text/html,text/plain,image/png,*/*';
  502. $this->assertTrue($this->RequestHandler->isAtom());
  503. $this->assertFalse($this->RequestHandler->isRSS());
  504. $_SERVER['HTTP_ACCEPT'] = 'application/rss+xml,text/xml,application/xml,application/xhtml+xml,text/html,text/plain,image/png,*/*';
  505. $this->assertFalse($this->RequestHandler->isAtom());
  506. $this->assertTrue($this->RequestHandler->isRSS());
  507. $this->assertFalse($this->RequestHandler->isWap());
  508. $_SERVER['HTTP_ACCEPT'] = 'text/vnd.wap.wml,text/html,text/plain,image/png,*/*';
  509. $this->assertTrue($this->RequestHandler->isWap());
  510. $_SERVER['HTTP_ACCEPT'] = 'application/rss+xml,text/xml,application/xml,application/xhtml+xml,text/html,text/plain,image/png,*/*';
  511. }
  512. /**
  513. * testResponseContentType method
  514. *
  515. * @return void
  516. */
  517. public function testResponseContentType() {
  518. $this->assertEquals('html', $this->RequestHandler->responseType());
  519. $this->assertTrue($this->RequestHandler->respondAs('atom'));
  520. $this->assertEquals('atom', $this->RequestHandler->responseType());
  521. }
  522. /**
  523. * testMobileDeviceDetection method
  524. *
  525. * @return void
  526. */
  527. public function testMobileDeviceDetection() {
  528. $request = $this->getMock('CakeRequest');
  529. $request->expects($this->once())->method('is')
  530. ->with('mobile')
  531. ->will($this->returnValue(true));
  532. $this->RequestHandler->request = $request;
  533. $this->assertTrue($this->RequestHandler->isMobile());
  534. }
  535. /**
  536. * testRequestProperties method
  537. *
  538. * @return void
  539. */
  540. public function testRequestProperties() {
  541. $request = $this->getMock('CakeRequest');
  542. $request->expects($this->once())->method('is')
  543. ->with('ssl')
  544. ->will($this->returnValue(true));
  545. $this->RequestHandler->request = $request;
  546. $this->assertTrue($this->RequestHandler->isSsl());
  547. }
  548. /**
  549. * testRequestMethod method
  550. *
  551. * @return void
  552. */
  553. public function testRequestMethod() {
  554. $request = $this->getMock('CakeRequest');
  555. $request->expects($this->at(0))->method('is')
  556. ->with('get')
  557. ->will($this->returnValue(true));
  558. $request->expects($this->at(1))->method('is')
  559. ->with('post')
  560. ->will($this->returnValue(false));
  561. $request->expects($this->at(2))->method('is')
  562. ->with('delete')
  563. ->will($this->returnValue(true));
  564. $request->expects($this->at(3))->method('is')
  565. ->with('put')
  566. ->will($this->returnValue(false));
  567. $this->RequestHandler->request = $request;
  568. $this->assertTrue($this->RequestHandler->isGet());
  569. $this->assertFalse($this->RequestHandler->isPost());
  570. $this->assertTrue($this->RequestHandler->isDelete());
  571. $this->assertFalse($this->RequestHandler->isPut());
  572. }
  573. /**
  574. * test that map alias converts aliases to content types.
  575. *
  576. * @return void
  577. */
  578. public function testMapAlias() {
  579. $result = $this->RequestHandler->mapAlias('xml');
  580. $this->assertEquals('application/xml', $result);
  581. $result = $this->RequestHandler->mapAlias('text/html');
  582. $this->assertNull($result);
  583. $result = $this->RequestHandler->mapAlias('wap');
  584. $this->assertEquals('text/vnd.wap.wml', $result);
  585. $result = $this->RequestHandler->mapAlias(array('xml', 'js', 'json'));
  586. $expected = array('application/xml', 'application/javascript', 'application/json');
  587. $this->assertEquals($expected, $result);
  588. }
  589. /**
  590. * test accepts() on the component
  591. *
  592. * @return void
  593. */
  594. public function testAccepts() {
  595. $_SERVER['HTTP_ACCEPT'] = 'text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5';
  596. $this->assertTrue($this->RequestHandler->accepts(array('js', 'xml', 'html')));
  597. $this->assertFalse($this->RequestHandler->accepts(array('gif', 'jpeg', 'foo')));
  598. $_SERVER['HTTP_ACCEPT'] = '*/*;q=0.5';
  599. $this->assertFalse($this->RequestHandler->accepts('rss'));
  600. }
  601. /**
  602. * test accepts and prefers methods.
  603. *
  604. * @return void
  605. */
  606. public function testPrefers() {
  607. $_SERVER['HTTP_ACCEPT'] = 'text/xml,application/xml,application/xhtml+xml,text/html,text/plain,image/png,*/*';
  608. $this->assertNotEquals('rss', $this->RequestHandler->prefers());
  609. $this->RequestHandler->ext = 'rss';
  610. $this->assertEquals('rss', $this->RequestHandler->prefers());
  611. $this->assertFalse($this->RequestHandler->prefers('xml'));
  612. $this->assertEquals('xml', $this->RequestHandler->prefers(array('js', 'xml', 'xhtml')));
  613. $this->assertFalse($this->RequestHandler->prefers(array('red', 'blue')));
  614. $this->assertEquals('xhtml', $this->RequestHandler->prefers(array('js', 'json', 'xhtml')));
  615. $this->assertTrue($this->RequestHandler->prefers(array('rss')), 'Should return true if input matches ext.');
  616. $this->assertFalse($this->RequestHandler->prefers(array('html')), 'No match with ext, return false.');
  617. $_SERVER['HTTP_ACCEPT'] = 'text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5';
  618. $this->_init();
  619. $this->assertEquals('xml', $this->RequestHandler->prefers());
  620. $_SERVER['HTTP_ACCEPT'] = '*/*;q=0.5';
  621. $this->assertEquals('html', $this->RequestHandler->prefers());
  622. $this->assertFalse($this->RequestHandler->prefers('rss'));
  623. }
  624. /**
  625. * testCustomContent method
  626. *
  627. * @return void
  628. */
  629. public function testCustomContent() {
  630. $_SERVER['HTTP_ACCEPT'] = 'text/x-mobile,text/html;q=0.9,text/plain;q=0.8,*/*;q=0.5';
  631. $this->RequestHandler->setContent('mobile', 'text/x-mobile');
  632. $this->RequestHandler->startup($this->Controller);
  633. $this->assertEquals('mobile', $this->RequestHandler->prefers());
  634. }
  635. /**
  636. * testClientProperties method
  637. *
  638. * @return void
  639. */
  640. public function testClientProperties() {
  641. $request = $this->getMock('CakeRequest');
  642. $request->expects($this->once())->method('referer');
  643. $request->expects($this->once())->method('clientIp')->will($this->returnValue(false));
  644. $this->RequestHandler->request = $request;
  645. $this->RequestHandler->getReferer();
  646. $this->RequestHandler->getClientIP(false);
  647. }
  648. /**
  649. * test that ajax requests involving redirects trigger requestAction instead.
  650. *
  651. * @return void
  652. */
  653. public function testAjaxRedirectAsRequestAction() {
  654. App::build(array(
  655. 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
  656. ), App::RESET);
  657. $this->Controller->RequestHandler = $this->getMock('RequestHandlerComponent', array('_stop'), array(&$this->Controller->Components));
  658. $this->Controller->request = $this->getMock('CakeRequest');
  659. $this->Controller->response = $this->getMock('CakeResponse', array('_sendHeader'));
  660. $this->Controller->RequestHandler->request = $this->Controller->request;
  661. $this->Controller->RequestHandler->response = $this->Controller->response;
  662. $this->Controller->request->expects($this->any())->method('is')->will($this->returnValue(true));
  663. $this->Controller->RequestHandler->expects($this->once())->method('_stop');
  664. ob_start();
  665. $this->Controller->RequestHandler->beforeRedirect(
  666. $this->Controller, array('controller' => 'request_handler_test', 'action' => 'destination')
  667. );
  668. $result = ob_get_clean();
  669. $this->assertRegExp('/posts index/', $result, 'RequestAction redirect failed.');
  670. App::build();
  671. }
  672. /**
  673. * test that ajax requests involving redirects don't force no layout
  674. * this would cause the ajax layout to not be rendered.
  675. *
  676. * @return void
  677. */
  678. public function testAjaxRedirectAsRequestActionStillRenderingLayout() {
  679. App::build(array(
  680. 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
  681. ), App::RESET);
  682. $this->Controller->RequestHandler = $this->getMock('RequestHandlerComponent', array('_stop'), array(&$this->Controller->Components));
  683. $this->Controller->request = $this->getMock('CakeRequest');
  684. $this->Controller->response = $this->getMock('CakeResponse', array('_sendHeader'));
  685. $this->Controller->RequestHandler->request = $this->Controller->request;
  686. $this->Controller->RequestHandler->response = $this->Controller->response;
  687. $this->Controller->request->expects($this->any())->method('is')->will($this->returnValue(true));
  688. $this->Controller->RequestHandler->expects($this->once())->method('_stop');
  689. ob_start();
  690. $this->Controller->RequestHandler->beforeRedirect(
  691. $this->Controller, array('controller' => 'request_handler_test', 'action' => 'ajax2_layout')
  692. );
  693. $result = ob_get_clean();
  694. $this->assertRegExp('/posts index/', $result, 'RequestAction redirect failed.');
  695. $this->assertRegExp('/Ajax!/', $result, 'Layout was not rendered.');
  696. App::build();
  697. }
  698. /**
  699. * test that the beforeRedirect callback properly converts
  700. * array urls into their correct string ones, and adds base => false so
  701. * the correct urls are generated.
  702. *
  703. * @link http://cakephp.lighthouseapp.com/projects/42648-cakephp-1x/tickets/276
  704. * @return void
  705. */
  706. public function testBeforeRedirectCallbackWithArrayUrl() {
  707. $_SERVER['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest';
  708. Router::setRequestInfo(array(
  709. array('plugin' => null, 'controller' => 'accounts', 'action' => 'index', 'pass' => array(), 'named' => array(), 'form' => array(), 'url' => array('url' => 'accounts/')),
  710. array('base' => '/officespace', 'here' => '/officespace/accounts/', 'webroot' => '/officespace/')
  711. ));
  712. $RequestHandler = $this->getMock('RequestHandlerComponent', array('_stop'), array(&$this->Controller->Components));
  713. $RequestHandler->response = $this->getMock('CakeResponse', array('_sendHeader'));
  714. $RequestHandler->request = new CakeRequest('posts/index');
  715. $RequestHandler->response = $this->getMock('CakeResponse', array('_sendHeader'));
  716. ob_start();
  717. $RequestHandler->beforeRedirect(
  718. $this->Controller,
  719. array('controller' => 'request_handler_test', 'action' => 'param_method', 'first', 'second')
  720. );
  721. $result = ob_get_clean();
  722. $this->assertEquals('one: first two: second', $result);
  723. }
  724. /**
  725. * assure that beforeRedirect with a status code will correctly set the status header
  726. *
  727. * @return void
  728. */
  729. public function testBeforeRedirectCallingHeader() {
  730. $_SERVER['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest';
  731. $controller = $this->getMock('Controller', array('header'));
  732. $RequestHandler = $this->getMock('RequestHandlerComponent', array('_stop'), array(&$this->Controller->Components));
  733. $RequestHandler->response = $this->getMock('CakeResponse', array('_sendHeader','statusCode'));
  734. $RequestHandler->request = $this->getMock('CakeRequest');
  735. $RequestHandler->request->expects($this->once())->method('is')
  736. ->with('ajax')
  737. ->will($this->returnValue(true));
  738. $RequestHandler->response->expects($this->once())->method('statusCode')->with(403);
  739. ob_start();
  740. $RequestHandler->beforeRedirect($controller, 'request_handler_test/param_method/first/second', 403);
  741. $result = ob_get_clean();
  742. }
  743. /**
  744. * @expectedException CakeException
  745. * @return void
  746. */
  747. public function testAddInputTypeException() {
  748. $this->RequestHandler->addInputType('csv', array('I am not callable'));
  749. }
  750. /**
  751. * Test checkNotModified method
  752. *
  753. * @return void
  754. **/
  755. public function testCheckNotModifiedByEtagStar() {
  756. $_SERVER['HTTP_IF_NONE_MATCH'] = '*';
  757. $RequestHandler = $this->getMock('RequestHandlerComponent', array('_stop'), array(&$this->Controller->Components));
  758. $RequestHandler->response = $this->getMock('CakeResponse', array('notModified'));
  759. $RequestHandler->response->etag('something');
  760. $RequestHandler->response->expects($this->once())->method('notModified');
  761. $this->assertFalse($RequestHandler->beforeRender($this->Controller));
  762. }
  763. /**
  764. * Test checkNotModified method
  765. *
  766. * @return void
  767. **/
  768. public function testCheckNotModifiedByEtagExact() {
  769. $_SERVER['HTTP_IF_NONE_MATCH'] = 'W/"something", "other"';
  770. $RequestHandler = $this->getMock('RequestHandlerComponent', array('_stop'), array(&$this->Controller->Components));
  771. $RequestHandler->response = $this->getMock('CakeResponse', array('notModified'));
  772. $RequestHandler->response->etag('something', true);
  773. $RequestHandler->response->expects($this->once())->method('notModified');
  774. $this->assertFalse($RequestHandler->beforeRender($this->Controller));
  775. }
  776. /**
  777. * Test checkNotModified method
  778. *
  779. * @return void
  780. **/
  781. public function testCheckNotModifiedByEtagAndTime() {
  782. $_SERVER['HTTP_IF_NONE_MATCH'] = 'W/"something", "other"';
  783. $_SERVER['HTTP_IF_MODIFIED_SINCE'] = '2012-01-01 00:00:00';
  784. $RequestHandler = $this->getMock('RequestHandlerComponent', array('_stop'), array(&$this->Controller->Components));
  785. $RequestHandler->response = $this->getMock('CakeResponse', array('notModified'));
  786. $RequestHandler->response->etag('something', true);
  787. $RequestHandler->response->modified('2012-01-01 00:00:00');
  788. $RequestHandler->response->expects($this->once())->method('notModified');
  789. $this->assertFalse($RequestHandler->beforeRender($this->Controller));
  790. }
  791. /**
  792. * Test checkNotModified method
  793. *
  794. * @return void
  795. **/
  796. public function testCheckNotModifiedNoInfo() {
  797. $RequestHandler = $this->getMock('RequestHandlerComponent', array('_stop'), array(&$this->Controller->Components));
  798. $RequestHandler->response = $this->getMock('CakeResponse', array('notModified'));
  799. $RequestHandler->response->expects($this->never())->method('notModified');
  800. $this->assertNull($RequestHandler->beforeRender($this->Controller));
  801. }
  802. }