Differences Between: [Versions 310 and 311] [Versions 39 and 311]
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 namespace core_backup; 18 19 use backup; 20 use backup_attribute; 21 use backup_controller_dbops; 22 use backup_final_element; 23 use backup_nested_element; 24 use backup_optigroup; 25 use backup_optigroup_element; 26 use backup_processor_exception; 27 use backup_structure_processor; 28 use base_element_struct_exception; 29 use base_optigroup_exception; 30 use base_processor; 31 use memory_xml_output; 32 use xml_writer; 33 34 defined('MOODLE_INTERNAL') || die(); 35 36 // Include all the needed stuff. 37 require_once (__DIR__.'/fixtures/structure_fixtures.php'); 38 39 global $CFG; 40 require_once($CFG->dirroot . '/backup/util/xml/output/memory_xml_output.class.php'); 41 42 /** 43 * Unit test case the all the backup structure classes. Note: Uses database 44 * 45 * @package core_backup 46 * @category test 47 * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com} 48 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 49 */ 50 class structure_test extends \advanced_testcase { 51 52 /** @var int Store the inserted forum->id for use in test functions */ 53 protected $forumid; 54 /** @var int Store the inserted discussion1->id for use in test functions */ 55 protected $discussionid1; 56 /** @var int Store the inserted discussion2->id for use in test functions */ 57 protected $discussionid2; 58 /** @var int Store the inserted post1->id for use in test functions */ 59 protected $postid1; 60 /** @var int Store the inserted post2->id for use in test functions */ 61 protected $postid2; 62 /** @var int Store the inserted post3->id for use in test functions */ 63 protected $postid3; 64 /** @var int Store the inserted post4->id for use in test functions */ 65 protected $postid4; 66 /** @var int Official contextid for these tests */ 67 protected $contextid; 68 69 70 protected function setUp(): void { 71 parent::setUp(); 72 73 $this->resetAfterTest(true); 74 75 $this->contextid = 666; // Let's assume this is the context for the forum 76 $this->fill_records(); // Add common stuff needed by various test methods 77 } 78 79 private function fill_records() { 80 global $DB; 81 82 // Create one forum 83 $forum_data = (object)array('course' => 1, 'name' => 'Test forum', 'intro' => 'Intro forum'); 84 $this->forumid = $DB->insert_record('forum', $forum_data); 85 // With two related file 86 $f1_forum_data = (object)array( 87 'contenthash' => 'testf1', 'contextid' => $this->contextid, 88 'component'=>'mod_forum', 'filearea' => 'intro', 'filename' => 'tf1', 'itemid' => 0, 89 'filesize' => 123, 'timecreated' => 0, 'timemodified' => 0, 90 'pathnamehash' => 'testf1' 91 ); 92 $DB->insert_record('files', $f1_forum_data); 93 $f2_forum_data = (object)array( 94 'contenthash' => 'tesft2', 'contextid' => $this->contextid, 95 'component'=>'mod_forum', 'filearea' => 'intro', 'filename' => 'tf2', 'itemid' => 0, 96 'filesize' => 123, 'timecreated' => 0, 'timemodified' => 0, 97 'pathnamehash' => 'testf2' 98 ); 99 $DB->insert_record('files', $f2_forum_data); 100 101 // Create two discussions 102 $discussion1 = (object)array('course' => 1, 'forum' => $this->forumid, 'name' => 'd1', 'userid' => 100, 'groupid' => 200); 103 $this->discussionid1 = $DB->insert_record('forum_discussions', $discussion1); 104 $discussion2 = (object)array('course' => 1, 'forum' => $this->forumid, 'name' => 'd2', 'userid' => 101, 'groupid' => 201); 105 $this->discussionid2 = $DB->insert_record('forum_discussions', $discussion2); 106 107 // Create four posts 108 $post1 = (object)array('discussion' => $this->discussionid1, 'userid' => 100, 'subject' => 'p1', 'message' => 'm1'); 109 $this->postid1 = $DB->insert_record('forum_posts', $post1); 110 $post2 = (object)array('discussion' => $this->discussionid1, 'parent' => $this->postid1, 'userid' => 102, 'subject' => 'p2', 'message' => 'm2'); 111 $this->postid2 = $DB->insert_record('forum_posts', $post2); 112 $post3 = (object)array('discussion' => $this->discussionid1, 'parent' => $this->postid2, 'userid' => 103, 'subject' => 'p3', 'message' => 'm3'); 113 $this->postid3 = $DB->insert_record('forum_posts', $post3); 114 $post4 = (object)array('discussion' => $this->discussionid2, 'userid' => 101, 'subject' => 'p4', 'message' => 'm4'); 115 $this->postid4 = $DB->insert_record('forum_posts', $post4); 116 // With two related file 117 $f1_post1 = (object)array( 118 'contenthash' => 'testp1', 'contextid' => $this->contextid, 'component'=>'mod_forum', 119 'filearea' => 'post', 'filename' => 'tp1', 'itemid' => $this->postid1, 120 'filesize' => 123, 'timecreated' => 0, 'timemodified' => 0, 121 'pathnamehash' => 'testp1' 122 ); 123 $DB->insert_record('files', $f1_post1); 124 $f1_post2 = (object)array( 125 'contenthash' => 'testp2', 'contextid' => $this->contextid, 'component'=>'mod_forum', 126 'filearea' => 'attachment', 'filename' => 'tp2', 'itemid' => $this->postid2, 127 'filesize' => 123, 'timecreated' => 0, 'timemodified' => 0, 128 'pathnamehash' => 'testp2' 129 ); 130 $DB->insert_record('files', $f1_post2); 131 132 // Create two ratings 133 $rating1 = (object)array( 134 'contextid' => $this->contextid, 'userid' => 104, 'itemid' => $this->postid1, 'rating' => 2, 135 'scaleid' => -1, 'timecreated' => time(), 'timemodified' => time()); 136 $r1id = $DB->insert_record('rating', $rating1); 137 $rating2 = (object)array( 138 'contextid' => $this->contextid, 'userid' => 105, 'itemid' => $this->postid1, 'rating' => 3, 139 'scaleid' => -1, 'timecreated' => time(), 'timemodified' => time()); 140 $r2id = $DB->insert_record('rating', $rating2); 141 142 // Create 1 reads 143 $read1 = (object)array('userid' => 102, 'forumid' => $this->forumid, 'discussionid' => $this->discussionid2, 'postid' => $this->postid4); 144 $DB->insert_record('forum_read', $read1); 145 } 146 147 /** 148 * Backup structures tests (construction, definition and execution) 149 */ 150 function test_backup_structure_construct() { 151 global $DB; 152 153 $backupid = 'Testing Backup ID'; // Official backupid for these tests 154 155 // Create all the elements that will conform the tree 156 $forum = new backup_nested_element('forum', 157 array('id'), 158 array( 159 'type', 'name', 'intro', 'introformat', 160 'assessed', 'assesstimestart', 'assesstimefinish', 'scale', 161 'maxbytes', 'maxattachments', 'forcesubscribe', 'trackingtype', 162 'rsstype', 'rssarticles', 'timemodified', 'warnafter', 163 'blockafter', 164 new backup_final_element('blockperiod'), 165 new \mock_skip_final_element('completiondiscussions'), 166 new \mock_modify_final_element('completionreplies'), 167 new \mock_final_element_interceptor('completionposts')) 168 ); 169 $discussions = new backup_nested_element('discussions'); 170 $discussion = new backup_nested_element('discussion', 171 array('id'), 172 array( 173 'forum', 'name', 'firstpost', 'userid', 174 'groupid', 'assessed', 'timemodified', 'usermodified', 175 'timestart', 'timeend') 176 ); 177 $posts = new backup_nested_element('posts'); 178 $post = new backup_nested_element('post', 179 array('id'), 180 array( 181 'discussion', 'parent', 'userid', 'created', 182 'modified', 'mailed', 'subject', 'message', 183 'messageformat', 'messagetrust', 'attachment', 'totalscore', 184 'mailnow') 185 ); 186 $ratings = new backup_nested_element('ratings'); 187 $rating = new backup_nested_element('rating', 188 array('id'), 189 array('userid', 'itemid', 'time', 'post_rating') 190 ); 191 $reads = new backup_nested_element('readposts'); 192 $read = new backup_nested_element('read', 193 array('id'), 194 array( 195 'userid', 'discussionid', 'postid', 196 'firstread', 'lastread') 197 ); 198 $inventeds = new backup_nested_element('invented_elements', 199 array('reason', 'version') 200 ); 201 $invented = new backup_nested_element('invented', 202 null, 203 array('one', 'two', 'three') 204 ); 205 $one = $invented->get_final_element('one'); 206 $one->add_attributes(array('attr1', 'attr2')); 207 208 // Build the tree 209 $forum->add_child($discussions); 210 $discussions->add_child($discussion); 211 212 $discussion->add_child($posts); 213 $posts->add_child($post); 214 215 $post->add_child($ratings); 216 $ratings->add_child($rating); 217 218 $forum->add_child($reads); 219 $reads->add_child($read); 220 221 $forum->add_child($inventeds); 222 $inventeds->add_child($invented); 223 224 // Let's add 1 optigroup with 4 elements 225 $alternative1 = new backup_optigroup_element('alternative1', 226 array('name', 'value'), '../../id', $this->postid1); 227 $alternative2 = new backup_optigroup_element('alternative2', 228 array('name', 'value'), backup::VAR_PARENTID, $this->postid2); 229 $alternative3 = new backup_optigroup_element('alternative3', 230 array('name', 'value'), '/forum/discussions/discussion/posts/post/id', $this->postid3); 231 $alternative4 = new backup_optigroup_element('alternative4', 232 array('forumtype', 'forumname')); // Alternative without conditions 233 // Create the optigroup, adding one element 234 $optigroup = new backup_optigroup('alternatives', $alternative1, false); 235 // Add second opti element 236 $optigroup->add_child($alternative2); 237 238 // Add optigroup to post element 239 $post->add_optigroup($optigroup); 240 // Add third opti element, on purpose after the add_optigroup() line above to check param evaluation works ok 241 $optigroup->add_child($alternative3); 242 // Add 4th opti element (the one without conditions, so will be present always) 243 $optigroup->add_child($alternative4); 244 245 /// Create some new nested elements, both named 'dupetest1', and add them to alternative1 and alternative2 246 /// (not problem as far as the optigroup in not unique) 247 $dupetest1 = new backup_nested_element('dupetest1', null, array('field1', 'field2')); 248 $dupetest2 = new backup_nested_element('dupetest2', null, array('field1', 'field2')); 249 $dupetest3 = new backup_nested_element('dupetest3', null, array('field1', 'field2')); 250 $dupetest4 = new backup_nested_element('dupetest1', null, array('field1', 'field2')); 251 $dupetest1->add_child($dupetest3); 252 $dupetest2->add_child($dupetest4); 253 $alternative1->add_child($dupetest1); 254 $alternative2->add_child($dupetest2); 255 256 // Define sources 257 $forum->set_source_table('forum', array('id' => backup::VAR_ACTIVITYID)); 258 $discussion->set_source_sql('SELECT * 259 FROM {forum_discussions} 260 WHERE forum = ?', 261 array('/forum/id') 262 ); 263 $post->set_source_table('forum_posts', array('discussion' => '/forum/discussions/discussion/id')); 264 $rating->set_source_sql('SELECT * 265 FROM {rating} 266 WHERE itemid = ?', 267 array(backup::VAR_PARENTID) 268 ); 269 270 $read->set_source_table('forum_read', array('forumid' => '../../id')); 271 272 $inventeds->set_source_array(array((object)array('reason' => 'I love Moodle', 'version' => '1.0'), 273 (object)array('reason' => 'I love Moodle', 'version' => '2.0'))); // 2 object array 274 $invented->set_source_array(array((object)array('one' => 1, 'two' => 2, 'three' => 3), 275 (object)array('one' => 11, 'two' => 22, 'three' => 33))); // 2 object array 276 277 // Set optigroup_element sources 278 $alternative1->set_source_array(array((object)array('name' => 'alternative1', 'value' => 1))); // 1 object array 279 // Skip alternative2 source definition on purpose (will be tested) 280 // $alternative2->set_source_array(array((object)array('name' => 'alternative2', 'value' => 2))); // 1 object array 281 $alternative3->set_source_array(array((object)array('name' => 'alternative3', 'value' => 3))); // 1 object array 282 // Alternative 4 source is the forum type and name, so we'll get that in ALL posts (no conditions) that 283 // have not another alternative (post4 in our testing data in the only not matching any other alternative) 284 $alternative4->set_source_sql('SELECT type AS forumtype, name AS forumname 285 FROM {forum} 286 WHERE id = ?', 287 array('/forum/id') 288 ); 289 // Set children of optigroup_element source 290 $dupetest1->set_source_array(array((object)array('field1' => '1', 'field2' => 1))); // 1 object array 291 $dupetest2->set_source_array(array((object)array('field1' => '2', 'field2' => 2))); // 1 object array 292 $dupetest3->set_source_array(array((object)array('field1' => '3', 'field2' => 3))); // 1 object array 293 $dupetest4->set_source_array(array((object)array('field1' => '4', 'field2' => 4))); // 1 object array 294 295 // Define some aliases 296 $rating->set_source_alias('rating', 'post_rating'); // Map the 'rating' value from DB to 'post_rating' final element 297 298 // Mark to detect files of type 'forum_intro' in forum (and not item id) 299 $forum->annotate_files('mod_forum', 'intro', null); 300 301 // Mark to detect file of type 'forum_post' and 'forum_attachment' in post (with itemid being post->id) 302 $post->annotate_files('mod_forum', 'post', 'id'); 303 $post->annotate_files('mod_forum', 'attachment', 'id'); 304 305 // Mark various elements to be annotated 306 $discussion->annotate_ids('user1', 'userid'); 307 $post->annotate_ids('forum_post', 'id'); 308 $rating->annotate_ids('user2', 'userid'); 309 $rating->annotate_ids('forum_post', 'itemid'); 310 311 // Create the backup_ids_temp table 312 backup_controller_dbops::create_backup_ids_temp_table($backupid); 313 314 // Instantiate in memory xml output 315 $xo = new memory_xml_output(); 316 317 // Instantiate xml_writer and start it 318 $xw = new xml_writer($xo); 319 $xw->start(); 320 321 // Instantiate the backup processor 322 $processor = new backup_structure_processor($xw); 323 324 // Set some variables 325 $processor->set_var(backup::VAR_ACTIVITYID, $this->forumid); 326 $processor->set_var(backup::VAR_BACKUPID, $backupid); 327 $processor->set_var(backup::VAR_CONTEXTID,$this->contextid); 328 329 // Process the backup structure with the backup processor 330 $forum->process($processor); 331 332 // Stop the xml_writer 333 $xw->stop(); 334 335 // Check various counters 336 $this->assertEquals($forum->get_counter(), $DB->count_records('forum')); 337 $this->assertEquals($discussion->get_counter(), $DB->count_records('forum_discussions')); 338 $this->assertEquals($rating->get_counter(), $DB->count_records('rating')); 339 $this->assertEquals($read->get_counter(), $DB->count_records('forum_read')); 340 $this->assertEquals($inventeds->get_counter(), 2); // Array 341 342 // Perform some validations with the generated XML 343 $dom = new \DomDocument(); 344 $dom->loadXML($xo->get_allcontents()); 345 $xpath = new \DOMXPath($dom); 346 // Some more counters 347 $query = '/forum/discussions/discussion/posts/post'; 348 $posts = $xpath->query($query); 349 $this->assertEquals($posts->length, $DB->count_records('forum_posts')); 350 $query = '/forum/invented_elements/invented'; 351 $inventeds = $xpath->query($query); 352 $this->assertEquals($inventeds->length, 2*2); 353 354 // Check ratings information against DB 355 $ratings = $dom->getElementsByTagName('rating'); 356 $this->assertEquals($ratings->length, $DB->count_records('rating')); 357 foreach ($ratings as $rating) { 358 $ratarr = array(); 359 $ratarr['id'] = $rating->getAttribute('id'); 360 foreach ($rating->childNodes as $node) { 361 if ($node->nodeType != XML_TEXT_NODE) { 362 $ratarr[$node->nodeName] = $node->nodeValue; 363 } 364 } 365 $this->assertEquals($DB->get_field('rating', 'userid', array('id' => $ratarr['id'])), $ratarr['userid']); 366 $this->assertEquals($DB->get_field('rating', 'itemid', array('id' => $ratarr['id'])), $ratarr['itemid']); 367 $this->assertEquals($DB->get_field('rating', 'rating', array('id' => $ratarr['id'])), $ratarr['post_rating']); 368 } 369 370 // Check forum has "blockeperiod" with value 0 (was declared by object instead of name) 371 $query = '/forum[blockperiod="0"]'; 372 $result = $xpath->query($query); 373 $this->assertEquals(1, $result->length); 374 375 // Check forum is missing "completiondiscussions" (as we are using mock_skip_final_element) 376 $query = '/forum/completiondiscussions'; 377 $result = $xpath->query($query); 378 $this->assertEquals(0, $result->length); 379 380 // Check forum has "completionreplies" with value "original was 0, now changed" (because of mock_modify_final_element) 381 $query = '/forum[completionreplies="original was 0, now changed"]'; 382 $result = $xpath->query($query); 383 $this->assertEquals(1, $result->length); 384 385 // Check forum has "completionposts" with value "intercepted!" (because of mock_final_element_interceptor) 386 $query = '/forum[completionposts="intercepted!"]'; 387 $result = $xpath->query($query); 388 $this->assertEquals(1, $result->length); 389 390 // Check there isn't any alternative2 tag, as far as it hasn't source defined 391 $query = '//alternative2'; 392 $result = $xpath->query($query); 393 $this->assertEquals(0, $result->length); 394 395 // Check there are 4 "field1" elements 396 $query = '/forum/discussions/discussion/posts/post//field1'; 397 $result = $xpath->query($query); 398 $this->assertEquals(4, $result->length); 399 400 // Check first post has one name element with value "alternative1" 401 $query = '/forum/discussions/discussion/posts/post[@id="'.$this->postid1.'"][name="alternative1"]'; 402 $result = $xpath->query($query); 403 $this->assertEquals(1, $result->length); 404 405 // Check there are two "dupetest1" elements 406 $query = '/forum/discussions/discussion/posts/post//dupetest1'; 407 $result = $xpath->query($query); 408 $this->assertEquals(2, $result->length); 409 410 // Check second post has one name element with value "dupetest2" 411 $query = '/forum/discussions/discussion/posts/post[@id="'.$this->postid2.'"]/dupetest2'; 412 $result = $xpath->query($query); 413 $this->assertEquals(1, $result->length); 414 415 // Check element "dupetest2" of second post has one field1 element with value "2" 416 $query = '/forum/discussions/discussion/posts/post[@id="'.$this->postid2.'"]/dupetest2[field1="2"]'; 417 $result = $xpath->query($query); 418 $this->assertEquals(1, $result->length); 419 420 // Check forth post has no name element 421 $query = '/forum/discussions/discussion/posts/post[@id="'.$this->postid4.'"]/name'; 422 $result = $xpath->query($query); 423 $this->assertEquals(0, $result->length); 424 425 // Check 1st, 2nd and 3rd posts have no forumtype element 426 $query = '/forum/discussions/discussion/posts/post[@id="'.$this->postid1.'"]/forumtype'; 427 $result = $xpath->query($query); 428 $this->assertEquals(0, $result->length); 429 $query = '/forum/discussions/discussion/posts/post[@id="'.$this->postid2.'"]/forumtype'; 430 $result = $xpath->query($query); 431 $this->assertEquals(0, $result->length); 432 $query = '/forum/discussions/discussion/posts/post[@id="'.$this->postid3.'"]/forumtype'; 433 $result = $xpath->query($query); 434 $this->assertEquals(0, $result->length); 435 436 // Check 4th post has one forumtype element with value "general" 437 // (because it doesn't matches alternatives 1, 2, 3, then alternative 4, 438 // the one without conditions is being applied) 439 $query = '/forum/discussions/discussion/posts/post[@id="'.$this->postid4.'"][forumtype="general"]'; 440 $result = $xpath->query($query); 441 $this->assertEquals(1, $result->length); 442 443 // Check annotations information against DB 444 // Count records in original tables 445 $c_postsid = $DB->count_records_sql('SELECT COUNT(DISTINCT id) FROM {forum_posts}'); 446 $c_dissuserid = $DB->count_records_sql('SELECT COUNT(DISTINCT userid) FROM {forum_discussions}'); 447 $c_ratuserid = $DB->count_records_sql('SELECT COUNT(DISTINCT userid) FROM {rating}'); 448 // Count records in backup_ids_table 449 $f_forumpost = $DB->count_records('backup_ids_temp', array('backupid' => $backupid, 'itemname' => 'forum_post')); 450 $f_user1 = $DB->count_records('backup_ids_temp', array('backupid' => $backupid, 'itemname' => 'user1')); 451 $f_user2 = $DB->count_records('backup_ids_temp', array('backupid' => $backupid, 'itemname' => 'user2')); 452 $c_notbackupid = $DB->count_records_select('backup_ids_temp', 'backupid != ?', array($backupid)); 453 // Peform tests by comparing counts 454 $this->assertEquals($c_notbackupid, 0); // there isn't any record with incorrect backupid 455 $this->assertEquals($c_postsid, $f_forumpost); // All posts have been registered 456 $this->assertEquals($c_dissuserid, $f_user1); // All users coming from discussions have been registered 457 $this->assertEquals($c_ratuserid, $f_user2); // All users coming from ratings have been registered 458 459 // Check file annotations against DB 460 $fannotations = $DB->get_records('backup_ids_temp', array('backupid' => $backupid, 'itemname' => 'file')); 461 $ffiles = $DB->get_records('files', array('contextid' => $this->contextid)); 462 $this->assertEquals(count($fannotations), count($ffiles)); // Same number of recs in both (all files have been annotated) 463 foreach ($fannotations as $annotation) { // Check ids annotated 464 $this->assertTrue($DB->record_exists('files', array('id' => $annotation->itemid))); 465 } 466 467 // Drop the backup_ids_temp table 468 backup_controller_dbops::drop_backup_ids_temp_table('testingid'); 469 } 470 471 /** 472 * Backup structures wrong tests (trying to do things the wrong way) 473 */ 474 function test_backup_structure_wrong() { 475 476 // Instantiate the backup processor 477 $processor = new backup_structure_processor(new xml_writer(new memory_xml_output())); 478 $this->assertTrue($processor instanceof base_processor); 479 480 // Set one var twice 481 $processor->set_var('onenewvariable', 999); 482 try { 483 $processor->set_var('onenewvariable', 999); 484 $this->assertTrue(false, 'backup_processor_exception expected'); 485 } catch (\Exception $e) { 486 $this->assertTrue($e instanceof backup_processor_exception); 487 $this->assertEquals($e->errorcode, 'processorvariablealreadyset'); 488 $this->assertEquals($e->a, 'onenewvariable'); 489 } 490 491 // Get non-existing var 492 try { 493 $var = $processor->get_var('nonexistingvar'); 494 $this->assertTrue(false, 'backup_processor_exception expected'); 495 } catch (\Exception $e) { 496 $this->assertTrue($e instanceof backup_processor_exception); 497 $this->assertEquals($e->errorcode, 'processorvariablenotfound'); 498 $this->assertEquals($e->a, 'nonexistingvar'); 499 } 500 501 // Create nested element and try ro get its parent id (doesn't exisit => exception) 502 $ne = new backup_nested_element('test', 'one', 'two', 'three'); 503 try { 504 $ne->set_source_table('forum', array('id' => backup::VAR_PARENTID)); 505 $ne->process($processor); 506 $this->assertTrue(false, 'base_element_struct_exception expected'); 507 } catch (\Exception $e) { 508 $this->assertTrue($e instanceof base_element_struct_exception); 509 $this->assertEquals($e->errorcode, 'cannotfindparentidforelement'); 510 } 511 512 // Try to process one nested/final/attribute elements without processor 513 $ne = new backup_nested_element('test', 'one', 'two', 'three'); 514 try { 515 $ne->process(new \stdClass()); 516 $this->assertTrue(false, 'base_element_struct_exception expected'); 517 } catch (\Exception $e) { 518 $this->assertTrue($e instanceof base_element_struct_exception); 519 $this->assertEquals($e->errorcode, 'incorrect_processor'); 520 } 521 $fe = new backup_final_element('test'); 522 try { 523 $fe->process(new \stdClass()); 524 $this->assertTrue(false, 'base_element_struct_exception expected'); 525 } catch (\Exception $e) { 526 $this->assertTrue($e instanceof base_element_struct_exception); 527 $this->assertEquals($e->errorcode, 'incorrect_processor'); 528 } 529 $at = new backup_attribute('test'); 530 try { 531 $at->process(new \stdClass()); 532 $this->assertTrue(false, 'base_element_struct_exception expected'); 533 } catch (\Exception $e) { 534 $this->assertTrue($e instanceof base_element_struct_exception); 535 $this->assertEquals($e->errorcode, 'incorrect_processor'); 536 } 537 538 // Try to put an incorrect alias 539 $ne = new backup_nested_element('test', 'one', 'two', 'three'); 540 try { 541 $ne->set_source_alias('last', 'nonexisting'); 542 $this->assertTrue(false, 'base_element_struct_exception expected'); 543 } catch (\Exception $e) { 544 $this->assertTrue($e instanceof base_element_struct_exception); 545 $this->assertEquals($e->errorcode, 'incorrectaliasfinalnamenotfound'); 546 $this->assertEquals($e->a, 'nonexisting'); 547 } 548 549 // Try various incorrect paths specifying source 550 $ne = new backup_nested_element('test', 'one', 'two', 'three'); 551 try { 552 $ne->set_source_table('forum', array('/test/subtest')); 553 $this->assertTrue(false, 'base_element_struct_exception expected'); 554 } catch (\Exception $e) { 555 $this->assertTrue($e instanceof base_element_struct_exception); 556 $this->assertEquals($e->errorcode, 'baseelementincorrectfinalorattribute'); 557 $this->assertEquals($e->a, 'subtest'); 558 } 559 try { 560 $ne->set_source_table('forum', array('/wrongtest')); 561 $this->assertTrue(false, 'base_element_struct_exception expected'); 562 } catch (\Exception $e) { 563 $this->assertTrue($e instanceof base_element_struct_exception); 564 $this->assertEquals($e->errorcode, 'baseelementincorrectgrandparent'); 565 $this->assertEquals($e->a, 'wrongtest'); 566 } 567 try { 568 $ne->set_source_table('forum', array('../nonexisting')); 569 $this->assertTrue(false, 'base_element_struct_exception expected'); 570 } catch (\Exception $e) { 571 $this->assertTrue($e instanceof base_element_struct_exception); 572 $this->assertEquals($e->errorcode, 'baseelementincorrectparent'); 573 $this->assertEquals($e->a, '..'); 574 } 575 576 // Try various incorrect file annotations 577 578 $ne = new backup_nested_element('test', 'one', 'two', 'three'); 579 $ne->annotate_files('test', 'filearea', null); 580 try { 581 $ne->annotate_files('test', 'filearea', null); // Try to add annotations twice 582 $this->assertTrue(false, 'base_element_struct_exception expected'); 583 } catch (\Exception $e) { 584 $this->assertTrue($e instanceof base_element_struct_exception); 585 $this->assertEquals($e->errorcode, 'annotate_files_duplicate_annotation'); 586 $this->assertEquals($e->a, 'test/filearea/'); 587 } 588 589 $ne = new backup_nested_element('test', 'one', 'two', 'three'); 590 try { 591 $ne->annotate_files('test', 'filearea', 'four'); // Incorrect element 592 $this->assertTrue(false, 'base_element_struct_exception expected'); 593 } catch (\Exception $e) { 594 $this->assertTrue($e instanceof base_element_struct_exception); 595 $this->assertEquals($e->errorcode, 'baseelementincorrectfinalorattribute'); 596 $this->assertEquals($e->a, 'four'); 597 } 598 599 // Try to add incorrect element to backup_optigroup 600 $bog = new backup_optigroup('test'); 601 try { 602 $bog->add_child(new backup_nested_element('test2')); 603 $this->assertTrue(false, 'base_optigroup_exception expected'); 604 } catch (\Exception $e) { 605 $this->assertTrue($e instanceof base_optigroup_exception); 606 $this->assertEquals($e->errorcode, 'optigroup_element_incorrect'); 607 $this->assertEquals($e->a, 'backup_nested_element'); 608 } 609 610 $bog = new backup_optigroup('test'); 611 try { 612 $bog->add_child('test2'); 613 $this->assertTrue(false, 'base_optigroup_exception expected'); 614 } catch (\Exception $e) { 615 $this->assertTrue($e instanceof base_optigroup_exception); 616 $this->assertEquals($e->errorcode, 'optigroup_element_incorrect'); 617 $this->assertEquals($e->a, 'non object'); 618 } 619 620 try { 621 $bog = new backup_optigroup('test', new \stdClass()); 622 $this->assertTrue(false, 'base_optigroup_exception expected'); 623 } catch (\Exception $e) { 624 $this->assertTrue($e instanceof base_optigroup_exception); 625 $this->assertEquals($e->errorcode, 'optigroup_elements_incorrect'); 626 } 627 628 // Try a wrong processor with backup_optigroup 629 $bog = new backup_optigroup('test'); 630 try { 631 $bog->process(new \stdClass()); 632 $this->assertTrue(false, 'base_element_struct_exception expected'); 633 } catch (\Exception $e) { 634 $this->assertTrue($e instanceof base_element_struct_exception); 635 $this->assertEquals($e->errorcode, 'incorrect_processor'); 636 } 637 638 // Try duplicating used elements with backup_optigroup 639 // Adding top->down 640 $bog = new backup_optigroup('test', null, true); 641 $boge1 = new backup_optigroup_element('boge1'); 642 $boge2 = new backup_optigroup_element('boge2'); 643 $ne1 = new backup_nested_element('ne1'); 644 $ne2 = new backup_nested_element('ne1'); 645 $bog->add_child($boge1); 646 $bog->add_child($boge2); 647 $boge1->add_child($ne1); 648 try { 649 $boge2->add_child($ne2); 650 $this->assertTrue(false, 'base_optigroup_exception expected'); 651 } catch (\Exception $e) { 652 $this->assertTrue($e instanceof base_optigroup_exception); 653 $this->assertEquals($e->errorcode, 'multiple_optigroup_duplicate_element'); 654 $this->assertEquals($e->a, 'ne1'); 655 } 656 // Adding down->top 657 $bog = new backup_optigroup('test', null, true); 658 $boge1 = new backup_optigroup_element('boge1'); 659 $boge2 = new backup_optigroup_element('boge2'); 660 $ne1 = new backup_nested_element('ne1'); 661 $ne2 = new backup_nested_element('ne1'); 662 $boge1->add_child($ne1); 663 $boge2->add_child($ne2); 664 $bog->add_child($boge1); 665 try { 666 $bog->add_child($boge2); 667 $this->assertTrue(false, 'base_element_struct_exception expected'); 668 } catch (\Exception $e) { 669 $this->assertTrue($e instanceof base_element_struct_exception); 670 $this->assertEquals($e->errorcode, 'baseelementexisting'); 671 $this->assertEquals($e->a, 'ne1'); 672 } 673 } 674 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body