Differences Between: [Versions 310 and 403] [Versions 311 and 403] [Versions 39 and 403] [Versions 400 and 403]
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 gradeimport_csv; 18 19 defined('MOODLE_INTERNAL') || die(); 20 21 global $CFG; 22 require_once($CFG->dirroot . '/grade/import/csv/tests/fixtures/phpunit_gradeimport_csv_load_data.php'); 23 require_once($CFG->libdir . '/csvlib.class.php'); 24 require_once($CFG->libdir . '/grade/grade_item.php'); 25 require_once($CFG->libdir . '/grade/tests/fixtures/lib.php'); 26 27 /** 28 * Unit tests for lib.php 29 * 30 * @package gradeimport_csv 31 * @copyright 2014 Adrian Greeve 32 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 33 */ 34 class load_data_test extends \grade_base_testcase { 35 36 /** @var string $oktext Text to be imported. This data should have no issues being imported. */ 37 protected $oktext = '"First name","Last name","ID number",Institution,Department,"Email address","Assignment: Assignment for grape group", "Feedback: Assignment for grape group","Assignment: Second new grade item","Course total" 38 Anne,Able,,"Moodle HQ","Rock on!",student7@example.com,56.00,"We welcome feedback",,56.00 39 Bobby,Bunce,,"Moodle HQ","Rock on!",student5@example.com,75.00,,45.0,75.00'; 40 41 /** @var string $badtext Text to be imported. This data has an extra column and should not succeed in being imported. */ 42 protected $badtext = '"First name","Last name","ID number",Institution,Department,"Email address","Assignment: Assignment for grape group","Course total" 43 Anne,Able,,"Moodle HQ","Rock on!",student7@example.com,56.00,56.00,78.00 44 Bobby,Bunce,,"Moodle HQ","Rock on!",student5@example.com,75.00,75.00'; 45 46 /** @var string $csvtext CSV data to be imported with Last download from this course column. */ 47 protected $csvtext = '"First name","Last name","ID number",Institution,Department,"Email address","Assignment: Assignment for grape group", "Feedback: Assignment for grape group","Course total","Last downloaded from this course" 48 Anne,Able,,"Moodle HQ","Rock on!",student7@example.com,56.00,"We welcome feedback",56.00,{exportdate} 49 Bobby,Bunce,,"Moodle HQ","Rock on!",student5@example.com,75.00,,75.00,{exportdate}'; 50 51 /** @var int $iid Import ID. */ 52 protected $iid; 53 54 /** @var object $csvimport a csv_import_reader object that handles the csv import. */ 55 protected $csvimport; 56 57 /** @var array $columns The first row of the csv file. These are the columns of the import file.*/ 58 protected $columns; 59 60 public function tearDown(): void { 61 $this->csvimport = null; 62 } 63 64 /** 65 * Load up the above text through the csv import. 66 * 67 * @param string $content Text to be imported into the gradebook. 68 * @return array All text separated by commas now in an array. 69 */ 70 protected function csv_load($content) { 71 // Import the csv strings. 72 $this->iid = \csv_import_reader::get_new_iid('grade'); 73 $this->csvimport = new \csv_import_reader($this->iid, 'grade'); 74 75 $this->csvimport->load_csv_content($content, 'utf8', 'comma'); 76 $this->columns = $this->csvimport->get_columns(); 77 78 $this->csvimport->init(); 79 while ($line = $this->csvimport->next()) { 80 $testarray[] = $line; 81 } 82 83 return $testarray; 84 } 85 86 /** 87 * Test loading data and returning preview content. 88 */ 89 public function test_load_csv_content() { 90 $encoding = 'utf8'; 91 $separator = 'comma'; 92 $previewrows = 5; 93 $csvpreview = new \phpunit_gradeimport_csv_load_data(); 94 $csvpreview->load_csv_content($this->oktext, $encoding, $separator, $previewrows); 95 96 $expecteddata = array(array( 97 'Anne', 98 'Able', 99 '', 100 'Moodle HQ', 101 'Rock on!', 102 'student7@example.com', 103 56.00, 104 'We welcome feedback', 105 '', 106 56.00 107 ), 108 array( 109 'Bobby', 110 'Bunce', 111 '', 112 'Moodle HQ', 113 'Rock on!', 114 'student5@example.com', 115 75.00, 116 '', 117 45.0, 118 75.00 119 ) 120 ); 121 122 $expectedheaders = array( 123 'First name', 124 'Last name', 125 'ID number', 126 'Institution', 127 'Department', 128 'Email address', 129 'Assignment: Assignment for grape group', 130 'Feedback: Assignment for grape group', 131 'Assignment: Second new grade item', 132 'Course total' 133 ); 134 // Check that general data is returned as expected. 135 $this->assertEquals($csvpreview->get_previewdata(), $expecteddata); 136 // Check that headers are returned as expected. 137 $this->assertEquals($csvpreview->get_headers(), $expectedheaders); 138 139 // Check that errors are being recorded. 140 $csvpreview = new \phpunit_gradeimport_csv_load_data(); 141 $csvpreview->load_csv_content($this->badtext, $encoding, $separator, $previewrows); 142 // Columns shouldn't match. 143 $this->assertEquals($csvpreview->get_error(), get_string('csvweirdcolumns', 'error')); 144 } 145 146 /** 147 * Test fetching grade items for the course. 148 */ 149 public function test_fetch_grade_items() { 150 151 $gradeitemsarray = \grade_item::fetch_all(array('courseid' => $this->courseid)); 152 $gradeitems = \phpunit_gradeimport_csv_load_data::fetch_grade_items($this->courseid); 153 154 // Make sure that each grade item is located in the gradeitemsarray. 155 foreach ($gradeitems as $key => $gradeitem) { 156 $this->assertArrayHasKey($key, $gradeitemsarray); 157 } 158 159 // Get the key for a specific grade item. 160 $quizkey = null; 161 foreach ($gradeitemsarray as $key => $value) { 162 if ($value->itemname == "Quiz grade item") { 163 $quizkey = $key; 164 } 165 } 166 167 // Expected modified item name. 168 $testitemname = get_string('modulename', $gradeitemsarray[$quizkey]->itemmodule) . ': ' . 169 $gradeitemsarray[$quizkey]->itemname; 170 // Check that an item that is a module, is concatenated properly. 171 $this->assertEquals($testitemname, $gradeitems[$quizkey]); 172 } 173 174 /** 175 * Test the inserting of grade record data. 176 */ 177 public function test_insert_grade_record() { 178 global $DB, $USER; 179 180 $user = $this->getDataGenerator()->create_user(); 181 $this->setAdminUser(); 182 183 $record = new \stdClass(); 184 $record->itemid = 4; 185 $record->newgradeitem = 25; 186 $record->finalgrade = 62.00; 187 $record->feedback = 'Some test feedback'; 188 189 $testobject = new \phpunit_gradeimport_csv_load_data(); 190 191 $testobject->test_insert_grade_record($record, $user->id, new \grade_item()); 192 193 $gradeimportvalues = $DB->get_records('grade_import_values'); 194 // Get the insert id. 195 $key = key($gradeimportvalues); 196 197 $testarray = array(); 198 $testarray[$key] = new \stdClass(); 199 $testarray[$key]->id = $key; 200 $testarray[$key]->itemid = $record->itemid; 201 $testarray[$key]->newgradeitem = $record->newgradeitem; 202 $testarray[$key]->userid = $user->id; 203 $testarray[$key]->finalgrade = $record->finalgrade; 204 $testarray[$key]->feedback = $record->feedback; 205 $testarray[$key]->importcode = $testobject->get_importcode(); 206 $testarray[$key]->importer = $USER->id; 207 $testarray[$key]->importonlyfeedback = 0; 208 209 // Check that the record was inserted into the database. 210 $this->assertEquals($gradeimportvalues, $testarray); 211 } 212 213 /** 214 * Test preparing a new grade item for import into the gradebook. 215 */ 216 public function test_import_new_grade_item() { 217 global $DB; 218 219 $this->setAdminUser(); 220 $this->csv_load($this->oktext); 221 $columns = $this->columns; 222 223 // The assignment is item 6. 224 $key = 6; 225 $testobject = new \phpunit_gradeimport_csv_load_data(); 226 227 // Key for this assessment. 228 $this->csvimport->init(); 229 $testarray = array(); 230 while ($line = $this->csvimport->next()) { 231 $testarray[] = $testobject->test_import_new_grade_item($columns, $key, $line[$key]); 232 } 233 234 // Query the database and check how many results were inserted. 235 $newgradeimportitems = $DB->get_records('grade_import_newitem'); 236 $this->assertEquals(count($testarray), count($newgradeimportitems)); 237 } 238 239 /** 240 * Data provider for \gradeimport_csv_load_data_testcase::test_check_user_exists(). 241 * 242 * @return array 243 */ 244 public function check_user_exists_provider() { 245 return [ 246 'Fetch by email' => [ 247 'email', 's1@example.com', true 248 ], 249 'Fetch by email, different case' => [ 250 'email', 'S1@EXAMPLE.COM', true 251 ], 252 'Fetch data using a non-existent email' => [ 253 'email', 's2@example.com', false 254 ], 255 'Multiple accounts with the same email' => [ 256 'email', 's1@example.com', false, 1 257 ], 258 'Fetch data using a valid user ID' => [ 259 'id', true, true 260 ], 261 'Fetch data using a non-existent user ID' => [ 262 'id', false, false 263 ], 264 'Fetch data using a valid username' => [ 265 'username', 's1', true 266 ], 267 'Fetch data using a valid username, different case' => [ 268 'username', 'S1', true 269 ], 270 'Fetch data using an invalid username' => [ 271 'username', 's2', false 272 ], 273 'Fetch data using a valid ID Number' => [ 274 'idnumber', 's1', true 275 ], 276 'Fetch data using an invalid ID Number' => [ 277 'idnumber', 's2', false 278 ], 279 ]; 280 } 281 282 /** 283 * Check that the user matches a user in the system. 284 * 285 * @dataProvider check_user_exists_provider 286 * @param string $field The field to use for the query. 287 * @param string|boolean $value The field value. When fetching by ID, set true to fetch valid user ID, false otherwise. 288 * @param boolean $successexpected Whether we expect for a user to be found or not. 289 * @param int $allowaccountssameemail Value for $CFG->allowaccountssameemail 290 */ 291 public function test_check_user_exists($field, $value, $successexpected, $allowaccountssameemail = 0) { 292 $this->resetAfterTest(); 293 294 $generator = $this->getDataGenerator(); 295 296 // Need to add one of the users into the system. 297 $user = $generator->create_user([ 298 'firstname' => 'Anne', 299 'lastname' => 'Able', 300 'email' => 's1@example.com', 301 'idnumber' => 's1', 302 'username' => 's1', 303 ]); 304 305 if ($allowaccountssameemail) { 306 // Create another user with the same email address. 307 $generator->create_user(['email' => 's1@example.com']); 308 } 309 310 // Since the data provider can't know what user ID to use, do a special handling for ID field tests. 311 if ($field === 'id') { 312 if ($value) { 313 // Test for fetching data using a valid user ID. Use the generated user's ID. 314 $value = $user->id; 315 } else { 316 // Test for fetching data using a non-existent user ID. 317 $value = $user->id + 1; 318 } 319 } 320 321 $userfields = [ 322 'field' => $field, 323 'label' => 'Field label: ' . $field 324 ]; 325 326 $testobject = new \phpunit_gradeimport_csv_load_data(); 327 328 // Check whether the user exists. If so, then the user id is returned. Otherwise, it returns null. 329 $userid = $testobject->test_check_user_exists($value, $userfields); 330 331 if ($successexpected) { 332 // Check that the user id returned matches with the user that we created. 333 $this->assertEquals($user->id, $userid); 334 335 // Check that there are no errors. 336 $this->assertEmpty($testobject->get_gradebookerrors()); 337 338 } else { 339 // Check that the userid is null. 340 $this->assertNull($userid); 341 342 // Check that expected error message and actual message match. 343 $gradebookerrors = $testobject->get_gradebookerrors(); 344 $mappingobject = (object)[ 345 'field' => $userfields['label'], 346 'value' => $value, 347 ]; 348 if ($allowaccountssameemail) { 349 $expectederrormessage = get_string('usermappingerrormultipleusersfound', 'grades', $mappingobject); 350 } else { 351 $expectederrormessage = get_string('usermappingerror', 'grades', $mappingobject); 352 } 353 354 $this->assertEquals($expectederrormessage, $gradebookerrors[0]); 355 } 356 } 357 358 /** 359 * Test preparing feedback for inserting / updating into the gradebook. 360 */ 361 public function test_create_feedback() { 362 363 $testarray = $this->csv_load($this->oktext); 364 $testobject = new \phpunit_gradeimport_csv_load_data(); 365 366 // Try to insert some feedback for an assessment. 367 $feedback = $testobject->test_create_feedback($this->courseid, 1, $testarray[0][7]); 368 369 // Expected result. 370 $expectedfeedback = array('itemid' => 1, 'feedback' => $testarray[0][7]); 371 $this->assertEquals((array)$feedback, $expectedfeedback); 372 } 373 374 /** 375 * Test preparing grade_items for upgrading into the gradebook. 376 */ 377 public function test_update_grade_item() { 378 379 $testarray = $this->csv_load($this->oktext); 380 $testobject = new \phpunit_gradeimport_csv_load_data(); 381 382 // We're not using scales so no to this option. 383 $verbosescales = 0; 384 // Map and key are to retrieve the grade_item that we are updating. 385 $map = array(1); 386 $key = 0; 387 // We return the new grade array for saving. 388 $newgrades = $testobject->test_update_grade_item($this->courseid, $map, $key, $verbosescales, $testarray[0][6]); 389 390 $expectedresult = array(); 391 $expectedresult[0] = new \stdClass(); 392 $expectedresult[0]->itemid = 1; 393 $expectedresult[0]->finalgrade = $testarray[0][6]; 394 395 $this->assertEquals($newgrades, $expectedresult); 396 397 // Try sending a bad grade value (A letter instead of a float / int). 398 $newgrades = $testobject->test_update_grade_item($this->courseid, $map, $key, $verbosescales, 'A'); 399 // The $newgrades variable should be null. 400 $this->assertNull($newgrades); 401 $expectederrormessage = get_string('badgrade', 'grades'); 402 // Check that the error message is what we expect. 403 $gradebookerrors = $testobject->get_gradebookerrors(); 404 $this->assertEquals($expectederrormessage, $gradebookerrors[0]); 405 } 406 407 /** 408 * Test importing data and mapping it with items in the course. 409 */ 410 public function test_map_user_data_with_value() { 411 // Need to add one of the users into the system. 412 $user = new \stdClass(); 413 $user->firstname = 'Anne'; 414 $user->lastname = 'Able'; 415 $user->email = 'student7@example.com'; 416 $userdetail = $this->getDataGenerator()->create_user($user); 417 418 $testarray = $this->csv_load($this->oktext); 419 $testobject = new \phpunit_gradeimport_csv_load_data(); 420 421 // We're not using scales so no to this option. 422 $verbosescales = 0; 423 // Map and key are to retrieve the grade_item that we are updating. 424 $map = array(1); 425 $key = 0; 426 427 // Test new user mapping. This should return the user id if there were no problems. 428 $userid = $testobject->test_map_user_data_with_value('useremail', $testarray[0][5], $this->columns, $map, $key, 429 $this->courseid, $map[$key], $verbosescales); 430 $this->assertEquals($userid, $userdetail->id); 431 432 $newgrades = $testobject->test_map_user_data_with_value('new', $testarray[0][6], $this->columns, $map, $key, 433 $this->courseid, $map[$key], $verbosescales); 434 // Check that the final grade is the same as the one inserted. 435 $this->assertEquals($testarray[0][6], $newgrades[0]->finalgrade); 436 437 $newgrades = $testobject->test_map_user_data_with_value('new', $testarray[0][8], $this->columns, $map, $key, 438 $this->courseid, $map[$key], $verbosescales); 439 // Check that the final grade is the same as the one inserted. 440 // The testobject should now contain 2 new grade items. 441 $this->assertEquals(2, count($newgrades)); 442 // Because this grade item is empty, the value for final grade should be null. 443 $this->assertNull($newgrades[1]->finalgrade); 444 445 $feedback = $testobject->test_map_user_data_with_value('feedback', $testarray[0][7], $this->columns, $map, $key, 446 $this->courseid, $map[$key], $verbosescales); 447 // Expected result. 448 $resultarray = array(); 449 $resultarray[0] = new \stdClass(); 450 $resultarray[0]->itemid = 1; 451 $resultarray[0]->feedback = $testarray[0][7]; 452 $this->assertEquals($feedback, $resultarray); 453 454 // Default behaviour (update a grade item). 455 $newgrades = $testobject->test_map_user_data_with_value('default', $testarray[0][6], $this->columns, $map, $key, 456 $this->courseid, $map[$key], $verbosescales); 457 $this->assertEquals($testarray[0][6], $newgrades[0]->finalgrade); 458 } 459 460 /** 461 * Test importing data into the gradebook. 462 */ 463 public function test_prepare_import_grade_data() { 464 global $DB; 465 466 // Need to add one of the users into the system. 467 $user = new \stdClass(); 468 $user->firstname = 'Anne'; 469 $user->lastname = 'Able'; 470 $user->email = 'student7@example.com'; 471 // Insert user 1. 472 $this->getDataGenerator()->create_user($user); 473 $user = new \stdClass(); 474 $user->firstname = 'Bobby'; 475 $user->lastname = 'Bunce'; 476 $user->email = 'student5@example.com'; 477 // Insert user 2. 478 $this->getDataGenerator()->create_user($user); 479 480 $this->csv_load($this->oktext); 481 482 $importcode = 007; 483 $verbosescales = 0; 484 485 // Form data object. 486 $formdata = new \stdClass(); 487 $formdata->mapfrom = 5; 488 $formdata->mapto = 'useremail'; 489 $formdata->mapping_0 = 0; 490 $formdata->mapping_1 = 0; 491 $formdata->mapping_2 = 0; 492 $formdata->mapping_3 = 0; 493 $formdata->mapping_4 = 0; 494 $formdata->mapping_5 = 0; 495 $formdata->mapping_6 = 'new'; 496 $formdata->mapping_7 = 'feedback_2'; 497 $formdata->mapping_8 = 0; 498 $formdata->mapping_9 = 0; 499 $formdata->map = 1; 500 $formdata->id = 2; 501 $formdata->iid = $this->iid; 502 $formdata->importcode = $importcode; 503 $formdata->forceimport = false; 504 505 // Blam go time. 506 $testobject = new \phpunit_gradeimport_csv_load_data(); 507 $dataloaded = $testobject->prepare_import_grade_data($this->columns, $formdata, $this->csvimport, $this->courseid, '', '', 508 $verbosescales); 509 // If everything inserted properly then this should be true. 510 $this->assertTrue($dataloaded); 511 } 512 513 /* 514 * Test importing csv data into the gradebook using "Last downloaded from this course" column and force import option. 515 */ 516 public function test_force_import_option () { 517 518 // Need to add users into the system. 519 $user = new \stdClass(); 520 $user->firstname = 'Anne'; 521 $user->lastname = 'Able'; 522 $user->email = 'student7@example.com'; 523 $user->id_number = 1; 524 $user1 = $this->getDataGenerator()->create_user($user); 525 $user = new \stdClass(); 526 $user->firstname = 'Bobby'; 527 $user->lastname = 'Bunce'; 528 $user->email = 'student5@example.com'; 529 $user->id_number = 2; 530 $user2 = $this->getDataGenerator()->create_user($user); 531 532 // Create a new grade item. 533 $params = array( 534 'itemtype' => 'manual', 535 'itemname' => 'Grade item 1', 536 'gradetype' => GRADE_TYPE_VALUE, 537 'courseid' => $this->courseid 538 ); 539 $gradeitem = new \grade_item($params, false); 540 $gradeitemid = $gradeitem->insert(); 541 542 $importcode = 001; 543 $verbosescales = 0; 544 545 // Form data object. 546 $formdata = new \stdClass(); 547 $formdata->mapfrom = 5; 548 $formdata->mapto = 'useremail'; 549 $formdata->mapping_0 = 0; 550 $formdata->mapping_1 = 0; 551 $formdata->mapping_2 = 0; 552 $formdata->mapping_3 = 0; 553 $formdata->mapping_4 = 0; 554 $formdata->mapping_5 = 0; 555 $formdata->mapping_6 = $gradeitemid; 556 $formdata->mapping_7 = 'feedback_2'; 557 $formdata->mapping_8 = 0; 558 $formdata->mapping_9 = 0; 559 $formdata->map = 1; 560 $formdata->id = 2; 561 $formdata->iid = $this->iid; 562 $formdata->importcode = $importcode; 563 $formdata->forceimport = false; 564 565 // Add last download from this course column to csv content. 566 $exportdate = time(); 567 $newcsvdata = str_replace('{exportdate}', $exportdate, $this->csvtext); 568 $this->csv_load($newcsvdata); 569 $testobject = new \phpunit_gradeimport_csv_load_data(); 570 $dataloaded = $testobject->prepare_import_grade_data($this->columns, $formdata, $this->csvimport, 571 $this->courseid, '', '', $verbosescales); 572 $this->assertTrue($dataloaded); 573 574 // We must update the last modified date. 575 grade_import_commit($this->courseid, $importcode, false, false); 576 577 // Test using force import disabled and a date in the past. 578 $pastdate = strtotime('-1 day', time()); 579 $newcsvdata = str_replace('{exportdate}', $pastdate, $this->csvtext); 580 $this->csv_load($newcsvdata); 581 $testobject = new \phpunit_gradeimport_csv_load_data(); 582 $dataloaded = $testobject->prepare_import_grade_data($this->columns, $formdata, $this->csvimport, 583 $this->courseid, '', '', $verbosescales); 584 $this->assertFalse($dataloaded); 585 $errors = $testobject->get_gradebookerrors(); 586 $this->assertEquals($errors[0], get_string('gradealreadyupdated', 'grades', fullname($user1))); 587 588 // Test using force import enabled and a date in the past. 589 $formdata->forceimport = true; 590 $testobject = new \phpunit_gradeimport_csv_load_data(); 591 $dataloaded = $testobject->prepare_import_grade_data($this->columns, $formdata, $this->csvimport, 592 $this->courseid, '', '', $verbosescales); 593 $this->assertTrue($dataloaded); 594 595 // Test importing using an old exported file (2 years ago). 596 $formdata->forceimport = false; 597 $twoyearsago = strtotime('-2 year', time()); 598 $newcsvdata = str_replace('{exportdate}', $twoyearsago, $this->csvtext); 599 $this->csv_load($newcsvdata); 600 $testobject = new \phpunit_gradeimport_csv_load_data(); 601 $dataloaded = $testobject->prepare_import_grade_data($this->columns, $formdata, $this->csvimport, 602 $this->courseid, '', '', $verbosescales); 603 $this->assertFalse($dataloaded); 604 $errors = $testobject->get_gradebookerrors(); 605 $this->assertEquals($errors[0], get_string('invalidgradeexporteddate', 'grades')); 606 607 // Test importing using invalid exported date. 608 $baddate = '0123A56B89'; 609 $newcsvdata = str_replace('{exportdate}', $baddate, $this->csvtext); 610 $this->csv_load($newcsvdata); 611 $formdata->mapping_6 = $gradeitemid; 612 $testobject = new \phpunit_gradeimport_csv_load_data(); 613 $dataloaded = $testobject->prepare_import_grade_data($this->columns, $formdata, $this->csvimport, 614 $this->courseid, '', '', $verbosescales); 615 $this->assertFalse($dataloaded); 616 $errors = $testobject->get_gradebookerrors(); 617 $this->assertEquals($errors[0], get_string('invalidgradeexporteddate', 'grades')); 618 619 // Test importing using date in the future. 620 $oneyearahead = strtotime('+1 year', time()); 621 $oldcsv = str_replace('{exportdate}', $oneyearahead, $this->csvtext); 622 $this->csv_load($oldcsv); 623 $formdata->mapping_6 = $gradeitemid; 624 $testobject = new \phpunit_gradeimport_csv_load_data(); 625 $dataloaded = $testobject->prepare_import_grade_data($this->columns, $formdata, $this->csvimport, 626 $this->courseid, '', '', $verbosescales); 627 $this->assertFalse($dataloaded); 628 $errors = $testobject->get_gradebookerrors(); 629 $this->assertEquals($errors[0], get_string('invalidgradeexporteddate', 'grades')); 630 } 631 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body