PaginatorComponentTest.php 41 KB

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