1<?php 2/* 3 +-----------------------------------------------------------------------------+ 4 | ILIAS open source | 5 +-----------------------------------------------------------------------------+ 6 | Copyright (c) 1998-2009 ILIAS open source, University of Cologne | 7 | | 8 | This program is free software; you can redistribute it and/or | 9 | modify it under the terms of the GNU General Public License | 10 | as published by the Free Software Foundation; either version 2 | 11 | of the License, or (at your option) any later version. | 12 | | 13 | This program is distributed in the hope that it will be useful, | 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 16 | GNU General Public License for more details. | 17 | | 18 | You should have received a copy of the GNU General Public License | 19 | along with this program; if not, write to the Free Software | 20 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 21 +-----------------------------------------------------------------------------+ 22*/ 23 24require_once(__DIR__ . "/mocks.php"); 25 26/** 27 * TestCase for the ilObjStudyProgramme 28 * @group needsInstalledILIAS 29 * 30 * @author Michael Herren <mh@studer-raimann.ch> 31 * @author Richard Klees <richard.klees@concepts-and-training.de> 32 * @author Stefan Hecken <stefan.hecken@concepts-and-training.de> 33 * @version 1.0.0 34 */ 35class ilObjStudyProgrammeTest extends PHPUnit_Framework_TestCase 36{ 37 protected $backupGlobals = false; 38 39 protected function setUp() 40 { 41 PHPUnit_Framework_Error_Deprecated::$enabled = false; 42 43 require_once("./Modules/StudyProgramme/classes/class.ilObjStudyProgramme.php"); 44 45 include_once("./Services/PHPUnit/classes/class.ilUnitUtil.php"); 46 ilUnitUtil::performInitialisation(); 47 48 $this->root_object = ilObjStudyProgramme::createInstance(); 49 $this->root_object_obj_id = $this->root_object->getId(); 50 $this->root_object_ref_id = $this->root_object->getRefId(); 51 $this->root_object->putInTree(ROOT_FOLDER_ID); 52 53 // 54 55 global $DIC; 56 $tree = $DIC['tree']; 57 $this->tree = $tree; 58 59 global $DIC; 60 $objDefinition = $DIC['objDefinition']; 61 $this->obj_definition = $objDefinition; 62 } 63 64 protected function tearDown() 65 { 66 if ($this->root_object) { 67 $this->root_object->delete(); 68 } 69 } 70 71 /** 72 * Test creation of ilObjStudyProgramme 73 */ 74 public function testCreation() 75 { 76 $this->assertNotEmpty($this->root_object_obj_id); 77 $this->assertGreaterThan(0, $this->root_object_obj_id); 78 79 $this->assertNotEmpty($this->root_object_ref_id); 80 $this->assertGreaterThan(0, $this->root_object_ref_id); 81 82 $this->assertTrue($this->tree->isInTree($this->root_object_ref_id)); 83 } 84 85 public function testDefaults() 86 { 87 $this->assertEquals($this->root_object->getStatus(), ilStudyProgramme::STATUS_DRAFT); 88 } 89 90 /** 91 * Test loading of ilObjStudyProgramme with obj_id. and ref_id 92 * 93 * @depends testCreation 94 */ 95 public function testLoadByObjId() 96 { 97 $loaded = new ilObjStudyProgramme($this->root_object_obj_id, false); 98 $orig = $this->root_object; 99 $load_ref_id = ilObjStudyProgramme::getInstanceByRefId($this->root_object_ref_id); 100 101 $this->assertNotNull($loaded); 102 $this->assertGreaterThan(0, $loaded->getId()); 103 $this->assertEquals($orig->getId(), $loaded->getId()); 104 $this->assertEquals( 105 $orig->getLastChange()->get(IL_CAL_DATETIME), 106 $loaded->getLastChange()->get(IL_CAL_DATETIME) 107 ); 108 $this->assertEquals($orig->getPoints(), $loaded->getPoints()); 109 $this->assertEquals($orig->getLPMode(), $loaded->getLPMode()); 110 $this->assertEquals($orig->getStatus(), $loaded->getStatus()); 111 } 112 113 /** 114 * Test loading of ilObjStudyProgramme with ref_id. 115 * 116 * @depends testCreation 117 */ 118 public function testLoadByRefId() 119 { 120 $loaded = new ilObjStudyProgramme($this->root_object_ref_id); 121 $orig = $this->root_object; 122 123 $this->assertNotNull($loaded); 124 $this->assertGreaterThan(0, $loaded->getId()); 125 $this->assertEquals($orig->getId(), $loaded->getId()); 126 $this->assertEquals( 127 $orig->getLastChange()->get(IL_CAL_DATETIME), 128 $loaded->getLastChange()->get(IL_CAL_DATETIME) 129 ); 130 $this->assertEquals($orig->getPoints(), $loaded->getPoints()); 131 $this->assertEquals($orig->getLPMode(), $loaded->getLPMode()); 132 $this->assertEquals($orig->getStatus(), $loaded->getStatus()); 133 } 134 135 /** 136 * Test loading over getInstance 137 * 138 * @depends testCreation 139 */ 140 public function testGetInstanceByRefId() 141 { 142 require_once("Modules/StudyProgramme/classes/class.ilObjStudyProgrammeCache.php"); 143 144 ilObjStudyProgrammeCache::singleton()->test_clear(); 145 $this->assertTrue(ilObjStudyProgrammeCache::singleton()->test_isEmpty()); 146 147 $loaded = ilObjStudyProgramme::getInstanceByRefId($this->root_object_ref_id); 148 $orig = $this->root_object; 149 150 $this->assertNotNull($loaded); 151 $this->assertGreaterThan(0, $loaded->getId()); 152 $this->assertEquals($orig->getId(), $loaded->getId()); 153 $this->assertEquals( 154 $orig->getLastChange()->get(IL_CAL_DATETIME), 155 $loaded->getLastChange()->get(IL_CAL_DATETIME) 156 ); 157 $this->assertEquals($orig->getPoints(), $loaded->getPoints()); 158 $this->assertEquals($orig->getLPMode(), $loaded->getLPMode()); 159 $this->assertEquals($orig->getStatus(), $loaded->getStatus()); 160 } 161 162 /** 163 * Test tings on ilObjStudyProgramme 164 * 165 * @depends testCreation 166 */ 167 public function testSettings() 168 { 169 $obj = ilObjStudyProgramme::getInstanceByRefId($this->root_object_ref_id); 170 171 $obj->setPoints(10); 172 $obj->setStatus(ilStudyProgramme::STATUS_ACTIVE); 173 $obj->update(); 174 175 $obj = ilObjStudyProgramme::getInstanceByRefId($this->root_object_ref_id); 176 177 $this->assertEquals(10, $obj->getPoints()); 178 $this->assertEquals(ilStudyProgramme::STATUS_ACTIVE, $obj->getStatus()); 179 180 $midnight = strtotime("today midnight"); 181 $this->assertGreaterThan($midnight, $obj->getLastChange()->getUnixTime()); 182 } 183 184 /** 185 * Test deletion of a ilObjStudyProgramme 186 * 187 * @depends testCreation 188 */ 189 public function testDelete() 190 { 191 $deleted_object = ilObjStudyProgramme::getInstanceByRefId($this->root_object_ref_id); 192 193 $this->assertTrue($deleted_object->delete()); 194 } 195 196 /** 197 * Creates a small tree, used by various tests. 198 */ 199 protected function createSmallTree() 200 { 201 $first_node = ilObjStudyProgramme::createInstance(); 202 $second_node = ilObjStudyProgramme::createInstance(); 203 $third_node = ilObjStudyProgramme::createInstance(); 204 205 $this->root_object->addNode($first_node); 206 $this->root_object->addNode($second_node); 207 $this->root_object->addNode($third_node); 208 209 $third_first_node = ilObjStudyProgramme::createInstance(); 210 $third_node->addNode($third_first_node); 211 } 212 213 /** 214 * Test creating a small tree 215 * 216 * @depends testCreation 217 */ 218 public function testTreeCreation() 219 { 220 $this->createSmallTree(); 221 $this->assertEquals(3, $this->root_object->getAmountOfChildren()); 222 } 223 224 /** 225 * Test function to get children or information about them 226 * 227 * @depends testTreeCreation 228 * @depends testGetInstanceByRefId 229 */ 230 public function testTreeGetChildren() 231 { 232 $this->createSmallTree(); 233 234 $children = $this->root_object->getChildren(); 235 $this->assertEquals(3, count($children), "getChildren()"); 236 237 $children = ilObjStudyProgramme::getAllChildren($this->root_object_ref_id); 238 $this->assertEquals(4, count($children), "ilObjStudyProgramme::getAllChildren(" . $this->root_object_ref_id . ")"); 239 240 $this->assertTrue($this->root_object->hasChildren(), "hasChildren()"); 241 $this->assertEquals(3, $this->root_object->getAmountOfChildren(), "getAmountOfChildren()"); 242 243 $this->assertFalse($children[0]->hasChildren(), "hasChildren()"); 244 $this->assertEquals(0, $children[0]->getAmountOfChildren(), "getAmountOfChildren()"); 245 $this->assertEquals(0, count($children[0]->getChildren())); 246 } 247 248 /** 249 * Test getParent on ilObjStudyProgramme 250 * 251 * @depends testTreeCreation 252 */ 253 public function testTreeGetParent() 254 { 255 $this->createSmallTree(); 256 $children = $this->root_object->getChildren(); 257 258 $child = $children[0]; 259 $this->assertNotNull($child->getParent()); 260 $this->assertNull($this->root_object->getParent()); 261 } 262 263 /** 264 * @depends testTreeCreation 265 */ 266 public function testTreeGetParents() 267 { 268 $this->createSmallTree(); 269 $node3 = ilObjStudyProgramme::createInstance(); 270 $children = $this->root_object->getChildren(); 271 $children[0]->addNode($node3); 272 273 $parents = $node3->getParents(); 274 $parent_ids = array_map(function ($node) { 275 return $node->getId(); 276 }, $parents); 277 $parent_ids_expected = array( $this->root_object->getId() 278 , $children[0]->getId() 279 ); 280 281 $this->assertEquals($parent_ids_expected, $parent_ids); 282 } 283 284 /** 285 * Test getDepth on ilObjStudyProgramme 286 * 287 * @depends testTreeCreation 288 */ 289 public function testTreeDepth() 290 { 291 $this->createSmallTree(); 292 $children = $this->root_object->getChildren(); 293 294 $child = $children[0]; 295 296 $this->assertEquals(1, $child->getDepth()); 297 } 298 299 /** 300 * Test getRoot on ilObjStudyProgramme 301 * 302 * @depends testTreeCreation 303 */ 304 public function testTreeGetRoot() 305 { 306 $this->createSmallTree(); 307 $children = $this->root_object->getChildren(); 308 $child = $children[0]; 309 310 $this->assertEquals($this->root_object->getId(), $child->getRoot()->getId()); 311 } 312 313 /** 314 * Test applyToSubTreeNodes on ilObjStudyProgramme. 315 * 316 * @depends testTreeCreation 317 */ 318 public function testApplyToSubTreeNodes() 319 { 320 $this->createSmallTree(); 321 $children = $this->root_object->getChildren(); 322 323 $val = 0; 324 $this->root_object->applyToSubTreeNodes(function ($node) use (&$val) { 325 $val += $node->getPoints(); 326 }); 327 328 // We didn't make modification on the points of the nodes. 329 $this->assertEquals($val, 5 * ilStudyProgramme::DEFAULT_POINTS); 330 331 332 $this->root_object->setPoints(1); 333 $children[0]->setPoints(2); 334 $children[1]->setPoints(4); 335 $children[2]->setPoints(1); 336 337 $third_level = $children[2]->getChildren(); 338 $third_level[0]->setPoints(2); 339 340 $val = 0; 341 $this->root_object->applyToSubTreeNodes(function ($node) use (&$val) { 342 $val += $node->getPoints(); 343 }); 344 345 $this->assertEquals($val, 10); 346 } 347 348 /** 349 * Test on addNode. 350 * 351 * @depends testTreeCreation 352 */ 353 public function testAddNode() 354 { 355 $this->createSmallTree(); 356 357 $children = $this->root_object->getChildren(); 358 $child = $children[0]; 359 $grandchild = new ilObjStudyProgramme(); 360 $grandchild->create(); 361 $child->addNode($grandchild); 362 363 $this->assertEquals($child->getId(), $grandchild->getParent()->getId()); 364 $this->assertEquals( 365 $this->root_object->getId(), 366 $grandchild->getRoot()->getId(), 367 "Root of grandchild is root of tree." 368 ); 369 $this->assertEquals(1, $child->getAmountOfChildren()); 370 $this->assertEquals(2, $grandchild->getDepth()); 371 $this->assertEquals($child->getLPMode(), ilStudyProgramme::MODE_POINTS); 372 } 373 374 /** 375 * Test on removeNode. 376 * 377 * @depends testTreeCreation 378 */ 379 public function testRemoveNode() 380 { 381 $this->createSmallTree(); 382 383 $children = $this->root_object->getChildren(); 384 $child = $children[0]; 385 $this->root_object->removeNode($child); 386 387 // Is not in tree anymore... 388 $raised = false; 389 try { 390 $child->getParent(); 391 } catch (ilStudyProgrammeTreeException $e) { 392 $raised = true; 393 } 394 $this->assertTrue($raised, "Child does not raise on getParent after it is removed."); 395 396 $this->assertEquals(2, $this->root_object->getAmountOfChildren()); 397 398 // Can't be removed a second time... 399 $raised = false; 400 try { 401 $this->root_object->removeNode($child); 402 } catch (ilStudyProgrammeTreeException $e) { 403 $raised = true; 404 } 405 $this->assertTrue($raised, "Child can be removed two times."); 406 } 407 408 /** 409 * Test on addLeaf. 410 * 411 * @depends testTreeCreation 412 */ 413 public function testAddLeaf() 414 { 415 $this->createSmallTree(); 416 $mock_leaf = new ilStudyProgrammeLeafMock(); 417 418 $children = $this->root_object->getChildren(); 419 $first_child = $children[0]; 420 421 $first_child->addLeaf($mock_leaf); 422 423 // We use our mock factory, since the original factory won't know how 424 // to create our mock leaf. 425 $first_child->object_factory = new ilObjectFactoryWrapperMock(); 426 427 $this->assertEquals(3, $this->root_object->getAmountOfChildren(), "getAmountOfChildren()"); 428 // Check if StudyProgrammes are not counted as LP-Children 429 $this->assertEquals(0, $this->root_object->getAmountOfLPChildren(), "getAmountOfLPChildren() on root"); 430 $this->assertEquals(false, $this->root_object->hasLPChildren(), "hasLPChildren() on root"); 431 432 $this->assertEquals(1, $first_child->getAmountOfLPChildren(), "getAmountOfLPChildren() on first child"); 433 $this->assertEquals(true, $first_child->hasLPChildren(), "hasLPChildren() on first child"); 434 $this->assertEquals($first_child->getLPMode(), ilStudyProgramme::MODE_LP_COMPLETED); 435 436 $lp_children = $first_child->getLPChildren(); 437 $this->assertEquals(1, count($lp_children)); 438 $this->assertEquals($mock_leaf->getId(), $lp_children[0]->getId()); 439 } 440 441 /** 442 * Test on removeLead. 443 * 444 * @depends testAddLeaf 445 */ 446 public function testRemoveLeaf() 447 { 448 $mock_leaf = new ilStudyProgrammeLeafMock(); 449 $this->root_object->addLeaf($mock_leaf); 450 451 $this->root_object->removeLeaf($mock_leaf); 452 $this->assertEquals(0, $this->root_object->getAmountOfChildren(), "getAmountOfChildren()"); 453 $this->assertEquals(0, $this->root_object->getAmountOfLPChildren(), "getAmountOfLPChildren()"); 454 455 $lp_children = $this->root_object->getLPChildren(); 456 $this->assertEquals(0, count($lp_children)); 457 } 458 459 /** 460 * Test whether nodes can only be added when there is no leaf in the 461 * parent and vice versa. 462 */ 463 public function testAddWrongChildType() 464 { 465 $this->createSmallTree(); 466 $children = $this->root_object->getChildren(); 467 $child_n = $children[0]; 468 $child_l = $children[1]; 469 470 $mock_leaf1 = new ilStudyProgrammeLeafMock(); 471 $mock_leaf2 = new ilStudyProgrammeLeafMock(); 472 $node1 = new ilObjStudyProgramme(); 473 $node2 = new ilObjStudyProgramme(); 474 $node1->create(); 475 $node2->create(); 476 477 $child_n->addNode($node1); 478 $child_l->addLeaf($mock_leaf1); 479 480 $raised = false; 481 try { 482 $child_n->addLeaf($mock_leaf2); 483 } catch (ilStudyProgrammeTreeException $e) { 484 $raised = true; 485 } 486 $this->assertTrue($raised, "Could add leaf to program containing node."); 487 488 $raised = false; 489 try { 490 $child_n->addLeaf($mock_leaf2); 491 } catch (ilStudyProgrammeTreeException $e) { 492 $raised = true; 493 } 494 $this->assertTrue($raised, "Could add node to program containing leaf."); 495 } 496 497 /** 498 * Test on moveTo. 499 */ 500 public function testMoveTo() 501 { 502 $this->createSmallTree(); 503 $children = $this->root_object->getChildren(); 504 $child_l = $children[0]; 505 $child_r = $children[1]; 506 $child_m = $children[2]; 507 508 $child_r->moveTo($child_l); 509 510 $this->assertEquals(2, $child_r->getDepth()); 511 $this->assertEquals($child_l->getId(), $child_r->getParent()->getId()); 512 $this->assertEquals(2, $this->root_object->getAmountOfChildren()); 513 $this->assertEquals(1, $child_l->getAmountOfChildren()); 514 515 // test recursive moving 516 $this->assertEquals(1, $child_m->getAmountOfChildren()); 517 518 $child_m->moveTo($child_r); 519 520 $m_children = $child_m->getChildren(); 521 $first_third_node = $m_children[0]; 522 523 $this->assertEquals(3, $child_m->getDepth()); 524 $this->assertEquals(1, $child_m->getAmountOfChildren()); 525 $this->assertNotNull($first_third_node); 526 $this->assertEquals(4, $first_third_node->getDepth()); 527 $this->assertEquals($child_m->getId(), $first_third_node->getParent()->getId()); 528 529 $this->assertEquals(1, $this->root_object->getAmountOfChildren()); 530 $this->assertEquals(3, count(ilObjStudyProgramme::getAllChildren($child_l->getRefId()))); 531 } 532 533 /** 534 * @expectedException ilStudyProgrammeTreeException 535 */ 536 public function testCantRemoveNodeWithRelevantProgress() 537 { 538 $this->createSmallTree(); 539 $children = $this->root_object->getChildren(); 540 $child_l = $children[0]; 541 $child_r = $children[1]; 542 $this->root_object->setStatus(ilStudyProgramme::STATUS_ACTIVE); 543 $child_l->setStatus(ilStudyProgramme::STATUS_ACTIVE); 544 $child_r->setStatus(ilStudyProgramme::STATUS_ACTIVE); 545 546 $user = new ilObjUser(); 547 $user->create(); 548 549 $child_l->assignUser($user->getId()); 550 $this->root_object->removeNode($child_l); 551 } 552 553 public function testCanRemoveNodeWithNotRelevantProgress() 554 { 555 $this->createSmallTree(); 556 $children = $this->root_object->getChildren(); 557 $child_l = $children[0]; 558 $child_r = $children[1]; 559 $this->root_object->setStatus(ilStudyProgramme::STATUS_ACTIVE); 560 $child_l->setStatus(ilStudyProgramme::STATUS_ACTIVE); 561 $child_r->setStatus(ilStudyProgramme::STATUS_OUTDATED); 562 563 $user = new ilObjUser(); 564 $user->create(); 565 566 $this->root_object->assignUser($user->getId()); 567 $this->root_object->removeNode($child_r); 568 } 569 570 public function testCreateableSubObjects() 571 { 572 $this->createSmallTree(); 573 $children = $this->root_object->getChildren(); 574 $child_l = $children[0]; 575 576 $all_possible_subobjects = $this->root_object->getPossibleSubObjects(); 577 // don't take rolfs into account, we don't need rolf anymore 578 unset($all_possible_subobjects["rolf"]); 579 580 // this is course reference and training programme 581 $this->assertCount(2, $all_possible_subobjects); 582 $this->assertArrayHasKey("prg", $all_possible_subobjects); 583 $this->assertArrayHasKey("crsr", $all_possible_subobjects); 584 585 // root already contains program nodes, so course ref is forbidden 586 $subobjs = ilObjStudyProgramme::getCreatableSubObjects($all_possible_subobjects, $this->root_object->getRefId()); 587 $this->assertCount(1, $subobjs); 588 $this->assertArrayHasKey("prg", $subobjs); 589 590 // first node contains nothing, so course ref and program node are allowed 591 $subobjs = ilObjStudyProgramme::getCreatableSubObjects($all_possible_subobjects, $child_l->getRefId()); 592 $this->assertCount(2, $subobjs); 593 $this->assertArrayHasKey("prg", $subobjs); 594 $this->assertArrayHasKey("crsr", $subobjs); 595 596 $mock_leaf = new ilStudyProgrammeLeafMock(); 597 $children = $this->root_object->getChildren(); 598 $child_l->object_factory = new ilObjectFactoryWrapperMock(); 599 $child_l->addLeaf($mock_leaf); 600 601 // Now we added a leaf, so no program nodes are allowed anymore. 602 $subobjs = ilObjStudyProgramme::getCreatableSubObjects($all_possible_subobjects, $child_l->getRefId()); 603 $this->assertCount(1, $subobjs); 604 $this->assertArrayHasKey("crsr", $subobjs); 605 } 606 607 public function testCreatableSubObjectsWithoutRef() 608 { 609 $all_possible_subobjects = $this->obj_definition->getSubObjects("prg"); 610 // don't take rolfs into account, we don't need rolf anymore 611 unset($all_possible_subobjects["rolf"]); 612 $this->assertEquals( 613 $all_possible_subobjects, 614 ilObjStudyProgramme::getCreatableSubObjects($all_possible_subobjects, null) 615 ); 616 } 617 618 /** 619 * @expectedException ilException 620 */ 621 public function testCreatableSubObjectsRaisesOnNonProgramRef() 622 { 623 ilObjStudyProgramme::getCreatableSubObjects(array(), 9); 624 } 625 626 public function testDeleteRemovesEntriesInPrgSettings() 627 { 628 $this->root_object->delete(); 629 $this->root_object = null; 630 631 global $DIC; 632 $ilDB = $DIC['ilDB']; 633 $res = $ilDB->query( 634 "SELECT COUNT(*) cnt " 635 . " FROM " . ilStudyProgramme::returnDbTableName() 636 . " WHERE obj_id = " . $this->root_object_obj_id 637 ); 638 $rec = $ilDB->fetchAssoc($res); 639 $this->assertEquals(0, $rec["cnt"]); 640 } 641 642 public function testCreatePermissionExists() 643 { 644 // Ask for permission id for creation of "foobar" to check assumption 645 // that lookupCreateOperationIds just drops unknown object types. 646 $op_ids = ilRbacReview::lookupCreateOperationIds(array("prg", "foobar")); 647 $this->assertCount(1, $op_ids); 648 } 649} 650