Proyectos de Subversion Moodle

Rev

Ir a la última revisión | | 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 core_h5p;
18
 
19
use core_collator;
20
use Moodle\H5PCore;
21
use Moodle\H5PDisplayOptionBehaviour;
22
 
23
// phpcs:disable moodle.NamingConventions.ValidFunctionName.LowercaseMethod
24
 
25
/**
26
 *
27
 * Test class covering the H5PFrameworkInterface interface implementation.
28
 *
29
 * @package    core_h5p
30
 * @category   test
31
 * @copyright  2019 Mihail Geshoski <mihail@moodle.com>
32
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
33
 * @covers     \core_h5p\framework
34
 * @runTestsInSeparateProcesses
35
 */
36
class framework_test extends \advanced_testcase {
37
 
38
    /** @var \core_h5p\framework */
39
    private $framework;
40
 
41
    /**
42
     * Set up function for tests.
43
     */
44
    public function setUp(): void {
45
        $factory = new \core_h5p\factory();
46
        $this->framework = $factory->get_framework();
47
    }
48
 
49
    /**
50
     * Test the behaviour of getPlatformInfo().
51
     */
52
    public function test_getPlatformInfo() {
53
        global $CFG;
54
 
55
        $platforminfo = $this->framework->getPlatformInfo();
56
 
57
        $expected = array(
58
            'name' => 'Moodle',
59
            'version' => $CFG->version,
60
            'h5pVersion' => $CFG->version
61
        );
62
 
63
        $this->assertEquals($expected, $platforminfo);
64
    }
65
 
66
    /**
67
     * Test the behaviour of fetchExternalData() when the store path is not defined.
68
     *
69
     * This test is intensive and requires downloading content of an external file,
70
     * therefore it might take longer time to execute.
71
     * In order to execute this test PHPUNIT_LONGTEST should be set to true in phpunit.xml or directly in config.php.
72
     */
73
    public function test_fetchExternalData_no_path_defined() {
74
 
75
        if (!PHPUNIT_LONGTEST) {
76
            $this->markTestSkipped('PHPUNIT_LONGTEST is not defined');
77
        }
78
 
79
        $this->resetAfterTest();
80
 
81
        $library = 'H5P.Accordion';
82
        // Provide a valid URL to an external H5P content.
83
        $url = $this->getExternalTestFileUrl('/'.$library.'.h5p');
84
 
85
        // Test fetching an external H5P content without defining a path to where the file should be stored.
86
        $data = $this->framework->fetchExternalData($url, null, true);
87
 
88
        // The response should not be empty and return true if the file was successfully downloaded.
89
        $this->assertNotEmpty($data);
90
        $this->assertTrue($data);
91
 
92
        $h5pfolderpath = $this->framework->getUploadedH5pFolderPath();
93
        // The uploaded file should exist on the filesystem.
94
        $this->assertTrue(file_exists($h5pfolderpath . '.h5p'));
95
    }
96
 
97
    /**
98
     * Test the behaviour of fetchExternalData() when the store path is defined.
99
     *
100
     * This test is intensive and requires downloading content of an external file,
101
     * therefore it might take longer time to execute.
102
     * In order to execute this test PHPUNIT_LONGTEST should be set to true in phpunit.xml or directly in config.php.
103
     */
104
    public function test_fetchExternalData_path_defined() {
105
        global $CFG;
106
 
107
        if (!PHPUNIT_LONGTEST) {
108
            $this->markTestSkipped('PHPUNIT_LONGTEST is not defined');
109
        }
110
 
111
        $this->resetAfterTest();
112
 
113
        $library = 'H5P.Accordion';
114
        // Provide a valid URL to an external H5P content.
115
        $url = $this->getExternalTestFileUrl('/'.$library.'.h5p');
116
 
117
        $h5pfolderpath = $CFG->tempdir . uniqid('/h5p-');
118
 
119
        $data = $this->framework->fetchExternalData($url, null, true, $h5pfolderpath . '.h5p');
120
 
121
        // The response should not be empty and return true if the content has been successfully saved to a file.
122
        $this->assertNotEmpty($data);
123
        $this->assertTrue($data);
124
 
125
        // The uploaded file should exist on the filesystem.
126
        $this->assertTrue(file_exists($h5pfolderpath . '.h5p'));
127
    }
128
 
129
    /**
130
     * Test the behaviour of fetchExternalData() when the URL is pointing to an external file that is
131
     * not an h5p content.
132
     *
133
     * This test is intensive and requires downloading content of an external file,
134
     * therefore it might take longer time to execute.
135
     * In order to execute this test PHPUNIT_LONGTEST should be set to true in phpunit.xml or directly in config.php.
136
     */
137
    public function test_fetchExternalData_url_not_h5p() {
138
 
139
        if (!PHPUNIT_LONGTEST) {
140
            // This test is intensive and requires downloading the content of an external file.
141
            $this->markTestSkipped('PHPUNIT_LONGTEST is not defined');
142
        }
143
 
144
        $this->resetAfterTest();
145
 
146
        // Provide an URL to an external file that is not an H5P content file.
147
        $url = $this->getExternalTestFileUrl('/h5pcontenttypes.json');
148
 
149
        $data = $this->framework->fetchExternalData($url, null, true);
150
 
151
        // The response should not be empty and return true if the content has been successfully saved to a file.
152
        $this->assertNotEmpty($data);
153
        $this->assertTrue($data);
154
 
155
        // The uploaded file should exist on the filesystem with it's original extension.
156
        // NOTE: The file would be later validated by the H5P Validator.
157
        $h5pfolderpath = $this->framework->getUploadedH5pFolderPath();
158
        $this->assertTrue(file_exists($h5pfolderpath . '.json'));
159
    }
160
 
161
    /**
162
     * Test the behaviour of fetchExternalData() when the URL is invalid.
163
     */
164
    public function test_fetchExternalData_url_invalid() {
165
        // Provide an invalid URL to an external file.
166
        $url = "someprotocol://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf";
167
 
168
        $data = $this->framework->fetchExternalData($url, null, true);
169
 
170
        // The response should be empty.
171
        $this->assertEmpty($data);
172
    }
173
 
174
    /**
175
     * Test the behaviour of setLibraryTutorialUrl().
176
     */
177
    public function test_setLibraryTutorialUrl() {
178
        global $DB;
179
 
180
        $this->resetAfterTest();
181
 
182
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
183
 
184
        // Create several libraries records.
185
        $lib1 = $generator->create_library_record('Library1', 'Lib1', 1, 0, 1, '', null, 'http://tutorial1.org',
186
            'http://example.org');
187
        $lib2 = $generator->create_library_record('Library2', 'Lib2', 2, 0, 1, '', null, 'http://tutorial2.org');
188
        $lib3 = $generator->create_library_record('Library3', 'Lib3', 3, 0);
189
 
190
        // Check only lib1 tutorial URL is updated.
191
        $url = 'https://newtutorial.cat';
192
        $this->framework->setLibraryTutorialUrl($lib1->machinename, $url);
193
 
194
        $libraries = $DB->get_records('h5p_libraries');
195
        $this->assertEquals($libraries[$lib1->id]->tutorial, $url);
196
        $this->assertNotEquals($libraries[$lib2->id]->tutorial, $url);
197
 
198
        // Check lib1 tutorial URL is set to null.
199
        $this->framework->setLibraryTutorialUrl($lib1->machinename, null);
200
 
201
        $libraries = $DB->get_records('h5p_libraries');
202
        $this->assertCount(3, $libraries);
203
        $this->assertNull($libraries[$lib1->id]->tutorial);
204
 
205
        // Check no tutorial URL is set if library name doesn't exist.
206
        $this->framework->setLibraryTutorialUrl('Unexisting library', $url);
207
 
208
        $libraries = $DB->get_records('h5p_libraries');
209
        $this->assertCount(3, $libraries);
210
        $this->assertNull($libraries[$lib1->id]->tutorial);
211
        $this->assertEquals($libraries[$lib2->id]->tutorial, 'http://tutorial2.org');
212
        $this->assertNull($libraries[$lib3->id]->tutorial);
213
 
214
        // Check tutorial is set as expected when it was null.
215
        $this->framework->setLibraryTutorialUrl($lib3->machinename, $url);
216
 
217
        $libraries = $DB->get_records('h5p_libraries');
218
        $this->assertEquals($libraries[$lib3->id]->tutorial, $url);
219
        $this->assertNull($libraries[$lib1->id]->tutorial);
220
        $this->assertEquals($libraries[$lib2->id]->tutorial, 'http://tutorial2.org');
221
    }
222
 
223
    /**
224
     * Test the behaviour of setErrorMessage().
225
     */
226
    public function test_setErrorMessage() {
227
        // Set an error message and an error code.
228
        $message = "Error message";
229
        $code = '404';
230
 
231
        // Set an error message.
232
        $this->framework->setErrorMessage($message, $code);
233
 
234
        // Get the error messages.
235
        $errormessages = $this->framework->getMessages('error');
236
 
237
        $expected = new \stdClass();
238
        $expected->code = 404;
239
        $expected->message = 'Error message';
240
 
241
        $this->assertEquals($expected, $errormessages[0]);
242
    }
243
 
244
    /**
245
     * Test the behaviour of setInfoMessage().
246
     */
247
    public function test_setInfoMessage() {
248
        $message = "Info message";
249
 
250
        // Set an info message.
251
        $this->framework->setInfoMessage($message);
252
 
253
        // Get the info messages.
254
        $infomessages = $this->framework->getMessages('info');
255
 
256
        $expected = 'Info message';
257
 
258
        $this->assertEquals($expected, $infomessages[0]);
259
    }
260
 
261
    /**
262
     * Test the behaviour of getMessages() when requesting the info messages.
263
     */
264
    public function test_getMessages_info() {
265
        // Set an info message.
266
        $this->framework->setInfoMessage("Info message");
267
        // Set an error message.
268
        $this->framework->setErrorMessage("Error message 1", 404);
269
 
270
        // Get the info messages.
271
        $infomessages = $this->framework->getMessages('info');
272
 
273
        $expected = 'Info message';
274
 
275
        // Make sure that only the info message has been returned.
276
        $this->assertCount(1, $infomessages);
277
        $this->assertEquals($expected, $infomessages[0]);
278
 
279
        $infomessages = $this->framework->getMessages('info');
280
 
281
        // Make sure the info messages have now been removed.
282
        $this->assertEmpty($infomessages);
283
    }
284
 
285
    /**
286
     * Test the behaviour of getMessages() when requesting the error messages.
287
     */
288
    public function test_getMessages_error() {
289
        // Set an info message.
290
        $this->framework->setInfoMessage("Info message");
291
        // Set an error message.
292
        $this->framework->setErrorMessage("Error message 1", 404);
293
        // Set another error message.
294
        $this->framework->setErrorMessage("Error message 2", 403);
295
 
296
        // Get the error messages.
297
        $errormessages = $this->framework->getMessages('error');
298
 
299
        // Make sure that only the error messages are being returned.
300
        $this->assertEquals(2, count($errormessages));
301
 
302
        $expected1 = (object) [
303
            'code' => 404,
304
            'message' => 'Error message 1'
305
        ];
306
 
307
        $expected2 = (object) [
308
            'code' => 403,
309
            'message' => 'Error message 2'
310
        ];
311
 
312
        $this->assertEquals($expected1, $errormessages[0]);
313
        $this->assertEquals($expected2, $errormessages[1]);
314
 
315
        $errormessages = $this->framework->getMessages('error');
316
 
317
        // Make sure the info messages have now been removed.
318
        $this->assertEmpty($errormessages);
319
    }
320
 
321
    /**
322
     * Test the behaviour of t() when translating existing string that does not require any arguments.
323
     */
324
    public function test_t_existing_string_no_args() {
325
        // Existing language string without passed arguments.
326
        $translation = $this->framework->t('No copyright information available for this content.');
327
 
328
        // Make sure the string translation has been returned.
329
        $this->assertEquals('No copyright information available for this content.', $translation);
330
    }
331
 
332
    /**
333
     * Test the behaviour of t() when translating existing string that does require parameters.
334
     */
335
    public function test_t_existing_string_args() {
336
        // Existing language string with passed arguments.
337
        $translation = $this->framework->t('Illegal option %option in %library',
338
            ['%option' => 'example', '%library' => 'Test library']);
339
 
340
        // Make sure the string translation has been returned.
341
        $this->assertEquals('Illegal option example in Test library', $translation);
342
    }
343
 
344
    /**
345
     * Test the behaviour of t() when translating non-existent string.
346
     */
347
    public function test_t_non_existent_string() {
348
        // Non-existing language string.
349
        $message = 'Random message %option';
350
 
351
        $translation = $this->framework->t($message);
352
 
353
        // Make sure a debugging message is triggered.
354
        $this->assertDebuggingCalled("String translation cannot be found. Please add a string definition for '" .
355
            $message . "' in the core_h5p component.");
356
        // As the string does not exist in the mapping array, make sure the passed message is returned.
357
        $this->assertEquals($message, $translation);
358
    }
359
 
360
    /**
361
     * Test the behaviour of getLibraryFileUrl() when requesting a file URL from an existing library and
362
     * the folder name is parsable.
363
     **/
364
    public function test_getLibraryFileUrl() {
365
        global $CFG;
366
 
367
        $this->resetAfterTest();
368
 
369
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
370
        // Create a library record.
371
        $lib = $generator->create_library_record('Library', 'Lib', 1, 1);
372
 
373
        $expected = "{$CFG->wwwroot}/pluginfile.php/1/core_h5p/libraries/{$lib->id}/Library-1.1/library.json";
374
 
375
        // Get the URL of a file from an existing library. The provided folder name is parsable.
376
        $actual = $this->framework->getLibraryFileUrl('Library-1.1', 'library.json');
377
 
378
        // Make sure the expected URL is returned.
379
        $this->assertEquals($expected, $actual);
380
    }
381
 
382
    /**
383
     * Test the behaviour of getLibraryFileUrl() when requesting a file URL from a non-existent library and
384
     * the folder name is parsable.
385
     **/
386
    public function test_getLibraryFileUrl_non_existent_library() {
387
        $this->resetAfterTest();
388
 
389
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
390
        // Create a library record.
391
        $generator->create_library_record('Library', 'Lib', 1, 1);
392
 
393
        // Get the URL of a file from a non-existent library. The provided folder name is parsable.
394
        $actual = $this->framework->getLibraryFileUrl('Library2-1.1', 'library.json');
395
 
396
        // Make sure a debugging message is triggered.
397
        $this->assertDebuggingCalled('The library "Library2-1.1" does not exist.');
398
 
399
        // Make sure that an URL is not returned.
400
        $this->assertEquals(null, $actual);
401
    }
402
 
403
    /**
404
     * Test the behaviour of getLibraryFileUrl() when requesting a file URL from an existing library and
405
     * the folder name is not parsable.
406
     **/
407
    public function test_getLibraryFileUrl_not_parsable_folder_name() {
408
        $this->resetAfterTest();
409
 
410
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
411
        // Create a library record.
412
        $generator->create_library_record('Library', 'Lib', 1, 1);
413
 
414
        // Get the URL of a file from an existing library. The provided folder name is not parsable.
415
        $actual = $this->framework->getLibraryFileUrl('Library1.1', 'library.json');
416
 
417
        // Make sure a debugging message is triggered.
418
        $this->assertDebuggingCalled(
419
            'The provided string value "Library1.1" is not a valid name for a library folder.');
420
 
421
        // Make sure that an URL is not returned.
422
        $this->assertEquals(null, $actual);
423
    }
424
 
425
    /**
426
     * Test the behaviour of getLibraryFileUrl() when requesting a file URL from a library that has multiple
427
     * versions and the folder name is parsable.
428
     **/
429
    public function test_getLibraryFileUrl_library_has_multiple_versions() {
430
        global $CFG;
431
 
432
        $this->resetAfterTest();
433
 
434
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
435
        // Create library records with a different minor version.
436
        $lib1 = $generator->create_library_record('Library', 'Lib', 1, 1);
437
        $lib2 = $generator->create_library_record('Library', 'Lib', 1, 3);
438
 
439
        $expected = "{$CFG->wwwroot}/pluginfile.php/1/core_h5p/libraries/{$lib2->id}/Library-1.3/library.json";
440
 
441
        // Get the URL of a file from an existing library (Library 1.3). The provided folder name is parsable.
442
        $actual = $this->framework->getLibraryFileUrl('Library-1.3', 'library.json');
443
 
444
        // Make sure the proper URL (from the requested library version) is returned.
445
        $this->assertEquals($expected, $actual);
446
    }
447
 
448
    /**
449
     * Test the behaviour of getLibraryFileUrl() when requesting a file URL from a library that has multiple
450
     * patch versions and the folder name is parsable.
451
     **/
452
    public function test_getLibraryFileUrl_library_has_multiple_patch_versions() {
453
        global $CFG;
454
 
455
        $this->resetAfterTest();
456
 
457
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
458
        // Create library records with a different patch version.
459
        $lib1 = $generator->create_library_record('Library', 'Lib', 1, 1, 2);
460
        $lib2 = $generator->create_library_record('Library', 'Lib', 1, 1, 4);
461
        $lib3 = $generator->create_library_record('Library', 'Lib', 1, 1, 3);
462
 
463
        $expected = "{$CFG->wwwroot}/pluginfile.php/1/core_h5p/libraries/{$lib2->id}/Library-1.1/library.json";
464
 
465
        // Get the URL of a file from an existing library. The provided folder name is parsable.
466
        $actual = $this->framework->getLibraryFileUrl('Library-1.1', 'library.json');
467
 
468
        // Make sure the proper URL (from the latest library patch) is returned.
469
        $this->assertEquals($expected, $actual);
470
    }
471
 
472
    /**
473
     * Test the behaviour of getLibraryFileUrl() when requesting a file URL from a sub-folder
474
     * of an existing library and the folder name is parsable.
475
     **/
476
    public function test_getLibraryFileUrl_library_subfolder() {
477
        global $CFG;
478
 
479
        $this->resetAfterTest();
480
 
481
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
482
        // Create a library record.
483
        $lib = $generator->create_library_record('Library', 'Lib', 1, 1);
484
 
485
        $expected = "{$CFG->wwwroot}/pluginfile.php/1/core_h5p/libraries/{$lib->id}/Library-1.1/css/example.css";
486
 
487
        // Get the URL of a file from a sub-folder from an existing library. The provided folder name is parsable.
488
        $actual = $this->framework->getLibraryFileUrl('Library-1.1/css', 'example.css');
489
 
490
        // Make sure the proper URL is returned.
491
        $this->assertEquals($expected, $actual);
492
    }
493
 
494
    /**
495
     * Test the behaviour of loadAddons().
496
     */
497
    public function test_loadAddons() {
498
        $this->resetAfterTest();
499
 
500
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
501
 
502
        // Create a Library addon (1.1).
503
        $generator->create_library_record('Library', 'Lib', 1, 1, 2,
504
            '', '/regex1/');
505
        // Create a Library addon (1.3).
506
        $generator->create_library_record('Library', 'Lib', 1, 3, 2,
507
            '', '/regex2/');
508
        // Create a Library addon (1.2).
509
        $generator->create_library_record('Library', 'Lib', 1, 2, 2,
510
            '', '/regex3/');
511
        // Create a Library1 addon (1.2)
512
        $generator->create_library_record('Library1', 'Lib1', 1, 2, 2,
513
            '', '/regex11/');
514
 
515
        // Load the latest version of each addon.
516
        $addons = $this->framework->loadAddons();
517
 
518
        // The addons array should return 2 results (Library and Library1 addon).
519
        $this->assertCount(2, $addons);
520
 
521
        // Ensure the addons array is consistently ordered before asserting their contents.
522
        core_collator::asort_array_of_arrays_by_key($addons, 'machineName');
523
        [$addonone, $addontwo] = array_values($addons);
524
 
525
        // Make sure the version 1.3 is the latest 'Library' addon version.
526
        $this->assertEquals('Library', $addonone['machineName']);
527
        $this->assertEquals(1, $addonone['majorVersion']);
528
        $this->assertEquals(3, $addonone['minorVersion']);
529
 
530
        // Make sure the version 1.2 is the latest 'Library1' addon version.
531
        $this->assertEquals('Library1', $addontwo['machineName']);
532
        $this->assertEquals(1, $addontwo['majorVersion']);
533
        $this->assertEquals(2, $addontwo['minorVersion']);
534
    }
535
 
536
    /**
537
     * Test the behaviour of loadLibraries().
538
     */
539
    public function test_loadLibraries() {
540
        $this->resetAfterTest();
541
 
542
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
543
 
544
        // Generate h5p related data.
545
        $generator->generate_h5p_data();
546
 
547
        // Load all libraries.
548
        $libraries = $this->framework->loadLibraries();
549
 
550
        // Make sure all libraries are returned.
551
        $this->assertNotEmpty($libraries);
552
        $this->assertCount(6, $libraries);
553
        $this->assertEquals('MainLibrary', $libraries['MainLibrary'][0]->machine_name);
554
        $this->assertEquals('1', $libraries['MainLibrary'][0]->major_version);
555
        $this->assertEquals('0', $libraries['MainLibrary'][0]->minor_version);
556
        $this->assertEquals('1', $libraries['MainLibrary'][0]->patch_version);
557
    }
558
 
559
    /**
560
     * Test the behaviour of test_getLibraryId() when requesting an existing machine name.
561
     */
562
    public function test_getLibraryId_existing_machine_name() {
563
        $this->resetAfterTest();
564
 
565
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
566
 
567
        // Create a library.
568
        $lib = $generator->create_library_record('Library', 'Lib', 1, 1, 2);
569
 
570
        // Request the library ID of the library with machine name 'Library'.
571
        $libraryid = $this->framework->getLibraryId('Library');
572
 
573
        // Make sure the library ID is being returned.
574
        $this->assertNotFalse($libraryid);
575
        $this->assertEquals($lib->id, $libraryid);
576
    }
577
 
578
    /**
579
     * Test the behaviour of test_getLibraryId() when requesting a non-existent machine name.
580
     */
581
    public function test_getLibraryId_non_existent_machine_name() {
582
        $this->resetAfterTest();
583
 
584
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
585
 
586
        // Create a library.
587
        $generator->create_library_record('Library', 'Lib', 1, 1, 2);
588
 
589
        // Request the library ID of the library with machinename => 'TestLibrary' (non-existent).
590
        $libraryid = $this->framework->getLibraryId('TestLibrary');
591
 
592
        // Make sure the library ID not being returned.
593
        $this->assertFalse($libraryid);
594
    }
595
 
596
    /**
597
     * Test the behaviour of test_getLibraryId() when requesting a non-existent major version.
598
     */
599
    public function test_getLibraryId_non_existent_major_version() {
600
        $this->resetAfterTest();
601
 
602
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
603
 
604
        // Create a library.
605
        $generator->create_library_record('Library', 'Lib', 1, 1, 2);
606
 
607
        // Request the library ID of the library with machine name => 'Library', majorversion => 2 (non-existent).
608
        $libraryid = $this->framework->getLibraryId('Library', 2);
609
 
610
        // Make sure the library ID not being returned.
611
        $this->assertFalse($libraryid);
612
    }
613
 
614
    /**
615
     * Test the behaviour of test_getLibraryId() when requesting a non-existent minor version.
616
     */
617
    public function test_getLibraryId_non_existent_minor_version() {
618
        $this->resetAfterTest();
619
 
620
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
621
 
622
        // Create a library.
623
        $generator->create_library_record('Library', 'Lib', 1, 1, 2);
624
 
625
        // Request the library ID of the library with machine name => 'Library',
626
        // majorversion => 1,  minorversion => 2 (non-existent).
627
        $libraryid = $this->framework->getLibraryId('Library', 1, 2);
628
 
629
        // Make sure the library ID not being returned.
630
        $this->assertFalse($libraryid);
631
    }
632
 
633
    /**
634
     * Test the behaviour of isPatchedLibrary().
635
     *
636
     * @dataProvider isPatchedLibrary_provider
637
     * @param array $libraryrecords Array containing data for the library creation
638
     * @param array $testlibrary Array containing the test library data
639
     * @param bool $expected The expectation whether the library is patched or not
640
     **/
641
    public function test_isPatchedLibrary(array $libraryrecords, array $testlibrary, bool $expected): void {
642
        $this->resetAfterTest();
643
 
644
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
645
 
646
        foreach ($libraryrecords as $library) {
647
            call_user_func_array([$generator, 'create_library_record'], $library);
648
        }
649
 
650
        $this->assertEquals($expected, $this->framework->isPatchedLibrary($testlibrary));
651
    }
652
 
653
    /**
654
     * Data provider for test_isPatchedLibrary().
655
     *
656
     * @return array
657
     */
658
    public function isPatchedLibrary_provider(): array {
659
        return [
660
            'Unpatched library. No different versioning' => [
661
                [
662
                    ['TestLibrary', 'Test', 1, 1, 2],
663
                ],
664
                [
665
                    'machineName' => 'TestLibrary',
666
                    'majorVersion' => 1,
667
                    'minorVersion' => 1,
668
                    'patchVersion' => 2
669
                ],
670
                false,
671
            ],
672
            'Major version identical; Minor version identical; Patch version newer' => [
673
                [
674
                    ['TestLibrary', 'Test', 1, 1, 2],
675
                ],
676
                [
677
                    'machineName' => 'TestLibrary',
678
                    'majorVersion' => 1,
679
                    'minorVersion' => 1,
680
                    'patchVersion' => 3
681
                ],
682
                true,
683
            ],
684
            'Major version identical; Minor version newer; Patch version newer' => [
685
                [
686
                    ['TestLibrary', 'Test', 1, 1, 2],
687
                ],
688
                [
689
                    'machineName' => 'TestLibrary',
690
                    'majorVersion' => 1,
691
                    'minorVersion' => 2,
692
                    'patchVersion' => 3
693
                ],
694
                false,
695
            ],
696
            'Major version identical; Minor version identical; Patch version older' => [
697
                [
698
                    ['TestLibrary', 'Test', 1, 1, 2],
699
                ],
700
                [
701
                    'machineName' => 'TestLibrary',
702
                    'majorVersion' => 1,
703
                    'minorVersion' => 1,
704
                    'patchVersion' => 1
705
                ],
706
                false,
707
            ],
708
            'Major version identical; Minor version newer; Patch version older' => [
709
                [
710
                    ['TestLibrary', 'Test', 1, 1, 2],
711
                ],
712
                [
713
                    'machineName' => 'TestLibrary',
714
                    'majorVersion' => 1,
715
                    'minorVersion' => 2,
716
                    'patchVersion' => 1
717
                ],
718
                false,
719
            ],
720
            'Major version newer; Minor version identical; Patch version older' => [
721
                [
722
                    ['TestLibrary', 'Test', 1, 1, 2],
723
                ],
724
                [
725
                    'machineName' => 'TestLibrary',
726
                    'majorVersion' => 2,
727
                    'minorVersion' => 1,
728
                    'patchVersion' => 1
729
                ],
730
                false,
731
            ],
732
            'Major version newer; Minor version identical; Patch version newer' => [
733
                [
734
                    ['TestLibrary', 'Test', 1, 1, 2],
735
                ],
736
                [
737
                    'machineName' => 'TestLibrary',
738
                    'majorVersion' => 2,
739
                    'minorVersion' => 1,
740
                    'patchVersion' => 3
741
                ],
742
                false,
743
            ],
744
 
745
            'Major version older; Minor version identical; Patch version older' => [
746
                [
747
                    ['TestLibrary', 'Test', 1, 1, 2],
748
                ],
749
                [
750
                    'machineName' => 'TestLibrary',
751
                    'majorVersion' => 0,
752
                    'minorVersion' => 1,
753
                    'patchVersion' => 1
754
                ],
755
                false,
756
            ],
757
            'Major version older; Minor version identical; Patch version newer' => [
758
                [
759
                    ['TestLibrary', 'Test', 1, 1, 2],
760
                ],
761
                [
762
                    'machineName' => 'TestLibrary',
763
                    'majorVersion' => 0,
764
                    'minorVersion' => 1,
765
                    'patchVersion' => 3
766
                ],
767
                false,
768
            ],
769
        ];
770
    }
771
 
772
    /**
773
     * Test the behaviour of isInDevMode().
774
     */
775
    public function test_isInDevMode() {
776
        $isdevmode = $this->framework->isInDevMode();
777
 
778
        $this->assertFalse($isdevmode);
779
    }
780
 
781
    /**
782
     * Test the behaviour of mayUpdateLibraries().
783
     */
784
    public function test_mayUpdateLibraries(): void {
785
        global $DB;
786
 
787
        $this->resetAfterTest();
788
 
789
        // Create some users.
790
        $contextsys = \context_system::instance();
791
        $user = $this->getDataGenerator()->create_user();
792
        $admin = get_admin();
793
        $managerrole = $DB->get_record('role', ['shortname' => 'manager'], '*', MUST_EXIST);
794
        $studentrole = $DB->get_record('role', ['shortname' => 'student'], '*', MUST_EXIST);
795
        $manager = $this->getDataGenerator()->create_user();
796
        role_assign($managerrole->id, $manager->id, $contextsys);
797
 
798
        // Create a course with a label and enrol the user.
799
        $course = $this->getDataGenerator()->create_course();
800
        $label = $this->getDataGenerator()->create_module('label', ['course' => $course->id]);
801
        list(, $labelcm) = get_course_and_cm_from_instance($label->id, 'label');
802
        $contextlabel = \context_module::instance($labelcm->id);
803
        $this->getDataGenerator()->enrol_user($user->id, $course->id, 'student');
804
 
805
        // Create the .h5p file.
806
        $path = __DIR__ . '/fixtures/h5ptest.zip';
807
 
808
        // Admin and manager should have permission to update libraries.
809
        $file = helper::create_fake_stored_file_from_path($path, $admin->id, $contextsys);
810
        $this->framework->set_file($file);
811
        $mayupdatelib = $this->framework->mayUpdateLibraries();
812
        $this->assertTrue($mayupdatelib);
813
 
814
        $file = helper::create_fake_stored_file_from_path($path, $manager->id, $contextsys);
815
        $this->framework->set_file($file);
816
        $mayupdatelib = $this->framework->mayUpdateLibraries();
817
        $this->assertTrue($mayupdatelib);
818
 
819
        // By default, normal user hasn't permission to update libraries (in both contexts, system and module label).
820
        $file = helper::create_fake_stored_file_from_path($path, $user->id, $contextsys);
821
        $this->framework->set_file($file);
822
        $mayupdatelib = $this->framework->mayUpdateLibraries();
823
        $this->assertFalse($mayupdatelib);
824
 
825
        $file = helper::create_fake_stored_file_from_path($path, $user->id, $contextlabel);
826
        $this->framework->set_file($file);
827
        $mayupdatelib = $this->framework->mayUpdateLibraries();
828
        $this->assertFalse($mayupdatelib);
829
 
830
        // If the current user (admin) can update libraries, the method should return true (even if the file userid hasn't the
831
        // required capabilility in the file context).
832
        $file = helper::create_fake_stored_file_from_path($path, $admin->id, $contextlabel);
833
        $this->framework->set_file($file);
834
        $mayupdatelib = $this->framework->mayUpdateLibraries();
835
        $this->assertTrue($mayupdatelib);
836
 
837
        // If the update capability is assigned to the user, they should be able to update the libraries (only in the context
838
        // where the capability has been assigned).
839
        $file = helper::create_fake_stored_file_from_path($path, $user->id, $contextlabel);
840
        $this->framework->set_file($file);
841
        $mayupdatelib = $this->framework->mayUpdateLibraries();
842
        $this->assertFalse($mayupdatelib);
843
        assign_capability('moodle/h5p:updatelibraries', CAP_ALLOW, $studentrole->id, $contextlabel);
844
        $mayupdatelib = $this->framework->mayUpdateLibraries();
845
        $this->assertTrue($mayupdatelib);
846
        $file = helper::create_fake_stored_file_from_path($path, $user->id, $contextsys);
847
        $this->framework->set_file($file);
848
        $mayupdatelib = $this->framework->mayUpdateLibraries();
849
        $this->assertFalse($mayupdatelib);
850
    }
851
 
852
    /**
853
     * Test the behaviour of get_file() and set_file().
854
     */
855
    public function test_get_file(): void {
856
        $this->resetAfterTest();
857
 
858
        // Create some users.
859
        $contextsys = \context_system::instance();
860
        $user = $this->getDataGenerator()->create_user();
861
 
862
        // The H5P file.
863
        $path = __DIR__ . '/fixtures/h5ptest.zip';
864
 
865
        // An error should be raised when it's called before initialitzing it.
866
        $this->expectException('coding_exception');
867
        $this->expectExceptionMessage('Using get_file() before file is set');
868
        $this->framework->get_file();
869
 
870
        // Check the value when only path and user are set.
871
        $file = helper::create_fake_stored_file_from_path($path, $user->id);
872
        $this->framework->set_file($file);
873
        $file = $this->framework->get_file();
874
        $this->assertEquals($user->id, $$file->get_userid());
875
        $this->assertEquals($contextsys->id, $file->get_contextid());
876
 
877
        // Check the value when also the context is set.
878
        $course = $this->getDataGenerator()->create_course();
879
        $contextcourse = \context_course::instance($course->id);
880
        $file = helper::create_fake_stored_file_from_path($path, $user->id, $contextcourse);
881
        $this->framework->set_file($file);
882
        $file = $this->framework->get_file();
883
        $this->assertEquals($user->id, $$file->get_userid());
884
        $this->assertEquals($contextcourse->id, $file->get_contextid());
885
    }
886
 
887
    /**
888
     * Test the behaviour of saveLibraryData() when saving data for a new library.
889
     */
890
    public function test_saveLibraryData_new_library() {
891
        global $DB;
892
 
893
        $this->resetAfterTest();
894
 
895
        $librarydata = array(
896
            'title' => 'Test',
897
            'machineName' => 'TestLibrary',
898
            'majorVersion' => '1',
899
            'minorVersion' => '0',
900
            'patchVersion' => '2',
901
            'runnable' => 1,
902
            'fullscreen' => 1,
903
            'preloadedJs' => array(
904
                array(
905
                    'path' => 'js/name.min.js'
906
                )
907
            ),
908
            'preloadedCss' => array(
909
                array(
910
                    'path' => 'css/name.css'
911
                )
912
            ),
913
            'dropLibraryCss' => array(
914
                array(
915
                    'machineName' => 'Name2'
916
                )
917
            )
918
        );
919
 
920
        // Create a new library.
921
        $this->framework->saveLibraryData($librarydata);
922
 
923
        $library = $DB->get_record('h5p_libraries', ['machinename' => $librarydata['machineName']]);
924
 
925
        // Make sure the library data was properly saved.
926
        $this->assertNotEmpty($library);
927
        $this->assertNotEmpty($librarydata['libraryId']);
928
        $this->assertEquals($librarydata['title'], $library->title);
929
        $this->assertEquals($librarydata['machineName'], $library->machinename);
930
        $this->assertEquals($librarydata['majorVersion'], $library->majorversion);
931
        $this->assertEquals($librarydata['minorVersion'], $library->minorversion);
932
        $this->assertEquals($librarydata['patchVersion'], $library->patchversion);
933
        $this->assertEquals($librarydata['preloadedJs'][0]['path'], $library->preloadedjs);
934
        $this->assertEquals($librarydata['preloadedCss'][0]['path'], $library->preloadedcss);
935
        $this->assertEquals($librarydata['dropLibraryCss'][0]['machineName'], $library->droplibrarycss);
936
    }
937
 
938
    /**
939
     * Test the behaviour of saveLibraryData() when saving (updating) data for an existing library.
940
     */
941
    public function test_saveLibraryData_existing_library() {
942
        global $DB;
943
 
944
        $this->resetAfterTest();
945
 
946
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
947
 
948
        // Create a library record.
949
        $library = $generator->create_library_record('TestLibrary', 'Test', 1, 0, 2);
950
 
951
        $librarydata = array(
952
            'libraryId' => $library->id,
953
            'title' => 'Test1',
954
            'machineName' => 'TestLibrary',
955
            'majorVersion' => '1',
956
            'minorVersion' => '2',
957
            'patchVersion' => '2',
958
            'runnable' => 1,
959
            'fullscreen' => 1,
960
            'preloadedJs' => array(
961
                array(
962
                    'path' => 'js/name.min.js'
963
                )
964
            ),
965
            'preloadedCss' => array(
966
                array(
967
                    'path' => 'css/name.css'
968
                )
969
            ),
970
            'dropLibraryCss' => array(
971
                array(
972
                    'machineName' => 'Name2'
973
                )
974
            )
975
        );
976
 
977
        // Update the library.
978
        $this->framework->saveLibraryData($librarydata, false);
979
 
980
        $library = $DB->get_record('h5p_libraries', ['machinename' => $librarydata['machineName']]);
981
 
982
        // Make sure the library data was properly updated.
983
        $this->assertNotEmpty($library);
984
        $this->assertNotEmpty($librarydata['libraryId']);
985
        $this->assertEquals($librarydata['title'], $library->title);
986
        $this->assertEquals($librarydata['machineName'], $library->machinename);
987
        $this->assertEquals($librarydata['majorVersion'], $library->majorversion);
988
        $this->assertEquals($librarydata['minorVersion'], $library->minorversion);
989
        $this->assertEquals($librarydata['patchVersion'], $library->patchversion);
990
        $this->assertEquals($librarydata['preloadedJs'][0]['path'], $library->preloadedjs);
991
        $this->assertEquals($librarydata['preloadedCss'][0]['path'], $library->preloadedcss);
992
        $this->assertEquals($librarydata['dropLibraryCss'][0]['machineName'], $library->droplibrarycss);
993
    }
994
 
995
    /**
996
     * Test the behaviour of insertContent().
997
     */
998
    public function test_insertContent() {
999
        global $DB;
1000
 
1001
        $this->resetAfterTest();
1002
 
1003
        $content = array(
1004
            'params' => json_encode(['param1' => 'Test']),
1005
            'library' => array(
1006
                'libraryId' => 1
1007
            ),
1008
            'disable' => 8
1009
        );
1010
 
1011
        // Insert h5p content.
1012
        $contentid = $this->framework->insertContent($content);
1013
 
1014
        // Get the entered content from the db.
1015
        $dbcontent = $DB->get_record('h5p', ['id' => $contentid]);
1016
 
1017
        // Make sure the h5p content was properly inserted.
1018
        $this->assertNotEmpty($dbcontent);
1019
        $this->assertEquals($content['params'], $dbcontent->jsoncontent);
1020
        $this->assertEquals($content['library']['libraryId'], $dbcontent->mainlibraryid);
1021
        $this->assertEquals($content['disable'], $dbcontent->displayoptions);
1022
    }
1023
 
1024
    /**
1025
     * Test the behaviour of insertContent().
1026
     */
1027
    public function test_insertContent_latestlibrary() {
1028
        global $DB;
1029
 
1030
        $this->resetAfterTest();
1031
 
1032
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
1033
        // Create a library record.
1034
        $lib = $generator->create_library_record('TestLibrary', 'Test', 1, 1, 2);
1035
 
1036
        $content = array(
1037
            'params' => json_encode(['param1' => 'Test']),
1038
            'library' => array(
1039
                'libraryId' => 0,
1040
                'machineName' => 'TestLibrary',
1041
            ),
1042
            'disable' => 8
1043
        );
1044
 
1045
        // Insert h5p content.
1046
        $contentid = $this->framework->insertContent($content);
1047
 
1048
        // Get the entered content from the db.
1049
        $dbcontent = $DB->get_record('h5p', ['id' => $contentid]);
1050
 
1051
        // Make sure the h5p content was properly inserted.
1052
        $this->assertNotEmpty($dbcontent);
1053
        $this->assertEquals($content['params'], $dbcontent->jsoncontent);
1054
        $this->assertEquals($content['disable'], $dbcontent->displayoptions);
1055
        // As the libraryId was empty, the latest library has been used.
1056
        $this->assertEquals($lib->id, $dbcontent->mainlibraryid);
1057
    }
1058
 
1059
    /**
1060
     * Test the behaviour of updateContent().
1061
     */
1062
    public function test_updateContent() {
1063
        global $DB;
1064
 
1065
        $this->resetAfterTest();
1066
 
1067
        /** @var \core_h5p_generator $generator */
1068
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
1069
 
1070
        // Create a library record.
1071
        $lib = $generator->create_library_record('TestLibrary', 'Test', 1, 1, 2);
1072
 
1073
        // Create an h5p content with 'TestLibrary' as it's main library.
1074
        $contentid = $generator->create_h5p_record($lib->id);
1075
 
1076
        $content = array(
1077
            'id' => $contentid,
1078
            'params' => json_encode(['param2' => 'Test2']),
1079
            'library' => array(
1080
                'libraryId' => $lib->id
1081
            ),
1082
            'disable' => 8
1083
        );
1084
 
1085
        // Update the h5p content.
1086
        $this->framework->updateContent($content);
1087
 
1088
        $h5pcontent = $DB->get_record('h5p', ['id' => $contentid]);
1089
 
1090
        // Make sure the h5p content was properly updated.
1091
        $this->assertNotEmpty($h5pcontent);
1092
        $this->assertNotEmpty($h5pcontent->pathnamehash);
1093
        $this->assertNotEmpty($h5pcontent->contenthash);
1094
        $this->assertEquals($content['params'], $h5pcontent->jsoncontent);
1095
        $this->assertEquals($content['library']['libraryId'], $h5pcontent->mainlibraryid);
1096
        $this->assertEquals($content['disable'], $h5pcontent->displayoptions);
1097
    }
1098
 
1099
    /**
1100
     * Test the behaviour of updateContent() with metadata.
1101
     *
1102
     * @covers ::updateContent
1103
     */
1104
    public function test_updateContent_withmetadata(): void {
1105
        global $DB;
1106
 
1107
        $this->resetAfterTest();
1108
 
1109
        /** @var \core_h5p_generator $generator */
1110
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
1111
 
1112
        // Create a library record.
1113
        $lib = $generator->create_library_record('TestLibrary', 'Test', 1, 1, 2);
1114
 
1115
        // Create an h5p content with 'TestLibrary' as it's main library.
1116
        $contentid = $generator->create_h5p_record($lib->id);
1117
 
1118
        $params = ['param2' => 'Test2'];
1119
        $metadata = [
1120
            'license' => 'CC BY',
1121
            'licenseVersion' => '4.0',
1122
            'yearFrom' => 2000,
1123
            'yearTo' => 2023,
1124
            'defaultLanguage' => 'ca',
1125
        ];
1126
        $content = [
1127
            'id' => $contentid,
1128
            'params' => json_encode($params),
1129
            'library' => [
1130
                'libraryId' => $lib->id,
1131
            ],
1132
            'disable' => 8,
1133
            'metadata' => $metadata,
1134
        ];
1135
 
1136
        // Update the h5p content.
1137
        $this->framework->updateContent($content);
1138
 
1139
        $h5pcontent = $DB->get_record('h5p', ['id' => $contentid]);
1140
 
1141
        // Make sure the h5p content was properly updated.
1142
        $this->assertNotEmpty($h5pcontent);
1143
        $this->assertNotEmpty($h5pcontent->pathnamehash);
1144
        $this->assertNotEmpty($h5pcontent->contenthash);
1145
        $this->assertEquals(json_encode(array_merge($params, ['metadata' => $metadata])), $h5pcontent->jsoncontent);
1146
        $this->assertEquals($content['library']['libraryId'], $h5pcontent->mainlibraryid);
1147
        $this->assertEquals($content['disable'], $h5pcontent->displayoptions);
1148
    }
1149
 
1150
    /**
1151
     * Test the behaviour of saveLibraryDependencies().
1152
     */
1153
    public function test_saveLibraryDependencies() {
1154
        global $DB;
1155
 
1156
        $this->resetAfterTest();
1157
 
1158
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
1159
 
1160
        // Create a library 'Library'.
1161
        $library = $generator->create_library_record('Library', 'Title');
1162
        // Create a library 'DependencyLibrary1'.
1163
        $dependency1 = $generator->create_library_record('DependencyLibrary1', 'DependencyTitle1');
1164
        // Create a library 'DependencyLibrary2'.
1165
        $dependency2 = $generator->create_library_record('DependencyLibrary2', 'DependencyTitle2');
1166
 
1167
        $dependencies = array(
1168
            array(
1169
                'machineName' => $dependency1->machinename,
1170
                'majorVersion' => $dependency1->majorversion,
1171
                'minorVersion' => $dependency1->minorversion
1172
            ),
1173
            array(
1174
                'machineName' => $dependency2->machinename,
1175
                'majorVersion' => $dependency2->majorversion,
1176
                'minorVersion' => $dependency2->minorversion
1177
            ),
1178
        );
1179
 
1180
        // Set 'DependencyLibrary1' and 'DependencyLibrary2' as library dependencies of 'Library'.
1181
        $this->framework->saveLibraryDependencies($library->id, $dependencies, 'preloaded');
1182
 
1183
        $libdependencies = $DB->get_records('h5p_library_dependencies', ['libraryid' => $library->id], 'id ASC');
1184
 
1185
        // Make sure the library dependencies for 'Library' are properly set.
1186
        $this->assertEquals(2, count($libdependencies));
1187
        $this->assertEquals($dependency1->id, reset($libdependencies)->requiredlibraryid);
1188
        $this->assertEquals($dependency2->id, end($libdependencies)->requiredlibraryid);
1189
    }
1190
 
1191
    /**
1192
     * Test the behaviour of deleteContentData().
1193
     */
1194
    public function test_deleteContentData() {
1195
        global $DB;
1196
 
1197
        $this->resetAfterTest();
1198
 
1199
        /** @var \core_h5p_generator $generator */
1200
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
1201
        // For the mod_h5pactivity component, the activity needs to be created too.
1202
        $course = $this->getDataGenerator()->create_course();
1203
        $user = $this->getDataGenerator()->create_and_enrol($course, 'student');
1204
        $this->setUser($user);
1205
        $activity = $this->getDataGenerator()->create_module('h5pactivity', ['course' => $course]);
1206
        $activitycontext = \context_module::instance($activity->cmid);
1207
        $filerecord = [
1208
            'contextid' => $activitycontext->id,
1209
            'component' => 'mod_h5pactivity',
1210
            'filearea' => 'package',
1211
            'itemid' => 0,
1212
            'filepath' => '/',
1213
            'filename' => 'dummy.h5p',
1214
            'addxapistate' => true,
1215
        ];
1216
 
1217
        // Generate some h5p related data.
1218
        $data = $generator->generate_h5p_data(false, $filerecord);
1219
        $h5pid = $data->h5pcontent->h5pid;
1220
 
1221
        // Make sure the particular h5p content exists in the DB.
1222
        $this->assertNotEmpty($DB->get_record('h5p', ['id' => $h5pid]));
1223
        // Make sure the content libraries exists in the DB.
1224
        $this->assertCount(5, $DB->get_records('h5p_contents_libraries', ['h5pid' => $h5pid]));
1225
        // Make sure the particular xAPI state exists in the DB.
1226
        $records = $DB->get_records('xapi_states');
1227
        $record = reset($records);
1228
        $this->assertCount(1, $records);
1229
        $this->assertNotNull($record->statedata);
1230
 
1231
        // Delete the h5p content and it's related data.
1232
        $this->framework->deleteContentData($h5pid);
1233
 
1234
        // The particular h5p content should no longer exist in the db.
1235
        $this->assertEmpty($DB->get_record('h5p', ['id' => $h5pid]));
1236
        // The particular content libraries should no longer exist in the db.
1237
        $this->assertEmpty($DB->get_record('h5p_contents_libraries', ['h5pid' => $h5pid]));
1238
        // The xAPI state should be reseted.
1239
        $records = $DB->get_records('xapi_states');
1240
        $record = reset($records);
1241
        $this->assertCount(1, $records);
1242
        $this->assertNull($record->statedata);
1243
    }
1244
 
1245
    /**
1246
     * Test the behaviour of resetContentUserData().
1247
     */
1248
    public function test_resetContentUserData() {
1249
        global $DB;
1250
 
1251
        $this->resetAfterTest();
1252
 
1253
        /** @var \core_h5p_generator $generator */
1254
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
1255
        // For the mod_h5pactivity component, the activity needs to be created too.
1256
        $course = $this->getDataGenerator()->create_course();
1257
        $user = $this->getDataGenerator()->create_and_enrol($course, 'student');
1258
        $this->setUser($user);
1259
        $activity = $this->getDataGenerator()->create_module('h5pactivity', ['course' => $course]);
1260
        $activitycontext = \context_module::instance($activity->cmid);
1261
        $filerecord = [
1262
            'contextid' => $activitycontext->id,
1263
            'component' => 'mod_h5pactivity',
1264
            'filearea' => 'package',
1265
            'itemid' => 0,
1266
            'filepath' => '/',
1267
            'filename' => 'dummy.h5p',
1268
            'addxapistate' => true,
1269
        ];
1270
 
1271
        // Generate some h5p related data.
1272
        $data = $generator->generate_h5p_data(false, $filerecord);
1273
        $h5pid = $data->h5pcontent->h5pid;
1274
 
1275
        // Make sure the H5P content, libraries and xAPI state exist in the DB.
1276
        $this->assertNotEmpty($DB->get_record('h5p', ['id' => $h5pid]));
1277
        $this->assertCount(5, $DB->get_records('h5p_contents_libraries', ['h5pid' => $h5pid]));
1278
        $records = $DB->get_records('xapi_states');
1279
        $record = reset($records);
1280
        $this->assertCount(1, $records);
1281
        $this->assertNotNull($record->statedata);
1282
 
1283
        // Reset the user data associated to this H5P content.
1284
        $this->framework->resetContentUserData($h5pid);
1285
 
1286
        // The H5P content should still exist in the db.
1287
        $this->assertNotEmpty($DB->get_record('h5p', ['id' => $h5pid]));
1288
        // The particular content libraries should still exist in the db.
1289
        $this->assertCount(5, $DB->get_records('h5p_contents_libraries', ['h5pid' => $h5pid]));
1290
        // The xAPI state should still exist in the db, but should be reset.
1291
        $records = $DB->get_records('xapi_states');
1292
        $record = reset($records);
1293
        $this->assertCount(1, $records);
1294
        $this->assertNull($record->statedata);
1295
    }
1296
 
1297
    /**
1298
     * Test the behaviour of deleteLibraryUsage().
1299
     */
1300
    public function test_deleteLibraryUsage() {
1301
        global $DB;
1302
 
1303
        $this->resetAfterTest();
1304
 
1305
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
1306
 
1307
        // Generate some h5p related data.
1308
        $data = $generator->generate_h5p_data();
1309
        $h5pid = $data->h5pcontent->h5pid;
1310
 
1311
        // Get the h5p content libraries from the DB.
1312
        $h5pcontentlibraries = $DB->get_records('h5p_contents_libraries', ['h5pid' => $h5pid]);
1313
 
1314
        // The particular h5p content should have 5 content libraries.
1315
        $this->assertNotEmpty($h5pcontentlibraries);
1316
        $this->assertCount(5, $h5pcontentlibraries);
1317
 
1318
        // Delete the h5p content and it's related data.
1319
        $this->framework->deleteLibraryUsage($h5pid);
1320
 
1321
        // Get the h5p content libraries from the DB.
1322
        $h5pcontentlibraries = $DB->get_record('h5p_contents_libraries', ['h5pid' => $h5pid]);
1323
 
1324
        // The particular h5p content libraries should no longer exist in the db.
1325
        $this->assertEmpty($h5pcontentlibraries);
1326
    }
1327
 
1328
    /**
1329
     * Test the behaviour of test_saveLibraryUsage().
1330
     */
1331
    public function test_saveLibraryUsage() {
1332
        global $DB;
1333
 
1334
        $this->resetAfterTest();
1335
 
1336
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
1337
 
1338
        // Create a library 'Library'.
1339
        $library = $generator->create_library_record('Library', 'Title');
1340
        // Create a library 'DependencyLibrary1'.
1341
        $dependency1 = $generator->create_library_record('DependencyLibrary1', 'DependencyTitle1');
1342
        // Create a library 'DependencyLibrary2'.
1343
        $dependency2 = $generator->create_library_record('DependencyLibrary2', 'DependencyTitle2');
1344
        // Create an h5p content with 'Library' as it's main library.
1345
        $contentid = $generator->create_h5p_record($library->id);
1346
 
1347
        $dependencies = array(
1348
            array(
1349
                'library' => array(
1350
                    'libraryId' => $dependency1->id,
1351
                    'machineName' => $dependency1->machinename,
1352
                    'dropLibraryCss' => $dependency1->droplibrarycss
1353
                ),
1354
                'type' => 'preloaded',
1355
                'weight' => 1
1356
            ),
1357
            array(
1358
                'library' => array(
1359
                    'libraryId' => $dependency2->id,
1360
                    'machineName' => $dependency2->machinename,
1361
                    'dropLibraryCss' => $dependency2->droplibrarycss
1362
                ),
1363
                'type' => 'preloaded',
1364
                'weight' => 2
1365
            ),
1366
        );
1367
 
1368
        // Save 'DependencyLibrary1' and 'DependencyLibrary2' as h5p content libraries.
1369
        $this->framework->saveLibraryUsage($contentid, $dependencies);
1370
 
1371
        // Get the h5p content libraries from the DB.
1372
        $libdependencies = $DB->get_records('h5p_contents_libraries', ['h5pid' => $contentid], 'id ASC');
1373
 
1374
        // Make sure that 'DependencyLibrary1' and 'DependencyLibrary2' are properly set as h5p content libraries.
1375
        $this->assertEquals(2, count($libdependencies));
1376
        $this->assertEquals($dependency1->id, reset($libdependencies)->libraryid);
1377
        $this->assertEquals($dependency2->id, end($libdependencies)->libraryid);
1378
    }
1379
 
1380
    /**
1381
     * Test the behaviour of getLibraryUsage() without skipping a particular h5p content.
1382
     */
1383
    public function test_getLibraryUsage_no_skip_content() {
1384
        $this->resetAfterTest();
1385
 
1386
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
1387
 
1388
        // Generate h5p related data.
1389
        $generateddata = $generator->generate_h5p_data();
1390
        // The Id of the library 'Library1'.
1391
        $library1id = $generateddata->lib1->data->id;
1392
        // The Id of the library 'Library2'.
1393
        $library2id = $generateddata->lib2->data->id;
1394
        // The Id of the library 'Library5'.
1395
        $library5id = $generateddata->lib5->data->id;
1396
 
1397
        // Get the library usage for 'Library1' (do not skip content).
1398
        $data = $this->framework->getLibraryUsage($library1id);
1399
 
1400
        $expected = array(
1401
            'content' => 1,
1402
            'libraries' => 1
1403
        );
1404
 
1405
        // Make sure 'Library1' is used by 1 content and is a dependency to 1 library.
1406
        $this->assertEquals($expected, $data);
1407
 
1408
        // Get the library usage for 'Library2' (do not skip content).
1409
        $data = $this->framework->getLibraryUsage($library2id);
1410
 
1411
        $expected = array(
1412
            'content' => 1,
1413
            'libraries' => 2,
1414
        );
1415
 
1416
        // Make sure 'Library2' is used by 1 content and is a dependency to 2 libraries.
1417
        $this->assertEquals($expected, $data);
1418
 
1419
         // Get the library usage for 'Library5' (do not skip content).
1420
        $data = $this->framework->getLibraryUsage($library5id);
1421
 
1422
        $expected = array(
1423
            'content' => 0,
1424
            'libraries' => 1,
1425
        );
1426
 
1427
        // Make sure 'Library5' is not used by any content and is a dependency to 1 library.
1428
        $this->assertEquals($expected, $data);
1429
    }
1430
 
1431
    /**
1432
     * Test the behaviour of getLibraryUsage() when skipping a particular content.
1433
     */
1434
    public function test_getLibraryUsage_skip_content() {
1435
        $this->resetAfterTest();
1436
 
1437
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
1438
 
1439
        // Generate h5p related data.
1440
        $generateddata = $generator->generate_h5p_data();
1441
        // The Id of the library 'Library1'.
1442
        $library1id = $generateddata->lib1->data->id;
1443
 
1444
        // Get the library usage for 'Library1' (skip content).
1445
        $data = $this->framework->getLibraryUsage($library1id, true);
1446
        $expected = array(
1447
            'content' => -1,
1448
            'libraries' => 1,
1449
        );
1450
 
1451
        // Make sure 'Library1' is a dependency to 1 library.
1452
        $this->assertEquals($expected, $data);
1453
    }
1454
 
1455
    /**
1456
     * Test the behaviour of loadLibrary() when requesting an existing library.
1457
     */
1458
    public function test_loadLibrary_existing_library() {
1459
        $this->resetAfterTest();
1460
 
1461
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
1462
 
1463
        // Generate h5p related data.
1464
        $generateddata = $generator->generate_h5p_data();
1465
        // The library data of 'Library1'.
1466
        $library1 = $generateddata->lib1->data;
1467
        // The library data of 'Library5'.
1468
        $library5 = $generateddata->lib5->data;
1469
 
1470
        // The preloaded dependencies.
1471
        $preloadeddependencies = array();
1472
 
1473
        foreach ($generateddata->lib1->dependencies as $preloadeddependency) {
1474
            $preloadeddependencies[] = array(
1475
                'machineName' => $preloadeddependency->machinename,
1476
                'majorVersion' => $preloadeddependency->majorversion,
1477
                'minorVersion' => $preloadeddependency->minorversion
1478
            );
1479
        }
1480
 
1481
        // Create a dynamic dependency.
1482
        $generator->create_library_dependency_record($library1->id, $library5->id, 'dynamic');
1483
 
1484
        $dynamicdependencies[] = array(
1485
            'machineName' => $library5->machinename,
1486
            'majorVersion' => $library5->majorversion,
1487
            'minorVersion' => $library5->minorversion
1488
        );
1489
 
1490
        // Load 'Library1' data.
1491
        $data = $this->framework->loadLibrary($library1->machinename, $library1->majorversion,
1492
            $library1->minorversion);
1493
 
1494
        $expected = array(
1495
            'libraryId' => $library1->id,
1496
            'title' => $library1->title,
1497
            'machineName' => $library1->machinename,
1498
            'majorVersion' => $library1->majorversion,
1499
            'minorVersion' => $library1->minorversion,
1500
            'patchVersion' => $library1->patchversion,
1501
            'runnable' => $library1->runnable,
1502
            'fullscreen' => $library1->fullscreen,
1503
            'embedTypes' => $library1->embedtypes,
1504
            'preloadedJs' => $library1->preloadedjs,
1505
            'preloadedCss' => $library1->preloadedcss,
1506
            'dropLibraryCss' => $library1->droplibrarycss,
1507
            'semantics' => $library1->semantics,
1508
            'preloadedDependencies' => $preloadeddependencies,
1509
            'dynamicDependencies' => $dynamicdependencies
1510
        );
1511
 
1512
        // Make sure the 'Library1' data is properly loaded.
1513
        $this->assertEquals($expected, $data);
1514
    }
1515
 
1516
    /**
1517
     * Test the behaviour of loadLibrary() when requesting a non-existent library.
1518
     */
1519
    public function test_loadLibrary_non_existent_library() {
1520
        $this->resetAfterTest();
1521
 
1522
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
1523
 
1524
        // Generate h5p related data.
1525
        $generator->generate_h5p_data();
1526
 
1527
        // Attempt to load a non-existent library.
1528
        $data = $this->framework->loadLibrary('MissingLibrary', 1, 2);
1529
 
1530
        // Make sure nothing is loaded.
1531
        $this->assertFalse($data);
1532
    }
1533
 
1534
    /**
1535
     * Test the behaviour of loadLibrarySemantics().
1536
     *
1537
     * @dataProvider loadLibrarySemantics_provider
1538
     * @param array $libraryrecords Array containing data for the library creation
1539
     * @param array $testlibrary Array containing the test library data
1540
     * @param string $expected The expected semantics value
1541
     **/
1542
    public function test_loadLibrarySemantics(array $libraryrecords, array $testlibrary, string $expected): void {
1543
        $this->resetAfterTest();
1544
 
1545
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
1546
 
1547
        foreach ($libraryrecords as $library) {
1548
            call_user_func_array([$generator, 'create_library_record'], $library);
1549
        }
1550
 
1551
        $this->assertEquals($expected, $this->framework->loadLibrarySemantics(
1552
            $testlibrary['machinename'], $testlibrary['majorversion'], $testlibrary['minorversion']));
1553
    }
1554
 
1555
    /**
1556
     * Data provider for test_loadLibrarySemantics().
1557
     *
1558
     * @return array
1559
     */
1560
    public function loadLibrarySemantics_provider(): array {
1561
 
1562
        $semantics = json_encode(
1563
            [
1564
                'type' => 'text',
1565
                'name' => 'text',
1566
                'label' => 'Plain text',
1567
                'description' => 'Please add some text'
1568
            ]
1569
        );
1570
 
1571
        return [
1572
            'Library with semantics' => [
1573
                [
1574
                    ['Library1', 'Lib1', 1, 1, 2, $semantics],
1575
                ],
1576
                [
1577
                    'machinename' => 'Library1',
1578
                    'majorversion' => 1,
1579
                    'minorversion' => 1
1580
                ],
1581
                $semantics,
1582
            ],
1583
            'Library without semantics' => [
1584
                [
1585
                    ['Library2', 'Lib2', 1, 2, 2, ''],
1586
                ],
1587
                [
1588
                    'machinename' => 'Library2',
1589
                    'majorversion' => 1,
1590
                    'minorversion' => 2
1591
                ],
1592
                '',
1593
            ]
1594
        ];
1595
    }
1596
 
1597
    /**
1598
     * Test the behaviour of alterLibrarySemantics().
1599
     */
1600
    public function test_alterLibrarySemantics() {
1601
        global $DB;
1602
 
1603
        $this->resetAfterTest();
1604
 
1605
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
1606
 
1607
        $semantics = json_encode(
1608
            array(
1609
                'type' => 'text',
1610
                'name' => 'text',
1611
                'label' => 'Plain text',
1612
                'description' => 'Please add some text'
1613
            )
1614
        );
1615
 
1616
        // Create a library 'Library1' with semantics.
1617
        $library1 = $generator->create_library_record('Library1', 'Lib1', 1, 1, 2, $semantics);
1618
 
1619
        $updatedsemantics = array(
1620
            'type' => 'text',
1621
            'name' => 'updated text',
1622
            'label' => 'Updated text',
1623
            'description' => 'Please add some text'
1624
        );
1625
 
1626
        // Alter the semantics of 'Library1'.
1627
        $this->framework->alterLibrarySemantics($updatedsemantics, 'Library1', 1, 1);
1628
 
1629
        // Get the semantics of 'Library1' from the DB.
1630
        $currentsemantics = $DB->get_field('h5p_libraries', 'semantics', array('id' => $library1->id));
1631
 
1632
        // The semantics for Library1 shouldn't be updated.
1633
        $this->assertEquals($semantics, $currentsemantics);
1634
    }
1635
 
1636
    /**
1637
     * Test the behaviour of deleteLibraryDependencies() when requesting to delete the
1638
     * dependencies of an existing library.
1639
     */
1640
    public function test_deleteLibraryDependencies_existing_library() {
1641
        global $DB;
1642
 
1643
        $this->resetAfterTest();
1644
 
1645
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
1646
 
1647
        // Generate h5p related data.
1648
        $data = $generator->generate_h5p_data();
1649
        // The data of the library 'Library1'.
1650
        $library1 = $data->lib1->data;
1651
 
1652
        // Get the dependencies of 'Library1'.
1653
        $dependencies = $DB->get_records('h5p_library_dependencies', ['libraryid' => $library1->id]);
1654
        // The 'Library1' should have 3 dependencies ('Library2', 'Library3', 'Library4').
1655
        $this->assertCount(3, $dependencies);
1656
 
1657
        // Delete the dependencies of 'Library1'.
1658
        $this->framework->deleteLibraryDependencies($library1->id);
1659
 
1660
        $dependencies = $DB->get_records('h5p_library_dependencies', ['libraryid' => $library1->id]);
1661
        // The 'Library1' should have 0 dependencies.
1662
        $this->assertCount(0, $dependencies);
1663
    }
1664
 
1665
    /**
1666
     * Test the behaviour of deleteLibraryDependencies() when requesting to delete the
1667
     * dependencies of a non-existent library.
1668
     */
1669
    public function test_deleteLibraryDependencies_non_existent_library() {
1670
        global $DB;
1671
 
1672
        $this->resetAfterTest();
1673
 
1674
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
1675
 
1676
        // Generate h5p related data.
1677
        $data = $generator->generate_h5p_data();
1678
        // The data of the library 'Library1'.
1679
        $library1 = $data->lib1->data;
1680
 
1681
        // Get the dependencies of 'Library1'.
1682
        $dependencies = $DB->get_records('h5p_library_dependencies', ['libraryid' => $library1->id]);
1683
        // The 'Library1' should have 3 dependencies ('Library2', 'Library3', 'Library4').
1684
        $this->assertCount(3, $dependencies);
1685
 
1686
        // Delete the dependencies of a non-existent library.
1687
        $this->framework->deleteLibraryDependencies(0);
1688
 
1689
        $dependencies = $DB->get_records('h5p_library_dependencies', ['libraryid' => $library1->id]);
1690
        // The 'Library1' should have 3 dependencies.
1691
        $this->assertCount(3, $dependencies);
1692
    }
1693
 
1694
    /**
1695
     * Test the behaviour of deleteLibrary().
1696
     */
1697
    public function test_deleteLibrary() {
1698
        global $DB;
1699
 
1700
        $this->resetAfterTest();
1701
 
1702
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
1703
 
1704
        // Generate h5p related data.
1705
        $data = $generator->generate_h5p_data(true);
1706
        // The data of the 'Library1' library.
1707
        $library1 = $data->lib1->data;
1708
 
1709
        // Get the library dependencies of 'Library1'.
1710
        $dependencies = $DB->get_records('h5p_library_dependencies', ['libraryid' => $library1->id]);
1711
 
1712
        // The 'Library1' should have 3 library dependencies ('Library2', 'Library3', 'Library4').
1713
        $this->assertCount(3, $dependencies);
1714
 
1715
        // Return the created 'Library1' files.
1716
        $libraryfiles = $DB->get_records('files',
1717
            array(
1718
                'component' => \core_h5p\file_storage::COMPONENT,
1719
                'filearea' => \core_h5p\file_storage::LIBRARY_FILEAREA,
1720
                'itemid' => $library1->id
1721
            )
1722
        );
1723
 
1724
        // The library ('Library1') should have 7 related folders/files.
1725
        $this->assertCount(7, $libraryfiles);
1726
 
1727
        // Delete the library.
1728
        $this->framework->deleteLibrary($library1);
1729
 
1730
        $lib1 = $DB->get_record('h5p_libraries', ['machinename' => $library1->machinename]);
1731
        $dependencies = $DB->get_records('h5p_library_dependencies', ['libraryid' => $library1->id]);
1732
        $libraryfiles = $DB->get_records('files',
1733
            array(
1734
                'component' => \core_h5p\file_storage::COMPONENT,
1735
                'filearea' => \core_h5p\file_storage::LIBRARY_FILEAREA,
1736
                'itemid' => $library1->id
1737
            )
1738
        );
1739
 
1740
        // The 'Library1' should not exist.
1741
        $this->assertEmpty($lib1);
1742
        // The library ('Library1')  should have 0 dependencies.
1743
        $this->assertCount(0, $dependencies);
1744
        // The library (library1) should have 0 related folders/files.
1745
        $this->assertCount(0, $libraryfiles);
1746
    }
1747
 
1748
    /**
1749
     * Test the behaviour of loadContent().
1750
     */
1751
    public function test_loadContent() {
1752
        global $DB;
1753
 
1754
        $this->resetAfterTest();
1755
 
1756
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
1757
 
1758
        // Generate h5p related data.
1759
        $data = $generator->generate_h5p_data();
1760
        // The Id of the created h5p content.
1761
        $h5pid = $data->h5pcontent->h5pid;
1762
        // Get the h5p content data from the DB.
1763
        $h5p = $DB->get_record('h5p', ['id' => $h5pid]);
1764
        // The data of content's main library ('MainLibrary').
1765
        $mainlibrary = $data->mainlib->data;
1766
 
1767
        // Load the h5p content.
1768
        $content = $this->framework->loadContent($h5pid);
1769
 
1770
        $expected = array(
1771
            'id' => $h5p->id,
1772
            'params' => $h5p->jsoncontent,
1773
            'embedType' => 'iframe',
1774
            'disable' => $h5p->displayoptions,
1775
            'title' => $mainlibrary->title,
1776
            'slug' => H5PCore::slugify($mainlibrary->title) . '-' . $h5p->id,
1777
            'filtered' => $h5p->filtered,
1778
            'libraryId' => $mainlibrary->id,
1779
            'libraryName' => $mainlibrary->machinename,
1780
            'libraryMajorVersion' => $mainlibrary->majorversion,
1781
            'libraryMinorVersion' => $mainlibrary->minorversion,
1782
            'libraryEmbedTypes' => $mainlibrary->embedtypes,
1783
            'libraryFullscreen' => $mainlibrary->fullscreen,
1784
            'metadata' => '',
1785
            'pathnamehash' => $h5p->pathnamehash
1786
        );
1787
 
1788
        $params = json_decode($h5p->jsoncontent);
1789
        if (empty($params->metadata)) {
1790
            $params->metadata = new \stdClass();
1791
        }
1792
        $expected['metadata'] = $params->metadata;
1793
        $expected['params'] = json_encode($params->params ?? $params);
1794
 
1795
        // The returned content should match the expected array.
1796
        $this->assertEquals($expected, $content);
1797
    }
1798
 
1799
    /**
1800
     * Test the behaviour of loadContentDependencies() when requesting content dependencies
1801
     * without specifying the dependency type.
1802
     */
1803
    public function test_loadContentDependencies_no_type_defined() {
1804
        $this->resetAfterTest();
1805
 
1806
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
1807
 
1808
        // Generate h5p related data.
1809
        $data = $generator->generate_h5p_data();
1810
        // The Id of the h5p content.
1811
        $h5pid = $data->h5pcontent->h5pid;
1812
        // The content dependencies.
1813
        $dependencies = $data->h5pcontent->contentdependencies;
1814
 
1815
        // Add Library5 as a content dependency (dynamic dependency type).
1816
        $library5 = $data->lib5->data;
1817
        $generator->create_contents_libraries_record($h5pid, $library5->id, 'dynamic');
1818
 
1819
        // Get all content dependencies.
1820
        $contentdependencies = $this->framework->loadContentDependencies($h5pid);
1821
 
1822
        $expected = array();
1823
        foreach ($dependencies as $dependency) {
1824
            $expected[$dependency->machinename] = array(
1825
                'libraryId' => $dependency->id,
1826
                'machineName' => $dependency->machinename,
1827
                'majorVersion' => $dependency->majorversion,
1828
                'minorVersion' => $dependency->minorversion,
1829
                'patchVersion' => $dependency->patchversion,
1830
                'preloadedCss' => $dependency->preloadedcss,
1831
                'preloadedJs' => $dependency->preloadedjs,
1832
                'dropCss' => '0',
1833
                'dependencyType' => 'preloaded'
1834
            );
1835
        }
1836
 
1837
        $expected = array_merge($expected,
1838
            array(
1839
                'Library5' => array(
1840
                    'libraryId' => $library5->id,
1841
                    'machineName' => $library5->machinename,
1842
                    'majorVersion' => $library5->majorversion,
1843
                    'minorVersion' => $library5->minorversion,
1844
                    'patchVersion' => $library5->patchversion,
1845
                    'preloadedCss' => $library5->preloadedcss,
1846
                    'preloadedJs' => $library5->preloadedjs,
1847
                    'dropCss' => '0',
1848
                    'dependencyType' => 'dynamic'
1849
                )
1850
            )
1851
        );
1852
 
1853
        // The loaded content dependencies should return 6 libraries.
1854
        $this->assertCount(6, $contentdependencies);
1855
        $this->assertEquals($expected, $contentdependencies);
1856
    }
1857
 
1858
    /**
1859
     * Test the behaviour of loadContentDependencies() when requesting content dependencies
1860
     * with specifying the dependency type.
1861
     */
1862
    public function test_loadContentDependencies_type_defined() {
1863
        $this->resetAfterTest();
1864
 
1865
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
1866
 
1867
        // Generate h5p related data.
1868
        $data = $generator->generate_h5p_data();
1869
        // The Id of the h5p content.
1870
        $h5pid = $data->h5pcontent->h5pid;
1871
        // The content dependencies.
1872
        $dependencies = $data->h5pcontent->contentdependencies;
1873
 
1874
        // Add Library5 as a content dependency (dynamic dependency type).
1875
        $library5 = $data->lib5->data;
1876
        $generator->create_contents_libraries_record($h5pid, $library5->id, 'dynamic');
1877
 
1878
        // Load all content dependencies of dependency type 'preloaded'.
1879
        $preloadeddependencies = $this->framework->loadContentDependencies($h5pid, 'preloaded');
1880
 
1881
        $expected = array();
1882
        foreach ($dependencies as $dependency) {
1883
            $expected[$dependency->machinename] = array(
1884
                'libraryId' => $dependency->id,
1885
                'machineName' => $dependency->machinename,
1886
                'majorVersion' => $dependency->majorversion,
1887
                'minorVersion' => $dependency->minorversion,
1888
                'patchVersion' => $dependency->patchversion,
1889
                'preloadedCss' => $dependency->preloadedcss,
1890
                'preloadedJs' => $dependency->preloadedjs,
1891
                'dropCss' => '0',
1892
                'dependencyType' => 'preloaded'
1893
            );
1894
        }
1895
 
1896
        // The loaded content dependencies should return 5 libraries.
1897
        $this->assertCount(5, $preloadeddependencies);
1898
        $this->assertEquals($expected, $preloadeddependencies);
1899
 
1900
        // Load all content dependencies of dependency type 'dynamic'.
1901
        $dynamicdependencies = $this->framework->loadContentDependencies($h5pid, 'dynamic');
1902
 
1903
        $expected = array(
1904
            'Library5' => array(
1905
                'libraryId' => $library5->id,
1906
                'machineName' => $library5->machinename,
1907
                'majorVersion' => $library5->majorversion,
1908
                'minorVersion' => $library5->minorversion,
1909
                'patchVersion' => $library5->patchversion,
1910
                'preloadedCss' => $library5->preloadedcss,
1911
                'preloadedJs' => $library5->preloadedjs,
1912
                'dropCss' => '0',
1913
                'dependencyType' => 'dynamic'
1914
            )
1915
        );
1916
 
1917
        // The loaded content dependencies should now return 1 library.
1918
        $this->assertCount(1, $dynamicdependencies);
1919
        $this->assertEquals($expected, $dynamicdependencies);
1920
    }
1921
 
1922
    /**
1923
     * Test the behaviour of getOption().
1924
     */
1925
    public function test_getOption(): void {
1926
        $this->resetAfterTest();
1927
 
1928
        // Get value for display_option_download.
1929
        $value = $this->framework->getOption(H5PCore::DISPLAY_OPTION_DOWNLOAD);
1930
        $expected = H5PDisplayOptionBehaviour::CONTROLLED_BY_AUTHOR_DEFAULT_OFF;
1931
        $this->assertEquals($expected, $value);
1932
 
1933
        // Get value for display_option_embed using default value (it should be ignored).
1934
        $value = $this->framework->getOption(H5PCore::DISPLAY_OPTION_EMBED, H5PDisplayOptionBehaviour::NEVER_SHOW);
1935
        $expected = H5PDisplayOptionBehaviour::CONTROLLED_BY_AUTHOR_DEFAULT_OFF;
1936
        $this->assertEquals($expected, $value);
1937
 
1938
        // Get value for unexisting setting without default.
1939
        $value = $this->framework->getOption('unexistingsetting');
1940
        $expected = false;
1941
        $this->assertEquals($expected, $value);
1942
 
1943
        // Get value for unexisting setting with default.
1944
        $value = $this->framework->getOption('unexistingsetting', 'defaultvalue');
1945
        $expected = 'defaultvalue';
1946
        $this->assertEquals($expected, $value);
1947
    }
1948
 
1949
    /**
1950
     * Test the behaviour of setOption().
1951
     */
1952
    public function test_setOption(): void {
1953
        $this->resetAfterTest();
1954
 
1955
        // Set value for 'newsetting' setting.
1956
        $name = 'newsetting';
1957
        $value = $this->framework->getOption($name);
1958
        $this->assertEquals(false, $value);
1959
        $newvalue = 'value1';
1960
        $this->framework->setOption($name, $newvalue);
1961
        $value = $this->framework->getOption($name);
1962
        $this->assertEquals($newvalue, $value);
1963
 
1964
        // Set value for display_option_download and then get it again. Check it hasn't changed.
1965
        $name = H5PCore::DISPLAY_OPTION_DOWNLOAD;
1966
        $newvalue = H5PDisplayOptionBehaviour::NEVER_SHOW;
1967
        $this->framework->setOption($name, $newvalue);
1968
        $value = $this->framework->getOption($name);
1969
        $expected = H5PDisplayOptionBehaviour::CONTROLLED_BY_AUTHOR_DEFAULT_OFF;
1970
        $this->assertEquals($expected, $value);
1971
    }
1972
 
1973
    /**
1974
     * Test the behaviour of updateContentFields().
1975
     */
1976
    public function test_updateContentFields() {
1977
        global $DB;
1978
 
1979
        $this->resetAfterTest();
1980
 
1981
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
1982
 
1983
        // Create 'Library1' library.
1984
        $library1 = $generator->create_library_record('Library1', 'Lib1', 1, 1, 2);
1985
        // Create 'Library2' library.
1986
        $library2 = $generator->create_library_record('Library2', 'Lib2', 1, 1, 2);
1987
 
1988
        // Create an h5p content with 'Library1' as it's main library.
1989
        $h5pid = $generator->create_h5p_record($library1->id, 'iframe');
1990
 
1991
        $updatedata = array(
1992
            'jsoncontent' => json_encode(['value' => 'test']),
1993
            'mainlibraryid' => $library2->id
1994
        );
1995
 
1996
        // Update h5p content fields.
1997
        $this->framework->updateContentFields($h5pid, $updatedata);
1998
 
1999
        // Get the h5p content from the DB.
2000
        $h5p = $DB->get_record('h5p', ['id' => $h5pid]);
2001
 
2002
        $expected = json_encode(['value' => 'test']);
2003
 
2004
        // Make sure the h5p content fields are properly updated.
2005
        $this->assertEquals($expected, $h5p->jsoncontent);
2006
        $this->assertEquals($library2->id, $h5p->mainlibraryid);
2007
    }
2008
 
2009
    /**
2010
     * Test the behaviour of clearFilteredParameters().
2011
     */
2012
    public function test_clearFilteredParameters() {
2013
        global $DB;
2014
 
2015
        $this->resetAfterTest();
2016
 
2017
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
2018
 
2019
        // Create 3 libraries.
2020
        $library1 = $generator->create_library_record('Library1', 'Lib1', 1, 1, 2);
2021
        $library2 = $generator->create_library_record('Library2', 'Lib2', 1, 1, 2);
2022
        $library3 = $generator->create_library_record('Library3', 'Lib3', 1, 1, 2);
2023
 
2024
        // Create h5p content with 'Library1' as a main library.
2025
        $h5pcontentid1 = $generator->create_h5p_record($library1->id);
2026
        // Create h5p content with 'Library1' as a main library.
2027
        $h5pcontentid2 = $generator->create_h5p_record($library1->id);
2028
        // Create h5p content with 'Library2' as a main library.
2029
        $h5pcontentid3 = $generator->create_h5p_record($library2->id);
2030
        // Create h5p content with 'Library3' as a main library.
2031
        $h5pcontentid4 = $generator->create_h5p_record($library3->id);
2032
 
2033
        $h5pcontent1 = $DB->get_record('h5p', ['id' => $h5pcontentid1]);
2034
        $h5pcontent2 = $DB->get_record('h5p', ['id' => $h5pcontentid2]);
2035
        $h5pcontent3 = $DB->get_record('h5p', ['id' => $h5pcontentid3]);
2036
        $h5pcontent4 = $DB->get_record('h5p', ['id' => $h5pcontentid4]);
2037
 
2038
        // The filtered parameters should be present in each h5p content.
2039
        $this->assertNotEmpty($h5pcontent1->filtered);
2040
        $this->assertNotEmpty($h5pcontent2->filtered);
2041
        $this->assertNotEmpty($h5pcontent3->filtered);
2042
        $this->assertNotEmpty($h5pcontent4->filtered);
2043
 
2044
        // Clear the filtered parameters for contents that have library1 and library3 as
2045
        // their main library.
2046
        $this->framework->clearFilteredParameters([$library1->id, $library3->id]);
2047
 
2048
        $h5pcontent1 = $DB->get_record('h5p', ['id' => $h5pcontentid1]);
2049
        $h5pcontent2 = $DB->get_record('h5p', ['id' => $h5pcontentid2]);
2050
        $h5pcontent3 = $DB->get_record('h5p', ['id' => $h5pcontentid3]);
2051
        $h5pcontent4 = $DB->get_record('h5p', ['id' => $h5pcontentid4]);
2052
 
2053
        // The filtered parameters should be still present only for the content that has
2054
        // library 2 as a main library.
2055
        $this->assertEmpty($h5pcontent1->filtered);
2056
        $this->assertEmpty($h5pcontent2->filtered);
2057
        $this->assertNotEmpty($h5pcontent3->filtered);
2058
        $this->assertEmpty($h5pcontent4->filtered);
2059
    }
2060
 
2061
    /**
2062
     * Test the behaviour of getNumNotFiltered().
2063
     */
2064
    public function test_getNumNotFiltered() {
2065
        global $DB;
2066
 
2067
        $this->resetAfterTest();
2068
 
2069
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
2070
 
2071
        // Create 3 libraries.
2072
        $library1 = $generator->create_library_record('Library1', 'Lib1', 1, 1, 2);
2073
        $library2 = $generator->create_library_record('Library2', 'Lib2', 1, 1, 2);
2074
        $library3 = $generator->create_library_record('Library3', 'Lib3', 1, 1, 2);
2075
 
2076
        // Create h5p content with library1 as a main library.
2077
        $h5pcontentid1 = $generator->create_h5p_record($library1->id);
2078
        // Create h5p content with library1 as a main library.
2079
        $h5pcontentid2 = $generator->create_h5p_record($library1->id);
2080
        // Create h5p content with library2 as a main library.
2081
        $h5pcontentid3 = $generator->create_h5p_record($library2->id);
2082
        // Create h5p content with library3 as a main library.
2083
        $h5pcontentid4 = $generator->create_h5p_record($library3->id);
2084
 
2085
        $h5pcontent1 = $DB->get_record('h5p', ['id' => $h5pcontentid1]);
2086
        $h5pcontent2 = $DB->get_record('h5p', ['id' => $h5pcontentid2]);
2087
        $h5pcontent3 = $DB->get_record('h5p', ['id' => $h5pcontentid3]);
2088
        $h5pcontent4 = $DB->get_record('h5p', ['id' => $h5pcontentid4]);
2089
 
2090
        // The filtered parameters should be present in each h5p content.
2091
        $this->assertNotEmpty($h5pcontent1->filtered);
2092
        $this->assertNotEmpty($h5pcontent2->filtered);
2093
        $this->assertNotEmpty($h5pcontent3->filtered);
2094
        $this->assertNotEmpty($h5pcontent4->filtered);
2095
 
2096
        // Clear the filtered parameters for contents that have library1 and library3 as
2097
        // their main library.
2098
        $this->framework->clearFilteredParameters([$library1->id, $library3->id]);
2099
 
2100
        $countnotfiltered = $this->framework->getNumNotFiltered();
2101
 
2102
        // 3 contents don't have their parameters filtered.
2103
        $this->assertEquals(3, $countnotfiltered);
2104
    }
2105
 
2106
    /**
2107
     * Test the behaviour of getNumContent().
2108
     */
2109
    public function test_getNumContent() {
2110
        $this->resetAfterTest();
2111
 
2112
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
2113
 
2114
        // Generate h5p related data.
2115
        $data = $generator->generate_h5p_data();
2116
 
2117
        // The 'MainLibrary' library data.
2118
        $mainlibrary = $data->mainlib->data;
2119
 
2120
        // The 'Library1' library data.
2121
        $library1 = $data->lib1->data;
2122
 
2123
        // Create new h5p content with MainLibrary as a main library.
2124
        $generator->create_h5p_record($mainlibrary->id);
2125
 
2126
        // Get the number of h5p contents that are using 'MainLibrary' as their main library.
2127
        $countmainlib = $this->framework->getNumContent($mainlibrary->id);
2128
 
2129
        // Get the number of h5p contents that are using 'Library1' as their main library.
2130
        $countlib1 = $this->framework->getNumContent($library1->id);
2131
 
2132
        // Make sure that 2 contents are using MainLibrary as their main library.
2133
        $this->assertEquals(2, $countmainlib);
2134
        // Make sure that 0 contents are using Library1 as their main library.
2135
        $this->assertEquals(0, $countlib1);
2136
    }
2137
 
2138
    /**
2139
     * Test the behaviour of getNumContent() when certain contents are being skipped.
2140
     */
2141
    public function test_getNumContent_skip_content() {
2142
        $this->resetAfterTest();
2143
 
2144
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
2145
 
2146
        // Generate h5p related data.
2147
        $data = $generator->generate_h5p_data();
2148
 
2149
        // The 'MainLibrary' library data.
2150
        $mainlibrary = $data->mainlib->data;
2151
 
2152
        // Create new h5p content with MainLibrary as a main library.
2153
        $h5pcontentid = $generator->create_h5p_record($mainlibrary->id);
2154
 
2155
        // Get the number of h5p contents that are using 'MainLibrary' as their main library.
2156
        // Skip the newly created content $h5pcontentid.
2157
        $countmainlib = $this->framework->getNumContent($mainlibrary->id, [$h5pcontentid]);
2158
 
2159
        // Make sure that 1 content is returned instead of 2 ($h5pcontentid being skipped).
2160
        $this->assertEquals(1, $countmainlib);
2161
    }
2162
 
2163
    /**
2164
     * Test the behaviour of isContentSlugAvailable().
2165
     */
2166
    public function test_isContentSlugAvailable() {
2167
        $this->resetAfterTest();
2168
 
2169
        $slug = 'h5p-test-slug-1';
2170
 
2171
        // Currently this returns always true. The slug is generated as a unique value for
2172
        // each h5p content and it is not stored in the h5p content table.
2173
        $isslugavailable = $this->framework->isContentSlugAvailable($slug);
2174
 
2175
        $this->assertTrue($isslugavailable);
2176
    }
2177
 
2178
    /**
2179
     * Test that a record is stored for cached assets.
2180
     */
2181
    public function test_saveCachedAssets() {
2182
        global $DB;
2183
 
2184
        $this->resetAfterTest();
2185
 
2186
        $libraries = array(
2187
            array(
2188
                'machineName' => 'H5P.TestLib',
2189
                'libraryId' => 405,
2190
            ),
2191
            array(
2192
                'FontAwesome' => 'FontAwesome',
2193
                'libraryId' => 406,
2194
            ),
2195
            array(
2196
                'machineName' => 'H5P.SecondLib',
2197
                'libraryId' => 407,
2198
            ),
2199
        );
2200
 
2201
        $key = 'testhashkey';
2202
 
2203
        $this->framework->saveCachedAssets($key, $libraries);
2204
 
2205
        $records = $DB->get_records('h5p_libraries_cachedassets');
2206
 
2207
        $this->assertCount(3, $records);
2208
    }
2209
 
2210
    /**
2211
     * Test that the correct libraries are removed from the cached assets table
2212
     */
2213
    public function test_deleteCachedAssets() {
2214
        global $DB;
2215
 
2216
        $this->resetAfterTest();
2217
 
2218
        $libraries = array(
2219
            array(
2220
                'machineName' => 'H5P.TestLib',
2221
                'libraryId' => 405,
2222
            ),
2223
            array(
2224
                'FontAwesome' => 'FontAwesome',
2225
                'libraryId' => 406,
2226
            ),
2227
            array(
2228
                'machineName' => 'H5P.SecondLib',
2229
                'libraryId' => 407,
2230
            ),
2231
        );
2232
 
2233
        $key1 = 'testhashkey';
2234
        $this->framework->saveCachedAssets($key1, $libraries);
2235
 
2236
        $libraries = array(
2237
            array(
2238
                'machineName' => 'H5P.DiffLib',
2239
                'libraryId' => 408,
2240
            ),
2241
            array(
2242
                'FontAwesome' => 'FontAwesome',
2243
                'libraryId' => 406,
2244
            ),
2245
            array(
2246
                'machineName' => 'H5P.ThirdLib',
2247
                'libraryId' => 409,
2248
            ),
2249
        );
2250
 
2251
        $key2 = 'secondhashkey';
2252
        $this->framework->saveCachedAssets($key2, $libraries);
2253
 
2254
        $libraries = array(
2255
            array(
2256
                'machineName' => 'H5P.AnotherDiffLib',
2257
                'libraryId' => 410,
2258
            ),
2259
            array(
2260
                'FontAwesome' => 'NotRelated',
2261
                'libraryId' => 411,
2262
            ),
2263
            array(
2264
                'machineName' => 'H5P.ForthLib',
2265
                'libraryId' => 412,
2266
            ),
2267
        );
2268
 
2269
        $key3 = 'threeforthewin';
2270
        $this->framework->saveCachedAssets($key3, $libraries);
2271
 
2272
        $records = $DB->get_records('h5p_libraries_cachedassets');
2273
        $this->assertCount(9, $records);
2274
 
2275
        // Selecting one library id will result in all related library entries also being deleted.
2276
        // Going to use the FontAwesome library id. The first two hashes should be returned.
2277
        $hashes = $this->framework->deleteCachedAssets(406);
2278
        $this->assertCount(2, $hashes);
2279
        $index = array_search($key1, $hashes);
2280
        $this->assertEquals($key1, $hashes[$index]);
2281
        $index = array_search($key2, $hashes);
2282
        $this->assertEquals($key2, $hashes[$index]);
2283
        $index = array_search($key3, $hashes);
2284
        $this->assertFalse($index);
2285
 
2286
        // Check that the records have been removed as well.
2287
        $records = $DB->get_records('h5p_libraries_cachedassets');
2288
        $this->assertCount(3, $records);
2289
    }
2290
 
2291
    /**
2292
     * Test the behaviour of getLibraryContentCount().
2293
     */
2294
    public function test_getLibraryContentCount() {
2295
        $this->resetAfterTest();
2296
 
2297
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
2298
 
2299
        // Generate h5p related data.
2300
        $data = $generator->generate_h5p_data();
2301
 
2302
        // The 'MainLibrary' library data.
2303
        $mainlibrary = $data->mainlib->data;
2304
 
2305
        // The 'Library2' library data.
2306
        $library2 = $data->lib2->data;
2307
 
2308
        // Create new h5p content with Library2 as it's main library.
2309
        $generator->create_h5p_record($library2->id);
2310
 
2311
        // Create new h5p content with MainLibrary as it's main library.
2312
        $generator->create_h5p_record($mainlibrary->id);
2313
 
2314
        $countlibrarycontent = $this->framework->getLibraryContentCount();
2315
 
2316
        $expected = array(
2317
            "{$mainlibrary->machinename} {$mainlibrary->majorversion}.{$mainlibrary->minorversion}" => 2,
2318
            "{$library2->machinename} {$library2->majorversion}.{$library2->minorversion}" => 1,
2319
        );
2320
 
2321
        // MainLibrary and Library1 are currently main libraries to the existing h5p contents.
2322
        // Should return the number of cases where MainLibrary and Library1 are main libraries to an h5p content.
2323
        $this->assertEquals($expected, $countlibrarycontent);
2324
    }
2325
 
2326
    /**
2327
     * Test the behaviour of test_libraryHasUpgrade().
2328
     *
2329
     * @dataProvider libraryHasUpgrade_provider
2330
     * @param array $libraryrecords Array containing data for the library creation
2331
     * @param array $testlibrary Array containing the test library data
2332
     * @param bool $expected The expectation whether the library is patched or not
2333
     **/
2334
    public function test_libraryHasUpgrade(array $libraryrecords, array $testlibrary, bool $expected): void {
2335
        $this->resetAfterTest();
2336
 
2337
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
2338
 
2339
        foreach ($libraryrecords as $library) {
2340
            call_user_func_array([$generator, 'create_library_record'], $library);
2341
        }
2342
 
2343
        $this->assertEquals($expected, $this->framework->libraryHasUpgrade($testlibrary));
2344
    }
2345
 
2346
    /**
2347
     * Data provider for test_libraryHasUpgrade().
2348
     *
2349
     * @return array
2350
     */
2351
    public function libraryHasUpgrade_provider(): array {
2352
        return [
2353
            'Lower major version; Identical lower version' => [
2354
                [
2355
                    ['Library', 'Lib', 2, 2],
2356
                ],
2357
                [
2358
                    'machineName' => 'Library',
2359
                    'majorVersion' => 1,
2360
                    'minorVersion' => 2
2361
                ],
2362
                true,
2363
            ],
2364
            'Major version identical; Lower minor version' => [
2365
                [
2366
                    ['Library', 'Lib', 2, 2],
2367
                ],
2368
                [
2369
                    'machineName' => 'Library',
2370
                    'majorVersion' => 2,
2371
                    'minorVersion' => 1
2372
                ],
2373
                true,
2374
            ],
2375
            'Major version identical; Minor version identical' => [
2376
                [
2377
                    ['Library', 'Lib', 2, 2],
2378
                ],
2379
                [
2380
                    'machineName' => 'Library',
2381
                    'majorVersion' => 2,
2382
                    'minorVersion' => 2
2383
                ],
2384
                false,
2385
            ],
2386
            'Major version higher; Minor version identical' => [
2387
                [
2388
                    ['Library', 'Lib', 2, 2],
2389
                ],
2390
                [
2391
                    'machineName' => 'Library',
2392
                    'majorVersion' => 3,
2393
                    'minorVersion' => 2
2394
                ],
2395
                false,
2396
            ],
2397
            'Major version identical; Minor version newer' => [
2398
                [
2399
                    ['Library', 'Lib', 2, 2],
2400
                ],
2401
                [
2402
                    'machineName' => 'Library',
2403
                    'majorVersion' => 2,
2404
                    'minorVersion' => 4
2405
                ],
2406
                false,
2407
            ]
2408
        ];
2409
    }
2410
 
2411
 
2412
    /**
2413
     * Test the behaviour of get_latest_library_version().
2414
     */
2415
    public function test_get_latest_library_version() {
2416
        global $DB;
2417
 
2418
        $this->resetAfterTest();
2419
 
2420
        $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
2421
        // Create a library record.
2422
        $machinename = 'TestLibrary';
2423
        $lib1 = $generator->create_library_record($machinename, 'Test', 1, 1, 2);
2424
        $lib2 = $generator->create_library_record($machinename, 'Test', 1, 2, 1);
2425
 
2426
        $content = array(
2427
            'params' => json_encode(['param1' => 'Test']),
2428
            'library' => array(
2429
                'libraryId' => 0,
2430
                'machineName' => 'TestLibrary',
2431
            ),
2432
            'disable' => 8
2433
        );
2434
 
2435
        // Get the latest id (at this point, should be lib2).
2436
        $latestlib = $this->framework->get_latest_library_version($machinename);
2437
        $this->assertEquals($lib2->id, $latestlib->id);
2438
 
2439
        // Get the latest id (at this point, should be lib3).
2440
        $lib3 = $generator->create_library_record($machinename, 'Test', 2, 1, 0);
2441
        $latestlib = $this->framework->get_latest_library_version($machinename);
2442
        $this->assertEquals($lib3->id, $latestlib->id);
2443
 
2444
        // Get the latest id (at this point, should be still lib3).
2445
        $lib4 = $generator->create_library_record($machinename, 'Test', 1, 1, 3);
2446
        $latestlib = $this->framework->get_latest_library_version($machinename);
2447
        $this->assertEquals($lib3->id, $latestlib->id);
2448
 
2449
        // Get the latest id (at this point, should be lib5).
2450
        $lib5 = $generator->create_library_record($machinename, 'Test', 2, 1, 6);
2451
        $latestlib = $this->framework->get_latest_library_version($machinename);
2452
        $this->assertEquals($lib5->id, $latestlib->id);
2453
    }
2454
}