PageRenderTime 87ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 1ms

/lib/simpletest/testnavigationlib.php

http://github.com/moodle/moodle
PHP | 502 lines | 389 code | 56 blank | 57 comment | 13 complexity | b844ffb1b06e3aade51babe607ed89b2 MD5 | raw file
Possible License(s): MIT, AGPL-3.0, MPL-2.0-no-copyleft-exception, LGPL-3.0, GPL-3.0, Apache-2.0, LGPL-2.1, BSD-3-Clause
  1. <?php
  2. // This file is part of Moodle - http://moodle.org/
  3. //
  4. // Moodle is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // Moodle is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
  16. /**
  17. * Unit tests for lib/navigationlib.php
  18. *
  19. * @package moodlecore
  20. * @copyright 2009 Sam Hemelryk
  21. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later (5)
  22. */
  23. if (!defined('MOODLE_INTERNAL')) {
  24. die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page
  25. }
  26. require_once($CFG->libdir . '/navigationlib.php');
  27. class navigation_node_test extends UnitTestCase {
  28. protected $tree;
  29. public static $includecoverage = array('./lib/navigationlib.php');
  30. public static $excludecoverage = array();
  31. protected $fakeproperties = array(
  32. 'text' => 'text',
  33. 'shorttext' => 'A very silly extra long short text string, more than 25 characters',
  34. 'key' => 'key',
  35. 'type' => 'navigation_node::TYPE_COURSE',
  36. 'action' => 'http://www.moodle.org/');
  37. protected $activeurl = null;
  38. protected $inactivenode = null;
  39. /**
  40. * @var navigation_node
  41. */
  42. public $node;
  43. public function setUp() {
  44. global $CFG, $PAGE;
  45. parent::setUp();
  46. $this->activeurl = $PAGE->url;
  47. navigation_node::override_active_url($this->activeurl);
  48. $this->inactiveurl = new moodle_url('http://www.moodle.com/');
  49. $this->fakeproperties['action'] = $this->inactiveurl;
  50. $this->node = new navigation_node('Test Node');
  51. $this->node->type = navigation_node::TYPE_SYSTEM;
  52. $demo1 = $this->node->add('demo1', $this->inactiveurl, navigation_node::TYPE_COURSE, null, 'demo1', new pix_icon('i/course', ''));
  53. $demo2 = $this->node->add('demo2', $this->inactiveurl, navigation_node::TYPE_COURSE, null, 'demo2', new pix_icon('i/course', ''));
  54. $demo3 = $this->node->add('demo3', $this->inactiveurl, navigation_node::TYPE_CATEGORY, null, 'demo3',new pix_icon('i/course', ''));
  55. $demo4 = $demo3->add('demo4', $this->inactiveurl,navigation_node::TYPE_COURSE, null, 'demo4', new pix_icon('i/course', ''));
  56. $demo5 = $demo3->add('demo5', $this->activeurl, navigation_node::TYPE_COURSE, null, 'demo5',new pix_icon('i/course', ''));
  57. $demo5->add('activity1', null, navigation_node::TYPE_ACTIVITY, null, 'activity1')->make_active();
  58. $hiddendemo1 = $this->node->add('hiddendemo1', $this->inactiveurl, navigation_node::TYPE_CATEGORY, null, 'hiddendemo1', new pix_icon('i/course', ''));
  59. $hiddendemo1->hidden = true;
  60. $hiddendemo1->add('hiddendemo2', $this->inactiveurl, navigation_node::TYPE_COURSE, null, 'hiddendemo2', new pix_icon('i/course', ''))->helpbutton = 'Here is a help button';;
  61. $hiddendemo1->add('hiddendemo3', $this->inactiveurl, navigation_node::TYPE_COURSE,null, 'hiddendemo3', new pix_icon('i/course', ''))->display = false;
  62. }
  63. public function test___construct() {
  64. global $CFG;
  65. $node = new navigation_node($this->fakeproperties);
  66. $this->assertEqual($node->text, $this->fakeproperties['text']);
  67. $this->assertEqual($node->title, $this->fakeproperties['text']);
  68. $this->assertTrue(strpos($this->fakeproperties['shorttext'], substr($node->shorttext,0, -3))===0);
  69. $this->assertEqual($node->key, $this->fakeproperties['key']);
  70. $this->assertEqual($node->type, $this->fakeproperties['type']);
  71. $this->assertEqual($node->action, $this->fakeproperties['action']);
  72. }
  73. public function test_add() {
  74. global $CFG;
  75. // Add a node with all args set
  76. $node1 = $this->node->add('test_add_1','http://www.moodle.org/',navigation_node::TYPE_COURSE,'testadd1','key',new pix_icon('i/course', ''));
  77. // Add a node with the minimum args required
  78. $node2 = $this->node->add('test_add_2',null, navigation_node::TYPE_CUSTOM,'testadd2');
  79. $node3 = $this->node->add(str_repeat('moodle ', 15),str_repeat('moodle', 15));
  80. $this->assertIsA($node1, 'navigation_node');
  81. $this->assertIsA($node2, 'navigation_node');
  82. $this->assertIsA($node3, 'navigation_node');
  83. $this->assertReference($node1, $this->node->get('key'));
  84. $this->assertReference($node2, $this->node->get($node2->key));
  85. $this->assertReference($node2, $this->node->get($node2->key, $node2->type));
  86. $this->assertReference($node3, $this->node->get($node3->key, $node3->type));
  87. }
  88. public function test_add_before() {
  89. global $CFG;
  90. // Create 3 nodes
  91. $node1 = navigation_node::create('test_add_1', null, navigation_node::TYPE_CUSTOM,
  92. 'test 1', 'testadd1');
  93. $node2 = navigation_node::create('test_add_2', null, navigation_node::TYPE_CUSTOM,
  94. 'test 2', 'testadd2');
  95. $node3 = navigation_node::create('test_add_3', null, navigation_node::TYPE_CUSTOM,
  96. 'test 3', 'testadd3');
  97. // Add node 2, then node 1 before 2, then node 3 at end
  98. $this->node->add_node($node2);
  99. $this->node->add_node($node1, 'testadd2');
  100. $this->node->add_node($node3);
  101. // Check the last 3 nodes are in 1, 2, 3 order and have those indexes
  102. foreach($this->node->children as $child) {
  103. $keys[] = $child->key;
  104. }
  105. $this->assertEqual('testadd1', $keys[count($keys)-3]);
  106. $this->assertEqual('testadd2', $keys[count($keys)-2]);
  107. $this->assertEqual('testadd3', $keys[count($keys)-1]);
  108. }
  109. public function test_add_class() {
  110. $node = $this->node->get('demo1');
  111. $this->assertIsA($node, 'navigation_node');
  112. if ($node !== false) {
  113. $node->add_class('myclass');
  114. $classes = $node->classes;
  115. $this->assertTrue(in_array('myclass', $classes));
  116. }
  117. }
  118. public function test_check_if_active() {
  119. // First test the string urls
  120. // demo1 -> action is http://www.moodle.org/, thus should be true
  121. $demo5 = $this->node->find('demo5', navigation_node::TYPE_COURSE);
  122. if ($this->assertIsA($demo5, 'navigation_node')) {
  123. $this->assertTrue($demo5->check_if_active());
  124. }
  125. // demo2 -> action is http://www.moodle.com/, thus should be false
  126. $demo2 = $this->node->get('demo2');
  127. if ($this->assertIsA($demo2, 'navigation_node')) {
  128. $this->assertFalse($demo2->check_if_active());
  129. }
  130. }
  131. public function test_contains_active_node() {
  132. // demo5, and activity1 were set to active during setup
  133. // Should be true as it contains all nodes
  134. $this->assertTrue($this->node->contains_active_node());
  135. // Should be true as demo5 is a child of demo3
  136. $this->assertTrue($this->node->get('demo3')->contains_active_node());
  137. // Obviously duff
  138. $this->assertFalse($this->node->get('demo1')->contains_active_node());
  139. // Should be true as demo5 contains activity1
  140. $this->assertTrue($this->node->get('demo3')->get('demo5')->contains_active_node());
  141. // Should be true activity1 is the active node
  142. $this->assertTrue($this->node->get('demo3')->get('demo5')->get('activity1')->contains_active_node());
  143. // Obviously duff
  144. $this->assertFalse($this->node->get('demo3')->get('demo4')->contains_active_node());
  145. }
  146. public function test_find_active_node() {
  147. $activenode1 = $this->node->find_active_node();
  148. $activenode2 = $this->node->get('demo1')->find_active_node();
  149. if ($this->assertIsA($activenode1, 'navigation_node')) {
  150. $this->assertReference($activenode1, $this->node->get('demo3')->get('demo5')->get('activity1'));
  151. }
  152. $this->assertNotA($activenode2, 'navigation_node');
  153. }
  154. public function test_find() {
  155. $node1 = $this->node->find('demo1', navigation_node::TYPE_COURSE);
  156. $node2 = $this->node->find('demo5', navigation_node::TYPE_COURSE);
  157. $node3 = $this->node->find('demo5', navigation_node::TYPE_CATEGORY);
  158. $node4 = $this->node->find('demo0', navigation_node::TYPE_COURSE);
  159. $this->assertIsA($node1, 'navigation_node');
  160. $this->assertIsA($node2, 'navigation_node');
  161. $this->assertNotA($node3, 'navigation_node');
  162. $this->assertNotA($node4, 'navigation_node');
  163. }
  164. public function test_find_expandable() {
  165. $expandable = array();
  166. $this->node->find_expandable($expandable);
  167. $this->assertEqual(count($expandable), 4);
  168. if (count($expandable) === 4) {
  169. $name = $expandable[0]['key'];
  170. $name .= $expandable[1]['key'];
  171. $name .= $expandable[2]['key'];
  172. $name .= $expandable[3]['key'];
  173. $this->assertEqual($name, 'demo1demo2demo4hiddendemo2');
  174. }
  175. }
  176. public function test_get() {
  177. $node1 = $this->node->get('demo1'); // Exists
  178. $node2 = $this->node->get('demo4'); // Doesn't exist for this node
  179. $node3 = $this->node->get('demo0'); // Doesn't exist at all
  180. $node4 = $this->node->get(false); // Sometimes occurs in nature code
  181. $this->assertIsA($node1, 'navigation_node');
  182. $this->assertFalse($node2);
  183. $this->assertFalse($node3);
  184. $this->assertFalse($node4);
  185. }
  186. public function test_get_css_type() {
  187. $csstype1 = $this->node->get('demo3')->get_css_type();
  188. $csstype2 = $this->node->get('demo3')->get('demo5')->get_css_type();
  189. $this->node->get('demo3')->get('demo5')->type = 1000;
  190. $csstype3 = $this->node->get('demo3')->get('demo5')->get_css_type();
  191. $this->assertEqual($csstype1, 'type_category');
  192. $this->assertEqual($csstype2, 'type_course');
  193. $this->assertEqual($csstype3, 'type_unknown');
  194. }
  195. public function test_make_active() {
  196. global $CFG;
  197. $node1 = $this->node->add('active node 1', null, navigation_node::TYPE_CUSTOM, null, 'anode1');
  198. $node2 = $this->node->add('active node 2', new moodle_url($CFG->wwwroot), navigation_node::TYPE_COURSE, null, 'anode2');
  199. $node1->make_active();
  200. $this->node->get('anode2')->make_active();
  201. $this->assertTrue($node1->isactive);
  202. $this->assertTrue($this->node->get('anode2')->isactive);
  203. }
  204. public function test_remove() {
  205. $remove1 = $this->node->add('child to remove 1', null, navigation_node::TYPE_CUSTOM, null, 'remove1');
  206. $remove2 = $this->node->add('child to remove 2', null, navigation_node::TYPE_CUSTOM, null, 'remove2');
  207. $remove3 = $remove2->add('child to remove 3', null, navigation_node::TYPE_CUSTOM, null, 'remove3');
  208. $this->assertIsA($remove1, 'navigation_node');
  209. $this->assertIsA($remove2, 'navigation_node');
  210. $this->assertIsA($remove3, 'navigation_node');
  211. $this->assertIsA($this->node->get('remove1'), 'navigation_node');
  212. $this->assertIsA($this->node->get('remove2'), 'navigation_node');
  213. $this->assertIsA($remove2->get('remove3'), 'navigation_node');
  214. $this->assertTrue($remove1->remove());
  215. $this->assertTrue($this->node->get('remove2')->remove());
  216. $this->assertTrue($remove2->get('remove3')->remove());
  217. $this->assertFalse($this->node->get('remove1'));
  218. $this->assertFalse($this->node->get('remove2'));
  219. }
  220. public function test_remove_class() {
  221. $this->node->add_class('testclass');
  222. $this->assertTrue($this->node->remove_class('testclass'));
  223. $this->assertFalse(in_array('testclass', $this->node->classes));
  224. }
  225. }
  226. /**
  227. * This is a dummy object that allows us to call protected methods within the
  228. * global navigation class by prefixing the methods with `exposed_`
  229. */
  230. class exposed_global_navigation extends global_navigation {
  231. protected $exposedkey = 'exposed_';
  232. public function __construct(moodle_page $page=null) {
  233. global $PAGE;
  234. if ($page === null) {
  235. $page = $PAGE;
  236. }
  237. parent::__construct($page);
  238. $this->cache = new navigation_cache('simpletest_nav');
  239. }
  240. public function __call($method, $arguments) {
  241. if (strpos($method,$this->exposedkey) !== false) {
  242. $method = substr($method, strlen($this->exposedkey));
  243. }
  244. if (method_exists($this, $method)) {
  245. return call_user_func_array(array($this, $method), $arguments);
  246. }
  247. throw new coding_exception('You have attempted to access a method that does not exist for the given object '.$method, DEBUG_DEVELOPER);
  248. }
  249. public function set_initialised() {
  250. $this->initialised = true;
  251. }
  252. }
  253. class mock_initialise_global_navigation extends global_navigation {
  254. static $count = 1;
  255. public function load_for_category() {
  256. $this->add('load_for_category', null, null, null, 'initcall'.self::$count);
  257. self::$count++;
  258. return 0;
  259. }
  260. public function load_for_course() {
  261. $this->add('load_for_course', null, null, null, 'initcall'.self::$count);
  262. self::$count++;
  263. return 0;
  264. }
  265. public function load_for_activity() {
  266. $this->add('load_for_activity', null, null, null, 'initcall'.self::$count);
  267. self::$count++;
  268. return 0;
  269. }
  270. public function load_for_user() {
  271. $this->add('load_for_user', null, null, null, 'initcall'.self::$count);
  272. self::$count++;
  273. return 0;
  274. }
  275. }
  276. class global_navigation_test extends UnitTestCase {
  277. /**
  278. * @var global_navigation
  279. */
  280. public $node;
  281. public static $includecoverage = array('./lib/navigationlib.php');
  282. public static $excludecoverage = array();
  283. public function setUp() {
  284. $this->node = new exposed_global_navigation();
  285. // Create an initial tree structure to work with
  286. $cat1 = $this->node->add('category 1', null, navigation_node::TYPE_CATEGORY, null, 'cat1');
  287. $cat2 = $this->node->add('category 2', null, navigation_node::TYPE_CATEGORY, null, 'cat2');
  288. $cat3 = $this->node->add('category 3', null, navigation_node::TYPE_CATEGORY, null, 'cat3');
  289. $sub1 = $cat2->add('sub category 1', null, navigation_node::TYPE_CATEGORY, null, 'sub1');
  290. $sub2 = $cat2->add('sub category 2', null, navigation_node::TYPE_CATEGORY, null, 'sub2');
  291. $sub3 = $cat2->add('sub category 3', null, navigation_node::TYPE_CATEGORY, null, 'sub3');
  292. $course1 = $sub2->add('course 1', null, navigation_node::TYPE_COURSE, null, 'course1');
  293. $course2 = $sub2->add('course 2', null, navigation_node::TYPE_COURSE, null, 'course2');
  294. $course3 = $sub2->add('course 3', null, navigation_node::TYPE_COURSE, null, 'course3');
  295. $section1 = $course2->add('section 1', null, navigation_node::TYPE_SECTION, null, 'sec1');
  296. $section2 = $course2->add('section 2', null, navigation_node::TYPE_SECTION, null, 'sec2');
  297. $section3 = $course2->add('section 3', null, navigation_node::TYPE_SECTION, null, 'sec3');
  298. $act1 = $section2->add('activity 1', null, navigation_node::TYPE_ACTIVITY, null, 'act1');
  299. $act2 = $section2->add('activity 2', null, navigation_node::TYPE_ACTIVITY, null, 'act2');
  300. $act3 = $section2->add('activity 3', null, navigation_node::TYPE_ACTIVITY, null, 'act3');
  301. $res1 = $section2->add('resource 1', null, navigation_node::TYPE_RESOURCE, null, 'res1');
  302. $res2 = $section2->add('resource 2', null, navigation_node::TYPE_RESOURCE, null, 'res2');
  303. $res3 = $section2->add('resource 3', null, navigation_node::TYPE_RESOURCE, null, 'res3');
  304. }
  305. public function test_format_display_course_content() {
  306. $this->assertTrue($this->node->exposed_format_display_course_content('topic'));
  307. $this->assertFalse($this->node->exposed_format_display_course_content('scorm'));
  308. $this->assertTrue($this->node->exposed_format_display_course_content('dummy'));
  309. }
  310. public function test_module_extends_navigation() {
  311. $this->assertTrue($this->node->exposed_module_extends_navigation('data'));
  312. $this->assertFalse($this->node->exposed_module_extends_navigation('test1'));
  313. }
  314. }
  315. /**
  316. * This is a dummy object that allows us to call protected methods within the
  317. * global navigation class by prefixing the methods with `exposed_`
  318. */
  319. class exposed_navbar extends navbar {
  320. protected $exposedkey = 'exposed_';
  321. public function __construct(moodle_page $page) {
  322. parent::__construct($page);
  323. $this->cache = new navigation_cache('simpletest_nav');
  324. }
  325. function __call($method, $arguments) {
  326. if (strpos($method,$this->exposedkey) !== false) {
  327. $method = substr($method, strlen($this->exposedkey));
  328. }
  329. if (method_exists($this, $method)) {
  330. return call_user_func_array(array($this, $method), $arguments);
  331. }
  332. throw new coding_exception('You have attempted to access a method that does not exist for the given object '.$method, DEBUG_DEVELOPER);
  333. }
  334. }
  335. class navigation_exposed_moodle_page extends moodle_page {
  336. public function set_navigation(navigation_node $node) {
  337. $this->_navigation = $node;
  338. }
  339. }
  340. class navbar_test extends UnitTestCase {
  341. protected $node;
  342. protected $oldnav;
  343. public static $includecoverage = array('./lib/navigationlib.php');
  344. public static $excludecoverage = array();
  345. public function setUp() {
  346. global $PAGE;
  347. $temptree = new global_navigation_test();
  348. $temptree->setUp();
  349. $temptree->node->find('course2', navigation_node::TYPE_COURSE)->make_active();
  350. $page = new navigation_exposed_moodle_page();
  351. $page->set_url($PAGE->url);
  352. $page->set_context($PAGE->context);
  353. $navigation = new exposed_global_navigation($page);
  354. $navigation->children = $temptree->node->children;
  355. $navigation->set_initialised();
  356. $page->set_navigation($navigation);
  357. $this->cache = new navigation_cache('simpletest_nav');
  358. $this->node = new exposed_navbar($page);
  359. }
  360. public function test_add() {
  361. // Add a node with all args set
  362. $this->node->add('test_add_1','http://www.moodle.org/',navigation_node::TYPE_COURSE,'testadd1','testadd1',new pix_icon('i/course', ''));
  363. // Add a node with the minimum args required
  364. $this->node->add('test_add_2','http://www.moodle.org/',navigation_node::TYPE_COURSE,'testadd2','testadd2',new pix_icon('i/course', ''));
  365. $this->assertIsA($this->node->get('testadd1'), 'navigation_node');
  366. $this->assertIsA($this->node->get('testadd2'), 'navigation_node');
  367. }
  368. public function test_has_items() {
  369. $this->assertTrue($this->node->has_items());
  370. }
  371. }
  372. class navigation_cache_test extends UnitTestCase {
  373. protected $cache;
  374. public static $includecoverage = array('./lib/navigationlib.php');
  375. public static $excludecoverage = array();
  376. public function setUp() {
  377. $this->cache = new navigation_cache('simpletest_nav');
  378. $this->cache->anysetvariable = true;
  379. }
  380. public function test___get() {
  381. $this->assertTrue($this->cache->anysetvariable);
  382. $this->assertEqual($this->cache->notasetvariable, null);
  383. }
  384. public function test___set() {
  385. $this->cache->myname = 'Sam Hemelryk';
  386. $this->assertTrue($this->cache->cached('myname'));
  387. $this->assertEqual($this->cache->myname, 'Sam Hemelryk');
  388. }
  389. public function test_cached() {
  390. $this->assertTrue($this->cache->cached('anysetvariable'));
  391. $this->assertFalse($this->cache->cached('notasetvariable'));
  392. }
  393. public function test_clear() {
  394. $cache = clone($this->cache);
  395. $this->assertTrue($cache->cached('anysetvariable'));
  396. $cache->clear();
  397. $this->assertFalse($cache->cached('anysetvariable'));
  398. }
  399. public function test_set() {
  400. $this->cache->set('software', 'Moodle');
  401. $this->assertTrue($this->cache->cached('software'));
  402. $this->assertEqual($this->cache->software, 'Moodle');
  403. }
  404. }
  405. /**
  406. * This is a dummy object that allows us to call protected methods within the
  407. * global navigation class by prefixing the methods with `exposed_`
  408. */
  409. class exposed_settings_navigation extends settings_navigation {
  410. protected $exposedkey = 'exposed_';
  411. function __construct() {
  412. global $PAGE;
  413. parent::__construct($PAGE);
  414. $this->cache = new navigation_cache('simpletest_nav');
  415. }
  416. function __call($method, $arguments) {
  417. if (strpos($method,$this->exposedkey) !== false) {
  418. $method = substr($method, strlen($this->exposedkey));
  419. }
  420. if (method_exists($this, $method)) {
  421. return call_user_func_array(array($this, $method), $arguments);
  422. }
  423. throw new coding_exception('You have attempted to access a method that does not exist for the given object '.$method, DEBUG_DEVELOPER);
  424. }
  425. }
  426. class settings_navigation_test extends UnitTestCase {
  427. protected $node;
  428. protected $cache;
  429. public static $includecoverage = array('./lib/navigationlib.php');
  430. public static $excludecoverage = array();
  431. public function setUp() {
  432. global $PAGE;
  433. $this->cache = new navigation_cache('simpletest_nav');
  434. $this->node = new exposed_settings_navigation();
  435. }
  436. public function test___construct() {
  437. $this->node = new exposed_settings_navigation();
  438. }
  439. public function test___initialise() {
  440. $this->node->initialise();
  441. $this->assertEqual($this->node->id, 'settingsnav');
  442. }
  443. public function test_in_alternative_role() {
  444. $this->assertFalse($this->node->exposed_in_alternative_role());
  445. }
  446. }