/lib/Cake/Test/Case/Controller/Component/PaginatorComponentTest.php

https://gitlab.com/fouzia23chowdhury/cakephpCRUD · PHP · 1421 lines · 923 code · 153 blank · 345 comment · 6 complexity · 52d49b6b913d86418b6c294f44e0c09f MD5 · raw file

  1. <?php
  2. /**
  3. * PaginatorComponentTest file
  4. *
  5. * Series of tests for paginator component.
  6. *
  7. * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
  8. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  9. *
  10. * Licensed under The MIT License
  11. * For full copyright and license information, please see the LICENSE.txt
  12. * Redistributions of files must retain the above copyright notice
  13. *
  14. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  15. * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
  16. * @package Cake.Test.Case.Controller.Component
  17. * @since CakePHP(tm) v 2.0
  18. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  19. */
  20. App::uses('Controller', 'Controller');
  21. App::uses('PaginatorComponent', 'Controller/Component');
  22. App::uses('CakeRequest', 'Network');
  23. App::uses('CakeResponse', 'Network');
  24. /**
  25. * PaginatorTestController class
  26. *
  27. * @package Cake.Test.Case.Controller.Component
  28. */
  29. class PaginatorTestController extends Controller {
  30. /**
  31. * components property
  32. *
  33. * @var array
  34. */
  35. public $components = array('Paginator');
  36. }
  37. /**
  38. * PaginatorControllerPost class
  39. *
  40. * @package Cake.Test.Case.Controller.Component
  41. */
  42. class PaginatorControllerPost extends CakeTestModel {
  43. /**
  44. * useTable property
  45. *
  46. * @var string
  47. */
  48. public $useTable = 'posts';
  49. /**
  50. * invalidFields property
  51. *
  52. * @var array
  53. */
  54. public $invalidFields = array('name' => 'error_msg');
  55. /**
  56. * lastQueries property
  57. *
  58. * @var array
  59. */
  60. public $lastQueries = array();
  61. /**
  62. * belongsTo property
  63. *
  64. * @var array
  65. */
  66. public $belongsTo = array('PaginatorAuthor' => array('foreignKey' => 'author_id'));
  67. /**
  68. * beforeFind method
  69. *
  70. * @param mixed $query
  71. * @return void
  72. */
  73. public function beforeFind($query) {
  74. array_unshift($this->lastQueries, $query);
  75. }
  76. /**
  77. * find method
  78. *
  79. * @param mixed $type
  80. * @param array $options
  81. * @return void
  82. */
  83. public function find($conditions = null, $fields = array(), $order = null, $recursive = null) {
  84. if ($conditions === 'popular') {
  85. $conditions = array($this->name . '.' . $this->primaryKey . ' > ' => '1');
  86. $options = Hash::merge($fields, compact('conditions'));
  87. return parent::find('all', $options);
  88. }
  89. return parent::find($conditions, $fields);
  90. }
  91. }
  92. /**
  93. * ControllerPaginateModel class
  94. *
  95. * @package Cake.Test.Case.Controller.Component
  96. */
  97. class ControllerPaginateModel extends CakeTestModel {
  98. /**
  99. * useTable property
  100. *
  101. * @var string
  102. */
  103. public $useTable = 'comments';
  104. /**
  105. * paginate method
  106. *
  107. * @return bool
  108. */
  109. public function paginate($conditions, $fields, $order, $limit, $page, $recursive, $extra) {
  110. $this->extra = $extra;
  111. return true;
  112. }
  113. /**
  114. * paginateCount
  115. *
  116. * @return void
  117. */
  118. public function paginateCount($conditions, $recursive, $extra) {
  119. $this->extraCount = $extra;
  120. }
  121. }
  122. /**
  123. * PaginatorControllerComment class
  124. *
  125. * @package Cake.Test.Case.Controller.Component
  126. */
  127. class PaginatorControllerComment extends CakeTestModel {
  128. /**
  129. * name property
  130. *
  131. * @var string
  132. */
  133. public $name = 'Comment';
  134. /**
  135. * useTable property
  136. *
  137. * @var string
  138. */
  139. public $useTable = 'comments';
  140. /**
  141. * alias property
  142. *
  143. * @var string
  144. */
  145. public $alias = 'PaginatorControllerComment';
  146. }
  147. /**
  148. * PaginatorAuthor class
  149. *
  150. * @package Cake.Test.Case.Controller.Component
  151. */
  152. class PaginatorAuthor extends CakeTestModel {
  153. /**
  154. * useTable property
  155. *
  156. * @var string
  157. */
  158. public $useTable = 'authors';
  159. /**
  160. * alias property
  161. *
  162. * @var string
  163. */
  164. public $virtualFields = array(
  165. 'joined_offset' => 'PaginatorAuthor.id + 1'
  166. );
  167. }
  168. /**
  169. * PaginatorCustomPost class
  170. *
  171. * @package Cake.Test.Case.Controller.Component
  172. */
  173. class PaginatorCustomPost extends CakeTestModel {
  174. /**
  175. * useTable property
  176. *
  177. * @var string
  178. */
  179. public $useTable = 'posts';
  180. /**
  181. * belongsTo property
  182. *
  183. * @var string
  184. */
  185. public $belongsTo = array('Author');
  186. /**
  187. * findMethods property
  188. *
  189. * @var array
  190. */
  191. public $findMethods = array(
  192. 'published' => true,
  193. 'totals' => true,
  194. 'totalsOperation' => true
  195. );
  196. /**
  197. * _findPublished custom find
  198. *
  199. * @return array
  200. */
  201. protected function _findPublished($state, $query, $results = array()) {
  202. if ($state === 'before') {
  203. $query['conditions']['published'] = 'Y';
  204. return $query;
  205. }
  206. return $results;
  207. }
  208. /**
  209. * _findTotals custom find
  210. *
  211. * @return array
  212. */
  213. protected function _findTotals($state, $query, $results = array()) {
  214. if ($state === 'before') {
  215. $query['fields'] = array('author_id');
  216. $this->virtualFields['total_posts'] = "COUNT({$this->alias}.id)";
  217. $query['fields'][] = 'total_posts';
  218. $query['group'] = array('author_id');
  219. $query['order'] = array('author_id' => 'ASC');
  220. return $query;
  221. }
  222. $this->virtualFields = array();
  223. return $results;
  224. }
  225. /**
  226. * _findTotalsOperation custom find
  227. *
  228. * @return array
  229. */
  230. protected function _findTotalsOperation($state, $query, $results = array()) {
  231. if ($state === 'before') {
  232. if (!empty($query['operation']) && $query['operation'] === 'count') {
  233. unset($query['limit']);
  234. $query['recursive'] = -1;
  235. $query['fields'] = array('COUNT(DISTINCT author_id) AS count');
  236. return $query;
  237. }
  238. $query['recursive'] = 0;
  239. $query['callbacks'] = 'before';
  240. $query['fields'] = array('author_id', 'Author.user');
  241. $this->virtualFields['total_posts'] = "COUNT({$this->alias}.id)";
  242. $query['fields'][] = 'total_posts';
  243. $query['group'] = array('author_id', 'Author.user');
  244. $query['order'] = array('author_id' => 'ASC');
  245. return $query;
  246. }
  247. $this->virtualFields = array();
  248. return $results;
  249. }
  250. }
  251. class PaginatorComponentTest extends CakeTestCase {
  252. /**
  253. * fixtures property
  254. *
  255. * @var array
  256. */
  257. public $fixtures = array('core.post', 'core.comment', 'core.author');
  258. /**
  259. * setup
  260. *
  261. * @return void
  262. */
  263. public function setUp() {
  264. parent::setUp();
  265. $this->request = new CakeRequest('controller_posts/index');
  266. $this->request->params['pass'] = $this->request->params['named'] = array();
  267. $this->Controller = new Controller($this->request);
  268. $this->Paginator = new PaginatorComponent($this->getMock('ComponentCollection'), array());
  269. $this->Paginator->Controller = $this->Controller;
  270. $this->Controller->Post = $this->getMock('Model');
  271. $this->Controller->Post->alias = 'Post';
  272. }
  273. /**
  274. * testPaginate method
  275. *
  276. * @return void
  277. */
  278. public function testPaginate() {
  279. $Controller = new PaginatorTestController($this->request);
  280. $Controller->uses = array('PaginatorControllerPost', 'PaginatorControllerComment');
  281. $Controller->request->params['pass'] = array('1');
  282. $Controller->request->query = array();
  283. $Controller->constructClasses();
  284. $Controller->PaginatorControllerPost->order = null;
  285. $Controller->Paginator->settings = array(
  286. 'order' => array('PaginatorControllerComment.id' => 'ASC')
  287. );
  288. $results = Hash::extract($Controller->Paginator->paginate('PaginatorControllerComment'), '{n}.PaginatorControllerComment.id');
  289. $this->assertEquals(array(1, 2, 3, 4, 5, 6), $results);
  290. $Controller->Paginator->settings = array(
  291. 'order' => array('PaginatorControllerPost.id' => 'ASC')
  292. );
  293. $results = Hash::extract($Controller->Paginator->paginate('PaginatorControllerPost'), '{n}.PaginatorControllerPost.id');
  294. $this->assertEquals(array(1, 2, 3), $results);
  295. $Controller->modelClass = null;
  296. $Controller->uses[0] = 'Plugin.PaginatorControllerPost';
  297. $results = Hash::extract($Controller->Paginator->paginate(), '{n}.PaginatorControllerPost.id');
  298. $this->assertEquals(array(1, 2, 3), $results);
  299. $Controller->request->params['named'] = array('page' => '-1');
  300. $results = Hash::extract($Controller->Paginator->paginate('PaginatorControllerPost'), '{n}.PaginatorControllerPost.id');
  301. $this->assertEquals(1, $Controller->params['paging']['PaginatorControllerPost']['page']);
  302. $this->assertEquals(array(1, 2, 3), $results);
  303. $Controller->request->params['named'] = array('sort' => 'PaginatorControllerPost.id', 'direction' => 'asc');
  304. $results = Hash::extract($Controller->Paginator->paginate('PaginatorControllerPost'), '{n}.PaginatorControllerPost.id');
  305. $this->assertEquals(1, $Controller->params['paging']['PaginatorControllerPost']['page']);
  306. $this->assertEquals(array(1, 2, 3), $results);
  307. $Controller->request->params['named'] = array('sort' => 'PaginatorControllerPost.id', 'direction' => 'desc');
  308. $results = Hash::extract($Controller->Paginator->paginate('PaginatorControllerPost'), '{n}.PaginatorControllerPost.id');
  309. $this->assertEquals(1, $Controller->params['paging']['PaginatorControllerPost']['page']);
  310. $this->assertEquals(array(3, 2, 1), $results);
  311. $Controller->request->params['named'] = array('sort' => 'id', 'direction' => 'desc');
  312. $results = Hash::extract($Controller->Paginator->paginate('PaginatorControllerPost'), '{n}.PaginatorControllerPost.id');
  313. $this->assertEquals(1, $Controller->params['paging']['PaginatorControllerPost']['page']);
  314. $this->assertEquals(array(3, 2, 1), $results);
  315. $Controller->request->params['named'] = array('sort' => 'NotExisting.field', 'direction' => 'desc', 'limit' => 2);
  316. $Controller->Paginator->paginate('PaginatorControllerPost');
  317. $this->assertEquals(1, $Controller->params['paging']['PaginatorControllerPost']['page']);
  318. $this->assertEquals(array(), $Controller->PaginatorControllerPost->lastQueries[1]['order'][0], 'no order should be set.');
  319. $Controller->request->params['named'] = array(
  320. 'sort' => 'PaginatorControllerPost.author_id', 'direction' => 'allYourBase'
  321. );
  322. $results = Hash::extract($Controller->Paginator->paginate('PaginatorControllerPost'), '{n}.PaginatorControllerPost.id');
  323. $this->assertEquals(array('PaginatorControllerPost.author_id' => 'asc'), $Controller->PaginatorControllerPost->lastQueries[0]['order'][0]);
  324. $this->assertEquals(array(1, 3, 2), $results);
  325. $Controller->request->params['named'] = array();
  326. $Controller->Paginator->settings = array('limit' => 0, 'maxLimit' => 10, 'paramType' => 'named');
  327. $Controller->Paginator->paginate('PaginatorControllerPost');
  328. $this->assertSame(1, $Controller->params['paging']['PaginatorControllerPost']['page']);
  329. $this->assertSame($Controller->params['paging']['PaginatorControllerPost']['pageCount'], 3);
  330. $this->assertFalse($Controller->params['paging']['PaginatorControllerPost']['prevPage']);
  331. $this->assertTrue($Controller->params['paging']['PaginatorControllerPost']['nextPage']);
  332. $Controller->request->params['named'] = array();
  333. $Controller->Paginator->settings = array('limit' => 'garbage!', 'maxLimit' => 10, 'paramType' => 'named');
  334. $Controller->Paginator->paginate('PaginatorControllerPost');
  335. $this->assertSame(1, $Controller->params['paging']['PaginatorControllerPost']['page']);
  336. $this->assertSame($Controller->params['paging']['PaginatorControllerPost']['pageCount'], 3);
  337. $this->assertFalse($Controller->params['paging']['PaginatorControllerPost']['prevPage']);
  338. $this->assertTrue($Controller->params['paging']['PaginatorControllerPost']['nextPage']);
  339. $Controller->request->params['named'] = array();
  340. $Controller->Paginator->settings = array('limit' => '-1', 'maxLimit' => 10, 'paramType' => 'named');
  341. $Controller->Paginator->paginate('PaginatorControllerPost');
  342. $this->assertSame($Controller->params['paging']['PaginatorControllerPost']['limit'], 1);
  343. $this->assertSame(1, $Controller->params['paging']['PaginatorControllerPost']['page']);
  344. $this->assertSame($Controller->params['paging']['PaginatorControllerPost']['pageCount'], 3);
  345. $this->assertFalse($Controller->params['paging']['PaginatorControllerPost']['prevPage']);
  346. $this->assertTrue($Controller->params['paging']['PaginatorControllerPost']['nextPage']);
  347. $Controller->Paginator->settings = array('conditions' => array('PaginatorAuthor.user' => 'mariano'));
  348. $Controller->Paginator->paginate('PaginatorControllerPost');
  349. $this->assertSame(2, $Controller->params['paging']['PaginatorControllerPost']['count']);
  350. }
  351. /**
  352. * Test that non-numeric values are rejected for page, and limit
  353. *
  354. * @return void
  355. */
  356. public function testPageParamCasting() {
  357. $this->Controller->Post->expects($this->at(0))
  358. ->method('hasMethod')
  359. ->with('paginate')
  360. ->will($this->returnValue(false));
  361. $this->Controller->Post->expects($this->at(1))
  362. ->method('find')
  363. ->will($this->returnValue(array('stuff')));
  364. $this->Controller->Post->expects($this->at(2))
  365. ->method('hasMethod')
  366. ->with('paginateCount')
  367. ->will($this->returnValue(false));
  368. $this->Controller->Post->expects($this->at(3))
  369. ->method('find')
  370. ->will($this->returnValue(2));
  371. $this->request->params['named'] = array('page' => '1 " onclick="alert(\'xss\');">');
  372. $this->Paginator->settings = array('limit' => 1, 'maxLimit' => 10, 'paramType' => 'named');
  373. $this->Paginator->paginate('Post');
  374. $this->assertSame(1, $this->request->params['paging']['Post']['page'], 'XSS exploit opened');
  375. }
  376. /**
  377. * testPaginateExtraParams method
  378. *
  379. * @return void
  380. */
  381. public function testPaginateExtraParams() {
  382. $Controller = new PaginatorTestController($this->request);
  383. $Controller->uses = array('PaginatorControllerPost', 'PaginatorControllerComment');
  384. $Controller->request->params['pass'] = array('1');
  385. $Controller->params['url'] = array();
  386. $Controller->constructClasses();
  387. $Controller->request->params['named'] = array('page' => '-1', 'contain' => array('PaginatorControllerComment'));
  388. $Controller->Paginator->settings = array(
  389. 'order' => array('PaginatorControllerPost.id' => 'ASC')
  390. );
  391. $result = $Controller->Paginator->paginate('PaginatorControllerPost');
  392. $this->assertEquals(1, $Controller->params['paging']['PaginatorControllerPost']['page']);
  393. $this->assertEquals(array(1, 2, 3), Hash::extract($result, '{n}.PaginatorControllerPost.id'));
  394. $this->assertTrue(!isset($Controller->PaginatorControllerPost->lastQueries[1]['contain']));
  395. $Controller->Paginator->settings = array(
  396. 'order' => array('PaginatorControllerPost.author_id')
  397. );
  398. $result = $Controller->Paginator->paginate('PaginatorControllerPost');
  399. $this->assertEquals(1, $Controller->params['paging']['PaginatorControllerPost']['page']);
  400. $this->assertEquals(array(1, 3, 2), Hash::extract($result, '{n}.PaginatorControllerPost.id'));
  401. $Controller->request->params['named'] = array('page' => '-1');
  402. $Controller->Paginator->settings = array(
  403. 'PaginatorControllerPost' => array(
  404. 'contain' => array('PaginatorControllerComment'),
  405. 'maxLimit' => 10,
  406. 'paramType' => 'named',
  407. 'order' => array('PaginatorControllerPost.id' => 'ASC')
  408. ),
  409. );
  410. $result = $Controller->Paginator->paginate('PaginatorControllerPost');
  411. $this->assertEquals(1, $Controller->params['paging']['PaginatorControllerPost']['page']);
  412. $this->assertEquals(array(1, 2, 3), Hash::extract($result, '{n}.PaginatorControllerPost.id'));
  413. $this->assertTrue(isset($Controller->PaginatorControllerPost->lastQueries[0]['contain']));
  414. $Controller->Paginator->settings = array(
  415. 'PaginatorControllerPost' => array(
  416. 'popular', 'fields' => array('id', 'title'), 'maxLimit' => 10, 'paramType' => 'named'
  417. ),
  418. );
  419. $result = $Controller->Paginator->paginate('PaginatorControllerPost');
  420. $this->assertEquals(array(2, 3), Hash::extract($result, '{n}.PaginatorControllerPost.id'));
  421. $this->assertEquals(array('PaginatorControllerPost.id > ' => '1'), $Controller->PaginatorControllerPost->lastQueries[0]['conditions']);
  422. $Controller->request->params['named'] = array('limit' => 12);
  423. $Controller->Paginator->settings = array('limit' => 30, 'maxLimit' => 100, 'paramType' => 'named');
  424. $result = $Controller->Paginator->paginate('PaginatorControllerPost');
  425. $paging = $Controller->params['paging']['PaginatorControllerPost'];
  426. $this->assertEquals(12, $Controller->PaginatorControllerPost->lastQueries[0]['limit']);
  427. $this->assertEquals(12, $paging['options']['limit']);
  428. $Controller = new PaginatorTestController($this->request);
  429. $Controller->uses = array('ControllerPaginateModel');
  430. $Controller->request->query = array();
  431. $Controller->constructClasses();
  432. $Controller->Paginator->settings = array(
  433. 'ControllerPaginateModel' => array(
  434. 'contain' => array('ControllerPaginateModel'),
  435. 'group' => 'Comment.author_id',
  436. 'maxLimit' => 10,
  437. 'paramType' => 'named'
  438. )
  439. );
  440. $result = $Controller->Paginator->paginate('ControllerPaginateModel');
  441. $expected = array(
  442. 'contain' => array('ControllerPaginateModel'),
  443. 'group' => 'Comment.author_id',
  444. 'maxLimit' => 10,
  445. 'paramType' => 'named'
  446. );
  447. $this->assertEquals($expected, $Controller->ControllerPaginateModel->extra);
  448. $this->assertEquals($expected, $Controller->ControllerPaginateModel->extraCount);
  449. $Controller->Paginator->settings = array(
  450. 'ControllerPaginateModel' => array(
  451. 'foo', 'contain' => array('ControllerPaginateModel'),
  452. 'group' => 'Comment.author_id',
  453. 'maxLimit' => 10,
  454. 'paramType' => 'named'
  455. )
  456. );
  457. $Controller->Paginator->paginate('ControllerPaginateModel');
  458. $expected = array(
  459. 'contain' => array('ControllerPaginateModel'),
  460. 'group' => 'Comment.author_id',
  461. 'type' => 'foo',
  462. 'maxLimit' => 10,
  463. 'paramType' => 'named'
  464. );
  465. $this->assertEquals($expected, $Controller->ControllerPaginateModel->extra);
  466. $this->assertEquals($expected, $Controller->ControllerPaginateModel->extraCount);
  467. }
  468. /**
  469. * Test that special paginate types are called and that the type param doesn't leak out into defaults or options.
  470. *
  471. * @return void
  472. */
  473. public function testPaginateSpecialType() {
  474. $Controller = new PaginatorTestController($this->request);
  475. $Controller->uses = array('PaginatorControllerPost', 'PaginatorControllerComment');
  476. $Controller->request->params['pass'][] = '1';
  477. $Controller->params['url'] = array();
  478. $Controller->constructClasses();
  479. $Controller->Paginator->settings = array(
  480. 'PaginatorControllerPost' => array(
  481. 'popular',
  482. 'fields' => array('id', 'title'),
  483. 'maxLimit' => 10,
  484. 'paramType' => 'named'
  485. )
  486. );
  487. $result = $Controller->Paginator->paginate('PaginatorControllerPost');
  488. $this->assertEquals(array(2, 3), Hash::extract($result, '{n}.PaginatorControllerPost.id'));
  489. $this->assertEquals(
  490. $Controller->PaginatorControllerPost->lastQueries[0]['conditions'],
  491. array('PaginatorControllerPost.id > ' => '1')
  492. );
  493. $this->assertFalse(isset($Controller->params['paging']['PaginatorControllerPost']['options'][0]));
  494. }
  495. /**
  496. * testDefaultPaginateParams method
  497. *
  498. * @return void
  499. */
  500. public function testDefaultPaginateParams() {
  501. $Controller = new PaginatorTestController($this->request);
  502. $Controller->modelClass = 'PaginatorControllerPost';
  503. $Controller->params['url'] = array();
  504. $Controller->constructClasses();
  505. $Controller->Paginator->settings = array(
  506. 'order' => 'PaginatorControllerPost.id DESC',
  507. 'maxLimit' => 10,
  508. 'paramType' => 'named'
  509. );
  510. $results = Hash::extract($Controller->Paginator->paginate('PaginatorControllerPost'), '{n}.PaginatorControllerPost.id');
  511. $this->assertEquals('PaginatorControllerPost.id DESC', $Controller->params['paging']['PaginatorControllerPost']['order']);
  512. $this->assertEquals(array(3, 2, 1), $results);
  513. }
  514. /**
  515. * test paginate() and model default order
  516. *
  517. * @return void
  518. */
  519. public function testPaginateOrderModelDefault() {
  520. $Controller = new PaginatorTestController($this->request);
  521. $Controller->uses = array('PaginatorControllerPost');
  522. $Controller->params['url'] = array();
  523. $Controller->constructClasses();
  524. $Controller->PaginatorControllerPost->order = array(
  525. $Controller->PaginatorControllerPost->alias . '.created' => 'desc'
  526. );
  527. $Controller->Paginator->settings = array(
  528. 'fields' => array('id', 'title', 'created'),
  529. 'maxLimit' => 10,
  530. 'paramType' => 'named'
  531. );
  532. $result = $Controller->Paginator->paginate('PaginatorControllerPost');
  533. $expected = array('2007-03-18 10:43:23', '2007-03-18 10:41:23', '2007-03-18 10:39:23');
  534. $this->assertEquals($expected, Hash::extract($result, '{n}.PaginatorControllerPost.created'));
  535. $this->assertEquals(
  536. $Controller->PaginatorControllerPost->order,
  537. $Controller->request->paging['PaginatorControllerPost']['options']['order']
  538. );
  539. $Controller->PaginatorControllerPost->order = array('PaginatorControllerPost.id');
  540. $result = $Controller->Paginator->validateSort($Controller->PaginatorControllerPost, array());
  541. $this->assertEquals(array('PaginatorControllerPost.id' => 'asc'), $result['order']);
  542. $Controller->PaginatorControllerPost->order = 'PaginatorControllerPost.id';
  543. $result = $Controller->Paginator->validateSort($Controller->PaginatorControllerPost, array());
  544. $this->assertArrayNotHasKey('order', $result);
  545. $Controller->PaginatorControllerPost->order = array(
  546. 'PaginatorControllerPost.id',
  547. 'PaginatorControllerPost.created' => 'asc'
  548. );
  549. $result = $Controller->Paginator->validateSort($Controller->PaginatorControllerPost, array());
  550. $expected = array(
  551. 'PaginatorControllerPost.id' => 'asc',
  552. 'PaginatorControllerPost.created' => 'asc'
  553. );
  554. $this->assertEquals($expected, $result['order']);
  555. }
  556. /**
  557. * test paginate() and virtualField interactions
  558. *
  559. * @return void
  560. */
  561. public function testPaginateOrderVirtualField() {
  562. $Controller = new PaginatorTestController($this->request);
  563. $Controller->uses = array('PaginatorControllerPost', 'PaginatorControllerComment');
  564. $Controller->params['url'] = array();
  565. $Controller->constructClasses();
  566. $Controller->PaginatorControllerPost->virtualFields = array(
  567. 'offset_test' => 'PaginatorControllerPost.id + 1'
  568. );
  569. $Controller->Paginator->settings = array(
  570. 'fields' => array('id', 'title', 'offset_test'),
  571. 'order' => array('offset_test' => 'DESC'),
  572. 'maxLimit' => 10,
  573. 'paramType' => 'named'
  574. );
  575. $result = $Controller->Paginator->paginate('PaginatorControllerPost');
  576. $this->assertEquals(array(4, 3, 2), Hash::extract($result, '{n}.PaginatorControllerPost.offset_test'));
  577. $Controller->request->params['named'] = array('sort' => 'offset_test', 'direction' => 'asc');
  578. $result = $Controller->Paginator->paginate('PaginatorControllerPost');
  579. $this->assertEquals(array(2, 3, 4), Hash::extract($result, '{n}.PaginatorControllerPost.offset_test'));
  580. }
  581. /**
  582. * test paginate() and virtualField on joined model
  583. *
  584. * @return void
  585. */
  586. public function testPaginateOrderVirtualFieldJoinedModel() {
  587. $Controller = new PaginatorTestController($this->request);
  588. $Controller->uses = array('PaginatorControllerPost');
  589. $Controller->params['url'] = array();
  590. $Controller->constructClasses();
  591. $Controller->PaginatorControllerPost->recursive = 0;
  592. $Controller->Paginator->settings = array(
  593. 'order' => array('PaginatorAuthor.joined_offset' => 'DESC'),
  594. 'maxLimit' => 10,
  595. 'paramType' => 'named'
  596. );
  597. $result = $Controller->Paginator->paginate('PaginatorControllerPost');
  598. $this->assertEquals(array(4, 2, 2), Hash::extract($result, '{n}.PaginatorAuthor.joined_offset'));
  599. $Controller->request->params['named'] = array('sort' => 'PaginatorAuthor.joined_offset', 'direction' => 'asc');
  600. $result = $Controller->Paginator->paginate('PaginatorControllerPost');
  601. $this->assertEquals(array(2, 2, 4), Hash::extract($result, '{n}.PaginatorAuthor.joined_offset'));
  602. }
  603. /**
  604. * Tests for missing models
  605. *
  606. * @expectedException MissingModelException
  607. * @return void
  608. */
  609. public function testPaginateMissingModel() {
  610. $Controller = new PaginatorTestController($this->request);
  611. $Controller->constructClasses();
  612. $Controller->Paginator->paginate('MissingModel');
  613. }
  614. /**
  615. * test that option merging prefers specific models
  616. *
  617. * @return void
  618. */
  619. public function testMergeOptionsModelSpecific() {
  620. $this->Paginator->settings = array(
  621. 'page' => 1,
  622. 'limit' => 20,
  623. 'maxLimit' => 100,
  624. 'paramType' => 'named',
  625. 'Post' => array(
  626. 'page' => 1,
  627. 'limit' => 10,
  628. 'maxLimit' => 50,
  629. 'paramType' => 'named',
  630. )
  631. );
  632. $result = $this->Paginator->mergeOptions('Silly');
  633. $this->assertEquals($this->Paginator->settings, $result);
  634. $result = $this->Paginator->mergeOptions('Post');
  635. $expected = array('page' => 1, 'limit' => 10, 'paramType' => 'named', 'maxLimit' => 50);
  636. $this->assertEquals($expected, $result);
  637. }
  638. /**
  639. * test mergeOptions with named params.
  640. *
  641. * @return void
  642. */
  643. public function testMergeOptionsNamedParams() {
  644. $this->request->params['named'] = array(
  645. 'page' => 10,
  646. 'limit' => 10
  647. );
  648. $this->Paginator->settings = array(
  649. 'page' => 1,
  650. 'limit' => 20,
  651. 'maxLimit' => 100,
  652. 'paramType' => 'named',
  653. );
  654. $result = $this->Paginator->mergeOptions('Post');
  655. $expected = array('page' => 10, 'limit' => 10, 'maxLimit' => 100, 'paramType' => 'named');
  656. $this->assertEquals($expected, $result);
  657. }
  658. /**
  659. * test mergeOptions with customFind key
  660. *
  661. * @return void
  662. */
  663. public function testMergeOptionsCustomFindKey() {
  664. $this->request->params['named'] = array(
  665. 'page' => 10,
  666. 'limit' => 10
  667. );
  668. $this->Paginator->settings = array(
  669. 'page' => 1,
  670. 'limit' => 20,
  671. 'maxLimit' => 100,
  672. 'paramType' => 'named',
  673. 'findType' => 'myCustomFind'
  674. );
  675. $result = $this->Paginator->mergeOptions('Post');
  676. $expected = array('page' => 10, 'limit' => 10, 'maxLimit' => 100, 'paramType' => 'named', 'findType' => 'myCustomFind');
  677. $this->assertEquals($expected, $result);
  678. }
  679. /**
  680. * test merging options from the querystring.
  681. *
  682. * @return void
  683. */
  684. public function testMergeOptionsQueryString() {
  685. $this->request->params['named'] = array(
  686. 'page' => 10,
  687. 'limit' => 10
  688. );
  689. $this->request->query = array(
  690. 'page' => 99,
  691. 'limit' => 75
  692. );
  693. $this->Paginator->settings = array(
  694. 'page' => 1,
  695. 'limit' => 20,
  696. 'maxLimit' => 100,
  697. 'paramType' => 'querystring',
  698. );
  699. $result = $this->Paginator->mergeOptions('Post');
  700. $expected = array('page' => 99, 'limit' => 75, 'maxLimit' => 100, 'paramType' => 'querystring');
  701. $this->assertEquals($expected, $result);
  702. }
  703. /**
  704. * test that the default whitelist doesn't let people screw with things they should not be allowed to.
  705. *
  706. * @return void
  707. */
  708. public function testMergeOptionsDefaultWhiteList() {
  709. $this->request->params['named'] = array(
  710. 'page' => 10,
  711. 'limit' => 10,
  712. 'fields' => array('bad.stuff'),
  713. 'recursive' => 1000,
  714. 'conditions' => array('bad.stuff'),
  715. 'contain' => array('bad')
  716. );
  717. $this->Paginator->settings = array(
  718. 'page' => 1,
  719. 'limit' => 20,
  720. 'maxLimit' => 100,
  721. 'paramType' => 'named',
  722. );
  723. $result = $this->Paginator->mergeOptions('Post');
  724. $expected = array('page' => 10, 'limit' => 10, 'maxLimit' => 100, 'paramType' => 'named');
  725. $this->assertEquals($expected, $result);
  726. }
  727. /**
  728. * test that modifying the whitelist works.
  729. *
  730. * @return void
  731. */
  732. public function testMergeOptionsExtraWhitelist() {
  733. $this->request->params['named'] = array(
  734. 'page' => 10,
  735. 'limit' => 10,
  736. 'fields' => array('bad.stuff'),
  737. 'recursive' => 1000,
  738. 'conditions' => array('bad.stuff'),
  739. 'contain' => array('bad')
  740. );
  741. $this->Paginator->settings = array(
  742. 'page' => 1,
  743. 'limit' => 20,
  744. 'maxLimit' => 100,
  745. 'paramType' => 'named',
  746. );
  747. $this->Paginator->whitelist[] = 'fields';
  748. $result = $this->Paginator->mergeOptions('Post');
  749. $expected = array(
  750. 'page' => 10, 'limit' => 10, 'maxLimit' => 100, 'paramType' => 'named', 'fields' => array('bad.stuff')
  751. );
  752. $this->assertEquals($expected, $result);
  753. }
  754. /**
  755. * test mergeOptions with limit > maxLimit in code.
  756. *
  757. * @return void
  758. */
  759. public function testMergeOptionsMaxLimit() {
  760. $this->Paginator->settings = array(
  761. 'limit' => 200,
  762. 'paramType' => 'named',
  763. );
  764. $result = $this->Paginator->mergeOptions('Post');
  765. $expected = array('page' => 1, 'limit' => 200, 'maxLimit' => 100, 'paramType' => 'named');
  766. $this->assertEquals($expected, $result);
  767. $this->Paginator->settings = array(
  768. 'maxLimit' => 10,
  769. 'paramType' => 'named',
  770. );
  771. $result = $this->Paginator->mergeOptions('Post');
  772. $expected = array('page' => 1, 'limit' => 20, 'maxLimit' => 10, 'paramType' => 'named');
  773. $this->assertEquals($expected, $result);
  774. $this->request->params['named'] = array(
  775. 'limit' => 500
  776. );
  777. $this->Paginator->settings = array(
  778. 'limit' => 150,
  779. 'paramType' => 'named',
  780. );
  781. $result = $this->Paginator->mergeOptions('Post');
  782. $expected = array('page' => 1, 'limit' => 500, 'maxLimit' => 100, 'paramType' => 'named');
  783. $this->assertEquals($expected, $result);
  784. }
  785. /**
  786. * test that invalid directions are ignored.
  787. *
  788. * @return void
  789. */
  790. public function testValidateSortInvalidDirection() {
  791. $model = $this->getMock('Model');
  792. $model->alias = 'model';
  793. $model->expects($this->any())->method('hasField')->will($this->returnValue(true));
  794. $options = array('sort' => 'something', 'direction' => 'boogers');
  795. $result = $this->Paginator->validateSort($model, $options);
  796. $this->assertEquals('asc', $result['order']['model.something']);
  797. }
  798. /**
  799. * Test that a really large page number gets clamped to the max page size.
  800. *
  801. * @expectedException NotFoundException
  802. * @return void
  803. */
  804. public function testOutOfRangePageNumberGetsClamped() {
  805. $Controller = new PaginatorTestController($this->request);
  806. $Controller->uses = array('PaginatorControllerPost');
  807. $Controller->params['named'] = array(
  808. 'page' => 3000,
  809. );
  810. $Controller->constructClasses();
  811. $Controller->PaginatorControllerPost->recursive = 0;
  812. $Controller->Paginator->paginate('PaginatorControllerPost');
  813. }
  814. /**
  815. * Test that a really REALLY large page number gets clamped to the max page size.
  816. *
  817. * @expectedException NotFoundException
  818. * @return void
  819. */
  820. public function testOutOfVeryBigPageNumberGetsClamped() {
  821. $Controller = new PaginatorTestController($this->request);
  822. $Controller->uses = array('PaginatorControllerPost');
  823. $Controller->params['named'] = array(
  824. 'page' => '3000000000000000000000000',
  825. );
  826. $Controller->constructClasses();
  827. $Controller->PaginatorControllerPost->recursive = 0;
  828. $Controller->Paginator->paginate('PaginatorControllerPost');
  829. }
  830. /**
  831. * testOutOfRangePageNumberAndPageCountZero
  832. *
  833. * @return void
  834. */
  835. public function testOutOfRangePageNumberAndPageCountZero() {
  836. $Controller = new PaginatorTestController($this->request);
  837. $Controller->uses = array('PaginatorControllerPost');
  838. $Controller->params['named'] = array(
  839. 'page' => '3000',
  840. );
  841. $Controller->constructClasses();
  842. $Controller->PaginatorControllerPost->recursive = 0;
  843. $Controller->paginate = array(
  844. 'conditions' => array('PaginatorControllerPost.id >' => 100)
  845. );
  846. try {
  847. $Controller->Paginator->paginate('PaginatorControllerPost');
  848. $this->fail();
  849. } catch (NotFoundException $e) {
  850. $this->assertEquals(
  851. 1,
  852. $Controller->request->params['paging']['PaginatorControllerPost']['page'],
  853. 'Page number should not be 0'
  854. );
  855. }
  856. }
  857. /**
  858. * test that fields not in whitelist won't be part of order conditions.
  859. *
  860. * @return void
  861. */
  862. public function testValidateSortWhitelistFailure() {
  863. $model = $this->getMock('Model');
  864. $model->alias = 'model';
  865. $model->expects($this->any())->method('hasField')->will($this->returnValue(true));
  866. $options = array('sort' => 'body', 'direction' => 'asc');
  867. $result = $this->Paginator->validateSort($model, $options, array('title', 'id'));
  868. $this->assertNull($result['order']);
  869. }
  870. /**
  871. * test that fields in the whitelist are not validated
  872. *
  873. * @return void
  874. */
  875. public function testValidateSortWhitelistTrusted() {
  876. $model = $this->getMock('Model');
  877. $model->alias = 'model';
  878. $model->expects($this->never())->method('hasField');
  879. $options = array('sort' => 'body', 'direction' => 'asc');
  880. $result = $this->Paginator->validateSort($model, $options, array('body'));
  881. $expected = array('body' => 'asc');
  882. $this->assertEquals($expected, $result['order']);
  883. }
  884. /**
  885. * test that virtual fields work.
  886. *
  887. * @return void
  888. */
  889. public function testValidateSortVirtualField() {
  890. $model = $this->getMock('Model');
  891. $model->alias = 'model';
  892. $model->expects($this->at(0))
  893. ->method('hasField')
  894. ->with('something')
  895. ->will($this->returnValue(false));
  896. $model->expects($this->at(1))
  897. ->method('hasField')
  898. ->with('something', true)
  899. ->will($this->returnValue(true));
  900. $options = array('sort' => 'something', 'direction' => 'desc');
  901. $result = $this->Paginator->validateSort($model, $options);
  902. $this->assertEquals('desc', $result['order']['something']);
  903. }
  904. /**
  905. * test that sorting fields is alias specific
  906. *
  907. * @return void
  908. */
  909. public function testValidateSortSharedFields() {
  910. $model = $this->getMock('Model');
  911. $model->alias = 'Parent';
  912. $model->Child = $this->getMock('Model');
  913. $model->Child->alias = 'Child';
  914. $model->expects($this->never())
  915. ->method('hasField');
  916. $model->Child->expects($this->at(0))
  917. ->method('hasField')
  918. ->with('something')
  919. ->will($this->returnValue(true));
  920. $options = array('sort' => 'Child.something', 'direction' => 'desc');
  921. $result = $this->Paginator->validateSort($model, $options);
  922. $this->assertEquals('desc', $result['order']['Child.something']);
  923. }
  924. /**
  925. * test that multiple sort works.
  926. *
  927. * @return void
  928. */
  929. public function testValidateSortMultiple() {
  930. $model = $this->getMock('Model');
  931. $model->alias = 'model';
  932. $model->expects($this->any())->method('hasField')->will($this->returnValue(true));
  933. $options = array(
  934. 'order' => array(
  935. 'author_id' => 'asc',
  936. 'title' => 'asc'
  937. )
  938. );
  939. $result = $this->Paginator->validateSort($model, $options);
  940. $expected = array(
  941. 'model.author_id' => 'asc',
  942. 'model.title' => 'asc'
  943. );
  944. $this->assertEquals($expected, $result['order']);
  945. }
  946. /**
  947. * Test that no sort doesn't trigger an error.
  948. *
  949. * @return void
  950. */
  951. public function testValidateSortNoSort() {
  952. $model = $this->getMock('Model');
  953. $model->alias = 'model';
  954. $model->expects($this->any())->method('hasField')->will($this->returnValue(true));
  955. $options = array('direction' => 'asc');
  956. $result = $this->Paginator->validateSort($model, $options, array('title', 'id'));
  957. $this->assertFalse(isset($result['order']));
  958. $options = array('order' => 'invalid desc');
  959. $result = $this->Paginator->validateSort($model, $options, array('title', 'id'));
  960. $this->assertEquals($options['order'], $result['order']);
  961. }
  962. /**
  963. * Test sorting with incorrect aliases on valid fields.
  964. *
  965. * @return void
  966. */
  967. public function testValidateSortInvalidAlias() {
  968. $model = $this->getMock('Model');
  969. $model->alias = 'Model';
  970. $model->expects($this->any())->method('hasField')->will($this->returnValue(true));
  971. $options = array('sort' => 'Derp.id');
  972. $result = $this->Paginator->validateSort($model, $options);
  973. $this->assertEquals(array(), $result['order']);
  974. }
  975. /**
  976. * test that maxLimit is respected
  977. *
  978. * @return void
  979. */
  980. public function testCheckLimit() {
  981. $result = $this->Paginator->checkLimit(array('limit' => 1000000, 'maxLimit' => 100));
  982. $this->assertEquals(100, $result['limit']);
  983. $result = $this->Paginator->checkLimit(array('limit' => 'sheep!', 'maxLimit' => 100));
  984. $this->assertEquals(1, $result['limit']);
  985. $result = $this->Paginator->checkLimit(array('limit' => '-1', 'maxLimit' => 100));
  986. $this->assertEquals(1, $result['limit']);
  987. $result = $this->Paginator->checkLimit(array('limit' => null, 'maxLimit' => 100));
  988. $this->assertEquals(1, $result['limit']);
  989. $result = $this->Paginator->checkLimit(array('limit' => 0, 'maxLimit' => 100));
  990. $this->assertEquals(1, $result['limit']);
  991. }
  992. /**
  993. * testPaginateMaxLimit
  994. *
  995. * @return void
  996. */
  997. public function testPaginateMaxLimit() {
  998. $Controller = new Controller($this->request);
  999. $Controller->uses = array('PaginatorControllerPost', 'ControllerComment');
  1000. $Controller->request->params['pass'][] = '1';
  1001. $Controller->constructClasses();
  1002. $Controller->request->params['named'] = array(
  1003. 'contain' => array('ControllerComment'), 'limit' => '1000'
  1004. );
  1005. $Controller->paginate('PaginatorControllerPost');
  1006. $this->assertEquals(100, $Controller->params['paging']['PaginatorControllerPost']['options']['limit']);
  1007. $Controller->request->params['named'] = array(
  1008. 'contain' => array('ControllerComment'), 'limit' => '1000', 'maxLimit' => 1000
  1009. );
  1010. $Controller->paginate('PaginatorControllerPost');
  1011. $this->assertEquals(100, $Controller->params['paging']['PaginatorControllerPost']['options']['limit']);
  1012. $Controller->request->params['named'] = array('contain' => array('ControllerComment'), 'limit' => '10');
  1013. $Controller->paginate('PaginatorControllerPost');
  1014. $this->assertEquals(10, $Controller->params['paging']['PaginatorControllerPost']['options']['limit']);
  1015. $Controller->request->params['named'] = array('contain' => array('ControllerComment'), 'limit' => '1000');
  1016. $Controller->paginate = array('maxLimit' => 2000, 'paramType' => 'named');
  1017. $Controller->paginate('PaginatorControllerPost');
  1018. $this->assertEquals(1000, $Controller->params['paging']['PaginatorControllerPost']['options']['limit']);
  1019. $Controller->request->params['named'] = array('contain' => array('ControllerComment'), 'limit' => '5000');
  1020. $Controller->paginate('PaginatorControllerPost');
  1021. $this->assertEquals(2000, $Controller->params['paging']['PaginatorControllerPost']['options']['limit']);
  1022. }
  1023. /**
  1024. * test paginate() and virtualField overlapping with real fields.
  1025. *
  1026. * @return void
  1027. */
  1028. public function testPaginateOrderVirtualFieldSharedWithRealField() {
  1029. $Controller = new Controller($this->request);
  1030. $Controller->uses = array('PaginatorControllerPost', 'PaginatorControllerComment');
  1031. $Controller->constructClasses();
  1032. $Controller->PaginatorControllerComment->virtualFields = array(
  1033. 'title' => 'PaginatorControllerComment.comment'
  1034. );
  1035. $Controller->PaginatorControllerComment->bindModel(array(
  1036. 'belongsTo' => array(
  1037. 'PaginatorControllerPost' => array(
  1038. 'className' => 'PaginatorControllerPost',
  1039. 'foreignKey' => 'article_id'
  1040. )
  1041. )
  1042. ), false);
  1043. $Controller->paginate = array(
  1044. 'fields' => array(
  1045. 'PaginatorControllerComment.id',
  1046. 'title',
  1047. 'PaginatorControllerPost.title'
  1048. ),
  1049. );
  1050. $Controller->request->params['named'] = array(
  1051. 'sort' => 'PaginatorControllerPost.title',
  1052. 'direction' => 'desc'
  1053. );
  1054. $result = Hash::extract(
  1055. $Controller->paginate('PaginatorControllerComment'),
  1056. '{n}.PaginatorControllerComment.id'
  1057. );
  1058. $result1 = array_splice($result, 0, 2);
  1059. sort($result1);
  1060. $this->assertEquals(array(5, 6), $result1);
  1061. sort($result);
  1062. $this->assertEquals(array(1, 2, 3, 4), $result);
  1063. }
  1064. /**
  1065. * test paginate() and custom find, to make sure the correct count is returned.
  1066. *
  1067. * @return void
  1068. */
  1069. public function testPaginateCustomFind() {
  1070. $Controller = new Controller($this->request);
  1071. $Controller->uses = array('PaginatorCustomPost');
  1072. $Controller->constructClasses();
  1073. $data = array('author_id' => 3, 'title' => 'Fourth Article', 'body' => 'Article Body, unpublished', 'published' => 'N');
  1074. $Controller->PaginatorCustomPost->create($data);
  1075. $result = $Controller->PaginatorCustomPost->save();
  1076. $this->assertTrue(!empty($result));
  1077. $result = $Controller->paginate();
  1078. $this->assertEquals(array(1, 2, 3, 4), Hash::extract($result, '{n}.PaginatorCustomPost.id'));
  1079. $result = $Controller->params['paging']['PaginatorCustomPost'];
  1080. $this->assertEquals(4, $result['current']);
  1081. $this->assertEquals(4, $result['count']);
  1082. $Controller->paginate = array('published');
  1083. $result = $Controller->paginate();
  1084. $this->assertEquals(array(1, 2, 3), Hash::extract($result, '{n}.PaginatorCustomPost.id'));
  1085. $result = $Controller->params['paging']['PaginatorCustomPost'];
  1086. $this->assertEquals(3, $result['current']);
  1087. $this->assertEquals(3, $result['count']);
  1088. $Controller->paginate = array('published', 'limit' => 2);
  1089. $result = $Controller->paginate();
  1090. $this->assertEquals(array(1, 2), Hash::extract($result, '{n}.PaginatorCustomPost.id'));
  1091. $result = $Controller->params['paging']['PaginatorCustomPost'];
  1092. $this->assertEquals(2, $result['current']);
  1093. $this->assertEquals(3, $result['count']);
  1094. $this->assertEquals(2, $result['pageCount']);
  1095. $this->assertTrue($result['nextPage']);
  1096. $this->assertFalse($result['prevPage']);
  1097. }
  1098. /**
  1099. * test paginate() and custom find with fields array, to make sure the correct count is returned.
  1100. *
  1101. * @return void
  1102. */
  1103. public function testPaginateCustomFindFieldsArray() {
  1104. $Controller = new Controller($this->request);
  1105. $Controller->uses = array('PaginatorCustomPost');
  1106. $Controller->constructClasses();
  1107. $data = array('author_id' => 3, 'title' => 'Fourth Article', 'body' => 'Article Body, unpublished', 'published' => 'N');
  1108. $Controller->PaginatorCustomPost->create($data);
  1109. $result = $Controller->PaginatorCustomPost->save();
  1110. $this->assertTrue(!empty($result));
  1111. $Controller->paginate = array(
  1112. 'list',
  1113. 'conditions' => array('PaginatorCustomPost.published' => 'Y'),
  1114. 'limit' => 2
  1115. );
  1116. $result = $Controller->paginate();
  1117. $expected = array(
  1118. 1 => 'First Post',
  1119. 2 => 'Second Post',
  1120. );
  1121. $this->assertEquals($expected, $result);
  1122. $result = $Controller->params['paging']['PaginatorCustomPost'];
  1123. $this->assertEquals(2, $result['current']);
  1124. $this->assertEquals(3, $result['count']);
  1125. $this->assertEquals(2, $result['pageCount']);
  1126. $this->assertTrue($result['nextPage']);
  1127. $this->assertFalse($result['prevPage']);
  1128. }
  1129. /**
  1130. * test paginate() and custom find with customFind key, to make sure the correct count is returned.
  1131. *
  1132. * @return void
  1133. */
  1134. public function testPaginateCustomFindWithCustomFindKey() {
  1135. $Controller = new Controller($this->request);
  1136. $Controller->uses = array('PaginatorCustomPost');
  1137. $Controller->constructClasses();
  1138. $data = array('author_id' => 3, 'title' => 'Fourth Article', 'body' => 'Article Body, unpublished', 'published' => 'N');
  1139. $Controller->PaginatorCustomPost->create($data);
  1140. $result = $Controller->PaginatorCustomPost->save();
  1141. $this->assertTrue(!empty($result));
  1142. $Controller->paginate = array(
  1143. 'conditions' => array('PaginatorCustomPost.published' => 'Y'),
  1144. 'findType' => 'list',
  1145. 'limit' => 2
  1146. );
  1147. $result = $Controller->paginate();
  1148. $expected = array(
  1149. 1 => 'First Post',
  1150. 2 => 'Second Post',
  1151. );
  1152. $this->assertEquals($expected, $result);
  1153. $result = $Controller->params['paging']['PaginatorCustomPost'];
  1154. $this->assertEquals(2, $result['current']);
  1155. $this->assertEquals(3, $result['count']);
  1156. $this->assertEquals(2, $result['pageCount']);
  1157. $this->assertTrue($result['nextPage']);
  1158. $this->assertFalse($result['prevPage']);
  1159. }
  1160. /**
  1161. * test paginate() and custom find with fields array, to make sure the correct count is returned.
  1162. *
  1163. * @return void
  1164. */
  1165. public function testPaginateCustomFindGroupBy() {
  1166. $Controller = new Controller($this->request);
  1167. $Controller->uses = array('PaginatorCustomPost');
  1168. $Controller->constructClasses();
  1169. $data = array('author_id' => 2, 'title' => 'Fourth Article', 'body' => 'Article Body, unpublished', 'published' => 'N');
  1170. $Controller->PaginatorCustomPost->create($data);
  1171. $result = $Controller->PaginatorCustomPost->save();
  1172. $this->assertTrue(!empty($result));
  1173. $Controller->paginate = array(
  1174. 'totals',
  1175. 'limit' => 2
  1176. );
  1177. $result = $Controller->paginate();
  1178. $expected = array(
  1179. array(
  1180. 'PaginatorCustomPost' => array(
  1181. 'author_id' => '1',
  1182. 'total_posts' => '2'
  1183. )
  1184. ),
  1185. array(
  1186. 'PaginatorCustomPost' => array(
  1187. 'author_id' => '2',
  1188. 'total_posts' => '1'
  1189. )
  1190. )
  1191. );
  1192. $this->assertEquals($expected, $result);
  1193. $result = $Controller->params['paging']['PaginatorCustomPost'];
  1194. $this->assertEquals(2, $result['current']);
  1195. $this->assertEquals(3, $result['count']);
  1196. $this->assertEquals(2, $result['pageCount']);
  1197. $this->assertTrue($result['nextPage']);
  1198. $this->assertFalse($result['prevPage']);
  1199. $Controller->paginate = array(
  1200. 'totals',
  1201. 'limit' => 2,
  1202. 'page' => 2
  1203. );
  1204. $result = $Controller->paginate();
  1205. $expected = array(
  1206. array(
  1207. 'PaginatorCustomPost' => array(
  1208. 'author_id' => '3',
  1209. 'total_posts' => '1'
  1210. )
  1211. ),
  1212. );
  1213. $this->assertEquals($expected, $result);
  1214. $result = $Controller->params['paging']['PaginatorCustomPost'];
  1215. $this->assertEquals(1, $result['current']);
  1216. $this->assertEquals(3, $result['count']);
  1217. $this->assertEquals(2, $result['pageCount']);
  1218. $this->assertFalse($result['nextPage']);
  1219. $this->assertTrue($result['prevPage']);
  1220. }
  1221. /**
  1222. * test paginate() and custom find with returning other query on count operation,
  1223. * to make sure the correct count is returned.
  1224. *
  1225. * @return void
  1226. */
  1227. public function testPaginateCustomFindCount() {
  1228. $Controller = new Controller($this->request);
  1229. $Controller->uses = array('PaginatorCustomPost');
  1230. $Controller->constructClasses();
  1231. $data = array('author_id' => 2, 'title' => 'Fourth Article', 'body' => 'Article Body, unpublished', 'published' => 'N');
  1232. $Controller->PaginatorCustomPost->create($data);
  1233. $result = $Controller->PaginatorCustomPost->save();
  1234. $this->assertTrue(!empty($result));
  1235. $Controller->paginate = array(
  1236. 'totalsOperation',
  1237. 'limit' => 2
  1238. );
  1239. $result = $Controller->paginate();
  1240. $expected = array(
  1241. array(
  1242. 'PaginatorCustomPost' => array(
  1243. 'author_id' => '1',
  1244. 'total_posts' => '2'
  1245. ),
  1246. 'Author' => array(
  1247. 'user' => 'mariano',
  1248. )
  1249. ),
  1250. array(
  1251. 'PaginatorCustomPost' => array(
  1252. 'author_id' => '2',
  1253. 'total_posts' => '1'
  1254. ),
  1255. 'Author' => array(
  1256. 'user' => 'nate'
  1257. )
  1258. )
  1259. );
  1260. $this->assertEquals($expected, $result);
  1261. $result = $Controller->params['paging']['PaginatorCustomPost'];
  1262. $this->assertEquals(2, $result['current']);
  1263. $this->assertEquals(3, $result['count']);
  1264. $this->assertEquals(2, $result['pageCount']);
  1265. $this->assertTrue($result['nextPage']);
  1266. $this->assertFalse($result['prevPage']);
  1267. }
  1268. }