IntegrationTestTraitTest.php 53 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
  5. * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  6. *
  7. * Licensed under The MIT License
  8. * For full copyright and license information, please see the LICENSE.txt
  9. * Redistributions of files must retain the above copyright notice
  10. *
  11. * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  12. * @link https://cakephp.org CakePHP(tm) Project
  13. * @since 3.0.0
  14. * @license https://opensource.org/licenses/mit-license.php MIT License
  15. */
  16. namespace Cake\Test\TestCase\TestSuite;
  17. use Cake\Controller\Controller;
  18. use Cake\Core\Configure;
  19. use Cake\Event\EventManager;
  20. use Cake\Http\Cookie\Cookie;
  21. use Cake\Http\Middleware\EncryptedCookieMiddleware;
  22. use Cake\Http\Response;
  23. use Cake\Http\Session;
  24. use Cake\Routing\Route\InflectedRoute;
  25. use Cake\Routing\Router;
  26. use Cake\Test\Fixture\AssertIntegrationTestCase;
  27. use Cake\TestSuite\IntegrationTestTrait;
  28. use Cake\TestSuite\TestCase;
  29. use Cake\Utility\Security;
  30. use PHPUnit\Framework\AssertionFailedError;
  31. use Zend\Diactoros\UploadedFile;
  32. /**
  33. * Self test of the IntegrationTestTrait
  34. */
  35. class IntegrationTestTraitTest extends TestCase
  36. {
  37. use IntegrationTestTrait;
  38. /**
  39. * stub encryption key.
  40. *
  41. * @var string
  42. */
  43. public $key = 'abcdabcdabcdabcdabcdabcdabcdabcdabcd';
  44. /**
  45. * Setup method
  46. *
  47. * @return void
  48. */
  49. public function setUp()
  50. {
  51. parent::setUp();
  52. static::setAppNamespace();
  53. Router::reload();
  54. Router::extensions(['json']);
  55. Router::scope('/', function ($routes) {
  56. $routes->registerMiddleware('cookie', new EncryptedCookieMiddleware(['secrets'], $this->key));
  57. $routes->applyMiddleware('cookie');
  58. $routes->setRouteClass(InflectedRoute::class);
  59. $routes->get('/get/:controller/:action', []);
  60. $routes->head('/head/:controller/:action', []);
  61. $routes->options('/options/:controller/:action', []);
  62. $routes->connect('/:controller/:action/*', []);
  63. });
  64. $this->configApplication(Configure::read('App.namespace') . '\Application', null);
  65. }
  66. /**
  67. * Tests that all data that used by the request is cast to strings
  68. *
  69. * @return void
  70. */
  71. public function testDataCastToString()
  72. {
  73. $data = [
  74. 'title' => 'Blog Post',
  75. 'status' => 1,
  76. 'published' => true,
  77. 'not_published' => false,
  78. 'comments' => [
  79. [
  80. 'body' => 'Comment',
  81. 'status' => 1,
  82. ],
  83. ],
  84. 'file' => [
  85. 'tmp_name' => __FILE__,
  86. 'size' => 42,
  87. 'error' => 0,
  88. 'type' => 'text/plain',
  89. 'name' => 'Uploaded file',
  90. ],
  91. 'pictures' => [
  92. 'name' => [
  93. ['file' => 'a-file.png'],
  94. ['file' => 'a-moose.png'],
  95. ],
  96. 'type' => [
  97. ['file' => 'image/png'],
  98. ['file' => 'image/jpg'],
  99. ],
  100. 'tmp_name' => [
  101. ['file' => __FILE__],
  102. ['file' => __FILE__],
  103. ],
  104. 'error' => [
  105. ['file' => 0],
  106. ['file' => 0],
  107. ],
  108. 'size' => [
  109. ['file' => 17188],
  110. ['file' => 2010],
  111. ],
  112. ],
  113. 'upload' => new UploadedFile(__FILE__, 42, 0),
  114. ];
  115. $request = $this->_buildRequest('/posts/add', 'POST', $data);
  116. $this->assertInternalType('string', $request['post']['status']);
  117. $this->assertInternalType('string', $request['post']['published']);
  118. $this->assertSame('0', $request['post']['not_published']);
  119. $this->assertInternalType('string', $request['post']['comments'][0]['status']);
  120. $this->assertInternalType('integer', $request['post']['file']['error']);
  121. $this->assertInternalType('integer', $request['post']['file']['size']);
  122. $this->assertInternalType('integer', $request['post']['pictures']['error'][0]['file']);
  123. $this->assertInternalType('integer', $request['post']['pictures']['error'][1]['file']);
  124. $this->assertInternalType('integer', $request['post']['pictures']['size'][0]['file']);
  125. $this->assertInternalType('integer', $request['post']['pictures']['size'][1]['file']);
  126. $this->assertInstanceOf(UploadedFile::class, $request['post']['upload']);
  127. }
  128. /**
  129. * Test building a request.
  130. *
  131. * @return void
  132. */
  133. public function testRequestBuilding()
  134. {
  135. $this->configRequest([
  136. 'headers' => [
  137. 'X-CSRF-Token' => 'abc123',
  138. 'Content-Type' => 'application/json',
  139. 'Accept' => 'application/json',
  140. ],
  141. 'base' => '',
  142. 'webroot' => '/',
  143. 'environment' => [
  144. 'PHP_AUTH_USER' => 'foo',
  145. 'PHP_AUTH_PW' => 'bar',
  146. ],
  147. ]);
  148. $this->cookie('split_token', 'def345');
  149. $this->session(['User' => ['id' => 1, 'username' => 'mark']]);
  150. $request = $this->_buildRequest('/tasks/add', 'POST', ['title' => 'First post']);
  151. $this->assertEquals('abc123', $request['environment']['HTTP_X_CSRF_TOKEN']);
  152. $this->assertEquals('application/json', $request['environment']['CONTENT_TYPE']);
  153. $this->assertEquals('/tasks/add', $request['url']);
  154. $this->assertArrayHasKey('split_token', $request['cookies']);
  155. $this->assertEquals('def345', $request['cookies']['split_token']);
  156. $this->assertEquals(['id' => '1', 'username' => 'mark'], $request['session']->read('User'));
  157. $this->assertEquals('foo', $request['environment']['PHP_AUTH_USER']);
  158. $this->assertEquals('bar', $request['environment']['PHP_AUTH_PW']);
  159. }
  160. /**
  161. * Test request building adds csrf tokens
  162. *
  163. * @return void
  164. */
  165. public function testRequestBuildingCsrfTokens()
  166. {
  167. $this->enableCsrfToken();
  168. $request = $this->_buildRequest('/tasks/add', 'POST', ['title' => 'First post']);
  169. $this->assertArrayHasKey('csrfToken', $request['cookies']);
  170. $this->assertArrayHasKey('_csrfToken', $request['post']);
  171. $this->assertSame($request['cookies']['csrfToken'], $request['post']['_csrfToken']);
  172. $this->cookie('csrfToken', '');
  173. $request = $this->_buildRequest('/tasks/add', 'POST', [
  174. '_csrfToken' => 'fale',
  175. 'title' => 'First post',
  176. ]);
  177. $this->assertSame('', $request['cookies']['csrfToken']);
  178. $this->assertSame('fale', $request['post']['_csrfToken']);
  179. }
  180. /**
  181. * Test multiple actions using CSRF tokens don't fail
  182. *
  183. * @return void
  184. */
  185. public function testEnableCsrfMultipleRequests()
  186. {
  187. $this->enableCsrfToken();
  188. $first = $this->_buildRequest('/tasks/add', 'POST', ['title' => 'First post']);
  189. $second = $this->_buildRequest('/tasks/add', 'POST', ['title' => 'Second post']);
  190. $this->assertSame(
  191. $first['cookies']['csrfToken'],
  192. $second['post']['_csrfToken'],
  193. 'Csrf token should match cookie'
  194. );
  195. $this->assertSame(
  196. $first['post']['_csrfToken'],
  197. $second['post']['_csrfToken'],
  198. 'Tokens should be consistent per test method'
  199. );
  200. }
  201. /**
  202. * Test pre-determined CSRF tokens.
  203. *
  204. * @return void
  205. */
  206. public function testEnableCsrfPredeterminedCookie()
  207. {
  208. $this->enableCsrfToken();
  209. $value = 'I am a teapot';
  210. $this->cookie('csrfToken', $value);
  211. $request = $this->_buildRequest('/tasks/add', 'POST', ['title' => 'First post']);
  212. $this->assertSame($value, $request['cookies']['csrfToken'], 'Csrf token should match cookie');
  213. $this->assertSame($value, $request['post']['_csrfToken'], 'Tokens should match');
  214. }
  215. /**
  216. * Test building a request, with query parameters
  217. *
  218. * @return void
  219. */
  220. public function testRequestBuildingQueryParameters()
  221. {
  222. $request = $this->_buildRequest('/tasks/view?archived=yes', 'GET', []);
  223. $this->assertSame('/tasks/view', $request['url']);
  224. $this->assertSame('archived=yes', $request['environment']['QUERY_STRING']);
  225. $this->assertSame('/tasks/view', $request['environment']['REQUEST_URI']);
  226. }
  227. /**
  228. * Test cookie encrypted
  229. *
  230. * @see CookieComponentControllerTest
  231. */
  232. public function testCookieEncrypted()
  233. {
  234. Security::setSalt($this->key);
  235. $this->cookieEncrypted('KeyOfCookie', 'Encrypted with aes by default');
  236. $request = $this->_buildRequest('/tasks/view', 'GET', []);
  237. $this->assertStringStartsWith('Q2FrZQ==.', $request['cookies']['KeyOfCookie']);
  238. }
  239. /**
  240. * Test sending get request and using default `test_app/config/routes.php`.
  241. *
  242. * @return void
  243. */
  244. public function testGetUsingApplicationWithPluginRoutes()
  245. {
  246. // first clean routes to have Router::$initailized === false
  247. Router::reload();
  248. $this->clearPlugins();
  249. $this->configApplication(Configure::read('App.namespace') . '\ApplicationWithPluginRoutes', null);
  250. $this->get('/test_plugin');
  251. $this->assertResponseOk();
  252. }
  253. /**
  254. * Test sending get request and using default `test_app/config/routes.php`.
  255. *
  256. * @return void
  257. */
  258. public function testGetUsingApplicationWithDefaultRoutes()
  259. {
  260. // first clean routes to have Router::$initailized === false
  261. Router::reload();
  262. $this->configApplication(Configure::read('App.namespace') . '\ApplicationWithDefaultRoutes', null);
  263. $this->get('/some_alias');
  264. $this->assertResponseOk();
  265. $this->assertEquals('5', $this->_getBodyAsString());
  266. }
  267. public function testExceptionsInMiddlewareJsonView()
  268. {
  269. Router::reload();
  270. Router::connect('/json_response/api_get_data', [
  271. 'controller' => 'JsonResponse',
  272. 'action' => 'apiGetData',
  273. ]);
  274. $this->configApplication(Configure::read('App.namespace') . '\ApplicationWithExceptionsInMiddleware', null);
  275. $this->_request['headers'] = [ "Accept" => "application/json" ];
  276. $this->get('/json_response/api_get_data');
  277. $this->assertResponseCode(403);
  278. $this->assertHeader('Content-Type', 'application/json');
  279. $this->assertResponseContains('"message": "Sample Message"');
  280. $this->assertResponseContains('"code": 403');
  281. }
  282. /**
  283. * Test sending head requests.
  284. *
  285. * @return void
  286. */
  287. public function testHead()
  288. {
  289. $this->assertNull($this->_response);
  290. $this->head('/request_action/test_request_action');
  291. $this->assertNotEmpty($this->_response);
  292. $this->assertInstanceOf('Cake\Http\Response', $this->_response);
  293. $this->assertResponseSuccess();
  294. $this->_response = null;
  295. $this->head('/head/request_action/test_request_action');
  296. $this->assertResponseSuccess();
  297. }
  298. /**
  299. * Test sending options requests.
  300. *
  301. * @return void
  302. */
  303. public function testOptions()
  304. {
  305. $this->assertNull($this->_response);
  306. $this->options('/request_action/test_request_action');
  307. $this->assertNotEmpty($this->_response);
  308. $this->assertInstanceOf('Cake\Http\Response', $this->_response);
  309. $this->assertResponseSuccess();
  310. $this->_response = null;
  311. $this->options('/options/request_action/test_request_action');
  312. $this->assertResponseSuccess();
  313. }
  314. /**
  315. * Test sending get requests sets the request method
  316. *
  317. * @return void
  318. */
  319. public function testGetSpecificRouteHttpServer()
  320. {
  321. $this->get('/get/request_action/test_request_action');
  322. $this->assertResponseOk();
  323. $this->assertEquals('This is a test', $this->_response->getBody());
  324. }
  325. /**
  326. * Test customizing the app class.
  327. *
  328. * @return void
  329. */
  330. public function testConfigApplication()
  331. {
  332. $this->expectException(\LogicException::class);
  333. $this->expectExceptionMessage('Cannot load "TestApp\MissingApp" for use in integration');
  334. $this->configApplication('TestApp\MissingApp', []);
  335. $this->get('/request_action/test_request_action');
  336. }
  337. /**
  338. * Test sending get requests with Http\Server
  339. *
  340. * @return void
  341. */
  342. public function testGetHttpServer()
  343. {
  344. $this->assertNull($this->_response);
  345. $this->get('/request_action/test_request_action');
  346. $this->assertNotEmpty($this->_response);
  347. $this->assertInstanceOf('Cake\Http\Response', $this->_response);
  348. $this->assertEquals('This is a test', $this->_response->getBody());
  349. $this->assertHeader('X-Middleware', 'true');
  350. }
  351. /**
  352. * Test that the PSR7 requests get query string data
  353. *
  354. * @return void
  355. */
  356. public function testGetQueryStringHttpServer()
  357. {
  358. $this->configRequest(['headers' => ['Content-Type' => 'text/plain']]);
  359. $this->get('/request_action/params_pass?q=query');
  360. $this->assertResponseOk();
  361. $this->assertResponseContains('"q":"query"');
  362. $this->assertResponseContains('"contentType":"text\/plain"');
  363. $this->assertHeader('X-Middleware', 'true');
  364. $request = $this->_controller->getRequest();
  365. $this->assertContains('/request_action/params_pass?q=query', $request->getRequestTarget());
  366. }
  367. /**
  368. * Test that the PSR7 requests get query string data
  369. *
  370. * @return void
  371. */
  372. public function testGetQueryStringSetsHere()
  373. {
  374. $this->configRequest(['headers' => ['Content-Type' => 'text/plain']]);
  375. $this->get('/request_action/params_pass?q=query');
  376. $this->assertResponseOk();
  377. $this->assertResponseContains('"q":"query"');
  378. $this->assertResponseContains('"contentType":"text\/plain"');
  379. $this->assertHeader('X-Middleware', 'true');
  380. $request = $this->_controller->getRequest();
  381. $this->assertContains('/request_action/params_pass?q=query', $request->getRequestTarget());
  382. $this->assertContains('/request_action/params_pass', $request->getAttribute('here'));
  383. }
  384. /**
  385. * Test that the PSR7 requests get cookies
  386. *
  387. * @return void
  388. */
  389. public function testGetCookiesHttpServer()
  390. {
  391. $this->configRequest(['cookies' => ['split_test' => 'abc']]);
  392. $this->get('/request_action/cookie_pass');
  393. $this->assertResponseOk();
  394. $this->assertResponseContains('"split_test":"abc"');
  395. $this->assertHeader('X-Middleware', 'true');
  396. }
  397. /**
  398. * Test that the PSR7 requests receive post data
  399. *
  400. * @return void
  401. */
  402. public function testPostDataHttpServer()
  403. {
  404. $this->post('/request_action/post_pass', ['title' => 'value']);
  405. $data = json_decode('' . $this->_response->getBody());
  406. $this->assertEquals('value', $data->title);
  407. $this->assertHeader('X-Middleware', 'true');
  408. }
  409. /**
  410. * Test that the uploaded files are passed correctly to the request
  411. *
  412. * @return void
  413. */
  414. public function testUploadedFiles()
  415. {
  416. $this->configRequest([
  417. 'files' => [
  418. 'file' => [
  419. 'tmp_name' => __FILE__,
  420. 'size' => 42,
  421. 'error' => 0,
  422. 'type' => 'text/plain',
  423. 'name' => 'Uploaded file',
  424. ],
  425. 'pictures' => [
  426. 'name' => [
  427. ['file' => 'a-file.png'],
  428. ['file' => 'a-moose.png'],
  429. ],
  430. 'type' => [
  431. ['file' => 'image/png'],
  432. ['file' => 'image/jpg'],
  433. ],
  434. 'tmp_name' => [
  435. ['file' => __FILE__],
  436. ['file' => __FILE__],
  437. ],
  438. 'error' => [
  439. ['file' => 0],
  440. ['file' => 0],
  441. ],
  442. 'size' => [
  443. ['file' => 17188],
  444. ['file' => 2010],
  445. ],
  446. ],
  447. 'upload' => new UploadedFile(__FILE__, 42, 0),
  448. ],
  449. ]);
  450. $this->post('/request_action/uploaded_files');
  451. $this->assertHeader('X-Middleware', 'true');
  452. $data = json_decode((string)$this->_response->getBody(), true);
  453. $this->assertEquals([
  454. 'file' => 'Uploaded file',
  455. 'pictures.0.file' => 'a-file.png',
  456. 'pictures.1.file' => 'a-moose.png',
  457. 'upload' => null,
  458. ], $data);
  459. }
  460. /**
  461. * Test that the PSR7 requests receive encoded data.
  462. *
  463. * @return void
  464. */
  465. public function testInputDataHttpServer()
  466. {
  467. $this->post('/request_action/input_test', '{"hello":"world"}');
  468. if ($this->_response->getBody()->isSeekable()) {
  469. $this->_response->getBody()->rewind();
  470. }
  471. $this->assertSame('world', $this->_response->getBody()->getContents());
  472. $this->assertHeader('X-Middleware', 'true');
  473. }
  474. /**
  475. * Test that the PSR7 requests receive encoded data.
  476. *
  477. * @return void
  478. */
  479. public function testInputDataSecurityToken()
  480. {
  481. $this->enableSecurityToken();
  482. $this->post('/request_action/input_test', '{"hello":"world"}');
  483. $this->assertSame('world', '' . $this->_response->getBody());
  484. $this->assertHeader('X-Middleware', 'true');
  485. }
  486. /**
  487. * Test that the PSR7 requests get cookies
  488. *
  489. * @return void
  490. */
  491. public function testSessionHttpServer()
  492. {
  493. $this->session(['foo' => 'session data']);
  494. $this->get('/request_action/session_test');
  495. $this->assertResponseOk();
  496. $this->assertResponseContains('session data');
  497. $this->assertHeader('X-Middleware', 'true');
  498. }
  499. /**
  500. * Test sending requests stores references to controller/view/layout.
  501. *
  502. * @return void
  503. */
  504. public function testRequestSetsProperties()
  505. {
  506. $this->post('/posts/index');
  507. $this->assertInstanceOf('Cake\Controller\Controller', $this->_controller);
  508. $this->assertNotEmpty($this->_viewName, 'View name not set');
  509. $this->assertContains('templates' . DS . 'Posts' . DS . 'index.php', $this->_viewName);
  510. $this->assertNotEmpty($this->_layoutName, 'Layout name not set');
  511. $this->assertContains('templates' . DS . 'layout' . DS . 'default.php', $this->_layoutName);
  512. $this->assertTemplate('index');
  513. $this->assertLayout('default');
  514. $this->assertEquals('value', $this->viewVariable('test'));
  515. }
  516. /**
  517. * Test PSR7 requests store references to controller/view/layout
  518. *
  519. * @return void
  520. */
  521. public function testRequestSetsPropertiesHttpServer()
  522. {
  523. $this->post('/posts/index');
  524. $this->assertInstanceOf('Cake\Controller\Controller', $this->_controller);
  525. $this->assertNotEmpty($this->_viewName, 'View name not set');
  526. $this->assertContains('templates' . DS . 'Posts' . DS . 'index.php', $this->_viewName);
  527. $this->assertNotEmpty($this->_layoutName, 'Layout name not set');
  528. $this->assertContains('templates' . DS . 'layout' . DS . 'default.php', $this->_layoutName);
  529. $this->assertTemplate('index');
  530. $this->assertLayout('default');
  531. $this->assertEquals('value', $this->viewVariable('test'));
  532. }
  533. /**
  534. * Tests URLs containing extensions.
  535. *
  536. * @return void
  537. */
  538. public function testRequestWithExt()
  539. {
  540. $this->get(['controller' => 'Posts', 'action' => 'ajax', '_ext' => 'json']);
  541. $this->assertResponseCode(200);
  542. }
  543. /**
  544. * Assert that the stored template doesn't change when cells are rendered.
  545. *
  546. * @return void
  547. */
  548. public function testAssertTemplateAfterCellRender()
  549. {
  550. $this->get('/posts/get');
  551. $this->assertContains('templates' . DS . 'Posts' . DS . 'get.php', $this->_viewName);
  552. $this->assertTemplate('get');
  553. $this->assertResponseContains('cellcontent');
  554. }
  555. /**
  556. * Test array URLs
  557. *
  558. * @return void
  559. */
  560. public function testArrayUrls()
  561. {
  562. $this->post(['controller' => 'Posts', 'action' => 'index', '_method' => 'POST']);
  563. $this->assertResponseOk();
  564. $this->assertEquals('value', $this->viewVariable('test'));
  565. }
  566. /**
  567. * Test array URLs with an empty router.
  568. *
  569. * @return void
  570. */
  571. public function testArrayUrlsEmptyRouter()
  572. {
  573. Router::reload();
  574. $this->assertEmpty(Router::getRouteCollection()->routes());
  575. $this->get(['controller' => 'Posts', 'action' => 'index']);
  576. $this->assertResponseOk();
  577. $this->assertEquals('value', $this->viewVariable('test'));
  578. }
  579. /**
  580. * Test flash and cookie assertions
  581. *
  582. * @return void
  583. */
  584. public function testFlashSessionAndCookieAsserts()
  585. {
  586. $this->post('/posts/index');
  587. $this->assertSession('An error message', 'Flash.flash.0.message');
  588. $this->assertCookie(1, 'remember_me');
  589. $this->assertCookieNotSet('user_id');
  590. }
  591. /**
  592. * Test flash and cookie assertions
  593. *
  594. * @return void
  595. */
  596. public function testFlashSessionAndCookieAssertsHttpServer()
  597. {
  598. $this->post('/posts/index');
  599. $this->assertSession('An error message', 'Flash.flash.0.message');
  600. $this->assertCookieNotSet('user_id');
  601. $this->assertCookie(1, 'remember_me');
  602. }
  603. /**
  604. * Test flash assertions stored with enableRememberFlashMessages() after they
  605. * are rendered
  606. *
  607. * @return void
  608. */
  609. public function testFlashAssertionsAfterRender()
  610. {
  611. $this->enableRetainFlashMessages();
  612. $this->get('/posts/index/with_flash');
  613. $this->assertSession('An error message', 'Flash.flash.0.message');
  614. }
  615. /**
  616. * Test flash assertions stored with enableRememberFlashMessages() even if
  617. * no view is rendered
  618. *
  619. * @return void
  620. */
  621. public function testFlashAssertionsWithNoRender()
  622. {
  623. $this->enableRetainFlashMessages();
  624. $this->get('/posts/flashNoRender');
  625. $this->assertRedirect();
  626. $this->assertSession('An error message', 'Flash.flash.0.message');
  627. }
  628. /**
  629. * Tests assertCookieNotSet assertion
  630. *
  631. * @return void
  632. */
  633. public function testAssertCookieNotSet()
  634. {
  635. $this->cookie('test', 'value');
  636. $this->get('/cookie_component_test/remove_cookie/test');
  637. $this->assertCookieNotSet('test');
  638. }
  639. /**
  640. * Tests the failure message for assertCookieNotSet
  641. *
  642. * @return void
  643. */
  644. public function testCookieNotSetFailure()
  645. {
  646. $this->expectException(AssertionFailedError::class);
  647. $this->expectExceptionMessage('Failed asserting that \'remember_me\' cookie was not set');
  648. $this->post('/posts/index');
  649. $this->assertCookieNotSet('remember_me');
  650. }
  651. /**
  652. * Tests the failure message for assertCookieNotSet when no
  653. * response whas generated
  654. *
  655. * @return void
  656. */
  657. public function testCookieNotSetFailureNoResponse()
  658. {
  659. $this->expectException(AssertionFailedError::class);
  660. $this->expectExceptionMessage('No response set, cannot assert content.');
  661. $this->assertCookieNotSet('remember_me');
  662. }
  663. /**
  664. * Test error handling and error page rendering.
  665. *
  666. * @return void
  667. */
  668. public function testPostAndErrorHandling()
  669. {
  670. $this->post('/request_action/error_method');
  671. $this->assertResponseNotEmpty();
  672. $this->assertResponseContains('Not there or here');
  673. $this->assertResponseContains('<!DOCTYPE html>');
  674. }
  675. /**
  676. * Test posting to a secured form action.
  677. *
  678. * @return void
  679. */
  680. public function testPostSecuredForm()
  681. {
  682. $this->enableSecurityToken();
  683. $data = [
  684. 'title' => 'Some title',
  685. 'body' => 'Some text',
  686. ];
  687. $this->post('/posts/securePost', $data);
  688. $this->assertResponseOk();
  689. $this->assertResponseContains('Request was accepted');
  690. }
  691. /**
  692. * Test posting to a secured form action with nested data.
  693. *
  694. * @return void
  695. */
  696. public function testPostSecuredFormNestedData()
  697. {
  698. $this->enableSecurityToken();
  699. $data = [
  700. 'title' => 'New post',
  701. 'comments' => [
  702. ['comment' => 'A new comment'],
  703. ],
  704. 'tags' => ['_ids' => [1, 2, 3, 4]],
  705. ];
  706. $this->post('/posts/securePost', $data);
  707. $this->assertResponseOk();
  708. $this->assertResponseContains('Request was accepted');
  709. }
  710. /**
  711. * Test posting to a secured form action.
  712. *
  713. * @return void
  714. */
  715. public function testPostSecuredFormWithQuery()
  716. {
  717. $this->enableSecurityToken();
  718. $data = [
  719. 'title' => 'Some title',
  720. 'body' => 'Some text',
  721. ];
  722. $this->post('/posts/securePost?foo=bar', $data);
  723. $this->assertResponseOk();
  724. $this->assertResponseContains('Request was accepted');
  725. }
  726. /**
  727. * Test posting to a secured form action with a query that has a part that
  728. * will be encoded by the security component
  729. *
  730. * @return void
  731. */
  732. public function testPostSecuredFormWithUnencodedQuery()
  733. {
  734. $this->enableSecurityToken();
  735. $data = [
  736. 'title' => 'Some title',
  737. 'body' => 'Some text',
  738. ];
  739. $this->post('/posts/securePost?foo=/', $data);
  740. $this->assertResponseOk();
  741. $this->assertResponseContains('Request was accepted');
  742. }
  743. /**
  744. * Test posting to a secured form action action.
  745. *
  746. * @return void
  747. */
  748. public function testPostSecuredFormFailure()
  749. {
  750. $data = [
  751. 'title' => 'Some title',
  752. 'body' => 'Some text',
  753. ];
  754. $this->post('/posts/securePost', $data);
  755. $this->assertResponseError();
  756. }
  757. /**
  758. * Test that exceptions being thrown are handled correctly.
  759. *
  760. * @return void
  761. */
  762. public function testWithExpectedException()
  763. {
  764. $this->get('/tests_apps/throw_exception');
  765. $this->assertResponseCode(500);
  766. }
  767. /**
  768. * Test that exceptions being thrown are handled correctly by the psr7 stack.
  769. *
  770. * @return void
  771. */
  772. public function testWithExpectedExceptionHttpServer()
  773. {
  774. $this->get('/tests_apps/throw_exception');
  775. $this->assertResponseCode(500);
  776. }
  777. /**
  778. * Test that exceptions being thrown are handled correctly.
  779. *
  780. * @return void
  781. */
  782. public function testWithUnexpectedException()
  783. {
  784. $this->expectException(AssertionFailedError::class);
  785. $this->get('/tests_apps/throw_exception');
  786. $this->assertResponseCode(501);
  787. }
  788. /**
  789. * Test redirecting and integration tests.
  790. *
  791. * @return void
  792. */
  793. public function testRedirect()
  794. {
  795. $this->post('/tests_apps/redirect_to');
  796. $this->assertResponseSuccess();
  797. $this->assertResponseCode(302);
  798. }
  799. /**
  800. * Test redirecting and psr7 stack
  801. *
  802. * @return void
  803. */
  804. public function testRedirectHttpServer()
  805. {
  806. $this->post('/tests_apps/redirect_to');
  807. $this->assertResponseCode(302);
  808. $this->assertHeader('X-Middleware', 'true');
  809. }
  810. /**
  811. * Test redirecting and integration tests.
  812. *
  813. * @return void
  814. */
  815. public function testRedirectPermanent()
  816. {
  817. $this->post('/tests_apps/redirect_to_permanent');
  818. $this->assertResponseSuccess();
  819. $this->assertResponseCode(301);
  820. }
  821. /**
  822. * Test the responseOk status assertion
  823. *
  824. * @return void
  825. */
  826. public function testAssertResponseStatusCodes()
  827. {
  828. $this->_response = new Response();
  829. $this->_response = $this->_response->withStatus(200);
  830. $this->assertResponseOk();
  831. $this->_response = $this->_response->withStatus(201);
  832. $this->assertResponseOk();
  833. $this->_response = $this->_response->withStatus(204);
  834. $this->assertResponseOk();
  835. $this->_response = $this->_response->withStatus(202);
  836. $this->assertResponseSuccess();
  837. $this->_response = $this->_response->withStatus(302);
  838. $this->assertResponseSuccess();
  839. $this->_response = $this->_response->withStatus(400);
  840. $this->assertResponseError();
  841. $this->_response = $this->_response->withStatus(417);
  842. $this->assertResponseError();
  843. $this->_response = $this->_response->withStatus(500);
  844. $this->assertResponseFailure();
  845. $this->_response = $this->_response->withStatus(505);
  846. $this->assertResponseFailure();
  847. $this->_response = $this->_response->withStatus(301);
  848. $this->assertResponseCode(301);
  849. }
  850. /**
  851. * Test the location header assertion.
  852. *
  853. * @return void
  854. */
  855. public function testAssertRedirect()
  856. {
  857. $this->_response = new Response();
  858. $this->_response = $this->_response->withHeader('Location', 'http://localhost/get/tasks/index');
  859. $this->assertRedirect();
  860. $this->assertRedirect('/get/tasks/index');
  861. $this->assertRedirect(['controller' => 'Tasks', 'action' => 'index']);
  862. $this->assertResponseEmpty();
  863. }
  864. /**
  865. * Test the location header assertion string not contains
  866. *
  867. * @return void
  868. */
  869. public function testAssertRedirectNotContains()
  870. {
  871. $this->_response = new Response();
  872. $this->_response = $this->_response->withHeader('Location', 'http://localhost/tasks/index');
  873. $this->assertRedirectNotContains('test');
  874. }
  875. /**
  876. * Test the location header assertion.
  877. *
  878. * @return void
  879. */
  880. public function testAssertNoRedirect()
  881. {
  882. $this->_response = new Response();
  883. $this->assertNoRedirect();
  884. }
  885. /**
  886. * Test the location header assertion.
  887. *
  888. * @return void
  889. */
  890. public function testAssertNoRedirectFail()
  891. {
  892. $test = new AssertIntegrationTestCase('testBadAssertNoRedirect');
  893. $result = $test->run();
  894. $this->assertFalse($result->wasSuccessful());
  895. $this->assertEquals(1, $result->failureCount());
  896. }
  897. /**
  898. * Test the location header assertion string contains
  899. *
  900. * @return void
  901. */
  902. public function testAssertRedirectContains()
  903. {
  904. $this->_response = new Response();
  905. $this->_response = $this->_response->withHeader('Location', 'http://localhost/tasks/index');
  906. $this->assertRedirectContains('/tasks/index');
  907. }
  908. /**
  909. * Test the header assertion.
  910. *
  911. * @return void
  912. */
  913. public function testAssertHeader()
  914. {
  915. $this->_response = new Response();
  916. $this->_response = $this->_response->withHeader('Etag', 'abc123');
  917. $this->assertHeader('Etag', 'abc123');
  918. }
  919. /**
  920. * Test the header contains assertion.
  921. *
  922. * @return void
  923. */
  924. public function testAssertHeaderContains()
  925. {
  926. $this->_response = new Response();
  927. $this->_response = $this->_response->withHeader('Etag', 'abc123');
  928. $this->assertHeaderContains('Etag', 'abc');
  929. }
  930. /**
  931. * Test the header not contains assertion.
  932. *
  933. * @return void
  934. */
  935. public function testAssertHeaderNotContains()
  936. {
  937. $this->_response = new Response();
  938. $this->_response = $this->_response->withHeader('Etag', 'abc123');
  939. $this->assertHeaderNotContains('Etag', 'xyz');
  940. }
  941. /**
  942. * Test the content type assertion.
  943. *
  944. * @return void
  945. */
  946. public function testAssertContentType()
  947. {
  948. $this->_response = new Response();
  949. $this->_response = $this->_response->withType('json');
  950. $this->assertContentType('json');
  951. $this->assertContentType('application/json');
  952. }
  953. /**
  954. * Test that type() in an action sets the content-type header.
  955. *
  956. * @return void
  957. */
  958. public function testContentTypeInAction()
  959. {
  960. $this->get('/tests_apps/set_type');
  961. $this->assertHeader('Content-Type', 'application/json');
  962. $this->assertContentType('json');
  963. $this->assertContentType('application/json');
  964. }
  965. /**
  966. * Test the content assertion.
  967. *
  968. * @return void
  969. */
  970. public function testAssertResponseEquals()
  971. {
  972. $this->_response = new Response();
  973. $this->_response = $this->_response->withStringBody('Some content');
  974. $this->assertResponseEquals('Some content');
  975. }
  976. /**
  977. * Test the negated content assertion.
  978. *
  979. * @return void
  980. */
  981. public function testAssertResponseNotEquals()
  982. {
  983. $this->_response = new Response();
  984. $this->_response = $this->_response->withStringBody('Some content');
  985. $this->assertResponseNotEquals('Some Content');
  986. }
  987. /**
  988. * Test the content assertion.
  989. *
  990. * @return void
  991. */
  992. public function testAssertResponseContains()
  993. {
  994. $this->_response = new Response();
  995. $this->_response = $this->_response->withStringBody('Some content');
  996. $this->assertResponseContains('content');
  997. }
  998. /**
  999. * Test the content assertion with no case sensitivity.
  1000. *
  1001. * @return void
  1002. */
  1003. public function testAssertResponseContainsWithIgnoreCaseFlag()
  1004. {
  1005. $this->_response = new Response();
  1006. $this->_response = $this->_response->withStringBody('Some content');
  1007. $this->assertResponseContains('some', 'Failed asserting that the body contains given content', true);
  1008. }
  1009. /**
  1010. * Test the negated content assertion.
  1011. *
  1012. * @return void
  1013. */
  1014. public function testAssertResponseNotContains()
  1015. {
  1016. $this->_response = new Response();
  1017. $this->_response = $this->_response->withStringBody('Some content');
  1018. $this->assertResponseNotContains('contents');
  1019. }
  1020. /**
  1021. * Test the content regexp assertion.
  1022. *
  1023. * @return void
  1024. */
  1025. public function testAssertResponseRegExp()
  1026. {
  1027. $this->_response = new Response();
  1028. $this->_response = $this->_response->withStringBody('Some content');
  1029. $this->assertResponseRegExp('/cont/');
  1030. }
  1031. /**
  1032. * Test the content regexp assertion failing
  1033. *
  1034. * @return void
  1035. */
  1036. public function testAssertResponseRegExpNoResponse()
  1037. {
  1038. $this->expectException(AssertionFailedError::class);
  1039. $this->expectExceptionMessage('No response set');
  1040. $this->assertResponseRegExp('/cont/');
  1041. }
  1042. /**
  1043. * Test the negated content regexp assertion.
  1044. *
  1045. * @return void
  1046. */
  1047. public function testAssertResponseNotRegExp()
  1048. {
  1049. $this->_response = new Response();
  1050. $this->_response = $this->_response->withStringBody('Some content');
  1051. $this->assertResponseNotRegExp('/cant/');
  1052. }
  1053. /**
  1054. * Test negated content regexp assertion failing
  1055. *
  1056. * @return void
  1057. */
  1058. public function testAssertResponseNotRegExpNoResponse()
  1059. {
  1060. $this->expectException(AssertionFailedError::class);
  1061. $this->expectExceptionMessage('No response set');
  1062. $this->assertResponseNotRegExp('/cont/');
  1063. }
  1064. /**
  1065. * Test that works in tandem with testEventManagerReset2 to
  1066. * test the EventManager reset.
  1067. *
  1068. * The return value is passed to testEventManagerReset2 as
  1069. * an arguments.
  1070. *
  1071. * @return \Cake\Event\EventManager
  1072. */
  1073. public function testEventManagerReset1()
  1074. {
  1075. $eventManager = EventManager::instance();
  1076. $this->assertInstanceOf('Cake\Event\EventManager', $eventManager);
  1077. return $eventManager;
  1078. }
  1079. /**
  1080. * Test if the EventManager is reset between tests.
  1081. *
  1082. * @depends testEventManagerReset1
  1083. * @return void
  1084. */
  1085. public function testEventManagerReset2($prevEventManager)
  1086. {
  1087. $this->assertInstanceOf('Cake\Event\EventManager', $prevEventManager);
  1088. $this->assertNotSame($prevEventManager, EventManager::instance());
  1089. }
  1090. /**
  1091. * Test sending file in requests.
  1092. *
  1093. * @return void
  1094. */
  1095. public function testSendFile()
  1096. {
  1097. $this->get('/posts/file');
  1098. $this->assertFileResponse(TEST_APP . 'TestApp' . DS . 'Controller' . DS . 'PostsController.php');
  1099. }
  1100. /**
  1101. * Test sending file with psr7 stack
  1102. *
  1103. * @return void
  1104. */
  1105. public function testSendFileHttpServer()
  1106. {
  1107. $this->get('/posts/file');
  1108. $this->assertFileResponse(TEST_APP . 'TestApp' . DS . 'Controller' . DS . 'PostsController.php');
  1109. }
  1110. /**
  1111. * Test that assertFile requires a response
  1112. *
  1113. * @return void
  1114. */
  1115. public function testAssertFileNoResponse()
  1116. {
  1117. $this->expectException(AssertionFailedError::class);
  1118. $this->expectExceptionMessage('No response set, cannot assert content');
  1119. $this->assertFileResponse('foo');
  1120. }
  1121. /**
  1122. * Test that assertFile requires a file
  1123. *
  1124. * @return void
  1125. */
  1126. public function testAssertFileNoFile()
  1127. {
  1128. $this->expectException(AssertionFailedError::class);
  1129. $this->expectExceptionMessage('Failed asserting that file was sent.');
  1130. $this->get('/posts/get');
  1131. $this->assertFileResponse('foo');
  1132. }
  1133. /**
  1134. * Test disabling the error handler middleware.
  1135. *
  1136. * @return void
  1137. */
  1138. public function testDisableErrorHandlerMiddleware()
  1139. {
  1140. $this->expectException(\Cake\Routing\Exception\MissingRouteException::class);
  1141. $this->expectExceptionMessage('A route matching "/foo" could not be found.');
  1142. $this->disableErrorHandlerMiddleware();
  1143. $this->get('/foo');
  1144. }
  1145. /**
  1146. * tests getting a secure action while passing a query string
  1147. *
  1148. * @return void
  1149. * @dataProvider methodsProvider
  1150. */
  1151. public function testSecureWithQueryString($method)
  1152. {
  1153. $this->enableSecurityToken();
  1154. $this->{$method}('/posts/securePost/?ids[]=1&ids[]=2');
  1155. $this->assertResponseOk();
  1156. }
  1157. /**
  1158. * Tests flash assertions
  1159. *
  1160. * @return void
  1161. * @throws \PHPUnit\Exception
  1162. */
  1163. public function testAssertFlashMessage()
  1164. {
  1165. $this->get('/posts/stacked_flash');
  1166. $this->assertFlashElement('flash/error');
  1167. $this->assertFlashElement('flash/success', 'custom');
  1168. $this->assertFlashMessage('Error 1');
  1169. $this->assertFlashMessageAt(0, 'Error 1');
  1170. $this->assertFlashElementAt(0, 'flash/error');
  1171. $this->assertFlashMessage('Error 2');
  1172. $this->assertFlashMessageAt(1, 'Error 2');
  1173. $this->assertFlashElementAt(1, 'flash/error');
  1174. $this->assertFlashMessage('Success 1', 'custom');
  1175. $this->assertFlashMessageAt(0, 'Success 1', 'custom');
  1176. $this->assertFlashElementAt(0, 'flash/success', 'custom');
  1177. $this->assertFlashMessage('Success 2', 'custom');
  1178. $this->assertFlashMessageAt(1, 'Success 2', 'custom');
  1179. $this->assertFlashElementAt(1, 'flash/success', 'custom');
  1180. }
  1181. /**
  1182. * Tests asserting flash messages without first sending a request
  1183. *
  1184. * @return void
  1185. */
  1186. public function testAssertFlashMessageWithoutSendingRequest()
  1187. {
  1188. $this->expectException(AssertionFailedError::class);
  1189. $message = 'There is no stored session data. Perhaps you need to run a request?';
  1190. $message .= ' Additionally, ensure `$this->enableRetainFlashMessages()` has been enabled for the test.';
  1191. $this->expectExceptionMessage($message);
  1192. $this->assertFlashMessage('Will not work');
  1193. }
  1194. /**
  1195. * tests failure messages for assertions
  1196. *
  1197. * @param string $assertion Assertion method
  1198. * @param string $message Expected failure message
  1199. * @param string $url URL to test
  1200. * @param mixed ...$rest
  1201. * @dataProvider assertionFailureMessagesProvider
  1202. */
  1203. public function testAssertionFailureMessages($assertion, $message, $url, ...$rest)
  1204. {
  1205. $this->expectException(AssertionFailedError::class);
  1206. $this->expectExceptionMessage($message);
  1207. Security::setSalt($this->key);
  1208. $this->get($url);
  1209. call_user_func_array([$this, $assertion], $rest);
  1210. }
  1211. /**
  1212. * data provider for assertion failure messages
  1213. *
  1214. * @return array
  1215. */
  1216. public function assertionFailureMessagesProvider()
  1217. {
  1218. $templateDir = TEST_APP . 'templates' . DS;
  1219. return [
  1220. 'assertContentType' => ['assertContentType', 'Failed asserting that \'test\' was set as the Content-Type.', '/posts/index', 'test'],
  1221. 'assertContentTypeVerbose' => ['assertContentType', 'Possibly related to Cake\Routing\Exception\MissingRouteException: "A route matching "/notfound" could not be found."', '/notfound', 'test'],
  1222. 'assertCookie' => ['assertCookie', 'Failed asserting that \'test\' was in cookie \'remember_me\'.', '/posts/index', 'test', 'remember_me'],
  1223. 'assertCookieVerbose' => ['assertCookie', 'Possibly related to Cake\Routing\Exception\MissingRouteException: "A route matching "/notfound" could not be found."', '/notfound', 'test', 'remember_me'],
  1224. 'assertCookieEncrypted' => ['assertCookieEncrypted', 'Failed asserting that \'test\' was encrypted in cookie \'secrets\'.', '/posts/secretCookie', 'test', 'secrets'],
  1225. 'assertCookieEncryptedVerbose' => ['assertCookieEncrypted', 'Possibly related to Cake\Routing\Exception\MissingRouteException: "A route matching "/notfound" could not be found."', '/notfound', 'test', 'NameOfCookie'],
  1226. 'assertCookieNotSet' => ['assertCookieNotSet', 'Failed asserting that \'remember_me\' cookie was not set.', '/posts/index', 'remember_me'],
  1227. 'assertFileResponse' => ['assertFileResponse', 'Failed asserting that \'test\' file was sent.', '/posts/file', 'test'],
  1228. 'assertFileResponseVerbose' => ['assertFileResponse', 'Possibly related to Cake\Routing\Exception\MissingRouteException: "A route matching "/notfound" could not be found."', '/notfound', 'test'],
  1229. 'assertHeader' => ['assertHeader', 'Failed asserting that \'test\' equals content in header \'X-Cake\'.', '/posts/header', 'X-Cake', 'test'],
  1230. 'assertHeaderContains' => ['assertHeaderContains', 'Failed asserting that \'test\' is in header \'X-Cake\'', '/posts/header', 'X-Cake', 'test'],
  1231. 'assertHeaderContainsVerbose' => ['assertHeaderContains', 'Possibly related to Cake\Routing\Exception\MissingRouteException: "A route matching "/notfound" could not be found."', '/notfound', 'X-Cake', 'test'],
  1232. 'assertHeaderNotContainsVerbose' => ['assertHeaderNotContains', 'Possibly related to Cake\Routing\Exception\MissingRouteException: "A route matching "/notfound" could not be found."', '/notfound', 'X-Cake', 'test'],
  1233. 'assertLayout' => ['assertLayout', 'Failed asserting that \'custom_layout\' equals layout file ' . $templateDir . 'layout' . DS . 'default.php.', '/posts/index', 'custom_layout'],
  1234. 'assertLayoutVerbose' => ['assertLayout', 'Possibly related to Cake\Routing\Exception\MissingRouteException: "A route matching "/notfound" could not be found."', '/notfound', 'custom_layout'],
  1235. 'assertRedirect' => ['assertRedirect', 'Failed asserting that \'http://localhost/\' equals content in header \'Location\'.', '/posts/flashNoRender', '/'],
  1236. 'assertRedirectVerbose' => ['assertRedirect', 'Possibly related to Cake\Routing\Exception\MissingRouteException: "A route matching "/notfound" could not be found."', '/notfound', '/'],
  1237. 'assertRedirectContains' => ['assertRedirectContains', 'Failed asserting that \'/posts/somewhere-else\' is in header \'Location\'.', '/posts/flashNoRender', '/posts/somewhere-else'],
  1238. 'assertRedirectContainsVerbose' => ['assertRedirectContains', 'Possibly related to Cake\Routing\Exception\MissingRouteException: "A route matching "/notfound" could not be found."', '/notfound', '/posts/somewhere-else'],
  1239. 'assertRedirectNotContainsVerbose' => ['assertRedirectNotContains', 'Possibly related to Cake\Routing\Exception\MissingRouteException: "A route matching "/notfound" could not be found."', '/notfound', '/posts/somewhere-else'],
  1240. 'assertResponseCode' => ['assertResponseCode', 'Failed asserting that 302 matches response status code 200.', '/posts/index', 302],
  1241. 'assertResponseContains' => ['assertResponseContains', 'Failed asserting that \'test\' is in response body.', '/posts/index', 'test'],
  1242. 'assertResponseEmpty' => ['assertResponseEmpty', 'Failed asserting that response body is empty.', '/posts/index'],
  1243. 'assertResponseEquals' => ['assertResponseEquals', 'Failed asserting that \'test\' matches response body.', '/posts/index', 'test'],
  1244. 'assertResponseEqualsVerbose' => ['assertResponseEquals', 'Possibly related to Cake\Routing\Exception\MissingRouteException: "A route matching "/notfound" could not be found."', '/notfound', 'test'],
  1245. 'assertResponseError' => ['assertResponseError', 'Failed asserting that 200 is between 400 and 429.', '/posts/index'],
  1246. 'assertResponseFailure' => ['assertResponseFailure', 'Failed asserting that 200 is between 500 and 505.', '/posts/index'],
  1247. 'assertResponseNotContains' => ['assertResponseNotContains', 'Failed asserting that \'index\' is not in response body.', '/posts/index', 'index'],
  1248. 'assertResponseNotEmpty' => ['assertResponseNotEmpty', 'Failed asserting that response body is not empty.', '/posts/empty_response'],
  1249. 'assertResponseNotEquals' => ['assertResponseNotEquals', 'Failed asserting that \'posts index\' does not match response body.', '/posts/index/error', 'posts index'],
  1250. 'assertResponseNotRegExp' => ['assertResponseNotRegExp', 'Failed asserting that /index/ PCRE pattern not found in response body.', '/posts/index/error', '/index/'],
  1251. 'assertResponseNotRegExpVerbose' => ['assertResponseNotRegExp', 'Possibly related to Cake\Routing\Exception\MissingRouteException: "A route matching "/notfound" could not be found."', '/notfound', '/index/'],
  1252. 'assertResponseOk' => ['assertResponseOk', 'Failed asserting that 404 is between 200 and 204.', '/posts/missing', '/index/'],
  1253. 'assertResponseRegExp' => ['assertResponseRegExp', 'Failed asserting that /test/ PCRE pattern found in response body.', '/posts/index/error', '/test/'],
  1254. 'assertResponseSuccess' => ['assertResponseSuccess', 'Failed asserting that 404 is between 200 and 308.', '/posts/missing'],
  1255. 'assertResponseSuccessVerbose' => ['assertResponseSuccess', 'Possibly related to Cake\Controller\Exception\MissingActionException: "Action PostsController::missing() could not be found, or is not accessible."', '/posts/missing'],
  1256. 'assertSession' => ['assertSession', 'Failed asserting that \'test\' is in session path \'Missing.path\'.', '/posts/index', 'test', 'Missing.path'],
  1257. 'assertTemplate' => ['assertTemplate', 'Failed asserting that \'custom_template\' equals template file ' . $templateDir . 'Posts' . DS . 'index.php.', '/posts/index', 'custom_template'],
  1258. 'assertTemplateVerbose' => ['assertTemplate', 'Possibly related to Cake\Routing\Exception\MissingRouteException: "A route matching "/notfound" could not be found."', '/notfound', 'custom_template'],
  1259. 'assertFlashMessage' => ['assertFlashMessage', 'Failed asserting that \'missing\' was in \'flash\' message.', '/posts/index', 'missing'],
  1260. 'assertFlashMessageWithKey' => ['assertFlashMessage', 'Failed asserting that \'missing\' was in \'auth\' message.', '/posts/index', 'missing', 'auth'],
  1261. 'assertFlashMessageAt' => ['assertFlashMessageAt', 'Failed asserting that \'missing\' was in \'flash\' message #0.', '/posts/index', 0, 'missing'],
  1262. 'assertFlashMessageAtWithKey' => ['assertFlashMessageAt', 'Failed asserting that \'missing\' was in \'auth\' message #0.', '/posts/index', 0, 'missing', 'auth'],
  1263. 'assertFlashElement' => ['assertFlashElement', 'Failed asserting that \'missing\' was in \'flash\' element.', '/posts/index', 'missing'],
  1264. 'assertFlashElementWithKey' => ['assertFlashElement', 'Failed asserting that \'missing\' was in \'auth\' element.', '/posts/index', 'missing', 'auth'],
  1265. 'assertFlashElementAt' => ['assertFlashElementAt', 'Failed asserting that \'missing\' was in \'flash\' element #0.', '/posts/index', 0, 'missing'],
  1266. 'assertFlashElementAtWithKey' => ['assertFlashElementAt', 'Failed asserting that \'missing\' was in \'auth\' element #0.', '/posts/index', 0, 'missing', 'auth'],
  1267. ];
  1268. }
  1269. /**
  1270. * data provider for HTTP methods
  1271. *
  1272. * @return array
  1273. */
  1274. public function methodsProvider()
  1275. {
  1276. return [
  1277. 'GET' => ['get'],
  1278. 'POST' => ['post'],
  1279. 'PATCH' => ['patch'],
  1280. 'PUT' => ['put'],
  1281. 'DELETE' => ['delete'],
  1282. ];
  1283. }
  1284. /**
  1285. * Test assertCookieNotSet is creating a verbose message
  1286. *
  1287. * @return void
  1288. */
  1289. public function testAssertCookieNotSetVerbose()
  1290. {
  1291. $this->expectException(AssertionFailedError::class);
  1292. $this->expectExceptionMessage('Possibly related to Cake\Routing\Exception\MissingRouteException: "A route matching "/notfound" could not be found."');
  1293. $this->get('/notfound');
  1294. $this->_response = $this->_response->withCookie(new Cookie('cookie', 'value'));
  1295. $this->assertCookieNotSet('cookie');
  1296. }
  1297. /**
  1298. * Test assertNoRedirect is creating a verbose message
  1299. *
  1300. * @return void
  1301. */
  1302. public function testAssertNoRedirectVerbose()
  1303. {
  1304. $this->expectException(AssertionFailedError::class);
  1305. $this->expectExceptionMessage('Possibly related to Cake\Routing\Exception\MissingRouteException: "A route matching "/notfound" could not be found."');
  1306. $this->get('/notfound');
  1307. $this->_response = $this->_response->withHeader('Location', '/redirect');
  1308. $this->assertNoRedirect();
  1309. }
  1310. /**
  1311. * Test the header assertion generating a verbose message.
  1312. *
  1313. * @return void
  1314. */
  1315. public function testAssertHeaderVerbose()
  1316. {
  1317. $this->expectException(AssertionFailedError::class);
  1318. $this->expectExceptionMessage('Possibly related to Cake\Routing\Exception\MissingRouteException: "A route matching "/notfound" could not be found."');
  1319. $this->get('/notfound');
  1320. $this->assertHeader('Etag', 'abc123');
  1321. }
  1322. /**
  1323. * Test the assertResponseNotEquals generates a verbose message.
  1324. *
  1325. * @return void
  1326. */
  1327. public function testAssertResponseNotEqualsVerbose()
  1328. {
  1329. $this->expectException(AssertionFailedError::class);
  1330. $this->expectExceptionMessage('Possibly related to Cake\Routing\Exception\MissingRouteException: "A route matching "/notfound" could not be found."');
  1331. $this->get('/notfound');
  1332. $this->_response = $this->_response->withStringBody('body');
  1333. $this->assertResponseNotEquals('body');
  1334. }
  1335. /**
  1336. * Test the assertResponseRegExp generates a verbose message.
  1337. *
  1338. * @return void
  1339. */
  1340. public function testAssertResponseRegExpVerbose()
  1341. {
  1342. $this->expectException(AssertionFailedError::class);
  1343. $this->expectExceptionMessage('Possibly related to Cake\Routing\Exception\MissingRouteException: "A route matching "/notfound" could not be found."');
  1344. $this->get('/notfound');
  1345. $this->_response = $this->_response->withStringBody('body');
  1346. $this->assertResponseRegExp('/patternNotFound/');
  1347. }
  1348. /**
  1349. * Test the assertion generates a verbose message for session related checks.
  1350. *
  1351. * @dataProvider assertionFailureSessionVerboseProvider
  1352. * @return void
  1353. */
  1354. public function testAssertSessionRelatedVerboseMessages($assertMethod, ...$rest)
  1355. {
  1356. $this->expectException(AssertionFailedError::class);
  1357. $this->expectExceptionMessage('Possibly related to OutOfBoundsException: "oh no!"');
  1358. $this->get('/posts/throw_exception');
  1359. $this->_requestSession = new Session();
  1360. call_user_func_array([$this, $assertMethod], $rest);
  1361. }
  1362. /**
  1363. * data provider for assertion verbose session related tests
  1364. *
  1365. * @return array
  1366. */
  1367. public function assertionFailureSessionVerboseProvider()
  1368. {
  1369. return [
  1370. 'assertFlashMessageVerbose' => ['assertFlashMessage', 'notfound'],
  1371. 'assertFlashMessageAtVerbose' => ['assertFlashMessageAt', 2, 'notfound'],
  1372. 'assertFlashElementVerbose' => ['assertFlashElement', 'notfound'],
  1373. 'assertSessionVerbose' => ['assertSession', 'notfound', 'notfound'],
  1374. ];
  1375. }
  1376. /**
  1377. * Test viewVariable not found
  1378. *
  1379. * @return void
  1380. */
  1381. public function testViewVariableNotFoundShouldReturnNull()
  1382. {
  1383. $this->_controller = new Controller();
  1384. $this->assertNull($this->viewVariable('notFound'));
  1385. }
  1386. }