Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
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 quizaccess_seb\external;
18
 
19
use quizaccess_seb\seb_quiz_settings;
20
 
21
defined('MOODLE_INTERNAL') || die();
22
 
23
require_once(__DIR__ . '/../test_helper_trait.php');
24
 
25
/**
26
 * PHPUnit tests for external function.
27
 *
28
 * @package    quizaccess_seb
29
 * @author     Andrew Madden <andrewmadden@catalyst-au.net>
30
 * @copyright  2021 Catalyst IT
31
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
32
 * @covers \quizaccess_seb\external\validate_quiz_access
33
 */
34
class validate_quiz_access_test extends \advanced_testcase {
35
    use \quizaccess_seb_test_helper_trait;
36
 
37
    /**
38
     * This method runs before every test.
39
     */
40
    public function setUp(): void {
41
        parent::setUp();
42
        $this->resetAfterTest();
43
 
44
        // Generate data objects.
45
        $this->course = $this->getDataGenerator()->create_course();
46
        $this->quiz = $this->create_test_quiz($this->course);
47
        $this->user = $this->getDataGenerator()->create_user();
48
        $this->getDataGenerator()->enrol_user($this->user->id, $this->course->id, 'student');
49
        $this->setUser($this->user);
50
    }
51
 
52
    /**
53
     * Bad parameter provider.
54
     *
55
     * @return array
56
     */
57
    public function bad_parameters_provider(): array {
58
        return [
59
            'no params' => [
60
                'cmid' => null,
61
                'url' => null,
62
                'configkey' => null,
63
                '/Invalid parameter value detected \(Missing required key in single structure: cmid\)/'
64
            ],
65
            'no course module id' => [
66
                'cmid' => null,
67
                'url' => 'https://www.example.com/moodle',
68
                'configkey' => hash('sha256', 'configkey'),
69
                '/Invalid parameter value detected \(Missing required key in single structure: cmid\)/'
70
            ],
71
            'no url' => [
72
                'cmid' => 123,
73
                'url' => null,
74
                'configkey' => hash('sha256', 'configkey'),
75
                '/Invalid parameter value detected \(Missing required key in single structure: url\)/'
76
            ],
77
            'cmid is not an int' => [
78
                'cmid' => 'test',
79
                'url' => 'https://www.example.com/moodle',
80
                'configkey' => null,
81
                '/Invalid external api parameter: the value is "test", the server was expecting "int" type/'
82
            ],
83
            'url is not a url' => [
84
                'cmid' => 123,
85
                'url' => 123,
86
                'configkey' => hash('sha256', 'configkey'),
87
                '/Invalid external api parameter: the value is "123", the server was expecting "url" type/'
88
            ],
89
        ];
90
    }
91
 
92
    /**
93
     * Test exception thrown for bad parameters.
94
     *
95
     * @param mixed $cmid Course module id.
96
     * @param mixed $url Page URL.
97
     * @param mixed $configkey SEB config key.
98
     * @param mixed $messageregex Error message regex to check.
99
     *
100
     * @dataProvider bad_parameters_provider
101
     */
11 efrain 102
    public function test_invalid_parameters($cmid, $url, $configkey, $messageregex): void {
1 efrain 103
        $params = [];
104
        if (!empty($cmid)) {
105
            $params['cmid'] = $cmid;
106
        }
107
        if (!empty($url)) {
108
            $params['url'] = $url;
109
        }
110
        if (!empty($configkey)) {
111
            $params['configkey'] = $configkey;
112
        }
113
 
114
        $this->expectException(\invalid_parameter_exception::class);
115
        $this->expectExceptionMessageMatches($messageregex);
116
        \core_external\external_api::validate_parameters(validate_quiz_keys::execute_parameters(), $params);
117
    }
118
 
119
    /**
120
     * Test that the user has permissions to access context.
121
     */
11 efrain 122
    public function test_context_is_not_valid_for_user(): void {
1 efrain 123
        // Set user as user not enrolled in course and quiz.
124
        $this->user = $this->getDataGenerator()->create_user();
125
        $this->setUser($this->user);
126
 
127
        $this->expectException(\require_login_exception::class);
128
        $this->expectExceptionMessage('Course or activity not accessible. (Not enrolled)');
129
        validate_quiz_keys::execute($this->quiz->cmid, 'https://www.example.com/moodle', 'configkey');
130
    }
131
 
132
    /**
133
     * Test exception thrown when no key provided.
134
     */
11 efrain 135
    public function test_no_keys_provided(): void {
1 efrain 136
        $this->expectException(\invalid_parameter_exception::class);
137
        $this->expectExceptionMessage('At least one Safe Exam Browser key must be provided.');
138
        validate_quiz_keys::execute($this->quiz->cmid, 'https://www.example.com/moodle');
139
    }
140
 
141
    /**
142
     * Test exception thrown if cmid doesn't match a quiz.
143
     */
11 efrain 144
    public function test_quiz_does_not_exist(): void {
1 efrain 145
        $this->setAdminUser();
146
        $forum = $this->getDataGenerator()->create_module('forum', ['course' => $this->course->id]);
147
        $this->expectException(\invalid_parameter_exception::class);
148
        $this->expectExceptionMessage('Quiz not found matching course module ID: ' . $forum->cmid);
149
        validate_quiz_keys::execute($forum->cmid, 'https://www.example.com/moodle', 'configkey');
150
    }
151
 
152
    /**
153
     * Test config key is valid.
154
     */
11 efrain 155
    public function test_config_key_valid(): void {
1 efrain 156
        $sink = $this->redirectEvents();
157
        // Test settings to populate the quiz.
158
        $settings = $this->get_test_settings([
159
            'quizid' => $this->quiz->id,
160
            'cmid' => $this->quiz->cmid,
161
        ]);
162
        $url = 'https://www.example.com/moodle';
163
 
164
        // Create the quiz settings.
165
        $quizsettings = new seb_quiz_settings(0, $settings);
166
        $quizsettings->save();
167
 
168
        $fullconfigkey = hash('sha256', $url . $quizsettings->get_config_key());
169
        $result = validate_quiz_keys::execute($this->quiz->cmid, $url, $fullconfigkey);
170
        $this->assertTrue($result['configkey']);
171
        $this->assertTrue($result['browserexamkey']);
172
 
173
        $events = $sink->get_events();
174
        $this->assertCount(0, $events);
175
    }
176
 
177
    /**
178
     * Test config key is not valid.
179
     */
11 efrain 180
    public function test_config_key_not_valid(): void {
1 efrain 181
        $sink = $this->redirectEvents();
182
        // Test settings to populate the quiz.
183
        $settings = $this->get_test_settings([
184
            'quizid' => $this->quiz->id,
185
            'cmid' => $this->quiz->cmid,
186
        ]);
187
 
188
        // Create the quiz settings.
189
        $quizsettings = new seb_quiz_settings(0, $settings);
190
        $quizsettings->save();
191
 
192
        $result = validate_quiz_keys::execute($this->quiz->cmid, 'https://www.example.com/moodle', 'badconfigkey');
193
        $this->assertFalse($result['configkey']);
194
        $this->assertTrue($result['browserexamkey']);
195
        $events = $sink->get_events();
196
        $this->assertCount(1, $events);
197
        $event = reset($events);
198
        $this->assertInstanceOf('\quizaccess_seb\event\access_prevented', $event);
199
        $this->assertStringContainsString('Invalid SEB config key', $event->get_description());
200
    }
201
 
202
    /**
203
     * Test browser exam key is valid.
204
     */
11 efrain 205
    public function test_browser_exam_key_valid(): void {
1 efrain 206
        $sink = $this->redirectEvents();
207
        // Test settings to populate the quiz.
208
        $url = 'https://www.example.com/moodle';
209
        $validbrowserexamkey = hash('sha256', 'validbrowserexamkey');
210
        $settings = $this->get_test_settings([
211
            'quizid' => $this->quiz->id,
212
            'cmid' => $this->quiz->cmid,
213
            'requiresafeexambrowser' => \quizaccess_seb\settings_provider::USE_SEB_CLIENT_CONFIG,
214
            'allowedbrowserexamkeys' => $validbrowserexamkey,
215
        ]);
216
 
217
        // Create the quiz settings.
218
        $quizsettings = new seb_quiz_settings(0, $settings);
219
        $quizsettings->save();
220
 
221
        $fullbrowserexamkey = hash('sha256', $url . $validbrowserexamkey);
222
        $result = validate_quiz_keys::execute($this->quiz->cmid, $url, null, $fullbrowserexamkey);
223
        $this->assertTrue($result['configkey']);
224
        $this->assertTrue($result['browserexamkey']);
225
        $events = $sink->get_events();
226
        $this->assertCount(0, $events);
227
    }
228
 
229
    /**
230
     * Test browser exam key is not valid.
231
     */
11 efrain 232
    public function test_browser_exam_key_not_valid(): void {
1 efrain 233
        $sink = $this->redirectEvents();
234
        // Test settings to populate the quiz.
235
        $validbrowserexamkey = hash('sha256', 'validbrowserexamkey');
236
        $settings = $this->get_test_settings([
237
            'quizid' => $this->quiz->id,
238
            'cmid' => $this->quiz->cmid,
239
            'requiresafeexambrowser' => \quizaccess_seb\settings_provider::USE_SEB_CLIENT_CONFIG,
240
            'allowedbrowserexamkeys' => $validbrowserexamkey,
241
        ]);
242
 
243
        // Create the quiz settings.
244
        $quizsettings = new seb_quiz_settings(0, $settings);
245
        $quizsettings->save();
246
 
247
        $result = validate_quiz_keys::execute($this->quiz->cmid, 'https://www.example.com/moodle', null,
248
                hash('sha256', 'badbrowserexamkey'));
249
        $this->assertTrue($result['configkey']);
250
        $this->assertFalse($result['browserexamkey']);
251
        $events = $sink->get_events();
252
        $this->assertCount(1, $events);
253
        $event = reset($events);
254
        $this->assertInstanceOf('\quizaccess_seb\event\access_prevented', $event);
255
        $this->assertStringContainsString('Invalid SEB browser key', $event->get_description());
256
    }
257
 
258
}