PageRenderTime 53ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/test/testsuite/generator/behavior/sluggable/SluggableBehaviorTest.php

http://github.com/propelorm/Propel
PHP | 465 lines | 382 code | 63 blank | 20 comment | 2 complexity | 44e65e35130d1440fb95aaa640d3712b MD5 | raw file
  1. <?php
  2. /**
  3. * This file is part of the Propel package.
  4. * For the full copyright and license information, please view the LICENSE
  5. * file that was distributed with this source code.
  6. *
  7. * @license MIT License
  8. */
  9. require_once dirname(__FILE__) . '/../../../../tools/helpers/bookstore/BookstoreTestBase.php';
  10. /**
  11. * Tests for SluggableBehavior class
  12. *
  13. * @author François Zaninotto
  14. * @version $Revision$
  15. * @package generator.behavior.sluggable
  16. */
  17. class SluggableBehaviorTest extends BookstoreTestBase
  18. {
  19. public function testParameters()
  20. {
  21. $table13 = Table13Peer::getTableMap();
  22. $this->assertEquals(count($table13->getColumns()), 3, 'Sluggable adds one columns by default');
  23. $this->assertTrue(method_exists('Table13', 'getSlug'), 'Sluggable adds a slug column by default');
  24. $table14 = Table14Peer::getTableMap();
  25. $this->assertEquals(count($table14->getColumns()), 3, 'Sluggable does not add a column when it already exists');
  26. $this->assertTrue(method_exists('Table14', 'getUrl'), 'Sluggable allows customization of slug_column name');
  27. $this->assertTrue(method_exists('Table14', 'getSlug'), 'Sluggable adds a standard getter for the slug column');
  28. }
  29. public function testObjectGetter()
  30. {
  31. $this->assertTrue(method_exists('Table13', 'getSlug'), 'Sluggable adds a getter for the slug column');
  32. $t = new Table13();
  33. $t->setSlug('foo');
  34. $this->assertEquals('foo', $t->getSlug(), 'getSlug() returns the object slug');
  35. $this->assertTrue(method_exists('Table14', 'getSlug'), 'Sluggable adds a getter for the slug column, even if the column does not have the default name');
  36. $t = new Table14();
  37. $t->setUrl('foo');
  38. $this->assertEquals('foo', $t->getSlug(), 'getSlug() returns the object slug');
  39. }
  40. public function testObjectSetter()
  41. {
  42. $this->assertTrue(method_exists('Table13', 'setSlug'), 'Sluggable adds a setter for the slug column');
  43. $t = new Table13();
  44. $t->setSlug('foo');
  45. $this->assertEquals('foo', $t->getSlug(), 'setSlug() sets the object slug');
  46. $this->assertTrue(method_exists('Table14', 'setSlug'), 'Sluggable adds a setter for the slug column, even if the column does not have the default name');
  47. $t = new Table14();
  48. $t->setSlug('foo');
  49. $this->assertEquals('foo', $t->getUrl(), 'setSlug() sets the object slug');
  50. }
  51. public function testObjectCreateRawSlug()
  52. {
  53. $t = new TestableTable13();
  54. $this->assertEquals('n-a', $t->createRawSlug(), 'createRawSlug() returns an empty string for an empty object with no pattern');
  55. $t->setTitle('Hello, World');
  56. $this->assertEquals('hello-world', $t->createRawSlug(), 'createRawSlug() returns the cleaned up object string representation by default');
  57. $t = new TestableTable14();
  58. $this->assertEquals('/foo/n-a/bar', $t->createRawSlug(), 'createRawSlug() returns a slug for an empty object with a pattern');
  59. $t->setTitle('Hello, World');
  60. $this->assertEquals('/foo/hello-world/bar', $t->createRawSlug(), 'createRawSlug() returns a slug based on a pattern');
  61. }
  62. public static function cleanupSlugProvider()
  63. {
  64. return array(
  65. array('', 'n-a'),
  66. array('foo', 'foo'),
  67. array('foo bar', 'foo-bar'),
  68. array('foo bar', 'foo-bar'),
  69. array('FoO', 'foo'),
  70. array('fôo', 'foo'),
  71. array(' foo ', 'foo'),
  72. array('f/o:o', 'f-o-o'),
  73. array('foo1', 'foo1'),
  74. );
  75. }
  76. /**
  77. * @dataProvider cleanupSlugProvider
  78. */
  79. public function testObjectCleanupSlugPart($in, $out)
  80. {
  81. $t = new TestableTable13();
  82. $this->assertEquals($out, $t->cleanupSlugPart($in), 'cleanupSlugPart() cleans up the slug part');
  83. }
  84. public static function limitSlugSizeProvider()
  85. {
  86. return array(
  87. array('123', '123'),
  88. array(str_repeat('*', 80), str_repeat('*', 80)),
  89. array(str_repeat('*', 97), str_repeat('*', 97)),
  90. array(str_repeat('*', 98), str_repeat('*', 97)),
  91. array(str_repeat('*', 99), str_repeat('*', 97)),
  92. array(str_repeat('*', 100), str_repeat('*', 97)),
  93. array(str_repeat('*', 150), str_repeat('*', 97)),
  94. );
  95. }
  96. /**
  97. * @dataProvider limitSlugSizeProvider
  98. */
  99. public function testObjectLimitSlugSize($in, $out)
  100. {
  101. $t = new TestableTable14();
  102. $this->assertEquals($out, $t->limitSlugSize($in), 'limitSlugsize() limits the slug size');
  103. }
  104. public function testObjectMakeSlugUnique()
  105. {
  106. Table13Query::create()->deleteAll();
  107. $t = new TestableTable13();
  108. $this->assertEquals('', $t->makeSlugUnique(''), 'makeSlugUnique() returns the input slug when the input is empty');
  109. $this->assertEquals('foo', $t->makeSlugUnique('foo'), 'makeSlugUnique() returns the input slug when the table is empty');
  110. $t->setSlug('foo');
  111. $t->save();
  112. $t = new TestableTable13();
  113. $this->assertEquals('bar', $t->makeSlugUnique('bar'), 'makeSlugUnique() returns the input slug when the table does not contain a similar slug');
  114. $t->save();
  115. $t = new TestableTable13();
  116. $this->assertEquals('foo-1', $t->makeSlugUnique('foo'), 'makeSlugUnique() returns an incremented input when it already exists');
  117. $t->setSlug('foo-1');
  118. $t->save();
  119. $t = new TestableTable13();
  120. $this->assertEquals('foo-2', $t->makeSlugUnique('foo'), 'makeSlugUnique() returns an incremented input when it already exists');
  121. TableWithScopeQuery::create()->deleteAll();
  122. $t = new TestTableWithScope();
  123. $this->assertEquals('foo', $t->makeSlugUnique('foo'), 'makeSlugUnique() returns the input slug when the table is empty');
  124. $t->setSlug('foo');
  125. $t->setScope(1);
  126. $t->save();
  127. $t = new TestTableWithScope();
  128. $t->setScope(1);
  129. $this->assertEquals('foo-1', $t->makeSlugUnique('foo'), 'makeSlugUnique() returns an incremented input when it already exists');
  130. $t->setSlug('foo-1');
  131. $t->save();
  132. $t = new TestTableWithScope();
  133. $t->setScope(1);
  134. $this->assertEquals('foo-2', $t->makeSlugUnique('foo'), 'makeSlugUnique() returns an incremented input when it already exists');
  135. }
  136. public function testObjectCreateSlug()
  137. {
  138. Table13Query::create()->deleteAll();
  139. $t = new TestableTable13();
  140. $this->assertEquals('n-a', $t->createSlug(), 'createSlug() returns n-a for an empty object');
  141. $t->setTitle('Hello, World!');
  142. $this->assertEquals('hello-world', $t->createSlug(), 'createSlug() returns a cleaned up slug');
  143. $t->setSlug('hello-world');
  144. $t->save();
  145. $t = new TestableTable13();
  146. $t->setTitle('Hello; wOrld');
  147. $this->assertEquals('hello-world-1', $t->createSlug(), 'createSlug() returns a unique slug');
  148. Table14Query::create()->deleteAll();
  149. $t = new TestableTable14();
  150. $this->assertEquals('/foo/n-a/bar', $t->createSlug(), 'createSlug() returns a slug for an empty object with a pattern');
  151. $t->setTitle('Hello, World!');
  152. $this->assertEquals('/foo/hello-world/bar', $t->createSlug(), 'createSlug() returns a cleaned up slug');
  153. $t->setSlug('/foo/hello-world/bar');
  154. $t->save();
  155. $t = new TestableTable14();
  156. $t->setTitle('Hello; wOrld:');
  157. $this->assertEquals('/foo/hello-world/bar/1', $t->createSlug(), 'createSlug() returns a unique slug');
  158. }
  159. public function testObjectPreSave()
  160. {
  161. Table14Query::create()->deleteAll();
  162. $t = new Table14();
  163. $t->save();
  164. $this->assertEquals('/foo/n-a/bar', $t->getSlug(), 'preSave() sets a default slug for empty objects');
  165. $t = new Table14();
  166. $t->setTitle('Hello, World');
  167. $t->save();
  168. $this->assertEquals('/foo/hello-world/bar', $t->getSlug(), 'preSave() sets a cleaned up slug for objects');
  169. $t = new Table14();
  170. $t->setTitle('Hello, World');
  171. $t->save();
  172. $this->assertEquals('/foo/hello-world/bar/1', $t->getSlug(), 'preSave() sets a unique slug for objects');
  173. $t = new Table14();
  174. $t->setTitle('Hello, World');
  175. $t->setSlug('/foo/custom/bar');
  176. $t->save();
  177. $this->assertEquals('/foo/custom/bar', $t->getSlug(), 'preSave() uses the given slug if it exists');
  178. $t = new Table14();
  179. $t->setTitle('Hello, World');
  180. $t->setSlug('/foo/custom/bar');
  181. $t->save();
  182. $this->assertEquals('/foo/custom/bar/1', $t->getSlug(), 'preSave() uses the given slug if it exists and makes it unique');
  183. }
  184. public function testObjectSlugLifecycle()
  185. {
  186. Table13Query::create()->deleteAll();
  187. $t = new Table13();
  188. $t->setTitle('Hello, World');
  189. $t->save();
  190. $this->assertEquals('hello-world', $t->getSlug(), 'preSave() creates a slug for new objects');
  191. $t->setSlug('hello-bar');
  192. $t->save();
  193. $this->assertEquals('hello-bar', $t->getSlug(), 'setSlug() allows to override default slug');
  194. $t->setSlug('');
  195. $t->save();
  196. $this->assertEquals('hello-world', $t->getSlug(), 'setSlug(null) relaunches the slug generation');
  197. Table14Query::create()->deleteAll();
  198. $t = new Table14();
  199. $t->setTitle('Hello, World2');
  200. $t->setSlug('hello-bar2');
  201. $t->save();
  202. $this->assertEquals('hello-bar2', $t->getSlug(), 'setSlug() allows to override default slug, even before save');
  203. $t->setSlug('');
  204. $t->save();
  205. $this->assertEquals('/foo/hello-world2/bar', $t->getSlug(), 'setSlug(null) relaunches the slug generation');
  206. }
  207. public function testObjectSlugAutoUpdate()
  208. {
  209. Table13Query::create()->deleteAll();
  210. $t = new Table13();
  211. $t->setTitle('Hello, World');
  212. $t->save();
  213. $this->assertEquals('hello-world', $t->getSlug(), 'preSave() creates a slug for new objects');
  214. $t->setTitle('Hello, My World');
  215. $t->save();
  216. $this->assertEquals('hello-my-world', $t->getSlug(), 'preSave() autoupdates slug on object change');
  217. $t->setTitle('Hello, My Whole New World');
  218. $t->setSlug('hello-bar');
  219. $t->save();
  220. $this->assertEquals('hello-bar', $t->getSlug(), 'preSave() does not autoupdate slug when it was set by the user');
  221. }
  222. public function testObjectSlugAutoUpdatePermanent()
  223. {
  224. Table14Query::create()->deleteAll();
  225. $t = new Table14();
  226. $t->setTitle('Hello, World');
  227. $t->save();
  228. $this->assertEquals('/foo/hello-world/bar', $t->getSlug(), 'preSave() creates a slug for new objects');
  229. $t->setTitle('Hello, My World');
  230. $t->save();
  231. $this->assertEquals('/foo/hello-world/bar', $t->getSlug(), 'preSave() does not autoupdate slug on object change for permanent slugs');
  232. $t->setSlug('hello-bar');
  233. $t->save();
  234. $this->assertEquals('hello-bar', $t->getSlug(), 'setSlug() still works for permanent slugs');
  235. }
  236. public function testQueryFindOneBySlug()
  237. {
  238. $this->assertFalse(method_exists('Table13Query', 'findOneBySlug'), 'The generated query does not provide a findOneBySlug() method if the slug column is "slug".');
  239. $this->assertTrue(method_exists('Table14Query', 'findOneBySlug'), 'The generated query provides a findOneBySlug() method if the slug column is not "slug".');
  240. Table14Query::create()->deleteAll();
  241. $t1 = new Table14();
  242. $t1->setTitle('Hello, World');
  243. $t1->save();
  244. $t2 = new Table14();
  245. $t2->setTitle('Hello, Cruel World');
  246. $t2->save();
  247. $t = Table14Query::create()->findOneBySlug('/foo/hello-world/bar');
  248. $this->assertEquals($t1, $t, 'findOneBySlug() returns a single object matching the slug');
  249. }
  250. public function testUniqueViolationWithoutScope()
  251. {
  252. TableWithScopeQuery::create()->deleteAll();
  253. $t = new TableWithScope();
  254. $t->setTitle('Hello, World');
  255. $t->save();
  256. $this->assertEquals('hello-world', $t->getSlug());
  257. try {
  258. $t = new TableWithScope();
  259. $t->setTitle('Hello, World');
  260. $t->save();
  261. $this->fail('Exception expected');
  262. } catch (Exception $e) {
  263. $this->assertTrue(true, 'Exception successfully thrown');
  264. }
  265. }
  266. public function testNoUniqueViolationWithScope()
  267. {
  268. TableWithScopeQuery::create()->deleteAll();
  269. $t = new TableWithScope();
  270. $t->setTitle('Hello, World');
  271. $t->save();
  272. $this->assertEquals('hello-world', $t->getSlug());
  273. try {
  274. $t = new TableWithScope();
  275. $t->setTitle('Hello, World');
  276. $t->setScope(1);
  277. $t->save();
  278. $this->assertEquals('hello-world', $t->getSlug());
  279. } catch (Exception $e) {
  280. $this->fail($e->getMessage());
  281. }
  282. }
  283. public function testPatternNonPermanent()
  284. {
  285. Table14PatternQuery::create()->deleteAll();
  286. $t = new Table14Pattern();
  287. $t->setTitle('Hello, World');
  288. $t->setTags('test,tag,php');
  289. $t->save();
  290. $this->assertEquals('/foo/hello-world/bar/test-tag-php', $t->getUrl());
  291. $t->setTags('php,propel');
  292. $t->save();
  293. $this->assertEquals('/foo/hello-world/bar/php-propel', $t->getUrl());
  294. $t->setTitle('Title2');
  295. $t->save();
  296. $this->assertEquals('/foo/title2/bar/php-propel', $t->getUrl());
  297. }
  298. public function testNumberOfQueriesForMakeUniqSlug()
  299. {
  300. Table13Query::create()->deleteAll();
  301. $con = Propel::getConnection(Table13Peer::DATABASE_NAME);
  302. for ($i=0; $i < 5; $i++) {
  303. $nbQuery = $con->getQueryCount();
  304. $t = new Table13();
  305. $t->setTitle('Hello, World');
  306. $t->save($con);
  307. $this->assertLessThanOrEqual(4, $con->getQueryCount() - $nbQuery, 'no more than 4 query to get a slug when it already exist');
  308. }
  309. }
  310. public function testSlugRegexp()
  311. {
  312. Table13Query::create()->deleteAll();
  313. $con = Propel::getConnection(Table13Peer::DATABASE_NAME);
  314. for ($i=0; $i < 3; $i++) {
  315. $t = new Table13();
  316. $t->setTitle('Hello, World');
  317. $t->save($con);
  318. }
  319. $this->assertEquals('hello-world-2', $t->getSlug());
  320. $t = new Table13();
  321. $t->setTitle('World');
  322. $t->save($con);
  323. $this->assertEquals('world', $t->getSlug());
  324. $t = new Table13();
  325. $t->setTitle('World');
  326. $t->save($con);
  327. $this->assertEquals('world-1', $t->getSlug());
  328. $t = new Table13();
  329. $t->setTitle('Hello, World');
  330. $t->save($con);
  331. $this->assertEquals('hello-world-3', $t->getSlug());
  332. $t = new Table13();
  333. $t->setTitle('World');
  334. $t->save($con);
  335. $this->assertEquals('world-2', $t->getSlug());
  336. $t = new Table13();
  337. $t->setTitle('World 000');
  338. $t->save($con);
  339. $this->assertEquals('world-000', $t->getSlug());
  340. $t = new Table13();
  341. $t->setTitle('World');
  342. $t->save($con);
  343. $this->assertEquals('world-101', $t->getSlug());
  344. $t = new Table13();
  345. $t->setTitle('World');
  346. $t->save($con);
  347. $this->assertEquals('world-102', $t->getSlug());
  348. }
  349. }
  350. class TestableTable13 extends Table13
  351. {
  352. public function createSlug()
  353. {
  354. return parent::createSlug();
  355. }
  356. public function createRawSlug()
  357. {
  358. return parent::createRawSlug();
  359. }
  360. public static function cleanupSlugPart($slug, $separator = '-')
  361. {
  362. return parent::cleanupSlugPart($slug, $separator);
  363. }
  364. public function makeSlugUnique($slug, $separator = '-', $increment = 0)
  365. {
  366. return parent::makeSlugUnique($slug, $separator, $increment);
  367. }
  368. }
  369. class TestableTable14 extends Table14
  370. {
  371. public function createSlug()
  372. {
  373. return parent::createSlug();
  374. }
  375. public function createRawSlug()
  376. {
  377. return parent::createRawSlug();
  378. }
  379. public static function limitSlugSize($slug, $incrementReservedSpace = 3)
  380. {
  381. return parent::limitSlugSize($slug, $incrementReservedSpace);
  382. }
  383. }
  384. class TestTableWithScope extends TableWithScope
  385. {
  386. public function createSlug()
  387. {
  388. return parent::createSlug();
  389. }
  390. public function createRawSlug()
  391. {
  392. return parent::createRawSlug();
  393. }
  394. public static function cleanupSlugPart($slug, $separator = '-')
  395. {
  396. return parent::cleanupSlugPart($slug, $separator);
  397. }
  398. public function makeSlugUnique($slug, $separator = '-', $increment = 0)
  399. {
  400. return parent::makeSlugUnique($slug, $separator, $increment);
  401. }
  402. }