MDL-67795 h5p: move methods from player to helper
[moodle.git] / h5p / tests / api_test.php
CommitLineData
64a2bd19
SA
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/**
18 * Testing the H5P API.
19 *
20 * @package core_h5p
21 * @category test
22 * @copyright 2020 Sara Arjona <sara@moodle.com>
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 */
25
26declare(strict_types = 1);
27
28namespace core_h5p;
29
30defined('MOODLE_INTERNAL') || die();
31
32/**
33 * Test class covering the H5P API.
34 *
35 * @package core_h5p
36 * @copyright 2020 Sara Arjona <sara@moodle.com>
37 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
38 */
39class api_testcase extends \advanced_testcase {
40
41 /**
42 * Test the behaviour of delete_library().
43 *
44 * @dataProvider delete_library_provider
45 * @param string $libraryname Machine name of the library to delete.
46 * @param int $expectedh5p Total of H5P contents expected after deleting the library.
47 * @param int $expectedlibraries Total of H5P libraries expected after deleting the library.
48 * @param int $expectedcontents Total of H5P content_libraries expected after deleting the library.
49 * @param int $expecteddependencies Total of H5P library dependencies expected after deleting the library.
50 */
51 public function test_delete_library(string $libraryname, int $expectedh5p, int $expectedlibraries,
52 int $expectedcontents, int $expecteddependencies): void {
53 global $DB;
54
55 $this->setRunTestInSeparateProcess(true);
56 $this->resetAfterTest();
57
58 // Generate h5p related data.
59 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
60 $generator->generate_h5p_data();
61 $generator->create_library_record('H5P.TestingLibrary', 'TestingLibrary', 1, 0);
62
63 // Check the current content in H5P tables is the expected.
64 $counth5p = $DB->count_records('h5p');
65 $counth5plibraries = $DB->count_records('h5p_libraries');
66 $counth5pcontents = $DB->count_records('h5p_contents_libraries');
67 $counth5pdependencies = $DB->count_records('h5p_library_dependencies');
68
69 $this->assertSame(1, $counth5p);
70 $this->assertSame(7, $counth5plibraries);
71 $this->assertSame(5, $counth5pcontents);
72 $this->assertSame(7, $counth5pdependencies);
73
74 // Delete this library.
75 $factory = new factory();
76 $library = $DB->get_record('h5p_libraries', ['machinename' => $libraryname]);
77 if ($library) {
78 api::delete_library($factory, $library);
79 }
80
81 // Check the expected libraries and content have been removed.
82 $counth5p = $DB->count_records('h5p');
83 $counth5plibraries = $DB->count_records('h5p_libraries');
84 $counth5pcontents = $DB->count_records('h5p_contents_libraries');
85 $counth5pdependencies = $DB->count_records('h5p_library_dependencies');
86
87 $this->assertSame($expectedh5p, $counth5p);
88 $this->assertSame($expectedlibraries, $counth5plibraries);
89 $this->assertSame($expectedcontents, $counth5pcontents);
90 $this->assertSame($expecteddependencies, $counth5pdependencies);
91 }
92
93 /**
94 * Data provider for test_delete_library().
95 *
96 * @return array
97 */
98 public function delete_library_provider(): array {
99 return [
100 'Delete MainLibrary' => [
101 'MainLibrary',
102 0,
103 6,
104 0,
105 4,
106 ],
107 'Delete Library1' => [
108 'Library1',
109 0,
110 5,
111 0,
112 1,
113 ],
114 'Delete Library2' => [
115 'Library2',
116 0,
117 4,
118 0,
119 1,
120 ],
121 'Delete Library3' => [
122 'Library3',
123 0,
124 4,
125 0,
126 0,
127 ],
128 'Delete Library4' => [
129 'Library4',
130 0,
131 4,
132 0,
133 1,
134 ],
135 'Delete Library5' => [
136 'Library5',
137 0,
138 3,
139 0,
140 0,
141 ],
142 'Delete a library without dependencies' => [
143 'H5P.TestingLibrary',
144 1,
145 6,
146 5,
147 7,
148 ],
149 'Delete unexisting library' => [
150 'LibraryX',
151 1,
152 7,
153 5,
154 7,
155 ],
156 ];
157 }
158
159 /**
160 * Test the behaviour of get_dependent_libraries().
161 *
162 * @dataProvider get_dependent_libraries_provider
163 * @param string $libraryname Machine name of the library to delete.
164 * @param int $expectedvalue Total of H5P required libraries expected.
165 */
166 public function test_get_dependent_libraries(string $libraryname, int $expectedvalue): void {
167 global $DB;
168
169 $this->resetAfterTest();
170
171 // Generate h5p related data.
172 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
173 $generator->generate_h5p_data();
174 $generator->create_library_record('H5P.TestingLibrary', 'TestingLibrary', 1, 0);
175
176 // Get required libraries.
177 $library = $DB->get_record('h5p_libraries', ['machinename' => $libraryname], 'id');
178 if ($library) {
179 $libraries = api::get_dependent_libraries((int)$library->id);
180 } else {
181 $libraries = [];
182 }
183
184 $this->assertCount($expectedvalue, $libraries);
185 }
186
187 /**
188 * Data provider for test_get_dependent_libraries().
189 *
190 * @return array
191 */
192 public function get_dependent_libraries_provider(): array {
193 return [
194 'Main library of a content' => [
195 'MainLibrary',
196 0,
197 ],
198 'Library1' => [
199 'Library1',
200 1,
201 ],
202 'Library2' => [
203 'Library2',
204 2,
205 ],
206 'Library without dependencies' => [
207 'H5P.TestingLibrary',
208 0,
209 ],
210 'Unexisting library' => [
211 'LibraryX',
212 0,
213 ],
214 ];
215 }
216
217 /**
218 * Test the behaviour of get_library().
219 *
220 * @dataProvider get_library_provider
221 * @param string $libraryname Machine name of the library to delete.
222 * @param bool $emptyexpected Wether the expected result is empty or not.
223 */
224 public function test_get_library(string $libraryname, bool $emptyexpected): void {
225 global $DB;
226
227 $this->resetAfterTest();
228
229 // Generate h5p related data.
230 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
231 $generator->generate_h5p_data();
232 $generator->create_library_record('H5P.TestingLibrary', 'TestingLibrary', 1, 0);
233
234 // Get the library identifier.
235 $library = $DB->get_record('h5p_libraries', ['machinename' => $libraryname], 'id');
236 if ($library) {
237 $result = api::get_library((int)$library->id);
238 } else {
239 $result = null;
240 }
241
242 if ($emptyexpected) {
243 $this->assertEmpty($result);
244 } else {
245 $this->assertEquals($library->id, $result->id);
246 $this->assertEquals($libraryname, $result->machinename);
247 }
248
249 }
250
251 /**
252 * Data provider for test_get_library().
253 *
254 * @return array
255 */
256 public function get_library_provider(): array {
257 return [
258 'Main library of a content' => [
259 'MainLibrary',
260 false,
261 ],
262 'Library1' => [
263 'Library1',
264 false,
265 ],
266 'Library without dependencies' => [
267 'H5P.TestingLibrary',
268 false,
269 ],
270 'Unexisting library' => [
271 'LibraryX',
272 true,
273 ],
274 ];
275 }
153c4562
SA
276
277 /**
278 * Test the behaviour of get_content_from_pluginfile_url().
279 */
280 public function test_get_content_from_pluginfile_url(): void {
281 $this->setRunTestInSeparateProcess(true);
282 $this->resetAfterTest();
283 $factory = new factory();
284
285 // Create the H5P data.
286 $filename = 'find-the-words.h5p';
287 $path = __DIR__ . '/fixtures/' . $filename;
288 $fakefile = helper::create_fake_stored_file_from_path($path);
289 $config = (object)[
290 'frame' => 1,
291 'export' => 1,
292 'embed' => 0,
293 'copyright' => 0,
294 ];
295
296 // Get URL for this H5P content file.
297 $syscontext = \context_system::instance();
298 $url = \moodle_url::make_pluginfile_url(
299 $syscontext->id,
300 \core_h5p\file_storage::COMPONENT,
301 'unittest',
302 $fakefile->get_itemid(),
303 '/',
304 $filename
305 );
306
307 // Scenario 1: Get the H5P for this URL and check there isn't any existing H5P (because it hasn't been saved).
308 list($newfile, $h5p) = api::get_content_from_pluginfile_url($url->out());
309 $this->assertEquals($fakefile->get_pathnamehash(), $newfile->get_pathnamehash());
310 $this->assertEquals($fakefile->get_contenthash(), $newfile->get_contenthash());
311 $this->assertFalse($h5p);
312
313 // Scenario 2: Save the H5P and check now the H5P is exactly the same as the original one.
314 $h5pid = helper::save_h5p($factory, $fakefile, $config);
315 list($newfile, $h5p) = api::get_content_from_pluginfile_url($url->out());
316
317 $this->assertEquals($h5pid, $h5p->id);
318 $this->assertEquals($fakefile->get_pathnamehash(), $h5p->pathnamehash);
319 $this->assertEquals($fakefile->get_contenthash(), $h5p->contenthash);
320
321 // Scenario 3: Get the H5P for an unexisting H5P file.
322 $url = \moodle_url::make_pluginfile_url(
323 $syscontext->id,
324 \core_h5p\file_storage::COMPONENT,
325 'unittest',
326 $fakefile->get_itemid(),
327 '/',
328 'unexisting.h5p'
329 );
330 list($newfile, $h5p) = api::get_content_from_pluginfile_url($url->out());
331 $this->assertFalse($newfile);
332 $this->assertFalse($h5p);
333 }
334
335 /**
336 * Test the behaviour of create_content_from_pluginfile_url().
337 */
338 public function test_create_content_from_pluginfile_url(): void {
339 global $DB;
340
341 $this->setRunTestInSeparateProcess(true);
342 $this->resetAfterTest();
343 $factory = new factory();
344
345 // Create the H5P data.
346 $filename = 'find-the-words.h5p';
347 $path = __DIR__ . '/fixtures/' . $filename;
348 $fakefile = helper::create_fake_stored_file_from_path($path);
349 $config = (object)[
350 'frame' => 1,
351 'export' => 1,
352 'embed' => 0,
353 'copyright' => 0,
354 ];
355
356 // Get URL for this H5P content file.
357 $syscontext = \context_system::instance();
358 $url = \moodle_url::make_pluginfile_url(
359 $syscontext->id,
360 \core_h5p\file_storage::COMPONENT,
361 'unittest',
362 $fakefile->get_itemid(),
363 '/',
364 $filename
365 );
366
367 // Scenario 1: Create the H5P from this URL and check the content is exactly the same as the fake file.
368 $messages = new \stdClass();
369 list($newfile, $h5pid) = api::create_content_from_pluginfile_url($url->out(), $config, $factory, $messages);
370 $this->assertNotFalse($h5pid);
371 $h5p = $DB->get_record('h5p', ['id' => $h5pid]);
372 $this->assertEquals($fakefile->get_pathnamehash(), $h5p->pathnamehash);
373 $this->assertEquals($fakefile->get_contenthash(), $h5p->contenthash);
374 $this->assertTrue(empty($messages->error));
375 $this->assertTrue(empty($messages->info));
376
377 // Scenario 2: Create the H5P for an unexisting H5P file.
378 $url = \moodle_url::make_pluginfile_url(
379 $syscontext->id,
380 \core_h5p\file_storage::COMPONENT,
381 'unittest',
382 $fakefile->get_itemid(),
383 '/',
384 'unexisting.h5p'
385 );
386 list($newfile, $h5p) = api::create_content_from_pluginfile_url($url->out(), $config, $factory, $messages);
387 $this->assertFalse($newfile);
388 $this->assertFalse($h5p);
389 $this->assertTrue(empty($messages->error));
390 $this->assertTrue(empty($messages->info));
391 }
392
393 /**
394 * Test the behaviour of delete_content_from_pluginfile_url().
395 */
396 public function test_delete_content_from_pluginfile_url(): void {
397 global $DB;
398
399 $this->setRunTestInSeparateProcess(true);
400 $this->resetAfterTest();
401 $factory = new factory();
402
403 // Create the H5P data.
404 $filename = 'find-the-words.h5p';
405 $path = __DIR__ . '/fixtures/' . $filename;
406 $fakefile = helper::create_fake_stored_file_from_path($path);
407 $config = (object)[
408 'frame' => 1,
409 'export' => 1,
410 'embed' => 0,
411 'copyright' => 0,
412 ];
413
414 // Get URL for this H5P content file.
415 $syscontext = \context_system::instance();
416 $url = \moodle_url::make_pluginfile_url(
417 $syscontext->id,
418 \core_h5p\file_storage::COMPONENT,
419 'unittest',
420 $fakefile->get_itemid(),
421 '/',
422 $filename
423 );
424
425 // Scenario 1: Try to remove the H5P content for an undeployed file.
426 list($newfile, $h5p) = api::get_content_from_pluginfile_url($url->out());
427 $this->assertEquals(0, $DB->count_records('h5p'));
428 api::delete_content_from_pluginfile_url($url->out(), $factory);
429 $this->assertEquals(0, $DB->count_records('h5p'));
430
431 // Scenario 2: Deploy an H5P from this URL, check it's created, remove it and check it has been removed as expected.
432 $this->assertEquals(0, $DB->count_records('h5p'));
433
434 $messages = new \stdClass();
435 list($newfile, $h5pid) = api::create_content_from_pluginfile_url($url->out(), $config, $factory, $messages);
436 $this->assertEquals(1, $DB->count_records('h5p'));
437
438 api::delete_content_from_pluginfile_url($url->out(), $factory);
439 $this->assertEquals(0, $DB->count_records('h5p'));
440
441 // Scenario 3: Try to remove the H5P for an unexisting H5P URL.
442 $url = \moodle_url::make_pluginfile_url(
443 $syscontext->id,
444 \core_h5p\file_storage::COMPONENT,
445 'unittest',
446 $fakefile->get_itemid(),
447 '/',
448 'unexisting.h5p'
449 );
450 $this->assertEquals(0, $DB->count_records('h5p'));
451 api::delete_content_from_pluginfile_url($url->out(), $factory);
452 $this->assertEquals(0, $DB->count_records('h5p'));
453 }
64a2bd19 454}