| 1 | efrain | 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 mod_quiz;
 | 
        
           |  |  | 18 |   | 
        
           |  |  | 19 | use backup;
 | 
        
           |  |  | 20 | use core_user;
 | 
        
           |  |  | 21 | use restore_controller;
 | 
        
           |  |  | 22 | use restore_dbops;
 | 
        
           |  |  | 23 |   | 
        
           |  |  | 24 | /**
 | 
        
           |  |  | 25 |  * Unit tests restoring quiz attempts
 | 
        
           |  |  | 26 |  *
 | 
        
           |  |  | 27 |  * @package     mod_quiz
 | 
        
           |  |  | 28 |  * @copyright   2021 Paul Holden <paulh@moodle.com>
 | 
        
           |  |  | 29 |  * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 | 
        
           |  |  | 30 |  */
 | 
        
           | 1441 | ariadna | 31 | final class restore_attempt_test extends \advanced_testcase {
 | 
        
           | 1 | efrain | 32 |   | 
        
           |  |  | 33 |     /**
 | 
        
           |  |  | 34 |      * Load required libraries
 | 
        
           |  |  | 35 |      */
 | 
        
           |  |  | 36 |     public static function setUpBeforeClass(): void {
 | 
        
           |  |  | 37 |         global $CFG;
 | 
        
           |  |  | 38 |   | 
        
           |  |  | 39 |         require_once("{$CFG->dirroot}/backup/util/includes/restore_includes.php");
 | 
        
           | 1441 | ariadna | 40 |         parent::setUpBeforeClass();
 | 
        
           | 1 | efrain | 41 |     }
 | 
        
           |  |  | 42 |   | 
        
           |  |  | 43 |     /**
 | 
        
           |  |  | 44 |      * Test restore dates.
 | 
        
           |  |  | 45 |      *
 | 
        
           |  |  | 46 |      * @covers \restore_quiz_activity_structure_step
 | 
        
           |  |  | 47 |      */
 | 
        
           |  |  | 48 |     public function test_restore_question_attempts_missing_users(): void {
 | 
        
           |  |  | 49 |         global $DB, $USER;
 | 
        
           |  |  | 50 |   | 
        
           |  |  | 51 |         $this->resetAfterTest();
 | 
        
           |  |  | 52 |         $this->setAdminUser();
 | 
        
           |  |  | 53 |   | 
        
           |  |  | 54 |         // Contains a quiz with four attempts from different users. The users are as follows (user ID -> user):
 | 
        
           |  |  | 55 |         // 3 -> User 01, 4 -> User 02, 5 -> User 03, 6 -> User 04.
 | 
        
           |  |  | 56 |         // The user details for User 02 and User 03 have been removed from the backup file.
 | 
        
           | 1441 | ariadna | 57 |         $testfixture = self::get_fixture_path(__NAMESPACE__, 'question_attempts_missing_users.mbz');
 | 
        
           | 1 | efrain | 58 |   | 
        
           |  |  | 59 |         // Extract our test fixture, ready to be restored.
 | 
        
           |  |  | 60 |         $backuptempdir = 'aaa';
 | 
        
           |  |  | 61 |         $backuppath = make_backup_temp_directory($backuptempdir);
 | 
        
           |  |  | 62 |         get_file_packer('application/vnd.moodle.backup')->extract_to_pathname($testfixture, $backuppath);
 | 
        
           |  |  | 63 |   | 
        
           |  |  | 64 |         // Do the restore to new course with default settings.
 | 
        
           |  |  | 65 |         $categoryid = $DB->get_field('course_categories', 'MIN(id)', []);
 | 
        
           |  |  | 66 |         $courseid = restore_dbops::create_new_course('Test fullname', 'Test shortname', $categoryid);
 | 
        
           |  |  | 67 |   | 
        
           |  |  | 68 |         $controller = new restore_controller($backuptempdir, $courseid, backup::INTERACTIVE_NO, backup::MODE_GENERAL, $USER->id,
 | 
        
           |  |  | 69 |             backup::TARGET_NEW_COURSE);
 | 
        
           |  |  | 70 |   | 
        
           | 1441 | ariadna | 71 |         $controller->execute_precheck();
 | 
        
           |  |  | 72 |         $results = $controller->get_precheck_results();
 | 
        
           |  |  | 73 |         // Backup contains categories attached to deprecated contexts so the results should only contain warnings for these.
 | 
        
           |  |  | 74 |         $this->assertCount(2, $results['warnings']);
 | 
        
           |  |  | 75 |         foreach ($results['warnings'] as $warning) {
 | 
        
           |  |  | 76 |             $this->assertStringContainsString('will be created at a question bank module context by restore', $warning);
 | 
        
           |  |  | 77 |         }
 | 
        
           |  |  | 78 |         $this->assertArrayNotHasKey('errors', $results);
 | 
        
           |  |  | 79 |   | 
        
           | 1 | efrain | 80 |         $controller->execute_plan();
 | 
        
           |  |  | 81 |         $controller->destroy();
 | 
        
           |  |  | 82 |   | 
        
           |  |  | 83 |         // Grade restore also generates some debugging.
 | 
        
           |  |  | 84 |         $this->assertDebuggingCalledCount(2);
 | 
        
           |  |  | 85 |   | 
        
           |  |  | 86 |         $restoredquiz = $DB->get_record('quiz', []);
 | 
        
           |  |  | 87 |   | 
        
           |  |  | 88 |         // Assert logs were added for User 02 and User 03, due to missing mapping lookup.
 | 
        
           |  |  | 89 |         $loginfomessages = $DB->get_fieldset_select('backup_logs', 'message', 'backupid = ? AND loglevel = ?', [
 | 
        
           |  |  | 90 |             $controller->get_restoreid(),
 | 
        
           |  |  | 91 |             backup::LOG_INFO,
 | 
        
           |  |  | 92 |         ]);
 | 
        
           |  |  | 93 |   | 
        
           |  |  | 94 |         $this->assertContains("Mapped user ID not found for user 4, quiz {$restoredquiz->id}, attempt 1. Skipping quiz attempt",
 | 
        
           |  |  | 95 |             $loginfomessages);
 | 
        
           |  |  | 96 |         $this->assertContains("Mapped user ID not found for user 5, quiz {$restoredquiz->id}, attempt 1. Skipping quiz attempt",
 | 
        
           |  |  | 97 |             $loginfomessages);
 | 
        
           |  |  | 98 |   | 
        
           |  |  | 99 |         // User 01 has supplied the wrong answer, assert dates match the backup file too.
 | 
        
           |  |  | 100 |         $user01attempt = $DB->get_record('quiz_attempts', [
 | 
        
           |  |  | 101 |             'quiz' => $restoredquiz->id,
 | 
        
           |  |  | 102 |             'userid' => core_user::get_user_by_username('user01')->id,
 | 
        
           |  |  | 103 |         ]);
 | 
        
           |  |  | 104 |   | 
        
           |  |  | 105 |         $this->assertEquals(1634751274, $user01attempt->timestart);
 | 
        
           |  |  | 106 |         $this->assertEquals(1634751290, $user01attempt->timefinish);
 | 
        
           |  |  | 107 |         $this->assertEquals(0.0, (float) $user01attempt->sumgrades);
 | 
        
           |  |  | 108 |   | 
        
           |  |  | 109 |         // User 04 has supplied the correct answer, assert dates match the backup file too.
 | 
        
           |  |  | 110 |         $user04attempt = $DB->get_record('quiz_attempts', [
 | 
        
           |  |  | 111 |             'quiz' => $restoredquiz->id,
 | 
        
           |  |  | 112 |             'userid' => core_user::get_user_by_username('user04')->id,
 | 
        
           |  |  | 113 |         ]);
 | 
        
           |  |  | 114 |   | 
        
           |  |  | 115 |         $this->assertEquals(1634751341, $user04attempt->timestart);
 | 
        
           |  |  | 116 |         $this->assertEquals(1634751347, $user04attempt->timefinish);
 | 
        
           |  |  | 117 |         $this->assertEquals(1.0, (float) $user04attempt->sumgrades);
 | 
        
           |  |  | 118 |     }
 | 
        
           |  |  | 119 | }
 |