1<?php
2// This file is part of Moodle - http://moodle.org/
3//
4// Moodle is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// Moodle is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
17/**
18 * Testing the H5peditorStorage interface implementation.
19 *
20 * @package    core_h5p
21 * @category   test
22 * @copyright  2020 Victor Deniz <victor@moodle.com>
23 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 */
25
26namespace core_h5p;
27
28use core_h5p\local\library\autoloader;
29
30/**
31 *
32 * Test class covering the H5peditorStorage interface implementation.
33 *
34 * @package    core_h5p
35 * @copyright  2020 Victor Deniz <victor@moodle.com>
36 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
37 *
38 * @runTestsInSeparateProcesses
39 */
40class editor_framework_testcase extends \advanced_testcase {
41
42    /** @var editor_framework H5P editor_framework instance */
43    protected $editorframework;
44
45    /**
46     * Set up function for tests.
47     */
48    protected function setUp(): void {
49        parent::setUp();
50
51        autoloader::register();
52
53        $this->editorframework = new editor_framework();
54    }
55
56    /**
57     * Test that the method getLanguage retrieves the translation of a library in the requested language.
58     *
59     * @dataProvider  get_language_provider
60     *
61     * @param  array  $datalib        Library data to create
62     * @param  string $lang           Language to retrieve the translation
63     * @param  bool   $emptyexpected  True when false value is expected; false, otherwise
64     * @param  string $machinename    The machine readable name of the library(content type)
65     * @param  int    $majorversion   Major part of version number
66     * @param  int    $minorversion   Minor part of version number
67     */
68    public function test_get_language(array $datalib, string $lang, ?bool $emptyexpected = false, ?string $machinename = '',
69            ?int $majorversion = 1, ?int $minorversion = 0): void {
70        $this->resetAfterTest(true);
71
72        // Fetch generator.
73        $generator = \testing_util::get_data_generator();
74        $h5pgenerator = $generator->get_plugin_generator('core_h5p');
75
76        $h5pfilestorage = new file_storage();
77        $h5ptempath = $h5pfilestorage->getTmpPath();
78
79        $expectedresult = '';
80        if ($datalib) {
81            $translations = [];
82            if (array_key_exists('translation', $datalib)) {
83                $translations = $datalib['translation'];
84            }
85            // Create DB entry for this library.
86            $tmplib = $h5pgenerator->create_library_record($datalib['machinename'], $datalib['title'], $datalib['majorversion'],
87                $datalib['minorversion']);
88            // Create the files for this libray.
89            [$library, $files] = $h5pgenerator->create_library($h5ptempath, $tmplib->id, $datalib['machinename'],
90                $datalib['majorversion'], $datalib['minorversion'], $translations);
91            $h5pfilestorage->saveLibrary($library);
92
93            // If machinename, majorversion or minorversion are empty, use the value in datalib.
94            if (empty($machinename)) {
95                $machinename = $datalib['machinename'];
96            }
97            if (empty($majorversion)) {
98                $majorversion = $datalib['majorversion'];
99            }
100            if (empty($minorversion)) {
101                $minorversion = $datalib['minorversion'];
102            }
103            if (!$emptyexpected && array_key_exists($lang, $translations)) {
104                $expectedresult = $translations[$lang];
105            }
106        }
107
108        // Get Language.
109        $json = $this->editorframework->getLanguage($machinename, $majorversion, $minorversion, $lang);
110
111        if ($emptyexpected) {
112            $this->assertFalse($json);
113        } else {
114            $this->assertEquals($expectedresult, $json);
115        }
116    }
117
118    /**
119     * Data provider for test_get_language().
120     *
121     * @return array
122     */
123    public function get_language_provider(): array {
124        return [
125            'No library' => [
126                [],
127                'en',
128                true,
129                'Library1',
130                1,
131                2,
132            ],
133            'One library created but getting translation from an unexisting one' => [
134                'Library1 1.2' => [
135                    'machinename' => 'Library1',
136                    'title' => 'Lib1',
137                    'majorversion' => 1,
138                    'minorversion' => 2,
139                    'translation' => [
140                        'es' => '{"libraryStrings": {"key": "valor"}}',
141                        'fr' => '{"libraryStrings": {"key": "valeur"}}',
142                    ],
143                ],
144                'es',
145                true,
146                'AnotherLibrary',
147            ],
148            'One library without any translation' => [
149                'Library1 1.2' => [
150                    'machinename' => 'Library1',
151                    'title' => 'Lib1',
152                    'majorversion' => 1,
153                    'minorversion' => 2,
154                ],
155                'es',
156                true,
157            ],
158            'One library with 2 translations (es and fr) - es' => [
159                'Library1 1.2' => [
160                    'machinename' => 'Library1',
161                    'title' => 'Lib1',
162                    'majorversion' => 1,
163                    'minorversion' => 2,
164                    'translation' => [
165                        'es' => '{"libraryStrings": {"key": "valor"}}',
166                        'fr' => '{"libraryStrings": {"key": "valeur"}}',
167                    ],
168                ],
169                'es',
170            ],
171            'One library with 2 translations (es and fr) - fr' => [
172                'Library1 1.2' => [
173                    'machinename' => 'Library1',
174                    'title' => 'Lib1',
175                    'majorversion' => 1,
176                    'minorversion' => 2,
177                    'translation' => [
178                        'es' => '{"libraryStrings": {"key": "valor"}}',
179                        'fr' => '{"libraryStrings": {"key": "valeur"}}',
180                    ],
181                ],
182                'fr',
183            ],
184            'One library with 2 translations (es and fr) - unexisting translation (de)' => [
185                'Library1 1.2' => [
186                    'machinename' => 'Library1',
187                    'title' => 'Lib1',
188                    'majorversion' => 1,
189                    'minorversion' => 2,
190                    'translation' => [
191                        'es' => '{"libraryStrings": {"key": "valor"}}',
192                        'fr' => '{"libraryStrings": {"key": "valeur"}}',
193                    ],
194                ],
195                'de',
196                true
197            ],
198            'One library with 3 translations (one of them English) - fr' => [
199                'Library1 1.2' => [
200                    'machinename' => 'Library1',
201                    'title' => 'Lib1',
202                    'majorversion' => 1,
203                    'minorversion' => 2,
204                    'translation' => [
205                        'en' => '{"libraryStrings": {"key": "value"}}',
206                        'es' => '{"libraryStrings": {"key": "valor"}}',
207                        'fr' => '{"libraryStrings": {"key": "valeur"}}',
208                    ],
209                ],
210                'fr',
211            ],
212            'One library with 3 translations (one of them English) - en' => [
213                'Library1 1.2' => [
214                    'machinename' => 'Library1',
215                    'title' => 'Lib1',
216                    'majorversion' => 1,
217                    'minorversion' => 2,
218                    'translation' => [
219                        'en' => '{"libraryStrings": {"key": "value"}}',
220                        'es' => '{"libraryStrings": {"key": "valor"}}',
221                        'fr' => '{"libraryStrings": {"key": "valeur"}}',
222                    ],
223                ],
224                'en',
225            ],
226        ];
227    }
228
229    /**
230     * Test that the method getAvailableLanguages retrieves all the language available of a library.
231     *
232     * @dataProvider  get_available_languages_provider
233     *
234     * @param  array  $datalib        Library data to create
235     * @param  array  $expectedlangs  Available languages expected.
236     * @param  string $machinename    The machine readable name of the library(content type)
237     * @param  int    $majorversion   Major part of version number
238     * @param  int    $minorversion   Minor part of version number
239     */
240    public function test_get_available_languages(array $datalib, ?array $expectedlangs = null, ?string $machinename = '',
241            ?int $majorversion = 1, ?int $minorversion = 0): void {
242        $this->resetAfterTest(true);
243
244        // Fetch generator.
245        $generator = \testing_util::get_data_generator();
246        $h5pgenerator = $generator->get_plugin_generator('core_h5p');
247
248        $h5pfilestorage = new file_storage();
249        $h5ptempath = $h5pfilestorage->getTmpPath();
250
251        $translations = [];
252        if ($datalib) {
253            if (array_key_exists('translation', $datalib)) {
254                $translations = $datalib['translation'];
255            }
256            // Create DB entry for this library.
257            $tmplib = $h5pgenerator->create_library_record($datalib['machinename'], $datalib['title'], $datalib['majorversion'],
258                $datalib['minorversion']);
259            // Create the files for this libray.
260            [$library, $files] = $h5pgenerator->create_library($h5ptempath, $tmplib->id, $datalib['machinename'],
261                $datalib['majorversion'], $datalib['minorversion'], $translations);
262            $h5pfilestorage->saveLibrary($library);
263
264            if (empty($machinename)) {
265                $machinename = $datalib['machinename'];
266            }
267            if (empty($majorversion)) {
268                $majorversion = $datalib['majorversion'];
269            }
270            if (empty($minorversion)) {
271                $minorversion = $datalib['minorversion'];
272            }
273        }
274
275        // Get available languages.
276        $langs = $this->editorframework->getAvailableLanguages($machinename, $majorversion, $minorversion);
277
278        $this->assertCount(count($expectedlangs), $langs);
279        $this->assertEquals(ksort($expectedlangs), ksort($langs));
280    }
281
282    /**
283     * Data provider for test_get_available_languages().
284     *
285     * @return array
286     */
287    public function get_available_languages_provider(): array {
288        return [
289            'No library' => [
290                [],
291                [],
292                'Library1',
293                1,
294                2,
295            ],
296            'One library created but getting available from an unexisting one' => [
297                'Library1 1.2' => [
298                    'machinename' => 'Library1',
299                    'title' => 'Lib1',
300                    'majorversion' => 1,
301                    'minorversion' => 2,
302                    'translation' => [
303                        'es' => '{"libraryStrings": {"key": "valor"}}',
304                        'fr' => '{"libraryStrings": {"key": "valeur"}}',
305                    ],
306                ],
307                [],
308                'Library2',
309                1,
310                2,
311            ],
312            'One library without any translation' => [
313                'Library1 1.2' => [
314                    'machinename' => 'Library1',
315                    'title' => 'Lib1',
316                    'majorversion' => 1,
317                    'minorversion' => 2,
318                ],
319                ['en'],
320            ],
321            'One library with 2 translations (es and fr)' => [
322                'Library1 1.2' => [
323                    'machinename' => 'Library1',
324                    'title' => 'Lib1',
325                    'majorversion' => 1,
326                    'minorversion' => 2,
327                    'translation' => [
328                        'es' => '{"libraryStrings": {"key": "valor"}}',
329                        'fr' => '{"libraryStrings": {"key": "valeur"}}',
330                    ],
331                ],
332                ['en', 'es', 'fr'],
333            ],
334            'One library with 3 translations (one of them English)' => [
335                'Library1 1.2' => [
336                    'machinename' => 'Library1',
337                    'title' => 'Lib1',
338                    'majorversion' => 1,
339                    'minorversion' => 2,
340                    'translation' => [
341                        'en' => '{"libraryStrings": {"key": "value"}}',
342                        'es' => '{"libraryStrings": {"key": "valor"}}',
343                        'fr' => '{"libraryStrings": {"key": "valeur"}}',
344                    ],
345                ],
346                ['en', 'es', 'fr'],
347            ],
348        ];
349    }
350
351    /**
352     * Test that the method getLibraries get the specified libraries or all the content types (runnable = 1).
353     */
354    public function test_getLibraries(): void {
355        $this->resetAfterTest(true);
356
357        $generator = \testing_util::get_data_generator();
358        $h5pgenerator = $generator->get_plugin_generator('core_h5p');
359
360        // Generate some h5p related data.
361        $data = $h5pgenerator->generate_h5p_data();
362
363        $expectedlibraries = [];
364        foreach ($data as $key => $value) {
365            if (isset($value->data)) {
366                $value->data->name = $value->data->machinename;
367                $value->data->majorVersion = $value->data->majorversion;
368                $value->data->minorVersion = $value->data->minorversion;
369                $expectedlibraries[$value->data->title] = $value->data;
370            }
371        }
372        ksort($expectedlibraries);
373
374        // Get all libraries.
375        $libraries = $this->editorframework->getLibraries();
376        foreach ($libraries as $library) {
377            $actuallibraries[] = $library->title;
378        }
379        sort($actuallibraries);
380
381        $this->assertEquals(array_keys($expectedlibraries), $actuallibraries);
382
383        // Get a subset of libraries.
384        $librariessubset = array_slice($expectedlibraries, 0, 4);
385
386        $actuallibraries = [];
387        $libraries = $this->editorframework->getLibraries($librariessubset);
388        foreach ($libraries as $library) {
389            $actuallibraries[] = $library->title;
390        }
391
392        $this->assertEquals(array_keys($librariessubset), $actuallibraries);
393    }
394}
395