MDL-67795 h5p: move methods from player to helper
[moodle.git] / h5p / tests / helper_test.php
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/>.
17 /**
18  * Testing the H5P helper.
19  *
20  * @package    core_h5p
21  * @category   test
22  * @copyright  2019 Sara Arjona <sara@moodle.com>
23  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24  */
26 declare(strict_types = 1);
28 namespace core_h5p;
30 use advanced_testcase;
32 /**
33  * Test class covering the H5P helper.
34  *
35  * @package    core_h5p
36  * @copyright  2019 Sara Arjona <sara@moodle.com>
37  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
38  */
39 class helper_testcase extends \advanced_testcase {
41     /**
42      * Test the behaviour of get_display_options().
43      *
44      * @dataProvider display_options_provider
45      * @param  bool   $frame     Whether the frame should be displayed or not
46      * @param  bool   $export    Whether the export action button should be displayed or not
47      * @param  bool   $embed     Whether the embed action button should be displayed or not
48      * @param  bool   $copyright Whether the copyright action button should be displayed or not
49      * @param  int    $expected The expectation with the displayoptions value
50      */
51     public function test_display_options(bool $frame, bool $export, bool $embed, bool $copyright, int $expected): void {
52         $this->setRunTestInSeparateProcess(true);
53         $this->resetAfterTest();
55         $factory = new \core_h5p\factory();
56         $core = $factory->get_core();
57         $config = (object)[
58             'frame' => $frame,
59             'export' => $export,
60             'embed' => $embed,
61             'copyright' => $copyright,
62         ];
64         // Test getting display options.
65         $displayoptions = helper::get_display_options($core, $config);
66         $this->assertEquals($expected, $displayoptions);
68         // Test decoding display options.
69         $decoded = helper::decode_display_options($core, $expected);
70         $this->assertEquals($decoded->export, $config->export);
71         $this->assertEquals($decoded->embed, $config->embed);
72         $this->assertEquals($decoded->copyright, $config->copyright);
73     }
75     /**
76      * Data provider for test_get_display_options().
77      *
78      * @return array
79      */
80     public function display_options_provider(): array {
81         return [
82             'All display options disabled' => [
83                 false,
84                 false,
85                 false,
86                 false,
87                 15,
88             ],
89             'All display options enabled' => [
90                 true,
91                 true,
92                 true,
93                 true,
94                 0,
95             ],
96             'Frame disabled and the rest enabled' => [
97                 false,
98                 true,
99                 true,
100                 true,
101                 0,
102             ],
103             'Only export enabled' => [
104                 false,
105                 true,
106                 false,
107                 false,
108                 12,
109             ],
110             'Only embed enabled' => [
111                 false,
112                 false,
113                 true,
114                 false,
115                 10,
116             ],
117             'Only copyright enabled' => [
118                 false,
119                 false,
120                 false,
121                 true,
122                 6,
123             ],
124         ];
125     }
127     /**
128      * Test the behaviour of save_h5p() when there are some missing libraries in the system.
129      * @runInSeparateProcess
130      */
131     public function test_save_h5p_missing_libraries(): void {
132         $this->resetAfterTest();
133         $factory = new \core_h5p\factory();
135         // Create a user.
136         $user = $this->getDataGenerator()->create_user();
137         $this->setUser($user);
139         // This is a valid .H5P file.
140         $path = __DIR__ . '/fixtures/greeting-card-887.h5p';
141         $file = helper::create_fake_stored_file_from_path($path, (int)$user->id);
142         $factory->get_framework()->set_file($file);
144         $config = (object)[
145             'frame' => 1,
146             'export' => 1,
147             'embed' => 0,
148             'copyright' => 0,
149         ];
151         // There are some missing libraries in the system, so an error should be returned.
152         $h5pid = helper::save_h5p($factory, $file, $config);
153         $this->assertFalse($h5pid);
154         $errors = $factory->get_framework()->getMessages('error');
155         $this->assertCount(1, $errors);
156         $error = reset($errors);
157         $this->assertEquals('missing-required-library', $error->code);
158         $this->assertEquals('Missing required library H5P.GreetingCard 1.0', $error->message);
159     }
161     /**
162      * Test the behaviour of save_h5p() when the libraries exist in the system.
163      * @runInSeparateProcess
164      */
165     public function test_save_h5p_existing_libraries(): void {
166         global $DB;
168         $this->resetAfterTest();
169         $factory = new \core_h5p\factory();
171         // Create a user.
172         $user = $this->getDataGenerator()->create_user();
173         $this->setUser($user);
175         // This is a valid .H5P file.
176         $path = __DIR__ . '/fixtures/greeting-card-887.h5p';
177         $file = helper::create_fake_stored_file_from_path($path, (int)$user->id);
178         $factory->get_framework()->set_file($file);
180         $config = (object)[
181             'frame' => 1,
182             'export' => 1,
183             'embed' => 0,
184             'copyright' => 0,
185         ];
186         // The required libraries exist in the system before saving the .h5p file.
187         $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
188         $lib = $generator->create_library_record('H5P.GreetingCard', 'GreetingCard', 1, 0);
189         $h5pid = helper::save_h5p($factory, $file, $config);
190         $this->assertNotEmpty($h5pid);
192         // No errors are raised.
193         $errors = $factory->get_framework()->getMessages('error');
194         $this->assertCount(0, $errors);
196         // And the content in the .h5p file has been saved as expected.
197         $h5p = $DB->get_record('h5p', ['id' => $h5pid]);
198         $this->assertEquals($lib->id, $h5p->mainlibraryid);
199         $this->assertEquals(helper::get_display_options($factory->get_core(), $config), $h5p->displayoptions);
200         $this->assertContains('Hello world!', $h5p->jsoncontent);
201     }
203     /**
204      * Test the behaviour of save_h5p() when the .h5p file is invalid.
205      * @runInSeparateProcess
206      */
207     public function test_save_h5p_invalid_file(): void {
208         $this->resetAfterTest();
209         $factory = new \core_h5p\factory();
211         // Create a user.
212         $user = $this->getDataGenerator()->create_user();
213         $this->setUser($user);
215         // Prepare an invalid .H5P file.
216         $path = __DIR__ . '/fixtures/h5ptest.zip';
217         $file = helper::create_fake_stored_file_from_path($path, (int)$user->id);
218         $factory->get_framework()->set_file($file);
219         $config = (object)[
220             'frame' => 1,
221             'export' => 1,
222             'embed' => 0,
223             'copyright' => 0,
224         ];
226         // When saving an invalid .h5p file, an error should be raised.
227         $h5pid = helper::save_h5p($factory, $file, $config);
228         $this->assertFalse($h5pid);
229         $errors = $factory->get_framework()->getMessages('error');
230         $this->assertCount(2, $errors);
232         $expectederrorcodes = ['invalid-content-folder', 'invalid-h5p-json-file'];
233         foreach ($errors as $error) {
234             $this->assertContains($error->code, $expectederrorcodes);
235         }
236     }
238     /**
239      * Test the behaviour of can_deploy_package().
240      */
241     public function test_can_deploy_package(): void {
242         $this->resetAfterTest();
243         $factory = new \core_h5p\factory();
245         // Create a user.
246         $user = $this->getDataGenerator()->create_user();
247         $admin = get_admin();
249         // Prepare a valid .H5P file.
250         $path = __DIR__ . '/fixtures/greeting-card-887.h5p';
252         // Files created by users can't be deployed.
253         $file = helper::create_fake_stored_file_from_path($path, (int)$user->id);
254         $factory->get_framework()->set_file($file);
255         $candeploy = helper::can_deploy_package($file);
256         $this->assertFalse($candeploy);
258         // Files created by admins can be deployed, even when the current user is not the admin.
259         $this->setUser($user);
260         $file = helper::create_fake_stored_file_from_path($path, (int)$admin->id);
261         $factory->get_framework()->set_file($file);
262         $candeploy = helper::can_deploy_package($file);
263         $this->assertTrue($candeploy);
264     }
266     /**
267      * Test the behaviour of can_update_library().
268      */
269     public function test_can_update_library(): void {
270         $this->resetAfterTest();
271         $factory = new \core_h5p\factory();
273         // Create a user.
274         $user = $this->getDataGenerator()->create_user();
275         $admin = get_admin();
277         // Prepare a valid .H5P file.
278         $path = __DIR__ . '/fixtures/greeting-card-887.h5p';
280         // Libraries can't be updated when the file has been created by users.
281         $file = helper::create_fake_stored_file_from_path($path, (int)$user->id);
282         $factory->get_framework()->set_file($file);
283         $candeploy = helper::can_update_library($file);
284         $this->assertFalse($candeploy);
286         // Libraries can be updated when the file has been created by admin, even when the current user is not the admin.
287         $this->setUser($user);
288         $file = helper::create_fake_stored_file_from_path($path, (int)$admin->id);
289         $factory->get_framework()->set_file($file);
290         $candeploy = helper::can_update_library($file);
291         $this->assertTrue($candeploy);
292     }
294     /**
295      * Test the behaviour of get_messages().
296      */
297     public function test_get_messages(): void {
298         $this->resetAfterTest();
300         $factory = new \core_h5p\factory();
301         $messages = new \stdClass();
303         helper::get_messages($messages, $factory);
304         $this->assertTrue(empty($messages->error));
305         $this->assertTrue(empty($messages->info));
307         // Add an some messages manually and check they are still there.
308         $messages->error['error1'] = 'Testing ERROR message';
309         $messages->info['info1'] = 'Testing INFO message';
310         $messages->info['info2'] = 'Testing INFO message';
311         helper::get_messages($messages, $factory);
312         $this->assertCount(1, $messages->error);
313         $this->assertCount(2, $messages->info);
315         // When saving an invalid .h5p file, 6 errors should be raised.
316         $path = __DIR__ . '/fixtures/h5ptest.zip';
317         $file = helper::create_fake_stored_file_from_path($path);
318         $factory->get_framework()->set_file($file);
319         $config = (object)[
320             'frame' => 1,
321             'export' => 1,
322             'embed' => 0,
323             'copyright' => 0,
324         ];
325         $h5pid = helper::save_h5p($factory, $file, $config);
326         $this->assertFalse($h5pid);
327         helper::get_messages($messages, $factory);
328         $this->assertCount(7, $messages->error);
329         $this->assertCount(2, $messages->info);
330     }