Differences Between: [Versions 310 and 311] [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403] [Versions 39 and 310]
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 /** 18 * File containing tests for the course class. 19 * 20 * @package tool_uploadcourse 21 * @copyright 2013 Frédéric Massart 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 defined('MOODLE_INTERNAL') || die(); 26 27 global $CFG; 28 29 /** 30 * Course test case. 31 * 32 * @package tool_uploadcourse 33 * @copyright 2013 Frédéric Massart 34 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or late 35 */ 36 class tool_uploadcourse_course_testcase extends advanced_testcase { 37 38 public function test_proceed_without_prepare() { 39 $this->resetAfterTest(true); 40 $mode = tool_uploadcourse_processor::MODE_CREATE_NEW; 41 $updatemode = tool_uploadcourse_processor::UPDATE_NOTHING; 42 $data = array(); 43 $co = new tool_uploadcourse_course($mode, $updatemode, $data); 44 $this->expectException(coding_exception::class); 45 $co->proceed(); 46 } 47 48 public function test_proceed_when_prepare_failed() { 49 $this->resetAfterTest(true); 50 $mode = tool_uploadcourse_processor::MODE_CREATE_NEW; 51 $updatemode = tool_uploadcourse_processor::UPDATE_NOTHING; 52 $data = array(); 53 $co = new tool_uploadcourse_course($mode, $updatemode, $data); 54 $this->assertFalse($co->prepare()); 55 $this->expectException(moodle_exception::class); 56 $co->proceed(); 57 } 58 59 public function test_proceed_when_already_started() { 60 $this->resetAfterTest(true); 61 $mode = tool_uploadcourse_processor::MODE_CREATE_NEW; 62 $updatemode = tool_uploadcourse_processor::UPDATE_NOTHING; 63 $data = array('shortname' => 'test', 'fullname' => 'New course', 'summary' => 'New', 'category' => 1); 64 $co = new tool_uploadcourse_course($mode, $updatemode, $data); 65 $this->assertTrue($co->prepare()); 66 $co->proceed(); 67 $this->expectException('coding_exception'); 68 $co->proceed(); 69 } 70 71 public function test_invalid_shortname() { 72 $this->resetAfterTest(true); 73 $mode = tool_uploadcourse_processor::MODE_CREATE_NEW; 74 $updatemode = tool_uploadcourse_processor::UPDATE_NOTHING; 75 $data = array('shortname' => '<invalid>', 'fullname' => 'New course', 'summary' => 'New', 'category' => 1); 76 $co = new tool_uploadcourse_course($mode, $updatemode, $data); 77 $this->assertFalse($co->prepare()); 78 $this->assertArrayHasKey('invalidshortname', $co->get_errors()); 79 } 80 81 public function test_invalid_shortname_too_long() { 82 $this->resetAfterTest(); 83 84 $mode = tool_uploadcourse_processor::MODE_CREATE_NEW; 85 $updatemode = tool_uploadcourse_processor::UPDATE_NOTHING; 86 87 $upload = new tool_uploadcourse_course($mode, $updatemode, [ 88 'category' => 1, 89 'fullname' => 'New course', 90 'shortname' => str_repeat('X', 2000), 91 ]); 92 93 $this->assertFalse($upload->prepare()); 94 $this->assertArrayHasKey('invalidshortnametoolong', $upload->get_errors()); 95 } 96 97 public function test_invalid_fullname_too_long() { 98 $this->resetAfterTest(); 99 100 $mode = tool_uploadcourse_processor::MODE_CREATE_NEW; 101 $updatemode = tool_uploadcourse_processor::UPDATE_NOTHING; 102 103 $upload = new tool_uploadcourse_course($mode, $updatemode, [ 104 'category' => 1, 105 'fullname' => str_repeat('X', 2000), 106 ]); 107 108 $this->assertFalse($upload->prepare()); 109 $this->assertArrayHasKey('invalidfullnametoolong', $upload->get_errors()); 110 } 111 112 public function test_invalid_visibility() { 113 $this->resetAfterTest(true); 114 $mode = tool_uploadcourse_processor::MODE_CREATE_NEW; 115 $updatemode = tool_uploadcourse_processor::UPDATE_NOTHING; 116 $data = array('shortname' => 'test', 'fullname' => 'New course', 'summary' => 'New', 'category' => 1, 'visible' => 2); 117 $co = new tool_uploadcourse_course($mode, $updatemode, $data); 118 $this->assertFalse($co->prepare()); 119 $this->assertArrayHasKey('invalidvisibilitymode', $co->get_errors()); 120 } 121 122 public function test_create() { 123 global $DB; 124 $this->resetAfterTest(true); 125 126 // Existing course. 127 $c1 = $this->getDataGenerator()->create_course(array('shortname' => 'c1', 'summary' => 'Yay!')); 128 $this->assertTrue($DB->record_exists('course', array('shortname' => 'c1'))); 129 130 $updatemode = tool_uploadcourse_processor::UPDATE_NOTHING; 131 132 // Try to add a new course. 133 $mode = tool_uploadcourse_processor::MODE_CREATE_NEW; 134 $data = array('shortname' => 'newcourse', 'fullname' => 'New course', 'summary' => 'New', 'category' => 1); 135 $co = new tool_uploadcourse_course($mode, $updatemode, $data); 136 $this->assertTrue($co->prepare()); 137 $this->assertFalse($DB->record_exists('course', array('shortname' => 'newcourse'))); 138 $co->proceed(); 139 $course = $DB->get_record('course', array('shortname' => 'newcourse'), '*', MUST_EXIST); 140 $this->assertEquals(0, course_get_format($course)->get_course()->coursedisplay); 141 142 // Try to add a new course, that already exists. 143 $coursecount = $DB->count_records('course', array()); 144 $mode = tool_uploadcourse_processor::MODE_CREATE_NEW; 145 $data = array('shortname' => 'c1', 'fullname' => 'C1FN', 'summary' => 'C1', 'category' => 1); 146 $co = new tool_uploadcourse_course($mode, $updatemode, $data); 147 $this->assertFalse($co->prepare()); 148 $this->assertArrayHasKey('courseexistsanduploadnotallowed', $co->get_errors()); 149 $this->assertEquals($coursecount, $DB->count_records('course', array())); 150 $this->assertNotEquals('C1', $DB->get_field_select('course', 'summary', 'shortname = :s', array('s' => 'c1'))); 151 152 // Try to add new with shortname incrementation. 153 $mode = tool_uploadcourse_processor::MODE_CREATE_ALL; 154 $data = array('shortname' => 'c1', 'fullname' => 'C1FN', 'summary' => 'C1', 'category' => 1); 155 $co = new tool_uploadcourse_course($mode, $updatemode, $data); 156 $this->assertTrue($co->prepare()); 157 $co->proceed(); 158 $this->assertTrue($DB->record_exists('course', array('shortname' => 'c2'))); 159 160 // Add a new course with non-default course format option. 161 $mode = tool_uploadcourse_processor::MODE_CREATE_NEW; 162 $data = array('shortname' => 'c3', 'fullname' => 'C3', 'summary' => 'New c3', 'category' => 1, 163 'format' => 'weeks', 'coursedisplay' => 1); 164 $co = new tool_uploadcourse_course($mode, $updatemode, $data); 165 $this->assertTrue($co->prepare()); 166 $co->proceed(); 167 $course = $DB->get_record('course', array('shortname' => 'c3'), '*', MUST_EXIST); 168 $this->assertEquals(1, course_get_format($course)->get_course()->coursedisplay); 169 } 170 171 public function test_create_with_sections() { 172 global $DB; 173 $this->resetAfterTest(true); 174 $updatemode = tool_uploadcourse_processor::UPDATE_NOTHING; 175 $defaultnumsections = get_config('moodlecourse', 'numsections'); 176 177 // Add new course, make sure default number of sections is created. 178 $mode = tool_uploadcourse_processor::MODE_CREATE_NEW; 179 $data = array('shortname' => 'newcourse1', 'fullname' => 'New course1', 'format' => 'topics', 'category' => 1); 180 $co = new tool_uploadcourse_course($mode, $updatemode, $data); 181 $this->assertTrue($co->prepare()); 182 $co->proceed(); 183 $courseid = $DB->get_field('course', 'id', array('shortname' => 'newcourse1')); 184 $this->assertNotEmpty($courseid); 185 $this->assertEquals($defaultnumsections + 1, 186 $DB->count_records('course_sections', ['course' => $courseid])); 187 188 // Add new course specifying number of sections. 189 $mode = tool_uploadcourse_processor::MODE_CREATE_NEW; 190 $data = array('shortname' => 'newcourse2', 'fullname' => 'New course2', 'format' => 'topics', 'category' => 1, 191 'numsections' => 15); 192 $co = new tool_uploadcourse_course($mode, $updatemode, $data); 193 $this->assertTrue($co->prepare()); 194 $co->proceed(); 195 $courseid = $DB->get_field('course', 'id', array('shortname' => 'newcourse2')); 196 $this->assertNotEmpty($courseid); 197 $this->assertEquals(15 + 1, 198 $DB->count_records('course_sections', ['course' => $courseid])); 199 } 200 201 public function test_delete() { 202 global $DB; 203 $this->resetAfterTest(true); 204 205 $c1 = $this->getDataGenerator()->create_course(); 206 $c2 = $this->getDataGenerator()->create_course(); 207 208 $this->assertTrue($DB->record_exists('course', array('shortname' => $c1->shortname))); 209 $this->assertFalse($DB->record_exists('course', array('shortname' => 'DoesNotExist'))); 210 211 $mode = tool_uploadcourse_processor::MODE_CREATE_OR_UPDATE; 212 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 213 214 // Try delete when option not available. 215 $importoptions = array('candelete' => false); 216 $data = array('shortname' => $c1->shortname, 'delete' => 1); 217 $co = new tool_uploadcourse_course($mode, $updatemode, $data, array(), $importoptions); 218 $this->assertFalse($co->prepare()); 219 $this->assertArrayHasKey('coursedeletionnotallowed', $co->get_errors()); 220 $this->assertTrue($DB->record_exists('course', array('shortname' => $c1->shortname))); 221 222 // Try delete when not requested. 223 $importoptions = array('candelete' => true); 224 $data = array('shortname' => $c1->shortname, 'delete' => 0); 225 $co = new tool_uploadcourse_course($mode, $updatemode, $data, array(), $importoptions); 226 $this->assertTrue($co->prepare()); 227 $co->proceed(); 228 $this->assertTrue($DB->record_exists('course', array('shortname' => $c1->shortname))); 229 230 // Try delete when requested. 231 $importoptions = array('candelete' => true); 232 $data = array('shortname' => $c1->shortname, 'delete' => 1); 233 $co = new tool_uploadcourse_course($mode, $updatemode, $data, array(), $importoptions); 234 $this->assertTrue($co->prepare()); 235 $co->proceed(); 236 $this->assertFalse($DB->record_exists('course', array('shortname' => $c1->shortname))); 237 $this->assertTrue($DB->record_exists('course', array('shortname' => $c2->shortname))); 238 239 // Try deleting non-existing record, this should not fail. 240 $data = array('shortname' => 'DoesNotExist', 'delete' => 1); 241 $co = new tool_uploadcourse_course($mode, $updatemode, $data, array(), $importoptions); 242 $this->assertFalse($co->prepare()); 243 $this->assertArrayHasKey('cannotdeletecoursenotexist', $co->get_errors()); 244 } 245 246 public function test_update() { 247 global $DB; 248 $this->resetAfterTest(true); 249 250 $c1 = $this->getDataGenerator()->create_course(array('shortname' => 'c1')); 251 252 // Try to update with existing shortnames, not allowing creation, and updating nothing. 253 $mode = tool_uploadcourse_processor::MODE_UPDATE_ONLY; 254 $updatemode = tool_uploadcourse_processor::UPDATE_NOTHING; 255 $data = array('shortname' => 'c1', 'fullname' => 'New fullname'); 256 $co = new tool_uploadcourse_course($mode, $updatemode, $data); 257 $this->assertFalse($co->prepare()); 258 $this->assertArrayHasKey('updatemodedoessettonothing', $co->get_errors()); 259 260 // Try to update with non-existing shortnames. 261 $mode = tool_uploadcourse_processor::MODE_UPDATE_ONLY; 262 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 263 $data = array('shortname' => 'DoesNotExist', 'fullname' => 'New fullname'); 264 $co = new tool_uploadcourse_course($mode, $updatemode, $data); 265 $this->assertFalse($co->prepare()); 266 $this->assertArrayHasKey('coursedoesnotexistandcreatenotallowed', $co->get_errors()); 267 268 // Try a proper update. 269 $mode = tool_uploadcourse_processor::MODE_UPDATE_ONLY; 270 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 271 $data = array('shortname' => 'c1', 'fullname' => 'New fullname'); 272 $co = new tool_uploadcourse_course($mode, $updatemode, $data); 273 $this->assertTrue($co->prepare()); 274 $co->proceed(); 275 $this->assertEquals('New fullname', $DB->get_field_select('course', 'fullname', 'shortname = :s', array('s' => 'c1'))); 276 277 // Try a proper update with defaults. 278 $mode = tool_uploadcourse_processor::MODE_UPDATE_ONLY; 279 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_OR_DEFAUTLS; 280 $data = array('shortname' => 'c1', 'fullname' => 'Another fullname'); 281 $defaults = array('fullname' => 'Not this one', 'summary' => 'Awesome summary'); 282 $co = new tool_uploadcourse_course($mode, $updatemode, $data, $defaults); 283 $this->assertTrue($co->prepare()); 284 $co->proceed(); 285 $this->assertEquals('Another fullname', $DB->get_field_select('course', 'fullname', 'shortname = :s', array('s' => 'c1'))); 286 $this->assertEquals('Awesome summary', $DB->get_field_select('course', 'summary', 'shortname = :s', array('s' => 'c1'))); 287 288 // Try a proper update missing only. 289 $mode = tool_uploadcourse_processor::MODE_UPDATE_ONLY; 290 $updatemode = tool_uploadcourse_processor::UPDATE_MISSING_WITH_DATA_OR_DEFAUTLS; 291 $DB->set_field('course', 'summary', '', array('shortname' => 'c1')); 292 $this->assertEquals('', $DB->get_field_select('course', 'summary', 'shortname = :s', array('s' => 'c1'))); 293 $data = array('shortname' => 'c1', 'summary' => 'Fill in summary'); 294 $defaults = array('summary' => 'Do not use this summary'); 295 $co = new tool_uploadcourse_course($mode, $updatemode, $data, $defaults); 296 $this->assertTrue($co->prepare()); 297 $co->proceed(); 298 $this->assertEquals('Fill in summary', $DB->get_field_select('course', 'summary', 'shortname = :s', array('s' => 'c1'))); 299 300 // Try a proper update missing only using defaults. 301 $mode = tool_uploadcourse_processor::MODE_UPDATE_ONLY; 302 $updatemode = tool_uploadcourse_processor::UPDATE_MISSING_WITH_DATA_OR_DEFAUTLS; 303 $DB->set_field('course', 'summary', '', array('shortname' => 'c1')); 304 $this->assertEquals('', $DB->get_field_select('course', 'summary', 'shortname = :s', array('s' => 'c1'))); 305 $data = array('shortname' => 'c1'); 306 $defaults = array('summary' => 'Use this summary'); 307 $co = new tool_uploadcourse_course($mode, $updatemode, $data, $defaults); 308 $this->assertTrue($co->prepare()); 309 $co->proceed(); 310 $this->assertEquals('Use this summary', $DB->get_field_select('course', 'summary', 'shortname = :s', array('s' => 'c1'))); 311 312 // Update course format option. 313 $mode = tool_uploadcourse_processor::MODE_UPDATE_ONLY; 314 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 315 $data = array('shortname' => 'c1', 'coursedisplay' => 1); 316 $co = new tool_uploadcourse_course($mode, $updatemode, $data); 317 $this->assertTrue($co->prepare()); 318 $co->proceed(); 319 $course = $DB->get_record('course', array('shortname' => 'c1'), '*', MUST_EXIST); 320 $this->assertEquals(1, course_get_format($course)->get_course()->coursedisplay); 321 } 322 323 public function test_data_saved() { 324 global $DB; 325 $this->resetAfterTest(true); 326 327 $this->setAdminUser(); // To avoid warnings related to 'moodle/course:setforcedlanguage' capability check. 328 329 // Create. 330 $mode = tool_uploadcourse_processor::MODE_CREATE_NEW; 331 $updatemode = tool_uploadcourse_processor::UPDATE_NOTHING; 332 $data = array( 333 'shortname' => 'c1', 334 'fullname' => 'Fullname', 335 'category' => '1', 336 'visible' => '0', 337 'idnumber' => '123abc', 338 'summary' => 'Summary', 339 'format' => 'topics', 340 'theme' => 'afterburner', 341 'lang' => 'en', 342 'newsitems' => '7', 343 'showgrades' => '0', 344 'showreports' => '1', 345 'legacyfiles' => '1', 346 'maxbytes' => '1234', 347 'groupmode' => '2', 348 'groupmodeforce' => '1', 349 'enablecompletion' => '1', 350 'tags' => 'Cat, Dog', 351 352 'role_teacher' => 'Knight', 353 'role_manager' => 'Jedi', 354 355 'enrolment_1' => 'guest', 356 'enrolment_2' => 'self', 357 'enrolment_2_roleid' => '1', 358 'enrolment_3' => 'manual', 359 'enrolment_3_disable' => '1', 360 ); 361 362 // There should be a start date if there is a end date. 363 $data['enddate'] = '7 June 1990'; 364 $co = new tool_uploadcourse_course($mode, $updatemode, $data); 365 $this->assertFalse($co->prepare()); 366 $this->assertArrayHasKey('nostartdatenoenddate', $co->get_errors()); 367 368 $data['startdate'] = '8 June 1990'; 369 $co = new tool_uploadcourse_course($mode, $updatemode, $data); 370 $this->assertFalse($co->prepare()); 371 $this->assertArrayHasKey('enddatebeforestartdate', $co->get_errors()); 372 373 // They are correct now. 374 $data['enddate'] = '18 June 1990'; 375 376 $this->assertFalse($DB->record_exists('course', array('shortname' => 'c1'))); 377 $co = new tool_uploadcourse_course($mode, $updatemode, $data); 378 $this->assertTrue($co->prepare()); 379 $co->proceed(); 380 $this->assertTrue($DB->record_exists('course', array('shortname' => 'c1'))); 381 $course = $DB->get_record('course', array('shortname' => 'c1')); 382 $ctx = context_course::instance($course->id); 383 384 $this->assertEquals($data['fullname'], $course->fullname); 385 $this->assertEquals($data['category'], $course->category); 386 $this->assertEquals($data['visible'], $course->visible); 387 $this->assertEquals(mktime(0, 0, 0, 6, 8, 1990), $course->startdate); 388 $this->assertEquals(mktime(0, 0, 0, 6, 18, 1990), $course->enddate); 389 $this->assertEquals($data['idnumber'], $course->idnumber); 390 $this->assertEquals($data['summary'], $course->summary); 391 $this->assertEquals($data['format'], $course->format); 392 $this->assertEquals($data['theme'], $course->theme); 393 $this->assertEquals($data['lang'], $course->lang); 394 $this->assertEquals($data['newsitems'], $course->newsitems); 395 $this->assertEquals($data['showgrades'], $course->showgrades); 396 $this->assertEquals($data['showreports'], $course->showreports); 397 $this->assertEquals($data['legacyfiles'], $course->legacyfiles); 398 $this->assertEquals($data['maxbytes'], $course->maxbytes); 399 $this->assertEquals($data['groupmode'], $course->groupmode); 400 $this->assertEquals($data['groupmodeforce'], $course->groupmodeforce); 401 $this->assertEquals($data['enablecompletion'], $course->enablecompletion); 402 $this->assertEquals($data['tags'], join(', ', core_tag_tag::get_item_tags_array('core', 'course', $course->id))); 403 404 // Roles. 405 $roleids = array(); 406 $roles = get_all_roles(); 407 foreach ($roles as $role) { 408 $roleids[$role->shortname] = $role->id; 409 } 410 $this->assertEquals('Knight', $DB->get_field_select('role_names', 'name', 411 'roleid = :roleid AND contextid = :ctxid', array('ctxid' => $ctx->id, 'roleid' => $roleids['teacher']))); 412 $this->assertEquals('Jedi', $DB->get_field_select('role_names', 'name', 413 'roleid = :roleid AND contextid = :ctxid', array('ctxid' => $ctx->id, 'roleid' => $roleids['manager']))); 414 415 // Enrolment methods. 416 $enroldata = array(); 417 $instances = enrol_get_instances($course->id, false); 418 $this->assertCount(3, $instances); 419 foreach ($instances as $instance) { 420 $enroldata[$instance->enrol] = $instance; 421 } 422 423 $this->assertNotEmpty($enroldata['guest']); 424 $this->assertEquals(ENROL_INSTANCE_ENABLED, $enroldata['guest']->status); 425 $this->assertNotEmpty($enroldata['self']); 426 $this->assertEquals($data['enrolment_2_roleid'], $enroldata['self']->roleid); 427 $this->assertEquals(ENROL_INSTANCE_ENABLED, $enroldata['self']->status); 428 $this->assertNotEmpty($enroldata['manual']); 429 $this->assertEquals(ENROL_INSTANCE_DISABLED, $enroldata['manual']->status); 430 431 // Update existing course. 432 $cat = $this->getDataGenerator()->create_category(); 433 $mode = tool_uploadcourse_processor::MODE_UPDATE_ONLY; 434 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 435 $data = array( 436 'shortname' => 'c1', 437 'fullname' => 'Fullname 2', 438 'category' => $cat->id, 439 'visible' => '1', 440 'idnumber' => 'changeidn', 441 'summary' => 'Summary 2', 442 'format' => 'topics', 443 'theme' => 'classic', 444 'lang' => '', 445 'newsitems' => '2', 446 'showgrades' => '1', 447 'showreports' => '0', 448 'legacyfiles' => '0', 449 'maxbytes' => '4321', 450 'groupmode' => '1', 451 'groupmodeforce' => '0', 452 'enablecompletion' => '0', 453 454 'role_teacher' => 'Teacher', 455 'role_manager' => 'Manager', 456 457 'enrolment_1' => 'guest', 458 'enrolment_1_disable' => '1', 459 'enrolment_2' => 'self', 460 'enrolment_2_roleid' => '2', 461 'enrolment_3' => 'manual', 462 'enrolment_3_delete' => '1', 463 ); 464 465 $this->assertTrue($DB->record_exists('course', array('shortname' => 'c1'))); 466 467 $data['enddate'] = '31 June 1984'; 468 // Previous start and end dates are 8 and 18 June 1990. 469 $co = new tool_uploadcourse_course($mode, $updatemode, $data); 470 $this->assertFalse($co->prepare()); 471 $this->assertArrayHasKey('enddatebeforestartdate', $co->get_errors()); 472 473 $data['startdate'] = '19 June 1990'; 474 $co = new tool_uploadcourse_course($mode, $updatemode, $data); 475 $this->assertFalse($co->prepare()); 476 $this->assertArrayHasKey('enddatebeforestartdate', $co->get_errors()); 477 478 // They are correct now. 479 $data['startdate'] = '11 June 1984'; 480 481 $co = new tool_uploadcourse_course($mode, $updatemode, $data); 482 $this->assertTrue($co->prepare()); 483 $co->proceed(); 484 $course = $DB->get_record('course', array('shortname' => 'c1')); 485 $ctx = context_course::instance($course->id); 486 487 $this->assertEquals($data['fullname'], $course->fullname); 488 $this->assertEquals($data['category'], $course->category); 489 $this->assertEquals($data['visible'], $course->visible); 490 $this->assertEquals(mktime(0, 0, 0, 6, 11, 1984), $course->startdate); 491 $this->assertEquals(mktime(0, 0, 0, 6, 31, 1984), $course->enddate); 492 $this->assertEquals($data['idnumber'], $course->idnumber); 493 $this->assertEquals($data['summary'], $course->summary); 494 $this->assertEquals($data['format'], $course->format); 495 $this->assertEquals($data['theme'], $course->theme); 496 $this->assertEquals($data['lang'], $course->lang); 497 $this->assertEquals($data['newsitems'], $course->newsitems); 498 $this->assertEquals($data['showgrades'], $course->showgrades); 499 $this->assertEquals($data['showreports'], $course->showreports); 500 $this->assertEquals($data['legacyfiles'], $course->legacyfiles); 501 $this->assertEquals($data['maxbytes'], $course->maxbytes); 502 $this->assertEquals($data['groupmode'], $course->groupmode); 503 $this->assertEquals($data['groupmodeforce'], $course->groupmodeforce); 504 $this->assertEquals($data['enablecompletion'], $course->enablecompletion); 505 506 // Roles. 507 $roleids = array(); 508 $roles = get_all_roles(); 509 foreach ($roles as $role) { 510 $roleids[$role->shortname] = $role->id; 511 } 512 $this->assertEquals('Teacher', $DB->get_field_select('role_names', 'name', 513 'roleid = :roleid AND contextid = :ctxid', array('ctxid' => $ctx->id, 'roleid' => $roleids['teacher']))); 514 $this->assertEquals('Manager', $DB->get_field_select('role_names', 'name', 515 'roleid = :roleid AND contextid = :ctxid', array('ctxid' => $ctx->id, 'roleid' => $roleids['manager']))); 516 517 // Enrolment methods. 518 $enroldata = array(); 519 $instances = enrol_get_instances($course->id, false); 520 $this->assertCount(2, $instances); 521 foreach ($instances as $instance) { 522 $enroldata[$instance->enrol] = $instance; 523 } 524 525 $this->assertNotEmpty($enroldata['guest']); 526 $this->assertEquals(ENROL_INSTANCE_DISABLED, $enroldata['guest']->status); 527 $this->assertNotEmpty($enroldata['self']); 528 $this->assertEquals($data['enrolment_2_roleid'], $enroldata['self']->roleid); 529 $this->assertEquals(ENROL_INSTANCE_ENABLED, $enroldata['self']->status); 530 } 531 532 public function test_default_data_saved() { 533 global $DB; 534 $this->resetAfterTest(true); 535 536 // Create. 537 $mode = tool_uploadcourse_processor::MODE_CREATE_NEW; 538 $updatemode = tool_uploadcourse_processor::UPDATE_NOTHING; 539 $data = array( 540 'shortname' => 'c1', 541 ); 542 $defaultdata = array( 543 'fullname' => 'Fullname', 544 'category' => '1', 545 'visible' => '0', 546 'startdate' => 644803200, 547 'enddate' => 645667200, 548 'idnumber' => '123abc', 549 'summary' => 'Summary', 550 'format' => 'topics', 551 'theme' => 'afterburner', 552 'lang' => 'en', 553 'newsitems' => '7', 554 'showgrades' => '0', 555 'showreports' => '1', 556 'legacyfiles' => '1', 557 'maxbytes' => '1234', 558 'groupmode' => '2', 559 'groupmodeforce' => '1', 560 'enablecompletion' => '1', 561 ); 562 563 $this->assertFalse($DB->record_exists('course', array('shortname' => 'c1'))); 564 $co = new tool_uploadcourse_course($mode, $updatemode, $data, $defaultdata); 565 $this->assertTrue($co->prepare()); 566 $co->proceed(); 567 $this->assertTrue($DB->record_exists('course', array('shortname' => 'c1'))); 568 $course = $DB->get_record('course', array('shortname' => 'c1')); 569 $ctx = context_course::instance($course->id); 570 571 $this->assertEquals($defaultdata['fullname'], $course->fullname); 572 $this->assertEquals($defaultdata['category'], $course->category); 573 $this->assertEquals($defaultdata['visible'], $course->visible); 574 $this->assertEquals($defaultdata['startdate'], $course->startdate); 575 $this->assertEquals($defaultdata['enddate'], $course->enddate); 576 $this->assertEquals($defaultdata['idnumber'], $course->idnumber); 577 $this->assertEquals($defaultdata['summary'], $course->summary); 578 $this->assertEquals($defaultdata['format'], $course->format); 579 $this->assertEquals($defaultdata['theme'], $course->theme); 580 $this->assertEquals($defaultdata['lang'], $course->lang); 581 $this->assertEquals($defaultdata['newsitems'], $course->newsitems); 582 $this->assertEquals($defaultdata['showgrades'], $course->showgrades); 583 $this->assertEquals($defaultdata['showreports'], $course->showreports); 584 $this->assertEquals($defaultdata['legacyfiles'], $course->legacyfiles); 585 $this->assertEquals($defaultdata['maxbytes'], $course->maxbytes); 586 $this->assertEquals($defaultdata['groupmode'], $course->groupmode); 587 $this->assertEquals($defaultdata['groupmodeforce'], $course->groupmodeforce); 588 $this->assertEquals($defaultdata['enablecompletion'], $course->enablecompletion); 589 590 // Update. 591 $cat = $this->getDataGenerator()->create_category(); 592 $mode = tool_uploadcourse_processor::MODE_UPDATE_ONLY; 593 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_OR_DEFAUTLS; 594 $data = array( 595 'shortname' => 'c1', 596 ); 597 $defaultdata = array( 598 'fullname' => 'Fullname 2', 599 'category' => $cat->id, 600 'visible' => '1', 601 'startdate' => 455760000, 602 'enddate' => 457488000, 603 'idnumber' => 'changedid', 604 'summary' => 'Summary 2', 605 'format' => 'topics', 606 'theme' => 'classic', 607 'lang' => '', 608 'newsitems' => '2', 609 'showgrades' => '1', 610 'showreports' => '0', 611 'legacyfiles' => '0', 612 'maxbytes' => '1111', 613 'groupmode' => '1', 614 'groupmodeforce' => '0', 615 'enablecompletion' => '0', 616 ); 617 618 $this->assertTrue($DB->record_exists('course', array('shortname' => 'c1'))); 619 $co = new tool_uploadcourse_course($mode, $updatemode, $data, $defaultdata); 620 $this->assertTrue($co->prepare()); 621 $co->proceed(); 622 $this->assertTrue($DB->record_exists('course', array('shortname' => 'c1'))); 623 $course = $DB->get_record('course', array('shortname' => 'c1')); 624 $ctx = context_course::instance($course->id); 625 626 $this->assertEquals($defaultdata['fullname'], $course->fullname); 627 $this->assertEquals($defaultdata['category'], $course->category); 628 $this->assertEquals($defaultdata['visible'], $course->visible); 629 $this->assertEquals($defaultdata['startdate'], $course->startdate); 630 $this->assertEquals($defaultdata['enddate'], $course->enddate); 631 $this->assertEquals($defaultdata['idnumber'], $course->idnumber); 632 $this->assertEquals($defaultdata['summary'], $course->summary); 633 $this->assertEquals($defaultdata['format'], $course->format); 634 $this->assertEquals($defaultdata['theme'], $course->theme); 635 $this->assertEquals($defaultdata['lang'], $course->lang); 636 $this->assertEquals($defaultdata['newsitems'], $course->newsitems); 637 $this->assertEquals($defaultdata['showgrades'], $course->showgrades); 638 $this->assertEquals($defaultdata['showreports'], $course->showreports); 639 $this->assertEquals($defaultdata['legacyfiles'], $course->legacyfiles); 640 $this->assertEquals($defaultdata['maxbytes'], $course->maxbytes); 641 $this->assertEquals($defaultdata['groupmode'], $course->groupmode); 642 $this->assertEquals($defaultdata['groupmodeforce'], $course->groupmodeforce); 643 $this->assertEquals($defaultdata['enablecompletion'], $course->enablecompletion); 644 } 645 646 public function test_rename() { 647 global $DB; 648 $this->resetAfterTest(true); 649 650 $c1 = $this->getDataGenerator()->create_course(array('shortname' => 'c1')); 651 $c2 = $this->getDataGenerator()->create_course(array('shortname' => 'c2')); 652 653 // Cannot rename when creating. 654 $mode = tool_uploadcourse_processor::MODE_CREATE_NEW; 655 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 656 $importoptions = array('canrename' => true); 657 $data = array('shortname' => 'c1', 'rename' => 'newshortname'); 658 $co = new tool_uploadcourse_course($mode, $updatemode, $data, array(), $importoptions); 659 $this->assertFalse($co->prepare()); 660 $this->assertArrayHasKey('courseexistsanduploadnotallowed', $co->get_errors()); 661 662 // Cannot rename when creating. 663 $mode = tool_uploadcourse_processor::MODE_CREATE_ALL; 664 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 665 $importoptions = array('canrename' => true); 666 $data = array('shortname' => 'c1', 'rename' => 'newshortname', 'category' => 1, 'summary' => 'S', 'fullname' => 'F'); 667 $co = new tool_uploadcourse_course($mode, $updatemode, $data, array(), $importoptions); 668 $this->assertFalse($co->prepare()); 669 $this->assertArrayHasKey('canonlyrenameinupdatemode', $co->get_errors()); 670 671 // Error when not allowed to rename the course. 672 $mode = tool_uploadcourse_processor::MODE_UPDATE_ONLY; 673 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 674 $importoptions = array('canrename' => false); 675 $data = array('shortname' => 'c1', 'rename' => 'newshortname'); 676 $co = new tool_uploadcourse_course($mode, $updatemode, $data, array(), $importoptions); 677 $this->assertFalse($co->prepare()); 678 $this->assertArrayHasKey('courserenamingnotallowed', $co->get_errors()); 679 680 // Can rename when updating. 681 $mode = tool_uploadcourse_processor::MODE_CREATE_OR_UPDATE; 682 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 683 $importoptions = array('canrename' => true); 684 $data = array('shortname' => 'c1', 'rename' => 'newshortname'); 685 $co = new tool_uploadcourse_course($mode, $updatemode, $data, array(), $importoptions); 686 $this->assertTrue($co->prepare()); 687 $co->proceed(); 688 $this->assertEquals('newshortname', $DB->get_field_select('course', 'shortname', 'id = :id', array('id' => $c1->id))); 689 690 // Can rename when updating. 691 $mode = tool_uploadcourse_processor::MODE_UPDATE_ONLY; 692 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 693 $importoptions = array('canrename' => true); 694 $data = array('shortname' => 'newshortname', 'rename' => 'newshortname2'); 695 $co = new tool_uploadcourse_course($mode, $updatemode, $data, array(), $importoptions); 696 $this->assertTrue($co->prepare()); 697 $co->proceed(); 698 $this->assertEquals('newshortname2', $DB->get_field_select('course', 'shortname', 'id = :id', array('id' => $c1->id))); 699 700 // Error when course does not exist. 701 $mode = tool_uploadcourse_processor::MODE_CREATE_OR_UPDATE; 702 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 703 $importoptions = array('canrename' => true); 704 $data = array('shortname' => 'DoesNotExist', 'rename' => 'c1', 'category' => 1, 'summary' => 'S', 'fullname' => 'F'); 705 $co = new tool_uploadcourse_course($mode, $updatemode, $data, array(), $importoptions); 706 $this->assertFalse($co->prepare()); 707 $this->assertArrayHasKey('cannotrenamecoursenotexist', $co->get_errors()); 708 709 // Renaming still updates the other values. 710 $mode = tool_uploadcourse_processor::MODE_CREATE_OR_UPDATE; 711 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_OR_DEFAUTLS; 712 $importoptions = array('canrename' => true); 713 $data = array('shortname' => 'newshortname2', 'rename' => 'c1', 'fullname' => 'Another fullname!'); 714 $defaultdata = array('summary' => 'New summary!'); 715 $co = new tool_uploadcourse_course($mode, $updatemode, $data, $defaultdata, $importoptions); 716 $this->assertTrue($co->prepare()); 717 $co->proceed(); 718 $this->assertEquals('c1', $DB->get_field_select('course', 'shortname', 'id = :id', array('id' => $c1->id))); 719 $this->assertEquals('New summary!', $DB->get_field_select('course', 'summary', 'id = :id', array('id' => $c1->id))); 720 $this->assertEquals('Another fullname!', $DB->get_field_select('course', 'fullname', 'id = :id', array('id' => $c1->id))); 721 722 // Renaming with invalid shortname. 723 $mode = tool_uploadcourse_processor::MODE_CREATE_OR_UPDATE; 724 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 725 $importoptions = array('canrename' => true); 726 $data = array('shortname' => 'c1', 'rename' => '<span>invalid</span>'); 727 $co = new tool_uploadcourse_course($mode, $updatemode, $data, array(), $importoptions); 728 $this->assertFalse($co->prepare()); 729 $this->assertArrayHasKey('invalidshortname', $co->get_errors()); 730 731 // Renaming with invalid shortname. 732 $mode = tool_uploadcourse_processor::MODE_CREATE_OR_UPDATE; 733 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 734 $importoptions = array('canrename' => true); 735 $data = array('shortname' => 'c1', 'rename' => 'c2'); 736 $co = new tool_uploadcourse_course($mode, $updatemode, $data, array(), $importoptions); 737 $this->assertFalse($co->prepare()); 738 $this->assertArrayHasKey('cannotrenameshortnamealreadyinuse', $co->get_errors()); 739 } 740 741 public function test_restore_course() { 742 global $DB; 743 $this->resetAfterTest(true); 744 $this->setAdminUser(); 745 746 $c1 = $this->getDataGenerator()->create_course(); 747 $c1f1 = $this->getDataGenerator()->create_module('forum', array('course' => $c1->id)); 748 749 $mode = tool_uploadcourse_processor::MODE_CREATE_NEW; 750 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 751 $data = array('shortname' => 'A1', 'templatecourse' => $c1->shortname, 'summary' => 'A', 'category' => 1, 752 'fullname' => 'A1'); 753 $co = new tool_uploadcourse_course($mode, $updatemode, $data); 754 $this->assertTrue($co->prepare()); 755 $co->proceed(); 756 $course = $DB->get_record('course', array('shortname' => 'A1')); 757 $modinfo = get_fast_modinfo($course); 758 $found = false; 759 foreach ($modinfo->get_cms() as $cmid => $cm) { 760 if ($cm->modname == 'forum' && $cm->name == $c1f1->name) { 761 $found = true; 762 break; 763 } 764 } 765 $this->assertTrue($found); 766 767 // Restoring twice from the same course should work. 768 $data = array('shortname' => 'B1', 'templatecourse' => $c1->shortname, 'summary' => 'B', 'category' => 1, 769 'fullname' => 'B1'); 770 $co = new tool_uploadcourse_course($mode, $updatemode, $data); 771 $this->assertTrue($co->prepare()); 772 $co->proceed(); 773 $course = $DB->get_record('course', array('shortname' => 'B1')); 774 $modinfo = get_fast_modinfo($course); 775 $found = false; 776 foreach ($modinfo->get_cms() as $cmid => $cm) { 777 if ($cm->modname == 'forum' && $cm->name == $c1f1->name) { 778 $found = true; 779 break; 780 } 781 } 782 $this->assertTrue($found); 783 } 784 785 public function test_restore_file() { 786 global $DB; 787 $this->resetAfterTest(true); 788 $this->setAdminUser(); 789 790 $c1 = $this->getDataGenerator()->create_course(); 791 $c1f1 = $this->getDataGenerator()->create_module('forum', array('course' => $c1->id)); 792 793 // Restore from a file, checking that the file takes priority over the templatecourse. 794 $mode = tool_uploadcourse_processor::MODE_CREATE_NEW; 795 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 796 $data = array('shortname' => 'A1', 'backupfile' => __DIR__ . '/fixtures/backup.mbz', 797 'summary' => 'A', 'category' => 1, 'fullname' => 'A1', 'templatecourse' => $c1->shortname); 798 $co = new tool_uploadcourse_course($mode, $updatemode, $data); 799 $this->assertTrue($co->prepare()); 800 $co->proceed(); 801 $course = $DB->get_record('course', array('shortname' => 'A1')); 802 $modinfo = get_fast_modinfo($course); 803 $found = false; 804 foreach ($modinfo->get_cms() as $cmid => $cm) { 805 if ($cm->modname == 'glossary' && $cm->name == 'Imported Glossary') { 806 $found = true; 807 } else if ($cm->modname == 'forum' && $cm->name == $c1f1->name) { 808 // We should not find this! 809 $this->assertTrue(false); 810 } 811 } 812 $this->assertTrue($found); 813 814 // Restoring twice from the same file should work. 815 $data = array('shortname' => 'B1', 'backupfile' => __DIR__ . '/fixtures/backup.mbz', 816 'summary' => 'B', 'category' => 1, 'fullname' => 'B1'); 817 $co = new tool_uploadcourse_course($mode, $updatemode, $data); 818 $this->assertTrue($co->prepare()); 819 $co->proceed(); 820 $course = $DB->get_record('course', array('shortname' => 'B1')); 821 $modinfo = get_fast_modinfo($course); 822 $found = false; 823 foreach ($modinfo->get_cms() as $cmid => $cm) { 824 if ($cm->modname == 'glossary' && $cm->name == 'Imported Glossary') { 825 $found = true; 826 } else if ($cm->modname == 'forum' && $cm->name == $c1f1->name) { 827 // We should not find this! 828 $this->assertTrue(false); 829 } 830 } 831 $this->assertTrue($found); 832 } 833 834 /** 835 * Test that specifying course template respects default restore settings 836 */ 837 public function test_restore_file_settings() { 838 global $DB; 839 $this->resetAfterTest(true); 840 $this->setAdminUser(); 841 842 // Set admin config setting so that activities are not restored by default. 843 set_config('restore_general_activities', 0, 'restore'); 844 845 $c1 = $this->getDataGenerator()->create_course(); 846 847 $mode = tool_uploadcourse_processor::MODE_CREATE_NEW; 848 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 849 $data = array('shortname' => 'A1', 'backupfile' => __DIR__ . '/fixtures/backup.mbz', 850 'summary' => 'A', 'category' => 1, 'fullname' => 'A1', 'templatecourse' => $c1->shortname); 851 $co = new tool_uploadcourse_course($mode, $updatemode, $data); 852 $this->assertTrue($co->prepare()); 853 $co->proceed(); 854 $course = $DB->get_record('course', array('shortname' => 'A1')); 855 856 // Make sure the glossary is not restored. 857 $modinfo = get_fast_modinfo($course); 858 $this->assertEmpty($modinfo->get_instances_of('glossary')); 859 } 860 861 public function test_restore_invalid_file() { 862 $this->resetAfterTest(); 863 864 // Restore from a non-existing file should not be allowed. 865 $mode = tool_uploadcourse_processor::MODE_CREATE_NEW; 866 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 867 $data = array('shortname' => 'A1', 'backupfile' => '/lead/no/where', 868 'category' => 1, 'fullname' => 'A1'); 869 $co = new tool_uploadcourse_course($mode, $updatemode, $data); 870 $this->assertFalse($co->prepare()); 871 $this->assertArrayHasKey('cannotreadbackupfile', $co->get_errors()); 872 873 // Restore from an invalid file should not be allowed. 874 $mode = tool_uploadcourse_processor::MODE_CREATE_NEW; 875 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 876 $data = array('shortname' => 'A1', 'backupfile' => __FILE__, 877 'category' => 1, 'fullname' => 'A1'); 878 $co = new tool_uploadcourse_course($mode, $updatemode, $data); 879 880 $this->assertFalse($co->prepare()); 881 $this->assertArrayHasKey('invalidbackupfile', $co->get_errors()); 882 883 // Zip packer throws a debugging message, this assertion is only here to prevent 884 // the message from being displayed. 885 $this->assertDebuggingCalled(); 886 } 887 888 public function test_restore_invalid_course() { 889 $this->resetAfterTest(); 890 891 // Restore from an invalid file should not be allowed. 892 $mode = tool_uploadcourse_processor::MODE_CREATE_NEW; 893 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 894 $data = array('shortname' => 'A1', 'templatecourse' => 'iamnotavalidcourse', 895 'category' => 1, 'fullname' => 'A1'); 896 $co = new tool_uploadcourse_course($mode, $updatemode, $data); 897 $this->assertFalse($co->prepare()); 898 $this->assertArrayHasKey('coursetorestorefromdoesnotexist', $co->get_errors()); 899 } 900 901 /** 902 * Testing the reset on groups, group members and enrolments. 903 */ 904 public function test_reset() { 905 global $DB; 906 $this->resetAfterTest(true); 907 908 $c1 = $this->getDataGenerator()->create_course(); 909 $c1ctx = context_course::instance($c1->id); 910 $studentrole = $DB->get_record('role', array('shortname' => 'student')); 911 $teacherrole = $DB->get_record('role', array('shortname' => 'teacher')); 912 913 $u1 = $this->getDataGenerator()->create_user(); 914 $this->getDataGenerator()->enrol_user($u1->id, $c1->id, $studentrole->id); 915 $this->assertCount(1, get_enrolled_users($c1ctx)); 916 917 $g1 = $this->getDataGenerator()->create_group(array('courseid' => $c1->id)); 918 $this->getDataGenerator()->create_group_member(array('groupid' => $g1->id, 'userid' => $u1->id)); 919 $this->assertEquals(1, $DB->count_records('groups', array('courseid' => $c1->id))); 920 $this->assertTrue($DB->record_exists('groups_members', array('groupid' => $g1->id, 'userid' => $u1->id))); 921 922 // Wrong mode. 923 $mode = tool_uploadcourse_processor::MODE_CREATE_NEW; 924 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 925 $data = array('shortname' => 'DoesNotExist', 'reset' => '1', 'summary' => 'summary', 'fullname' => 'FN', 'category' => 1); 926 $co = new tool_uploadcourse_course($mode, $updatemode, $data); 927 $this->assertFalse($co->prepare()); 928 $this->assertArrayHasKey('canonlyresetcourseinupdatemode', $co->get_errors()); 929 $this->assertTrue($DB->record_exists('groups', array('id' => $g1->id))); 930 $this->assertTrue($DB->record_exists('groups_members', array('groupid' => $g1->id, 'userid' => $u1->id))); 931 $this->assertCount(1, get_enrolled_users($c1ctx)); 932 933 // Reset not allowed. 934 $mode = tool_uploadcourse_processor::MODE_UPDATE_ONLY; 935 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 936 $data = array('shortname' => $c1->shortname, 'reset' => '1'); 937 $importoptions = array('canreset' => false); 938 $co = new tool_uploadcourse_course($mode, $updatemode, $data, array(), $importoptions); 939 $this->assertFalse($co->prepare()); 940 $this->assertArrayHasKey('courseresetnotallowed', $co->get_errors()); 941 $this->assertTrue($DB->record_exists('groups', array('id' => $g1->id))); 942 $this->assertTrue($DB->record_exists('groups_members', array('groupid' => $g1->id, 'userid' => $u1->id))); 943 $this->assertCount(1, get_enrolled_users($c1ctx)); 944 945 // Reset allowed but not requested. 946 $mode = tool_uploadcourse_processor::MODE_UPDATE_ONLY; 947 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 948 $data = array('shortname' => $c1->shortname, 'reset' => '0'); 949 $importoptions = array('canreset' => true); 950 $co = new tool_uploadcourse_course($mode, $updatemode, $data, array(), $importoptions); 951 $this->assertTrue($co->prepare()); 952 $co->proceed(); 953 $this->assertTrue($DB->record_exists('groups', array('id' => $g1->id))); 954 $this->assertTrue($DB->record_exists('groups_members', array('groupid' => $g1->id, 'userid' => $u1->id))); 955 $this->assertCount(1, get_enrolled_users($c1ctx)); 956 957 // Reset passed as a default parameter, should not be taken in account. 958 $mode = tool_uploadcourse_processor::MODE_UPDATE_ONLY; 959 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 960 $data = array('shortname' => $c1->shortname); 961 $importoptions = array('canreset' => true); 962 $co = new tool_uploadcourse_course($mode, $updatemode, $data, array('reset' => 1), $importoptions); 963 $this->assertTrue($co->prepare()); 964 $co->proceed(); 965 $this->assertTrue($DB->record_exists('groups', array('id' => $g1->id))); 966 $this->assertTrue($DB->record_exists('groups_members', array('groupid' => $g1->id, 'userid' => $u1->id))); 967 $this->assertCount(1, get_enrolled_users($c1ctx)); 968 969 // Reset executed from data. 970 $mode = tool_uploadcourse_processor::MODE_UPDATE_ONLY; 971 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 972 $data = array('shortname' => $c1->shortname, 'reset' => 1); 973 $importoptions = array('canreset' => true); 974 $co = new tool_uploadcourse_course($mode, $updatemode, $data, array(), $importoptions); 975 $this->assertTrue($co->prepare()); 976 $co->proceed(); 977 $this->assertFalse($DB->record_exists('groups', array('id' => $g1->id))); 978 $this->assertFalse($DB->record_exists('groups_members', array('groupid' => $g1->id, 'userid' => $u1->id))); 979 $this->assertCount(0, get_enrolled_users($c1ctx)); 980 981 // Reset executed from import option. 982 $mode = tool_uploadcourse_processor::MODE_UPDATE_ONLY; 983 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 984 $data = array('shortname' => $c1->shortname, 'reset' => 0); 985 $importoptions = array('reset' => 1, 'canreset' => true); 986 $co = new tool_uploadcourse_course($mode, $updatemode, $data, array(), $importoptions); 987 988 $g1 = $this->getDataGenerator()->create_group(array('courseid' => $c1->id)); 989 $this->getDataGenerator()->create_group_member(array('groupid' => $g1->id, 'userid' => $u1->id)); 990 $this->assertEquals(1, $DB->count_records('groups', array('courseid' => $c1->id))); 991 $this->assertTrue($co->prepare()); 992 $co->proceed(); 993 $this->assertFalse($DB->record_exists('groups', array('id' => $g1->id))); 994 } 995 996 public function test_create_bad_category() { 997 global $DB; 998 $this->resetAfterTest(true); 999 1000 // Ensure fails when category cannot be resolved upon creation. 1001 $mode = tool_uploadcourse_processor::MODE_CREATE_NEW; 1002 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 1003 $data = array('shortname' => 'c1', 'summary' => 'summary', 'fullname' => 'FN', 'category' => 'Wrong cat'); 1004 $co = new tool_uploadcourse_course($mode, $updatemode, $data); 1005 $this->assertFalse($co->prepare()); 1006 $this->assertArrayHasKey('couldnotresolvecatgorybyid', $co->get_errors()); 1007 1008 // Ensure fails when category is 0 on create. 1009 $mode = tool_uploadcourse_processor::MODE_CREATE_NEW; 1010 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 1011 $data = array('shortname' => 'c1', 'summary' => 'summary', 'fullname' => 'FN', 'category' => '0'); 1012 $co = new tool_uploadcourse_course($mode, $updatemode, $data); 1013 $this->assertFalse($co->prepare()); 1014 $this->assertArrayHasKey('missingmandatoryfields', $co->get_errors()); 1015 1016 // Ensure fails when category cannot be resolved upon update. 1017 $c1 = $this->getDataGenerator()->create_course(); 1018 $mode = tool_uploadcourse_processor::MODE_UPDATE_ONLY; 1019 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 1020 $data = array('shortname' => $c1->shortname, 'category' => 'Wrong cat'); 1021 $co = new tool_uploadcourse_course($mode, $updatemode, $data); 1022 $this->assertFalse($co->prepare()); 1023 $this->assertArrayHasKey('couldnotresolvecatgorybyid', $co->get_errors()); 1024 1025 // Ensure does not update the category when it is 0. 1026 $c1 = $this->getDataGenerator()->create_course(); 1027 $mode = tool_uploadcourse_processor::MODE_UPDATE_ONLY; 1028 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 1029 $data = array('shortname' => $c1->shortname, 'category' => '0'); 1030 $co = new tool_uploadcourse_course($mode, $updatemode, $data); 1031 $this->assertTrue($co->prepare()); 1032 $this->assertEmpty($co->get_errors()); 1033 $this->assertEmpty($co->get_statuses()); 1034 $co->proceed(); 1035 $this->assertEquals($c1->category, $DB->get_field('course', 'category', array('id' => $c1->id))); 1036 1037 // Ensure does not update the category when it is set to 0 in the defaults. 1038 $c1 = $this->getDataGenerator()->create_course(); 1039 $mode = tool_uploadcourse_processor::MODE_UPDATE_ONLY; 1040 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_OR_DEFAUTLS; 1041 $data = array('shortname' => $c1->shortname); 1042 $defaults = array('category' => '0'); 1043 $co = new tool_uploadcourse_course($mode, $updatemode, $data, $defaults); 1044 $this->assertTrue($co->prepare()); 1045 $this->assertEmpty($co->get_errors()); 1046 $this->assertEmpty($co->get_statuses()); 1047 $co->proceed(); 1048 $this->assertEquals($c1->category, $DB->get_field('course', 'category', array('id' => $c1->id))); 1049 } 1050 1051 public function test_enrolment_data() { 1052 $this->resetAfterTest(true); 1053 1054 // We need to set the current user as one with the capability to edit manual enrolment instances in the new course. 1055 $this->setAdminUser(); 1056 1057 $mode = tool_uploadcourse_processor::MODE_CREATE_NEW; 1058 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 1059 $data = array('shortname' => 'c1', 'summary' => 'S', 'fullname' => 'FN', 'category' => '1'); 1060 $data['enrolment_1'] = 'manual'; 1061 $data['enrolment_1_role'] = 'teacher'; 1062 $data['enrolment_1_startdate'] = '2nd July 2013'; 1063 $data['enrolment_1_enddate'] = '2nd August 2013'; 1064 $data['enrolment_1_enrolperiod'] = '10 days'; 1065 $co = new tool_uploadcourse_course($mode, $updatemode, $data); 1066 $this->assertTrue($co->prepare()); 1067 $co->proceed(); 1068 1069 // Enrolment methods. 1070 $enroldata = array(); 1071 $instances = enrol_get_instances($co->get_id(), false); 1072 foreach ($instances as $instance) { 1073 $enroldata[$instance->enrol] = $instance; 1074 } 1075 1076 $this->assertNotEmpty($enroldata['manual']); 1077 $this->assertEquals(ENROL_INSTANCE_ENABLED, $enroldata['manual']->status); 1078 $this->assertEquals(strtotime($data['enrolment_1_startdate']), $enroldata['manual']->enrolstartdate); 1079 $this->assertEquals(strtotime('1970-01-01 GMT + ' . $data['enrolment_1_enrolperiod']), $enroldata['manual']->enrolperiod); 1080 $this->assertEquals(strtotime('12th July 2013'), $enroldata['manual']->enrolenddate); 1081 } 1082 1083 /** 1084 * Data provider for testing enrolment errors 1085 * 1086 * @return array 1087 */ 1088 public function enrolment_uploaddata_error_provider(): array { 1089 return [ 1090 ['errorcannotcreateorupdateenrolment', [ 1091 'shortname' => 'C1', 1092 'enrolment_1' => 'manual', 1093 ]], 1094 ['errorcannotdeleteenrolment', [ 1095 'shortname' => 'C1', 1096 'enrolment_1' => 'manual', 1097 'enrolment_1_delete' => '1', 1098 ]], 1099 ['errorcannotdisableenrolment', [ 1100 'shortname' => 'C1', 1101 'enrolment_1' => 'manual', 1102 'enrolment_1_disable' => '1', 1103 ]], 1104 ]; 1105 } 1106 1107 /** 1108 * Test that user without permission, cannot modify enrolment instances when creating courses 1109 * 1110 * @param string $expectederror 1111 * @param array $uploaddata 1112 * 1113 * @dataProvider enrolment_uploaddata_error_provider 1114 */ 1115 public function test_enrolment_error_create_course(string $expectederror, array $uploaddata): void { 1116 global $DB; 1117 1118 $this->resetAfterTest(); 1119 1120 // Create category in which to create the new course. 1121 $category = $this->getDataGenerator()->create_category(); 1122 $categorycontext = context_coursecat::instance($category->id); 1123 1124 $user = $this->getDataGenerator()->create_user(); 1125 $this->setUser($user); 1126 1127 // Assign the user as a manager of the category, disable ability to configure manual enrolment instances. 1128 $roleid = $DB->get_field('role', 'id', ['shortname' => 'manager']); 1129 role_assign($roleid, $user->id, $categorycontext); 1130 role_change_permission($roleid, $categorycontext, 'enrol/manual:config', CAP_PROHIBIT); 1131 1132 $mode = tool_uploadcourse_processor::MODE_CREATE_NEW; 1133 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 1134 1135 $upload = new tool_uploadcourse_course($mode, $updatemode, array_merge($uploaddata, [ 1136 'category' => $category->id, 1137 'fullname' => 'My course', 1138 ])); 1139 1140 // Enrolment validation isn't performed during 'prepare' for new courses. 1141 $this->assertTrue($upload->prepare()); 1142 $upload->proceed(); 1143 1144 $errors = $upload->get_errors(); 1145 $this->assertArrayHasKey($expectederror, $errors); 1146 1147 $this->assertEquals(get_string($expectederror, 'tool_uploadcourse', 'Manual enrolments'), 1148 (string) $errors[$expectederror]); 1149 } 1150 1151 /** 1152 * Test that user without permission, cannot modify enrolment instances when updating courses 1153 * 1154 * @param string $expectederror 1155 * @param array $uploaddata 1156 * 1157 * @dataProvider enrolment_uploaddata_error_provider 1158 */ 1159 public function test_enrolment_error_update_course(string $expectederror, array $uploaddata): void { 1160 global $DB; 1161 1162 $this->resetAfterTest(); 1163 1164 // Create category in which to create the new course. 1165 $category = $this->getDataGenerator()->create_category(); 1166 $categorycontext = context_coursecat::instance($category->id); 1167 1168 $course = $this->getDataGenerator()->create_course([ 1169 'category' => $category->id, 1170 'shortname' => $uploaddata['shortname'], 1171 ]); 1172 1173 $user = $this->getDataGenerator()->create_user(); 1174 $this->setUser($user); 1175 1176 // Assign the user as a manager of the category, disable ability to configure manual enrolment instances. 1177 $roleid = $DB->get_field('role', 'id', ['shortname' => 'manager']); 1178 role_assign($roleid, $user->id, $categorycontext); 1179 role_change_permission($roleid, $categorycontext, 'enrol/manual:config', CAP_PROHIBIT); 1180 1181 // Sanity check. 1182 $instances = enrol_get_instances($course->id, true); 1183 $this->assertCount(1, $instances); 1184 $this->assertEquals('manual', reset($instances)->enrol); 1185 1186 $mode = tool_uploadcourse_processor::MODE_UPDATE_ONLY; 1187 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 1188 1189 $upload = new tool_uploadcourse_course($mode, $updatemode, $uploaddata); 1190 1191 $this->assertFalse($upload->prepare()); 1192 1193 $errors = $upload->get_errors(); 1194 $this->assertArrayHasKey($expectederror, $errors); 1195 1196 $this->assertEquals(get_string($expectederror, 'tool_uploadcourse', 'Manual enrolments'), 1197 (string) $errors[$expectederror]); 1198 } 1199 1200 /** 1201 * Test upload processing of course custom fields 1202 */ 1203 public function test_custom_fields_data() { 1204 $this->resetAfterTest(); 1205 $this->setAdminUser(); 1206 1207 $course = $this->getDataGenerator()->create_course(['shortname' => 'C1']); 1208 1209 // Create our custom fields. 1210 $category = $this->get_customfield_generator()->create_category(); 1211 $this->create_custom_field($category, 'date', 'mydatefield'); 1212 $this->create_custom_field($category, 'text', 'mytextfield'); 1213 $this->create_custom_field($category, 'textarea', 'mytextareafield'); 1214 1215 // Perform upload. 1216 $mode = tool_uploadcourse_processor::MODE_UPDATE_ONLY; 1217 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 1218 $dataupload = [ 1219 'shortname' => $course->shortname, 1220 'customfield_mydatefield' => '2020-04-01 16:00', 1221 'customfield_mytextfield' => 'Hello', 1222 'customfield_mytextareafield' => 'Is it me you\'re looking for?', 1223 ]; 1224 1225 $uploader = new tool_uploadcourse_course($mode, $updatemode, $dataupload); 1226 $this->assertTrue($uploader->prepare()); 1227 $uploader->proceed(); 1228 1229 // Confirm presence of course custom fields. 1230 $data = \core_course\customfield\course_handler::create()->export_instance_data_object($course->id); 1231 $this->assertEqualsIgnoringCase('Wednesday, 1 April 2020, 4:00 PM', $data->mydatefield); 1232 $this->assertEquals($dataupload['customfield_mytextfield'], $data->mytextfield); 1233 $this->assertStringContainsString($dataupload['customfield_mytextareafield'], $data->mytextareafield); 1234 } 1235 1236 /** 1237 * Test upload processing of course custom field that is required but empty 1238 */ 1239 public function test_custom_fields_data_required() { 1240 $this->resetAfterTest(); 1241 $this->setAdminUser(); 1242 1243 $course = $this->getDataGenerator()->create_course(['shortname' => 'C1']); 1244 1245 // Create our custom field. 1246 $category = $this->get_customfield_generator()->create_category(); 1247 $this->create_custom_field($category, 'select', 'myselect', ['required' => true, 'options' => "Cat\nDog"]); 1248 1249 $mode = tool_uploadcourse_processor::MODE_UPDATE_ONLY; 1250 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 1251 $dataupload = [ 1252 'shortname' => $course->shortname, 1253 'customfield_myselect' => null, 1254 ]; 1255 1256 $uploader = new tool_uploadcourse_course($mode, $updatemode, $dataupload); 1257 $this->assertFalse($uploader->prepare()); 1258 $this->assertArrayHasKey('customfieldinvalid', $uploader->get_errors()); 1259 1260 // Try again with a default value. 1261 $defaults = [ 1262 'customfield_myselect' => 2, // Our second option: Dog. 1263 ]; 1264 1265 $uploader = new tool_uploadcourse_course($mode, $updatemode, $dataupload, $defaults); 1266 $this->assertTrue($uploader->prepare()); 1267 $uploader->proceed(); 1268 1269 // Confirm presence of course custom fields. 1270 $data = \core_course\customfield\course_handler::create()->export_instance_data_object($course->id); 1271 $this->assertEquals('Dog', $data->myselect); 1272 } 1273 1274 /** 1275 * Test upload processing of course custom field with an invalid select option 1276 */ 1277 public function test_custom_fields_data_invalid_select_option() { 1278 $this->resetAfterTest(); 1279 $this->setAdminUser(); 1280 1281 $course = $this->getDataGenerator()->create_course(['shortname' => 'C1']); 1282 1283 // Create our custom field. 1284 $category = $this->get_customfield_generator()->create_category(); 1285 $this->create_custom_field($category, 'select', 'myselect', 1286 ['required' => true, 'options' => "Cat\nDog", 'defaultvalue' => 'Cat']); 1287 1288 $mode = tool_uploadcourse_processor::MODE_UPDATE_ONLY; 1289 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 1290 $dataupload = [ 1291 'shortname' => $course->shortname, 1292 'customfield_myselect' => 'Fish', // No, invalid. 1293 ]; 1294 1295 $uploader = new tool_uploadcourse_course($mode, $updatemode, $dataupload); 1296 $this->assertTrue($uploader->prepare()); 1297 $uploader->proceed(); 1298 1299 // Confirm presence of course custom fields. 1300 $data = \core_course\customfield\course_handler::create()->export_instance_data_object($course->id); 1301 $this->assertEquals('Cat', $data->myselect); 1302 } 1303 1304 /** 1305 * Test upload processing of course custom field with an out of range date 1306 */ 1307 public function test_custom_fields_data_invalid_date() { 1308 $this->resetAfterTest(); 1309 $this->setAdminUser(); 1310 1311 $course = $this->getDataGenerator()->create_course(['shortname' => 'C1']); 1312 1313 // Create our custom field. 1314 $category = $this->get_customfield_generator()->create_category(); 1315 $this->create_custom_field($category, 'date', 'mydate', 1316 ['mindate' => strtotime('2020-04-01'), 'maxdate' => '2020-04-30']); 1317 1318 $mode = tool_uploadcourse_processor::MODE_UPDATE_ONLY; 1319 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 1320 $dataupload = [ 1321 'shortname' => $course->shortname, 1322 'customfield_mydate' => '2020-05-06', // Out of range. 1323 ]; 1324 1325 $uploader = new tool_uploadcourse_course($mode, $updatemode, $dataupload); 1326 $this->assertFalse($uploader->prepare()); 1327 $this->assertArrayHasKey('customfieldinvalid', $uploader->get_errors()); 1328 } 1329 1330 public function test_idnumber_problems() { 1331 $this->resetAfterTest(true); 1332 1333 $c1 = $this->getDataGenerator()->create_course(array('shortname' => 'sntaken', 'idnumber' => 'taken')); 1334 $c2 = $this->getDataGenerator()->create_course(); 1335 1336 // Create with existing ID number. 1337 $mode = tool_uploadcourse_processor::MODE_CREATE_NEW; 1338 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 1339 $data = array('shortname' => 'c2', 'summary' => 'summary', 'fullname' => 'FN', 'category' => '1', 1340 'idnumber' => $c1->idnumber); 1341 $co = new tool_uploadcourse_course($mode, $updatemode, $data); 1342 $this->assertFalse($co->prepare()); 1343 $this->assertArrayHasKey('idnumberalreadyinuse', $co->get_errors()); 1344 1345 // Rename to existing ID number. 1346 $mode = tool_uploadcourse_processor::MODE_UPDATE_ONLY; 1347 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 1348 $data = array('shortname' => $c2->shortname, 'rename' => 'SN', 'idnumber' => $c1->idnumber); 1349 $importoptions = array('canrename' => true); 1350 $co = new tool_uploadcourse_course($mode, $updatemode, $data, array(), $importoptions); 1351 $this->assertFalse($co->prepare()); 1352 $this->assertArrayHasKey('cannotrenameidnumberconflict', $co->get_errors()); 1353 1354 // Incrementing shortname increments idnumber. 1355 $mode = tool_uploadcourse_processor::MODE_CREATE_ALL; 1356 $updatemode = tool_uploadcourse_processor::UPDATE_NOTHING; 1357 $data = array('shortname' => $c1->shortname, 'idnumber' => $c1->idnumber, 'summary' => 'S', 'fullname' => 'F', 1358 'category' => 1); 1359 $co = new tool_uploadcourse_course($mode, $updatemode, $data, array(), array()); 1360 $this->assertTrue($co->prepare()); 1361 $this->assertArrayHasKey('courseshortnameincremented', $co->get_statuses()); 1362 $this->assertArrayHasKey('courseidnumberincremented', $co->get_statuses()); 1363 $data = $co->get_data(); 1364 $this->assertEquals('sntaken_2', $data['shortname']); 1365 $this->assertEquals('taken_2', $data['idnumber']); 1366 1367 // Incrementing shortname increments idnumber unless available. 1368 $mode = tool_uploadcourse_processor::MODE_CREATE_ALL; 1369 $updatemode = tool_uploadcourse_processor::UPDATE_NOTHING; 1370 $data = array('shortname' => $c1->shortname, 'idnumber' => 'nottaken', 'summary' => 'S', 'fullname' => 'F', 1371 'category' => 1); 1372 $co = new tool_uploadcourse_course($mode, $updatemode, $data, array(), array()); 1373 $this->assertTrue($co->prepare()); 1374 $this->assertArrayHasKey('courseshortnameincremented', $co->get_statuses()); 1375 $this->assertArrayNotHasKey('courseidnumberincremented', $co->get_statuses()); 1376 $data = $co->get_data(); 1377 $this->assertEquals('sntaken_2', $data['shortname']); 1378 $this->assertEquals('nottaken', $data['idnumber']); 1379 } 1380 1381 public function test_generate_shortname() { 1382 $this->resetAfterTest(true); 1383 1384 $c1 = $this->getDataGenerator()->create_course(array('shortname' => 'taken')); 1385 1386 // Generate a shortname. 1387 $mode = tool_uploadcourse_processor::MODE_CREATE_NEW; 1388 $updatemode = tool_uploadcourse_processor::UPDATE_NOTHING; 1389 $data = array('summary' => 'summary', 'fullname' => 'FN', 'category' => '1', 'idnumber' => 'IDN'); 1390 $importoptions = array('shortnametemplate' => '%i'); 1391 $co = new tool_uploadcourse_course($mode, $updatemode, $data, array(), $importoptions); 1392 $this->assertTrue($co->prepare()); 1393 $this->assertArrayHasKey('courseshortnamegenerated', $co->get_statuses()); 1394 1395 // Generate a shortname without a template. 1396 $mode = tool_uploadcourse_processor::MODE_CREATE_NEW; 1397 $updatemode = tool_uploadcourse_processor::UPDATE_NOTHING; 1398 $data = array('summary' => 'summary', 'fullname' => 'FN', 'category' => '1'); 1399 $co = new tool_uploadcourse_course($mode, $updatemode, $data, array(), array()); 1400 $this->assertFalse($co->prepare()); 1401 $this->assertArrayHasKey('missingshortnamenotemplate', $co->get_errors()); 1402 1403 // Generate a shortname in update mode. 1404 $mode = tool_uploadcourse_processor::MODE_UPDATE_ONLY; 1405 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 1406 $data = array('summary' => 'summary', 'fullname' => 'FN', 'category' => '1'); 1407 $importoptions = array('shortnametemplate' => '%f'); 1408 $co = new tool_uploadcourse_course($mode, $updatemode, $data, array(), $importoptions); 1409 $this->assertFalse($co->prepare()); 1410 // Commented because we never get here as the course without shortname does not exist. 1411 // $this->assertArrayHasKey('cannotgenerateshortnameupdatemode', $co->get_errors()); 1412 1413 // Generate a shortname to a course that already exists. 1414 $mode = tool_uploadcourse_processor::MODE_CREATE_NEW; 1415 $updatemode = tool_uploadcourse_processor::UPDATE_NOTHING; 1416 $data = array('summary' => 'summary', 'fullname' => 'taken', 'category' => '1'); 1417 $importoptions = array('shortnametemplate' => '%f'); 1418 $co = new tool_uploadcourse_course($mode, $updatemode, $data, array(), $importoptions); 1419 $this->assertFalse($co->prepare()); 1420 $this->assertArrayHasKey('generatedshortnamealreadyinuse', $co->get_errors()); 1421 1422 // Generate a shortname to a course that already exists will be incremented. 1423 $mode = tool_uploadcourse_processor::MODE_CREATE_ALL; 1424 $updatemode = tool_uploadcourse_processor::UPDATE_NOTHING; 1425 $data = array('summary' => 'summary', 'fullname' => 'taken', 'category' => '1'); 1426 $importoptions = array('shortnametemplate' => '%f'); 1427 $co = new tool_uploadcourse_course($mode, $updatemode, $data, array(), $importoptions); 1428 $this->assertTrue($co->prepare()); 1429 $this->assertArrayHasKey('courseshortnamegenerated', $co->get_statuses()); 1430 $this->assertArrayHasKey('courseshortnameincremented', $co->get_statuses()); 1431 } 1432 1433 public function test_mess_with_frontpage() { 1434 global $SITE; 1435 $this->resetAfterTest(true); 1436 1437 // Updating the front page. 1438 $mode = tool_uploadcourse_processor::MODE_UPDATE_ONLY; 1439 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 1440 $data = array('shortname' => $SITE->shortname, 'idnumber' => 'NewIDN'); 1441 $importoptions = array(); 1442 $co = new tool_uploadcourse_course($mode, $updatemode, $data, array(), $importoptions); 1443 $this->assertFalse($co->prepare()); 1444 $this->assertArrayHasKey('cannotupdatefrontpage', $co->get_errors()); 1445 1446 // Updating the front page. 1447 $mode = tool_uploadcourse_processor::MODE_CREATE_OR_UPDATE; 1448 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 1449 $data = array('shortname' => $SITE->shortname, 'idnumber' => 'NewIDN'); 1450 $importoptions = array(); 1451 $co = new tool_uploadcourse_course($mode, $updatemode, $data, array(), $importoptions); 1452 $this->assertFalse($co->prepare()); 1453 $this->assertArrayHasKey('cannotupdatefrontpage', $co->get_errors()); 1454 1455 // Generating a shortname should not be allowed in update mode, and so we cannot update the front page. 1456 $mode = tool_uploadcourse_processor::MODE_CREATE_OR_UPDATE; 1457 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 1458 $data = array('idnumber' => 'NewIDN', 'fullname' => 'FN', 'category' => 1); 1459 $importoptions = array('shortnametemplate' => $SITE->shortname); 1460 $co = new tool_uploadcourse_course($mode, $updatemode, $data, array(), $importoptions); 1461 $this->assertFalse($co->prepare()); 1462 $this->assertArrayHasKey('cannotgenerateshortnameupdatemode', $co->get_errors()); 1463 1464 // Renaming to the front page should not be allowed. 1465 $c1 = $this->getDataGenerator()->create_course(); 1466 $mode = tool_uploadcourse_processor::MODE_CREATE_OR_UPDATE; 1467 $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; 1468 $data = array('shortname' => $c1->shortname, 'fullname' => 'FN', 'idnumber' => 'NewIDN', 'rename' => $SITE->shortname); 1469 $importoptions = array('canrename' => true); 1470 $co = new tool_uploadcourse_course($mode, $updatemode, $data, array(), $importoptions); 1471 $this->assertFalse($co->prepare()); 1472 $this->assertArrayHasKey('cannotrenameshortnamealreadyinuse', $co->get_errors()); 1473 } 1474 1475 /** 1476 * Get custom field plugin generator 1477 * 1478 * @return core_customfield_generator 1479 */ 1480 protected function get_customfield_generator() : core_customfield_generator { 1481 return $this->getDataGenerator()->get_plugin_generator('core_customfield'); 1482 } 1483 1484 /** 1485 * Helper method to create custom course field 1486 * 1487 * @param \core_customfield\category_controller $category 1488 * @param string $type 1489 * @param string $shortname 1490 * @param array $configdata 1491 * @return \core_customfield\field_controller 1492 */ 1493 protected function create_custom_field(\core_customfield\category_controller $category, string $type, string $shortname, 1494 array $configdata = []) : \core_customfield\field_controller { 1495 1496 return $this->get_customfield_generator()->create_field([ 1497 'categoryid' => $category->get('id'), 1498 'type' => $type, 1499 'shortname' => $shortname, 1500 'configdata' => $configdata, 1501 ]); 1502 } 1503 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body