context.test 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. <?php
  2. /**
  3. * @file
  4. * Test the keyword substitution functionality.
  5. */
  6. class CtoolsContextIDTestCase extends DrupalWebTestCase {
  7. /**
  8. * {@inheritdoc}
  9. */
  10. public static function getInfo() {
  11. return array(
  12. 'name' => 'Context IDs',
  13. 'description' => 'Verify that Context IDs work properly.',
  14. 'group' => 'ctools',
  15. 'dependencies' => array('ctools'),
  16. );
  17. }
  18. /**
  19. * {@inheritdoc}
  20. */
  21. protected function setUp(array $modules = array()) {
  22. $modules[] = 'ctools';
  23. parent::setUp($modules);
  24. ctools_include('context');
  25. }
  26. private function getTestContexts() {
  27. $test_objects = array(
  28. array(),
  29. array(
  30. 'name' => 'foo_bar',
  31. ),
  32. array(
  33. 'id' => 25,
  34. ),
  35. array(
  36. 'id' => 5,
  37. 'name' => NULL,
  38. ),
  39. array(
  40. 'id' => 'a',
  41. 'name' => 'foo_bar',
  42. ),
  43. array(
  44. 'id' => 'z',
  45. 'name' => 'baz',
  46. ),
  47. array(
  48. 'id' => 15,
  49. 'name' => 'baz',
  50. ),
  51. array(
  52. 'id' => 'z',
  53. 'name' => 'foo',
  54. ),
  55. array(
  56. 'id' => 1,
  57. 'name' => 'foo',
  58. ),
  59. array(
  60. 'id' => 47,
  61. 'name' => 'bar',
  62. ),
  63. array(
  64. 'id' => 99,
  65. 'name' => 'bar',
  66. ),
  67. );
  68. return $test_objects;
  69. }
  70. /**
  71. * Test ctools_context_id where the context only has an id.
  72. */
  73. public function testContextId() {
  74. $context = array();
  75. $expected = 'context__1';
  76. $actual = ctools_context_id($context);
  77. $this->assertEqual($actual, $expected, 'Empty context has id ' . $expected);
  78. $context = array('id' => 4);
  79. $expected = 'context__4';
  80. $actual = ctools_context_id($context);
  81. $this->assertEqual($actual, $expected, 'Context 4 has id ' . $expected);
  82. $context = array('id' => 'a');
  83. $expected = 'context__a';
  84. $actual = ctools_context_id($context);
  85. $this->assertEqual($actual, $expected, 'Context "a" has id ' . $expected);
  86. }
  87. /**
  88. * Test ctools_context_id where the context has an id and a name.
  89. */
  90. public function testContextIdName() {
  91. $context = array('id' => '512', 'name' => 'foo');
  92. $expected = 'context_foo_512';
  93. $this->assertEqual(ctools_context_id($context), $expected, 'Context "512"/"foo" has id ' . $expected);
  94. $context = array('id' => '512', 'name' => 'foo_bar');
  95. $expected = 'context_foo_bar_512';
  96. $this->assertEqual(ctools_context_id($context), $expected, 'Context "512"/"foo_bar" has id ' . $expected);
  97. }
  98. /**
  99. * Test ctools_context_id where the context has an id & name, and a type is specified.
  100. */
  101. public function testContextIdNameType() {
  102. $type = 'sort';
  103. $context = array('id' => '512', 'name' => 'foo');
  104. $expected = 'sort_foo_512';
  105. $this->assertEqual(ctools_context_id($context, $type), $expected, 'Context "512" has id ' . $expected);
  106. $type = NULL;
  107. $context = array('id' => '512', 'name' => 'foo');
  108. $expected = '_foo_512';
  109. $this->assertEqual(ctools_context_id($context, $type), $expected, 'Context "512" has id ' . $expected);
  110. }
  111. /**
  112. * Test ctools_context_next_id in various scenarios.
  113. */
  114. public function testNextContextId() {
  115. $test_objects = $this->getTestContexts();
  116. // If no object list or name is given?
  117. $value = ctools_context_next_id(NULL, NULL);
  118. $expected = 1;
  119. $this->assertEqual($value, $expected, 'NULL objects have next id ' . $expected);
  120. // If no object list is given?
  121. $value = ctools_context_next_id(NULL, 'bar');
  122. $expected = 1;
  123. $this->assertEqual($value, $expected, 'NULL objects have next id ' . $expected);
  124. // If no object list is given (another way)?
  125. $value = ctools_context_next_id(array(), 'bar');
  126. $expected = 1;
  127. $this->assertEqual($value, $expected, 'Empty objects have next id ' . $expected);
  128. // The name is empty... which is just another name.
  129. $value = ctools_context_next_id($test_objects, '');
  130. $expected = 1;
  131. $this->assertEqual($value, $expected, 'Unnamed objects have next id ' . $expected . ' (got ' . $value . ')');
  132. // The value of the id key is not a number.
  133. $value = ctools_context_next_id($test_objects, 'foo_bar');
  134. $expected = 1;
  135. $this->assertEqual($value, $expected, 'Objects with non-integer ids are ignored ' . $expected);
  136. // One object's id is not a number (ignore) but another is valid.
  137. $value = ctools_context_next_id($test_objects, 'baz');
  138. $expected = 16;
  139. $this->assertEqual($value, $expected, 'Baz\'s objects have next id ' . $expected);
  140. // An expected case: there is one match and the id is numeric.
  141. $value = ctools_context_next_id($test_objects, 'foo');
  142. $expected = 2;
  143. $this->assertEqual($value, $expected, 'Foo\'s objects have next id ' . $expected);
  144. // Another expected case: there are multiple numeric IDs.
  145. $value = ctools_context_next_id($test_objects, 'bar');
  146. $expected = 100;
  147. $this->assertEqual($value, $expected, 'Bar\'s objects have next id ' . $expected);
  148. }
  149. }
  150. /**
  151. * Test the keyword substitution functionality.
  152. */
  153. class CtoolsContextKeywordsSubstitutionTestCase extends DrupalWebTestCase {
  154. /**
  155. * {@inheritdoc}
  156. */
  157. public static function getInfo() {
  158. return array(
  159. 'name' => 'Keywords substitution',
  160. 'description' => 'Verify that keywords are properly replaced with data.',
  161. 'group' => 'ctools',
  162. 'dependencies' => array('ctools'),
  163. );
  164. }
  165. /**
  166. * {@inheritdoc}
  167. */
  168. protected function setUp(array $modules = array()) {
  169. $modules[] = 'ctools';
  170. parent::setUp($modules);
  171. ctools_include('context');
  172. }
  173. /**
  174. * Test the keyword substitution.
  175. */
  176. public function testKeywordsSubstitution() {
  177. // Create node context for substitution.
  178. $node = $this->drupalCreateNode();
  179. $context = ctools_context_create('node', $node);
  180. $contexts = array('argument_1' => $context);
  181. // Run tests on some edge cases.
  182. $checks = array(
  183. array(
  184. '%node:changed:raw:',
  185. array('%title' => ''),
  186. "{$node->changed}:",
  187. t('Multi-level token has been replaced. Colon left untouched.'),
  188. ),
  189. array(
  190. '%node:title',
  191. array('%title' => ''),
  192. "{$node->title}",
  193. t('Keyword and converter have been replaced.'),
  194. ),
  195. array(
  196. '%%node:title',
  197. array('%title' => ''),
  198. "%node:title",
  199. t('Keyword after escaped percent sign left untouched.'),
  200. ),
  201. array(
  202. '%node:title%node:nid',
  203. array('%title' => ''),
  204. "{$node->title}{$node->nid}",
  205. t('Multiple substitutions have been replaced.'),
  206. ),
  207. array(
  208. '%node:title:',
  209. array('%title' => ''),
  210. "{$node->title}:",
  211. t('Colon after keyword and converter left untouched.'),
  212. ),
  213. array(
  214. '%node:title%%',
  215. array('%title' => ''),
  216. "{$node->title}%",
  217. t('Escaped percent sign after keyword and converter left untouched.'),
  218. ),
  219. array(
  220. '%%%node:title',
  221. array('%title' => ''),
  222. "%{$node->title}",
  223. t('Keyword after escaped and unescaped percent sign has been replaced.'),
  224. ),
  225. array(
  226. '%%foo:bar',
  227. array('%title' => ''),
  228. "%foo:bar",
  229. t('Non-existant context ignored.'),
  230. ),
  231. array(
  232. 'There was about 20%-30% difference in price.',
  233. array('%title' => ''),
  234. 'There was about 20%-30% difference in price.',
  235. t('Non-keyword percent sign left untouched.'),
  236. ),
  237. array(
  238. 'href="my%20file%2dname.pdf"',
  239. array('%title' => ''),
  240. 'href="my%20file%2dname.pdf"',
  241. t('HTTP URL escape left untouched.'),
  242. ),
  243. array(
  244. 'href="my%a0file%fdname.pdf"',
  245. array('%title' => ''),
  246. 'href="my%a0file%fdname.pdf"',
  247. t('HTTP URL escape (high-chars) left untouched.'),
  248. ),
  249. array(
  250. '<a href="http://www.example.com/here%20is%20a%20pdf.pdf">Click here!</a>',
  251. array('%title' => ''),
  252. '<a href="http://www.example.com/here%20is%20a%20pdf.pdf">Click here!</a>',
  253. t('HTTP URL escape percent sign left untouched in HTML.'),
  254. ),
  255. array(
  256. 'SELECT * FROM {table} WHERE field = "%s"',
  257. array('%title' => ''),
  258. 'SELECT * FROM {table} WHERE field = "%s"',
  259. t('SQL percent sign left untouched.'),
  260. ),
  261. array(
  262. '%title',
  263. array('%title' => 'foobar'),
  264. 'foobar',
  265. t('String value in $keywords array is returned.'),
  266. ),
  267. array(
  268. '%title',
  269. array('%title' => ''),
  270. '',
  271. t('Empty string value in $keywords array returns empty string.'),
  272. ),
  273. array(
  274. '%title',
  275. array('%title' => NULL),
  276. '',
  277. t('NULL value in $keywords array returns empty string.'),
  278. ),
  279. array(
  280. '%title',
  281. array('%title' => FALSE),
  282. '',
  283. t('FALSE value in $keywords array returns empty string.'),
  284. ),
  285. array(
  286. '%title',
  287. array('%title' => 11),
  288. '11',
  289. t('Integer value in $keywords array returns string representation of the integer.'),
  290. ),
  291. array(
  292. '%title',
  293. array('%title' => 'substring %title'),
  294. 'substring %title',
  295. t('Input value as substring in $keywords array left untouched.'),
  296. ),
  297. );
  298. foreach ($checks as $check) {
  299. list($string, $keywords, $expected_result, $message) = $check;
  300. $actual_result = ctools_context_keyword_substitute($string, $keywords, $contexts);
  301. $this->assertEqual($actual_result, $expected_result, $message);
  302. }
  303. }
  304. }
  305. /**
  306. * Test the context classes.
  307. */
  308. class CtoolsContextUnitTestCase extends DrupalUnitTestCase {
  309. /**
  310. * {@inheritdoc}
  311. */
  312. public static function getInfo() {
  313. return array(
  314. 'name' => 'Context unit tests',
  315. 'description' => 'Verifies that context classes behave correctly',
  316. 'group' => 'ctools',
  317. 'dependencies' => array('ctools'),
  318. );
  319. }
  320. /**
  321. * {@inheritdoc}
  322. */
  323. protected function setUp() {
  324. parent::setUp();
  325. require_once __DIR__ . '/../includes/context.inc';
  326. }
  327. /**
  328. * Tests that contexts have the correct required property value.
  329. */
  330. public function testOptionalRequiredContext() {
  331. $required_context = new ctools_context_required('test1');
  332. $this->assertTrue($required_context->required);
  333. $optional_context = new ctools_context_optional('test2');
  334. $this->assertFalse($optional_context->required);
  335. }
  336. }