PaginatorComponentTest.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752
  1. <?php
  2. /**
  3. * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
  4. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  11. * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
  12. * @since CakePHP(tm) v 2.0
  13. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\Test\TestCase\Controller\Component;
  16. use Cake\Controller\ComponentRegistry;
  17. use Cake\Controller\Component\PaginatorComponent;
  18. use Cake\Controller\Controller;
  19. use Cake\Core\Configure;
  20. use Cake\Database\ConnectionManager;
  21. use Cake\Error;
  22. use Cake\Network\Request;
  23. use Cake\ORM\TableRegistry;
  24. use Cake\TestSuite\TestCase;
  25. use Cake\Utility\Hash;
  26. /**
  27. * PaginatorTestController class
  28. *
  29. */
  30. class PaginatorTestController extends Controller {
  31. /**
  32. * components property
  33. *
  34. * @var array
  35. */
  36. public $components = array('Paginator');
  37. }
  38. class PaginatorComponentTest extends TestCase {
  39. /**
  40. * fixtures property
  41. *
  42. * @var array
  43. */
  44. public $fixtures = array('core.post', 'core.author');
  45. /**
  46. * setup
  47. *
  48. * @return void
  49. */
  50. public function setUp() {
  51. parent::setUp();
  52. Configure::write('App.namespace', 'TestApp');
  53. $this->request = new Request('controller_posts/index');
  54. $this->request->params['pass'] = array();
  55. $controller = new Controller($this->request);
  56. $registry = new ComponentRegistry($controller);
  57. $this->Paginator = new PaginatorComponent($registry, []);
  58. $this->Post = $this->getMock('Cake\ORM\Table', [], [], '', false);
  59. }
  60. /**
  61. * tearDown
  62. *
  63. * @return void
  64. */
  65. public function tearDown() {
  66. parent::tearDown();
  67. TableRegistry::clear();
  68. }
  69. /**
  70. * Test that non-numeric values are rejected for page, and limit
  71. *
  72. * @return void
  73. */
  74. public function testPageParamCasting() {
  75. $this->Post->expects($this->any())
  76. ->method('alias')
  77. ->will($this->returnValue('Posts'));
  78. $query = $this->_getMockFindQuery();
  79. $this->Post->expects($this->any())
  80. ->method('find')
  81. ->will($this->returnValue($query));
  82. $this->request->query = array('page' => '1 " onclick="alert(\'xss\');">');
  83. $settings = array('limit' => 1, 'maxLimit' => 10);
  84. $this->Paginator->paginate($this->Post, $settings);
  85. $this->assertSame(1, $this->request->params['paging']['Posts']['page'], 'XSS exploit opened');
  86. }
  87. /**
  88. * test that unknown keys in the default settings are
  89. * passed to the find operations.
  90. *
  91. * @return void
  92. */
  93. public function testPaginateExtraParams() {
  94. $this->request->query = array('page' => '-1');
  95. $settings = array(
  96. 'PaginatorPosts' => array(
  97. 'contain' => array('PaginatorAuthor'),
  98. 'maxLimit' => 10,
  99. 'group' => 'PaginatorPosts.published',
  100. 'order' => array('PaginatorPosts.id' => 'ASC')
  101. ),
  102. );
  103. $table = $this->_getMockPosts(['find']);
  104. $query = $this->_getMockFindQuery();
  105. $table->expects($this->once())
  106. ->method('find')
  107. ->with('all', [
  108. 'conditions' => [],
  109. 'contain' => ['PaginatorAuthor'],
  110. 'fields' => null,
  111. 'group' => 'PaginatorPosts.published',
  112. 'limit' => 10,
  113. 'order' => ['PaginatorPosts.id' => 'ASC'],
  114. 'page' => 1,
  115. ])
  116. ->will($this->returnValue($query));
  117. $this->Paginator->paginate($table, $settings);
  118. }
  119. /**
  120. * Test that special paginate types are called and that the type param doesn't leak out into defaults or options.
  121. *
  122. * @return void
  123. */
  124. public function testPaginateCustomFinder() {
  125. $settings = array(
  126. 'PaginatorPosts' => array(
  127. 'findType' => 'popular',
  128. 'fields' => array('id', 'title'),
  129. 'maxLimit' => 10,
  130. )
  131. );
  132. $table = $this->_getMockPosts(['findPopular']);
  133. $query = $this->_getMockFindQuery();
  134. $table->expects($this->any())
  135. ->method('findPopular')
  136. ->will($this->returnValue($query));
  137. $this->Paginator->paginate($table, $settings);
  138. $this->assertEquals('popular', $this->request->params['paging']['PaginatorPosts']['findType']);
  139. }
  140. /**
  141. * test that flat default pagination parameters work.
  142. *
  143. * @return void
  144. */
  145. public function testDefaultPaginateParams() {
  146. $settings = array(
  147. 'order' => ['PaginatorPosts.id' => 'DESC'],
  148. 'maxLimit' => 10,
  149. );
  150. $table = $this->_getMockPosts(['find']);
  151. $query = $this->_getMockFindQuery();
  152. $table->expects($this->once())
  153. ->method('find')
  154. ->with('all', [
  155. 'conditions' => [],
  156. 'fields' => null,
  157. 'limit' => 10,
  158. 'page' => 1,
  159. 'order' => ['PaginatorPosts.id' => 'DESC']
  160. ])
  161. ->will($this->returnValue($query));
  162. $this->Paginator->paginate($table, $settings);
  163. }
  164. /**
  165. * test that default sort and default direction are injected into request
  166. *
  167. * @return void
  168. */
  169. public function testDefaultPaginateParamsIntoRequest() {
  170. $settings = array(
  171. 'order' => ['PaginatorPosts.id' => 'DESC'],
  172. 'maxLimit' => 10,
  173. );
  174. $table = $this->_getMockPosts(['find']);
  175. $query = $this->_getMockFindQuery();
  176. $table->expects($this->once())
  177. ->method('find')
  178. ->with('all', [
  179. 'conditions' => [],
  180. 'fields' => null,
  181. 'limit' => 10,
  182. 'page' => 1,
  183. 'order' => ['PaginatorPosts.id' => 'DESC']
  184. ])
  185. ->will($this->returnValue($query));
  186. $this->Paginator->paginate($table, $settings);
  187. $this->assertEquals('PaginatorPosts.id', $this->request->params['paging']['PaginatorPosts']['sortDefault']);
  188. $this->assertEquals('DESC', $this->request->params['paging']['PaginatorPosts']['directionDefault']);
  189. }
  190. /**
  191. * test that option merging prefers specific models
  192. *
  193. * @return void
  194. */
  195. public function testMergeOptionsModelSpecific() {
  196. $settings = array(
  197. 'page' => 1,
  198. 'limit' => 20,
  199. 'maxLimit' => 100,
  200. 'Posts' => array(
  201. 'page' => 1,
  202. 'limit' => 10,
  203. 'maxLimit' => 50,
  204. )
  205. );
  206. $result = $this->Paginator->mergeOptions('Silly', $settings);
  207. $this->assertEquals($settings, $result);
  208. $result = $this->Paginator->mergeOptions('Posts', $settings);
  209. $expected = array('page' => 1, 'limit' => 10, 'maxLimit' => 50);
  210. $this->assertEquals($expected, $result);
  211. }
  212. /**
  213. * test mergeOptions with customFind key
  214. *
  215. * @return void
  216. */
  217. public function testMergeOptionsCustomFindKey() {
  218. $this->request->query = [
  219. 'page' => 10,
  220. 'limit' => 10
  221. ];
  222. $settings = [
  223. 'page' => 1,
  224. 'limit' => 20,
  225. 'maxLimit' => 100,
  226. 'findType' => 'myCustomFind'
  227. ];
  228. $result = $this->Paginator->mergeOptions('Post', $settings);
  229. $expected = array(
  230. 'page' => 10,
  231. 'limit' => 10,
  232. 'maxLimit' => 100,
  233. 'findType' => 'myCustomFind'
  234. );
  235. $this->assertEquals($expected, $result);
  236. }
  237. /**
  238. * test merging options from the querystring.
  239. *
  240. * @return void
  241. */
  242. public function testMergeOptionsQueryString() {
  243. $this->request->query = array(
  244. 'page' => 99,
  245. 'limit' => 75
  246. );
  247. $settings = array(
  248. 'page' => 1,
  249. 'limit' => 20,
  250. 'maxLimit' => 100,
  251. );
  252. $result = $this->Paginator->mergeOptions('Post', $settings);
  253. $expected = array('page' => 99, 'limit' => 75, 'maxLimit' => 100);
  254. $this->assertEquals($expected, $result);
  255. }
  256. /**
  257. * test that the default whitelist doesn't let people screw with things they should not be allowed to.
  258. *
  259. * @return void
  260. */
  261. public function testMergeOptionsDefaultWhiteList() {
  262. $this->request->query = array(
  263. 'page' => 10,
  264. 'limit' => 10,
  265. 'fields' => array('bad.stuff'),
  266. 'recursive' => 1000,
  267. 'conditions' => array('bad.stuff'),
  268. 'contain' => array('bad')
  269. );
  270. $settings = array(
  271. 'page' => 1,
  272. 'limit' => 20,
  273. 'maxLimit' => 100,
  274. );
  275. $result = $this->Paginator->mergeOptions('Post', $settings);
  276. $expected = array('page' => 10, 'limit' => 10, 'maxLimit' => 100);
  277. $this->assertEquals($expected, $result);
  278. }
  279. /**
  280. * test that modifying the whitelist works.
  281. *
  282. * @return void
  283. */
  284. public function testMergeOptionsExtraWhitelist() {
  285. $this->request->query = array(
  286. 'page' => 10,
  287. 'limit' => 10,
  288. 'fields' => array('bad.stuff'),
  289. 'recursive' => 1000,
  290. 'conditions' => array('bad.stuff'),
  291. 'contain' => array('bad')
  292. );
  293. $settings = array(
  294. 'page' => 1,
  295. 'limit' => 20,
  296. 'maxLimit' => 100,
  297. );
  298. $this->Paginator->whitelist[] = 'fields';
  299. $result = $this->Paginator->mergeOptions('Post', $settings);
  300. $expected = array(
  301. 'page' => 10, 'limit' => 10, 'maxLimit' => 100, 'fields' => array('bad.stuff')
  302. );
  303. $this->assertEquals($expected, $result);
  304. }
  305. /**
  306. * test mergeOptions with limit > maxLimit in code.
  307. *
  308. * @return void
  309. */
  310. public function testMergeOptionsMaxLimit() {
  311. $settings = array(
  312. 'limit' => 200,
  313. 'paramType' => 'named',
  314. );
  315. $result = $this->Paginator->mergeOptions('Post', $settings);
  316. $expected = array('page' => 1, 'limit' => 200, 'maxLimit' => 200, 'paramType' => 'named');
  317. $this->assertEquals($expected, $result);
  318. $settings = array(
  319. 'maxLimit' => 10,
  320. 'paramType' => 'named',
  321. );
  322. $result = $this->Paginator->mergeOptions('Post', $settings);
  323. $expected = array('page' => 1, 'limit' => 20, 'maxLimit' => 10, 'paramType' => 'named');
  324. $this->assertEquals($expected, $result);
  325. }
  326. /**
  327. * Integration test to ensure that validateSort is being used by paginate()
  328. *
  329. * @return void
  330. */
  331. public function testValidateSortInvalid() {
  332. $table = $this->_getMockPosts(['find']);
  333. $query = $this->_getMockFindQuery();
  334. $table->expects($this->once())
  335. ->method('find')
  336. ->with('all', [
  337. 'fields' => null,
  338. 'limit' => 20,
  339. 'conditions' => [],
  340. 'page' => 1,
  341. 'order' => ['PaginatorPosts.id' => 'asc'],
  342. ])
  343. ->will($this->returnValue($query));
  344. $this->request->query = [
  345. 'page' => 1,
  346. 'sort' => 'id',
  347. 'direction' => 'herp'
  348. ];
  349. $this->Paginator->paginate($table);
  350. $this->assertEquals('PaginatorPosts.id', $this->request->params['paging']['PaginatorPosts']['sort']);
  351. $this->assertEquals('asc', $this->request->params['paging']['PaginatorPosts']['direction']);
  352. }
  353. /**
  354. * test that invalid directions are ignored.
  355. *
  356. * @return void
  357. */
  358. public function testValidateSortInvalidDirection() {
  359. $model = $this->getMock('Cake\ORM\Table');
  360. $model->expects($this->any())
  361. ->method('alias')
  362. ->will($this->returnValue('model'));
  363. $model->expects($this->any())
  364. ->method('hasField')
  365. ->will($this->returnValue(true));
  366. $options = array('sort' => 'something', 'direction' => 'boogers');
  367. $result = $this->Paginator->validateSort($model, $options);
  368. $this->assertEquals('asc', $result['order']['model.something']);
  369. }
  370. /**
  371. * Test that a really large page number gets clamped to the max page size.
  372. *
  373. * @return void
  374. */
  375. public function testOutOfRangePageNumberGetsClamped() {
  376. $this->request->query['page'] = 3000;
  377. $table = TableRegistry::get('PaginatorPosts');
  378. try {
  379. $this->Paginator->paginate($table);
  380. $this->fail('No exception raised');
  381. } catch (\Cake\Error\NotFoundException $e) {
  382. $this->assertEquals(
  383. 1,
  384. $this->request->params['paging']['PaginatorPosts']['page'],
  385. 'Page number should not be 0'
  386. );
  387. }
  388. }
  389. /**
  390. * Test that a really REALLY large page number gets clamped to the max page size.
  391. *
  392. * @expectedException Cake\Error\NotFoundException
  393. * @return void
  394. */
  395. public function testOutOfVeryBigPageNumberGetsClamped() {
  396. $this->request->query = [
  397. 'page' => '3000000000000000000000000',
  398. ];
  399. $table = TableRegistry::get('PaginatorPosts');
  400. $this->Paginator->paginate($table);
  401. }
  402. /**
  403. * test that fields not in whitelist won't be part of order conditions.
  404. *
  405. * @return void
  406. */
  407. public function testValidateSortWhitelistFailure() {
  408. $model = $this->getMock('Cake\ORM\Table');
  409. $model->expects($this->any())
  410. ->method('alias')
  411. ->will($this->returnValue('model'));
  412. $model->expects($this->any())->method('hasField')->will($this->returnValue(true));
  413. $options = array(
  414. 'sort' => 'body',
  415. 'direction' => 'asc',
  416. 'sortWhitelist' => ['title', 'id']
  417. );
  418. $result = $this->Paginator->validateSort($model, $options);
  419. $this->assertEquals([], $result['order']);
  420. }
  421. /**
  422. * test that fields in the whitelist are not validated
  423. *
  424. * @return void
  425. */
  426. public function testValidateSortWhitelistTrusted() {
  427. $model = $this->getMock('Cake\ORM\Table');
  428. $model->expects($this->any())
  429. ->method('alias')
  430. ->will($this->returnValue('model'));
  431. $model->expects($this->never())->method('hasField');
  432. $options = array(
  433. 'sort' => 'body',
  434. 'direction' => 'asc',
  435. 'sortWhitelist' => ['body']
  436. );
  437. $result = $this->Paginator->validateSort($model, $options);
  438. $expected = array('body' => 'asc');
  439. $this->assertEquals($expected, $result['order']);
  440. }
  441. /**
  442. * test that multiple sort works.
  443. *
  444. * @return void
  445. */
  446. public function testValidateSortMultiple() {
  447. $model = $this->getMock('Cake\ORM\Table');
  448. $model->expects($this->any())
  449. ->method('alias')
  450. ->will($this->returnValue('model'));
  451. $model->expects($this->any())->method('hasField')->will($this->returnValue(true));
  452. $options = array(
  453. 'order' => array(
  454. 'author_id' => 'asc',
  455. 'title' => 'asc'
  456. )
  457. );
  458. $result = $this->Paginator->validateSort($model, $options);
  459. $expected = array(
  460. 'model.author_id' => 'asc',
  461. 'model.title' => 'asc'
  462. );
  463. $this->assertEquals($expected, $result['order']);
  464. }
  465. /**
  466. * Test that no sort doesn't trigger an error.
  467. *
  468. * @return void
  469. */
  470. public function testValidateSortNoSort() {
  471. $model = $this->getMock('Cake\ORM\Table');
  472. $model->expects($this->any())
  473. ->method('alias')
  474. ->will($this->returnValue('model'));
  475. $model->expects($this->any())->method('hasField')
  476. ->will($this->returnValue(true));
  477. $options = array(
  478. 'direction' => 'asc',
  479. 'sortWhitelist' => ['title', 'id'],
  480. );
  481. $result = $this->Paginator->validateSort($model, $options);
  482. $this->assertEquals([], $result['order']);
  483. }
  484. /**
  485. * Test sorting with incorrect aliases on valid fields.
  486. *
  487. * @return void
  488. */
  489. public function testValidateSortInvalidAlias() {
  490. $model = $this->getMock('Cake\ORM\Table');
  491. $model->expects($this->any())
  492. ->method('alias')
  493. ->will($this->returnValue('model'));
  494. $model->expects($this->any())->method('hasField')->will($this->returnValue(true));
  495. $options = array('sort' => 'Derp.id');
  496. $result = $this->Paginator->validateSort($model, $options);
  497. $this->assertEquals(array(), $result['order']);
  498. }
  499. /**
  500. * test that maxLimit is respected
  501. *
  502. * @return void
  503. */
  504. public function testCheckLimit() {
  505. $result = $this->Paginator->checkLimit(array('limit' => 1000000, 'maxLimit' => 100));
  506. $this->assertEquals(100, $result['limit']);
  507. $result = $this->Paginator->checkLimit(array('limit' => 'sheep!', 'maxLimit' => 100));
  508. $this->assertEquals(1, $result['limit']);
  509. $result = $this->Paginator->checkLimit(array('limit' => '-1', 'maxLimit' => 100));
  510. $this->assertEquals(1, $result['limit']);
  511. $result = $this->Paginator->checkLimit(array('limit' => null, 'maxLimit' => 100));
  512. $this->assertEquals(1, $result['limit']);
  513. $result = $this->Paginator->checkLimit(array('limit' => 0, 'maxLimit' => 100));
  514. $this->assertEquals(1, $result['limit']);
  515. }
  516. /**
  517. * Integration test for checkLimit() being applied inside paginate()
  518. *
  519. * @return void
  520. */
  521. public function testPaginateMaxLimit() {
  522. $table = TableRegistry::get('PaginatorPosts');
  523. $settings = [
  524. 'maxLimit' => 100,
  525. ];
  526. $this->request->query = [
  527. 'limit' => '1000'
  528. ];
  529. $this->Paginator->paginate($table, $settings);
  530. $this->assertEquals(100, $this->request->params['paging']['PaginatorPosts']['limit']);
  531. $this->request->query = [
  532. 'limit' => '10'
  533. ];
  534. $this->Paginator->paginate($table, $settings);
  535. $this->assertEquals(10, $this->request->params['paging']['PaginatorPosts']['limit']);
  536. }
  537. /**
  538. * test paginate() and custom find, to make sure the correct count is returned.
  539. *
  540. * @return void
  541. */
  542. public function testPaginateCustomFind() {
  543. $idExtractor = function ($result) {
  544. $ids = [];
  545. foreach ($result as $record) {
  546. $ids[] = $record->id;
  547. }
  548. return $ids;
  549. };
  550. $table = TableRegistry::get('PaginatorPosts');
  551. $data = array('author_id' => 3, 'title' => 'Fourth Article', 'body' => 'Article Body, unpublished', 'published' => 'N');
  552. $result = $table->save(new \Cake\ORM\Entity($data));
  553. $this->assertNotEmpty($result);
  554. $result = $this->Paginator->paginate($table);
  555. $this->assertCount(4, $result, '4 rows should come back');
  556. $this->assertEquals(array(1, 2, 3, 4), $idExtractor($result));
  557. $result = $this->request->params['paging']['PaginatorPosts'];
  558. $this->assertEquals(4, $result['current']);
  559. $this->assertEquals(4, $result['count']);
  560. $settings = array('findType' => 'published');
  561. $result = $this->Paginator->paginate($table, $settings);
  562. $this->assertCount(3, $result, '3 rows should come back');
  563. $this->assertEquals(array(1, 2, 3), $idExtractor($result));
  564. $result = $this->request->params['paging']['PaginatorPosts'];
  565. $this->assertEquals(3, $result['current']);
  566. $this->assertEquals(3, $result['count']);
  567. $settings = array('findType' => 'published', 'limit' => 2);
  568. $result = $this->Paginator->paginate($table, $settings);
  569. $this->assertCount(2, $result, '2 rows should come back');
  570. $this->assertEquals(array(1, 2), $idExtractor($result));
  571. $result = $this->request->params['paging']['PaginatorPosts'];
  572. $this->assertEquals(2, $result['current']);
  573. $this->assertEquals(3, $result['count']);
  574. $this->assertEquals(2, $result['pageCount']);
  575. $this->assertTrue($result['nextPage']);
  576. $this->assertFalse($result['prevPage']);
  577. }
  578. /**
  579. * test paginate() and custom find with fields array, to make sure the correct count is returned.
  580. *
  581. * @return void
  582. */
  583. public function testPaginateCustomFindFieldsArray() {
  584. $table = TableRegistry::get('PaginatorPosts');
  585. $data = array('author_id' => 3, 'title' => 'Fourth Article', 'body' => 'Article Body, unpublished', 'published' => 'N');
  586. $table->save(new \Cake\ORM\Entity($data));
  587. $settings = [
  588. 'findType' => 'list',
  589. 'conditions' => array('PaginatorPosts.published' => 'Y'),
  590. 'limit' => 2
  591. ];
  592. $results = $this->Paginator->paginate($table, $settings);
  593. $result = $results->toArray();
  594. $expected = array(
  595. 1 => 'First Post',
  596. 2 => 'Second Post',
  597. );
  598. $this->assertEquals($expected, $result);
  599. $result = $this->request->params['paging']['PaginatorPosts'];
  600. $this->assertEquals(2, $result['current']);
  601. $this->assertEquals(3, $result['count']);
  602. $this->assertEquals(2, $result['pageCount']);
  603. $this->assertTrue($result['nextPage']);
  604. $this->assertFalse($result['prevPage']);
  605. }
  606. /**
  607. * test paginate() and custom finders to ensure the count + find
  608. * use the custom type.
  609. *
  610. * @return void
  611. */
  612. public function testPaginateCustomFindCount() {
  613. $settings = array(
  614. 'findType' => 'published',
  615. 'limit' => 2
  616. );
  617. $table = $this->_getMockPosts(['find']);
  618. $query = $this->_getMockFindQuery();
  619. $table->expects($this->once())
  620. ->method('find')
  621. ->with('published', [
  622. 'conditions' => [],
  623. 'order' => [],
  624. 'limit' => 2,
  625. 'fields' => null,
  626. 'page' => 1,
  627. ])
  628. ->will($this->returnValue($query));
  629. $this->Paginator->paginate($table, $settings);
  630. }
  631. /**
  632. * Helper method for making mocks.
  633. *
  634. * @return Table
  635. */
  636. protected function _getMockPosts($methods = []) {
  637. return $this->getMock(
  638. 'TestApp\Model\Table\PaginatorPostsTable',
  639. $methods,
  640. [['connection' => ConnectionManager::get('test'), 'alias' => 'PaginatorPosts']]
  641. );
  642. }
  643. /**
  644. * Helper method for mocking queries.
  645. *
  646. * @return Query
  647. */
  648. protected function _getMockFindQuery() {
  649. $query = $this->getMockBuilder('Cake\ORM\Query')
  650. ->setMethods(['total', 'all', 'count'])
  651. ->disableOriginalConstructor()
  652. ->getMock();
  653. $results = $this->getMock('Cake\ORM\ResultSet', [], [], '', false);
  654. $query->expects($this->any())
  655. ->method('count')
  656. ->will($this->returnValue(2));
  657. $query->expects($this->any())
  658. ->method('all')
  659. ->will($this->returnValue($results));
  660. $query->expects($this->any())
  661. ->method('count')
  662. ->will($this->returnValue(2));
  663. return $query;
  664. }
  665. }