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 declare(strict_types = 1); 18 19 namespace mod_choice; 20 21 use advanced_testcase; 22 use cm_info; 23 use coding_exception; 24 use mod_choice\completion\custom_completion; 25 use moodle_exception; 26 27 defined('MOODLE_INTERNAL') || die(); 28 29 global $CFG; 30 require_once($CFG->libdir . '/completionlib.php'); 31 32 /** 33 * Class for unit testing mod_choice/custom_completion. 34 * 35 * @package mod_choice 36 * @copyright 2021 Jun Pataleta <jun@moodle.com> 37 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 38 */ 39 class custom_completion_test extends advanced_testcase { 40 41 /** 42 * Data provider for get_state(). 43 * 44 * @return array[] 45 */ 46 public function get_state_provider(): array { 47 return [ 48 'Undefined rule' => [ 49 'somenonexistentrule', COMPLETION_DISABLED, false, null, coding_exception::class 50 ], 51 'Rule not available' => [ 52 'completionsubmit', COMPLETION_DISABLED, false, null, moodle_exception::class 53 ], 54 'Rule available, user has not submitted' => [ 55 'completionsubmit', COMPLETION_ENABLED, false, COMPLETION_INCOMPLETE, null 56 ], 57 'Rule available, user has submitted' => [ 58 'completionsubmit', COMPLETION_ENABLED, true, COMPLETION_COMPLETE, null 59 ], 60 ]; 61 } 62 63 /** 64 * Test for get_state(). 65 * 66 * @dataProvider get_state_provider 67 * @param string $rule The custom completion rule. 68 * @param int $available Whether this rule is available. 69 * @param bool $submitted Whether the user has made a choice. 70 * @param int|null $status Expected status. 71 * @param string|null $exception Expected exception. 72 */ 73 public function test_get_state(string $rule, int $available, ?bool $submitted, ?int $status, ?string $exception) { 74 global $DB; 75 76 if (!is_null($exception)) { 77 $this->expectException($exception); 78 } 79 80 // Custom completion rule data for cm_info::customdata. 81 $customdataval = [ 82 'customcompletionrules' => [ 83 $rule => $available 84 ] 85 ]; 86 87 // Build a mock cm_info instance. 88 $mockcminfo = $this->getMockBuilder(cm_info::class) 89 ->disableOriginalConstructor() 90 ->onlyMethods(['__get']) 91 ->getMock(); 92 93 // Mock the return of the magic getter method when fetching the cm_info object's customdata and instance values. 94 $mockcminfo->expects($this->any()) 95 ->method('__get') 96 ->will($this->returnValueMap([ 97 ['customdata', $customdataval], 98 ['instance', 1], 99 ])); 100 101 // Mock the DB calls. 102 $DB = $this->createMock(get_class($DB)); 103 $DB->expects($this->atMost(1)) 104 ->method('record_exists') 105 ->willReturn($submitted); 106 107 $customcompletion = new custom_completion($mockcminfo, 2); 108 $this->assertEquals($status, $customcompletion->get_state($rule)); 109 } 110 111 /** 112 * Test for get_defined_custom_rules(). 113 */ 114 public function test_get_defined_custom_rules() { 115 $rules = custom_completion::get_defined_custom_rules(); 116 $this->assertCount(1, $rules); 117 $this->assertEquals('completionsubmit', reset($rules)); 118 } 119 120 /** 121 * Test for get_defined_custom_rule_descriptions(). 122 */ 123 public function test_get_custom_rule_descriptions() { 124 // Get defined custom rules. 125 $rules = custom_completion::get_defined_custom_rules(); 126 127 // Build a mock cm_info instance. 128 $mockcminfo = $this->getMockBuilder(cm_info::class) 129 ->disableOriginalConstructor() 130 ->onlyMethods(['__get']) 131 ->getMock(); 132 133 // Instantiate a custom_completion object using the mocked cm_info. 134 $customcompletion = new custom_completion($mockcminfo, 1); 135 136 // Get custom rule descriptions. 137 $ruledescriptions = $customcompletion->get_custom_rule_descriptions(); 138 139 // Confirm that defined rules and rule descriptions are consistent with each other. 140 $this->assertEquals(count($rules), count($ruledescriptions)); 141 foreach ($rules as $rule) { 142 $this->assertArrayHasKey($rule, $ruledescriptions); 143 } 144 } 145 146 /** 147 * Test for is_defined(). 148 */ 149 public function test_is_defined() { 150 // Build a mock cm_info instance. 151 $mockcminfo = $this->getMockBuilder(cm_info::class) 152 ->disableOriginalConstructor() 153 ->getMock(); 154 155 $customcompletion = new custom_completion($mockcminfo, 1); 156 157 // Rule is defined. 158 $this->assertTrue($customcompletion->is_defined('completionsubmit')); 159 160 // Undefined rule. 161 $this->assertFalse($customcompletion->is_defined('somerandomrule')); 162 } 163 164 /** 165 * Data provider for test_get_available_custom_rules(). 166 * 167 * @return array[] 168 */ 169 public function get_available_custom_rules_provider(): array { 170 return [ 171 'Completion submit available' => [ 172 COMPLETION_ENABLED, ['completionsubmit'] 173 ], 174 'Completion submit not available' => [ 175 COMPLETION_DISABLED, [] 176 ], 177 ]; 178 } 179 180 /** 181 * Test for get_available_custom_rules(). 182 * 183 * @dataProvider get_available_custom_rules_provider 184 * @param int $status 185 * @param array $expected 186 */ 187 public function test_get_available_custom_rules(int $status, array $expected) { 188 $customdataval = [ 189 'customcompletionrules' => [ 190 'completionsubmit' => $status 191 ] 192 ]; 193 194 // Build a mock cm_info instance. 195 $mockcminfo = $this->getMockBuilder(cm_info::class) 196 ->disableOriginalConstructor() 197 ->onlyMethods(['__get']) 198 ->getMock(); 199 200 // Mock the return of magic getter for the customdata attribute. 201 $mockcminfo->expects($this->any()) 202 ->method('__get') 203 ->with('customdata') 204 ->willReturn($customdataval); 205 206 $customcompletion = new custom_completion($mockcminfo, 1); 207 $this->assertEquals($expected, $customcompletion->get_available_custom_rules()); 208 } 209 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body