Proyectos de Subversion Moodle

Rev

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

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
 
18
/**
19
 * PHPUnit tests for fileconverter API.
20
 *
21
 * @package    core_files
22
 * @copyright  2017 Andrew nicols <andrew@nicols.co.uk>
23
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24
 */
25
defined('MOODLE_INTERNAL') || die();
26
 
27
global $CFG;
28
 
29
use core_files\conversion;
30
use core_files\converter;
31
 
32
/**
33
 * PHPUnit tests for fileconverter API.
34
 *
35
 * @package    core_files
36
 * @copyright  2017 Andrew nicols <andrew@nicols.co.uk>
37
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
38
 */
1441 ariadna 39
final class converter_test extends advanced_testcase {
1 efrain 40
 
41
    /**
42
     * Get a testable mock of the abstract files_converter class.
43
     *
44
     * @param   array   $mockedmethods A list of methods you intend to override
45
     *                  If no methods are specified, only abstract functions are mocked.
46
     * @return  \core_files\converter
47
     */
48
    protected function get_testable_mock($mockedmethods = []) {
49
        $converter = $this->getMockBuilder(\core_files\converter::class)
50
            ->onlyMethods($mockedmethods)
51
            ->getMockForAbstractClass();
52
 
53
        return $converter;
54
    }
55
 
56
    /**
57
     * Get a testable mock of the conversion.
58
     *
59
     * @param   array   $mockedmethods A list of methods you intend to override
60
     * @return  \core_files\conversion
61
     */
62
    protected function get_testable_conversion($mockedmethods = []) {
63
        $conversion = $this->getMockBuilder(\core_files\conversion::class)
64
            ->onlyMethods($mockedmethods)
65
            ->setConstructorArgs([0, (object) []])
66
            ->getMock();
67
 
68
        return $conversion;
69
    }
70
 
71
    /**
72
     * Get a testable mock of the abstract files_converter class.
73
     *
74
     * @param   array   $mockedmethods A list of methods you intend to override
75
     *                  If no methods are specified, only abstract functions are mocked.
76
     * @return  \core_files\converter_interface
77
     */
78
    protected function get_mocked_converter($mockedmethods = []) {
79
        $converter = $this->getMockBuilder(\core_files\converter_interface::class)
80
            ->onlyMethods($mockedmethods)
81
            ->getMockForAbstractClass();
82
 
83
        return $converter;
84
    }
85
 
86
    /**
87
     * Helper to create a stored file objectw with the given supplied content.
88
     *
89
     * @param   string  $filecontent The content of the mocked file
90
     * @param   string  $filename The file name to use in the stored_file
91
     * @param   array   $mockedmethods A list of methods you intend to override
92
     *                  If no methods are specified, only abstract functions are mocked.
93
     * @return  stored_file
94
     */
95
    protected function get_stored_file($filecontent = 'content', $filename = null, $filerecord = [], $mockedmethods = []) {
96
        global $CFG;
97
 
98
        $contenthash = sha1($filecontent);
99
        if (empty($filename)) {
100
            $filename = $contenthash;
101
        }
102
 
103
        $filerecord['contenthash'] = $contenthash;
104
        $filerecord['filesize'] = strlen($filecontent);
105
        $filerecord['filename'] = $filename;
106
        $filerecord['id'] = 42;
107
 
108
        $file = $this->getMockBuilder(stored_file::class)
109
            ->onlyMethods($mockedmethods)
110
            ->setConstructorArgs([get_file_storage(), (object) $filerecord])
111
            ->getMock();
112
 
113
        return $file;
114
    }
115
 
116
    /**
117
     * Helper to create a stored file object with the given supplied content.
118
     *
119
     * @param   string $filecontent The content of the mocked file
120
     * @param   string $filename The file name to use in the stored_file
121
     * @param   string $filerecord Any overrides to the filerecord
122
     * @return  stored_file
123
     */
124
    protected function create_stored_file($filecontent = 'content', $filename = 'testfile.txt', $filerecord = []) {
125
        $filerecord = array_merge([
126
                'contextid' => context_system::instance()->id,
127
                'component' => 'core',
128
                'filearea'  => 'unittest',
129
                'itemid'    => 0,
130
                'filepath'  => '/',
131
                'filename'  => $filename,
132
            ], $filerecord);
133
 
134
        $fs = get_file_storage();
135
        $file = $fs->create_file_from_string($filerecord, $filecontent);
136
 
137
        return $file;
138
    }
139
 
140
    /**
141
     * Get a mock of the file_storage API.
142
     *
143
     * @param   array   $mockedmethods A list of methods you intend to override
144
     * @return  file_storage
145
     */
146
    protected function get_file_storage_mock($mockedmethods = []) {
147
        $fs = $this->getMockBuilder(\file_storage::class)
148
            ->onlyMethods($mockedmethods)
149
            ->disableOriginalConstructor()
150
            ->getMock();
151
 
152
        return $fs;
153
    }
154
 
155
    /**
156
     * Test the start_conversion function.
157
     */
11 efrain 158
    public function test_start_conversion_existing_single(): void {
1 efrain 159
        $this->resetAfterTest();
160
 
161
        $sourcefile = $this->create_stored_file();
162
 
163
        $first = new conversion(0, (object) [
164
                'sourcefileid' => $sourcefile->get_id(),
165
                'targetformat' => 'pdf',
166
            ]);
167
        $first->create();
168
 
169
        $converter = $this->get_testable_mock(['poll_conversion']);
170
        $conversion = $converter->start_conversion($sourcefile, 'pdf', false);
171
 
172
        // The old conversions should still be present and match the one returned.
173
        $this->assertEquals($first->get('id'), $conversion->get('id'));
174
    }
175
 
176
    /**
177
     * Test the start_conversion function.
178
     */
11 efrain 179
    public function test_start_conversion_existing_multiple(): void {
1 efrain 180
        $this->resetAfterTest();
181
 
182
        $sourcefile = $this->create_stored_file();
183
 
184
        $first = new conversion(0, (object) [
185
                'sourcefileid' => $sourcefile->get_id(),
186
                'targetformat' => 'pdf',
187
            ]);
188
        $first->create();
189
 
190
        $second = new conversion(0, (object) [
191
                'sourcefileid' => $sourcefile->get_id(),
192
                'targetformat' => 'pdf',
193
            ]);
194
        $second->create();
195
 
196
        $converter = $this->get_testable_mock(['poll_conversion']);
197
        $conversion = $converter->start_conversion($sourcefile, 'pdf', false);
198
 
199
        // The old conversions should have been removed.
200
        $this->assertFalse(conversion::get_record(['id' => $first->get('id')]));
201
        $this->assertFalse(conversion::get_record(['id' => $second->get('id')]));
202
    }
203
 
204
    /**
205
     * Test the start_conversion function.
206
     */
11 efrain 207
    public function test_start_conversion_no_existing(): void {
1 efrain 208
        $this->resetAfterTest();
209
 
210
        $sourcefile = $this->create_stored_file();
211
 
212
        $converter = $this->get_testable_mock(['poll_conversion']);
213
        $conversion = $converter->start_conversion($sourcefile, 'pdf', false);
214
 
215
        $this->assertInstanceOf(\core_files\conversion::class, $conversion);
216
    }
217
 
218
    /**
219
     * Test the get_document_converter_classes function with no enabled plugins.
220
     */
11 efrain 221
    public function test_get_document_converter_classes_no_plugins(): void {
1 efrain 222
        $converter = $this->get_testable_mock(['get_enabled_plugins']);
223
        $converter->method('get_enabled_plugins')->willReturn([]);
224
 
225
        $method = new ReflectionMethod(\core_files\converter::class, 'get_document_converter_classes');
226
        $result = $method->invokeArgs($converter, ['docx', 'pdf']);
227
        $this->assertEmpty($result);
228
    }
229
 
230
    /**
231
     * Test the get_document_converter_classes function when no class was found.
232
     */
11 efrain 233
    public function test_get_document_converter_classes_plugin_class_not_found(): void {
1 efrain 234
        $converter = $this->get_testable_mock(['get_enabled_plugins']);
235
        $converter->method('get_enabled_plugins')->willReturn([
236
                'noplugin' => '\not\a\real\plugin',
237
            ]);
238
 
239
        $method = new ReflectionMethod(\core_files\converter::class, 'get_document_converter_classes');
240
        $result = $method->invokeArgs($converter, ['docx', 'pdf']);
241
        $this->assertEmpty($result);
242
    }
243
 
244
    /**
245
     * Test the get_document_converter_classes function when the returned classes do not meet requirements.
246
     */
11 efrain 247
    public function test_get_document_converter_classes_plugin_class_requirements_not_met(): void {
1 efrain 248
        $plugin = $this->getMockBuilder(\core_file_converter_requirements_not_met::class)
249
            ->onlyMethods([])
250
            ->getMock();
251
 
252
        $converter = $this->get_testable_mock(['get_enabled_plugins']);
253
        $converter->method('get_enabled_plugins')->willReturn([
254
                'test_plugin' => get_class($plugin),
255
            ]);
256
 
257
        $method = new ReflectionMethod(\core_files\converter::class, 'get_document_converter_classes');
258
        $result = $method->invokeArgs($converter, ['docx', 'pdf']);
259
        $this->assertEmpty($result);
260
    }
261
 
262
    /**
263
     * Test the get_document_converter_classes function when the returned classes do not meet requirements.
264
     */
11 efrain 265
    public function test_get_document_converter_classes_plugin_class_met_not_supported(): void {
1 efrain 266
        $plugin = $this->getMockBuilder(\core_file_converter_type_not_supported::class)
267
            ->onlyMethods([])
268
            ->getMock();
269
 
270
        $converter = $this->get_testable_mock(['get_enabled_plugins']);
271
        $converter->method('get_enabled_plugins')->willReturn([
272
                'test_plugin' => get_class($plugin),
273
            ]);
274
 
275
        $method = new ReflectionMethod(\core_files\converter::class, 'get_document_converter_classes');
276
        $result = $method->invokeArgs($converter, ['docx', 'pdf']);
277
        $this->assertEmpty($result);
278
    }
279
 
280
    /**
281
     * Test the get_document_converter_classes function when the returned classes do not meet requirements.
282
     */
11 efrain 283
    public function test_get_document_converter_classes_plugin_class_met_and_supported(): void {
1 efrain 284
        $plugin = $this->getMockBuilder(\core_file_converter_type_supported::class)
285
            ->onlyMethods([])
286
            ->getMock();
287
        $classname = get_class($plugin);
288
 
289
        $converter = $this->get_testable_mock(['get_enabled_plugins']);
290
        $converter->method('get_enabled_plugins')->willReturn([
291
                'test_plugin' => $classname,
292
            ]);
293
 
294
        $method = new ReflectionMethod(\core_files\converter::class, 'get_document_converter_classes');
295
        $result = $method->invokeArgs($converter, ['docx', 'pdf']);
296
        $this->assertCount(1, $result);
297
        $this->assertNotFalse(array_search($classname, $result));
298
    }
299
 
300
    /**
301
     * Test the can_convert_storedfile_to function with a directory.
302
     */
11 efrain 303
    public function test_can_convert_storedfile_to_directory(): void {
1 efrain 304
        $converter = $this->get_testable_mock();
305
 
306
        // A file with filename '.' is a directory.
307
        $file = $this->get_stored_file('', '.');
308
 
309
        $this->assertFalse($converter->can_convert_storedfile_to($file, 'target'));
310
    }
311
 
312
    /**
313
     * Test the can_convert_storedfile_to function with an empty file.
314
     */
11 efrain 315
    public function test_can_convert_storedfile_to_emptyfile(): void {
1 efrain 316
        $converter = $this->get_testable_mock();
317
 
318
        // A file with filename '.' is a directory.
319
        $file = $this->get_stored_file('');
320
 
321
        $this->assertFalse($converter->can_convert_storedfile_to($file, 'target'));
322
    }
323
 
324
    /**
325
     * Test the can_convert_storedfile_to function with a file with indistinguished mimetype.
326
     */
11 efrain 327
    public function test_can_convert_storedfile_to_no_mimetype(): void {
1 efrain 328
        $converter = $this->get_testable_mock();
329
 
330
        // A file with filename '.' is a directory.
331
        $file = $this->get_stored_file('example content', 'example', [
332
                'mimetype' => null,
333
            ]);
334
 
335
        $this->assertFalse($converter->can_convert_storedfile_to($file, 'target'));
336
    }
337
 
338
    /**
339
     * Test the can_convert_storedfile_to function with a file with a known mimetype and extension.
340
     */
11 efrain 341
    public function test_can_convert_storedfile_to_docx(): void {
1 efrain 342
        $returnvalue = (object) [];
343
 
344
        $converter = $this->get_testable_mock([
345
                'can_convert_format_to'
346
            ]);
347
 
348
        $types = \core_filetypes::get_types();
349
 
350
        $file = $this->get_stored_file('example content', 'example.docx', [
351
                'mimetype' => $types['docx']['type'],
352
            ]);
353
 
354
        $converter->expects($this->once())
355
            ->method('can_convert_format_to')
356
            ->willReturn($returnvalue);
357
 
358
        $result = $converter->can_convert_storedfile_to($file, 'target');
359
        $this->assertEquals($returnvalue, $result);
360
    }
361
 
362
 
363
    /**
364
     * Test the can_convert_format_to function.
365
     */
11 efrain 366
    public function test_can_convert_format_to_found(): void {
1 efrain 367
        $converter = $this->get_testable_mock(['get_document_converter_classes']);
368
 
369
        $mock = $this->get_mocked_converter();
370
 
371
        $converter->method('get_document_converter_classes')
372
            ->willReturn([$mock]);
373
 
374
        $result = $converter->can_convert_format_to('from', 'to');
375
        $this->assertTrue($result);
376
    }
377
 
378
    /**
379
     * Test the can_convert_format_to function.
380
     */
11 efrain 381
    public function test_can_convert_format_to_not_found(): void {
1 efrain 382
        $converter = $this->get_testable_mock(['get_document_converter_classes']);
383
 
384
        $converter->method('get_document_converter_classes')
385
            ->willReturn([]);
386
 
387
        $result = $converter->can_convert_format_to('from', 'to');
388
        $this->assertFalse($result);
389
    }
390
 
391
    /**
392
     * Test the can_convert_storedfile_to function with an empty file.
393
     */
11 efrain 394
    public function test_poll_conversion_in_progress(): void {
1 efrain 395
        $this->resetAfterTest();
396
 
397
        $converter = $this->get_testable_mock([
398
                'get_document_converter_classes',
399
                'get_next_converter',
400
            ]);
401
 
402
        $converter->method('get_document_converter_classes')->willReturn([]);
403
        $converter->method('get_next_converter')->willReturn(false);
404
        $file = $this->create_stored_file('example content', 'example', [
405
                'mimetype' => null,
406
            ]);
407
 
408
        $conversion = $this->get_testable_conversion([
409
                'get_converter_instance',
410
            ]);
411
        $conversion->set_sourcefile($file);
412
        $conversion->set('targetformat', 'target');
413
        $conversion->set('status', conversion::STATUS_IN_PROGRESS);
414
        $conversion->create();
415
 
416
        $converterinstance = $this->get_mocked_converter([
417
                'poll_conversion_status',
418
            ]);
419
        $converterinstance->expects($this->once())
420
            ->method('poll_conversion_status');
421
        $conversion->method('get_converter_instance')->willReturn($converterinstance);
422
 
423
        $converter->poll_conversion($conversion);
424
 
425
        $this->assertEquals(conversion::STATUS_IN_PROGRESS, $conversion->get('status'));
426
    }
427
 
428
    /**
429
     * Test poll_conversion with an in-progress conversion where we are
430
     * unable to instantiate the converter instance.
431
     */
11 efrain 432
    public function test_poll_conversion_in_progress_fail(): void {
1 efrain 433
        $this->resetAfterTest();
434
 
435
        $converter = $this->get_testable_mock([
436
                'get_document_converter_classes',
437
                'get_next_converter',
438
            ]);
439
 
440
        $converter->method('get_document_converter_classes')->willReturn([]);
441
        $converter->method('get_next_converter')->willReturn(false);
442
        $file = $this->create_stored_file('example content', 'example', [
443
                'mimetype' => null,
444
            ]);
445
 
446
        $conversion = $this->get_testable_conversion([
447
                'get_converter_instance',
448
            ]);
449
        $conversion->set_sourcefile($file);
450
        $conversion->set('targetformat', 'target');
451
        $conversion->set('status', conversion::STATUS_IN_PROGRESS);
452
        $conversion->create();
453
 
454
        $conversion->method('get_converter_instance')->willReturn(false);
455
 
456
        $converter->poll_conversion($conversion);
457
 
458
        $this->assertEquals(conversion::STATUS_FAILED, $conversion->get('status'));
459
    }
460
 
461
    /**
462
     * Test the can_convert_storedfile_to function with an empty file.
463
     */
11 efrain 464
    public function test_poll_conversion_none_supported(): void {
1 efrain 465
        $this->resetAfterTest();
466
 
467
        $converter = $this->get_testable_mock([
468
                'get_document_converter_classes',
469
                'get_next_converter',
470
            ]);
471
 
472
        $converter->method('get_document_converter_classes')->willReturn([]);
473
        $converter->method('get_next_converter')->willReturn(false);
474
        $file = $this->create_stored_file('example content', 'example', [
475
                'mimetype' => null,
476
            ]);
477
 
478
        $conversion = new conversion(0, (object) [
479
            'sourcefileid' => $file->get_id(),
480
            'targetformat' => 'target',
481
        ]);
482
        $conversion->create();
483
 
484
        $converter->poll_conversion($conversion);
485
 
486
        $this->assertEquals(conversion::STATUS_FAILED, $conversion->get('status'));
487
    }
488
 
489
    /**
490
     * Test the can_convert_storedfile_to function with an empty file.
491
     */
11 efrain 492
    public function test_poll_conversion_pick_first(): void {
1 efrain 493
        $this->resetAfterTest();
494
 
495
        $converterinstance = $this->get_mocked_converter([
496
                'start_document_conversion',
497
                'poll_conversion_status',
498
            ]);
499
        $converter = $this->get_testable_mock([
500
                'get_document_converter_classes',
501
                'get_next_converter',
502
            ]);
503
 
504
        $converter->method('get_document_converter_classes')->willReturn([]);
505
        $converter->method('get_next_converter')->willReturn(get_class($converterinstance));
506
        $file = $this->create_stored_file('example content', 'example', [
507
                'mimetype' => null,
508
            ]);
509
 
510
        $conversion = $this->get_testable_conversion([
511
                'get_converter_instance',
512
            ]);
513
        $conversion->set_sourcefile($file);
514
        $conversion->set('targetformat', 'target');
515
        $conversion->set('status', conversion::STATUS_PENDING);
516
        $conversion->create();
517
 
518
        $conversion->method('get_converter_instance')->willReturn($converterinstance);
519
 
520
        $converterinstance->expects($this->once())
521
            ->method('start_document_conversion');
522
        $converterinstance->expects($this->never())
523
            ->method('poll_conversion_status');
524
 
525
        $converter->poll_conversion($conversion);
526
 
527
        $this->assertEquals(conversion::STATUS_IN_PROGRESS, $conversion->get('status'));
528
    }
529
 
530
    /**
531
     * Test the can_convert_storedfile_to function with an empty file.
532
     */
11 efrain 533
    public function test_poll_conversion_pick_subsequent(): void {
1 efrain 534
        $this->resetAfterTest();
535
 
536
        $converterinstance = $this->get_mocked_converter([
537
                'start_document_conversion',
538
                'poll_conversion_status',
539
            ]);
540
        $converterinstance2 = $this->get_mocked_converter([
541
                'start_document_conversion',
542
                'poll_conversion_status',
543
            ]);
544
        $converter = $this->get_testable_mock([
545
                'get_document_converter_classes',
546
                'get_next_converter',
547
            ]);
548
 
549
        $converter->method('get_document_converter_classes')->willReturn([]);
1441 ariadna 550
        $getinvocations = $this->any();
551
        $converter
552
            ->expects($getinvocations)
553
            ->method('get_next_converter')
554
            ->willReturnCallback(fn (): string => match (self::getInvocationCount($getinvocations)) {
555
                1 => get_class($converterinstance),
556
                default => get_class($converterinstance2),
557
            });
1 efrain 558
 
559
        $file = $this->create_stored_file('example content', 'example', [
560
                'mimetype' => null,
561
            ]);
562
 
563
        $conversion = $this->get_testable_conversion([
564
                'get_converter_instance',
565
                'get_status',
566
            ]);
567
        $conversion->set_sourcefile($file);
568
        $conversion->set('targetformat', 'target');
569
        $conversion->set('status', conversion::STATUS_PENDING);
570
        $conversion->create();
571
 
1441 ariadna 572
        $statusinvocations = $this->atLeast(4);
573
        $conversion
574
            ->expects($statusinvocations)
575
            ->method('get_status')
576
            ->willReturnCallback(fn (): int => match (self::getInvocationCount($statusinvocations)) {
1 efrain 577
                // Initial status check.
1441 ariadna 578
                1 => conversion::STATUS_PENDING,
1 efrain 579
                // Second check to make sure it's still pending after polling.
1441 ariadna 580
                2 => conversion::STATUS_PENDING,
1 efrain 581
                // First one fails.
1441 ariadna 582
                3 => conversion::STATUS_FAILED,
1 efrain 583
                // Second one succeeds.
1441 ariadna 584
                4 => conversion::STATUS_COMPLETE,
1 efrain 585
                // And the final result checked in this unit test.
1441 ariadna 586
                default => conversion::STATUS_COMPLETE,
587
            });
1 efrain 588
 
1441 ariadna 589
        $instanceinvocations = $this->any();
590
        $conversion
591
            ->expects($instanceinvocations)
592
            ->method('get_converter_instance')
593
            ->willReturnCallback(fn (): object => match (self::getInvocationCount($instanceinvocations)) {
594
                1 => $converterinstance,
595
                default => $converterinstance2,
596
            });
1 efrain 597
 
598
        $converterinstance->expects($this->once())
599
            ->method('start_document_conversion');
600
        $converterinstance->expects($this->never())
601
            ->method('poll_conversion_status');
602
        $converterinstance2->expects($this->once())
603
            ->method('start_document_conversion');
604
        $converterinstance2->expects($this->never())
605
            ->method('poll_conversion_status');
606
 
607
        $converter->poll_conversion($conversion);
608
 
609
        $this->assertEquals(conversion::STATUS_COMPLETE, $conversion->get('status'));
610
    }
611
 
612
    /**
613
     * Test the start_conversion with a single converter which succeeds.
614
     */
11 efrain 615
    public function test_start_conversion_one_supported_success(): void {
1 efrain 616
        $this->resetAfterTest();
617
 
618
        $converter = $this->get_testable_mock([
619
                'get_document_converter_classes',
620
            ]);
621
 
622
        $converter->method('get_document_converter_classes')
623
            ->willReturn([\core_file_converter_type_successful::class]);
624
 
625
        $file = $this->create_stored_file('example content', 'example', [
626
                'mimetype' => null,
627
            ]);
628
 
629
        $conversion = $converter->start_conversion($file, 'target');
630
 
631
        $this->assertEquals(conversion::STATUS_COMPLETE, $conversion->get('status'));
632
    }
633
 
634
    /**
635
     * Test the start_conversion with a single converter which failes.
636
     */
11 efrain 637
    public function test_start_conversion_one_supported_failure(): void {
1 efrain 638
        $this->resetAfterTest();
639
 
640
        $converter = $this->get_testable_mock([
641
                'get_document_converter_classes',
642
            ]);
643
 
644
        $mock = $this->get_mocked_converter(['start_document_conversion']);
645
        $converter->method('get_document_converter_classes')
646
            ->willReturn([\core_file_converter_type_failed::class]);
647
 
648
        $file = $this->create_stored_file('example content', 'example', [
649
                'mimetype' => null,
650
            ]);
651
 
652
        $conversion = $converter->start_conversion($file, 'target');
653
 
654
        $this->assertEquals(conversion::STATUS_FAILED, $conversion->get('status'));
655
    }
656
 
657
    /**
658
     * Test the start_conversion with two converters - fail, then succeed.
659
     */
11 efrain 660
    public function test_start_conversion_two_supported(): void {
1 efrain 661
        $this->resetAfterTest();
662
 
663
        $converter = $this->get_testable_mock([
664
                'get_document_converter_classes',
665
            ]);
666
 
667
        $mock = $this->get_mocked_converter(['start_document_conversion']);
668
        $converter->method('get_document_converter_classes')
669
            ->willReturn([
670
                \core_file_converter_type_failed::class,
671
                \core_file_converter_type_successful::class,
672
            ]);
673
 
674
        $file = $this->create_stored_file('example content', 'example', [
675
                'mimetype' => null,
676
            ]);
677
 
678
        $conversion = $converter->start_conversion($file, 'target');
679
 
680
        $this->assertEquals(conversion::STATUS_COMPLETE, $conversion->get('status'));
681
    }
682
 
683
    /**
684
     * Ensure that get_next_converter returns false when no converters are available.
685
     */
11 efrain 686
    public function test_get_next_converter_no_converters(): void {
1 efrain 687
        $rcm = new \ReflectionMethod(converter::class, 'get_next_converter');
688
 
689
        $converter = new \core_files\converter();
690
        $result = $rcm->invoke($converter, [], null);
691
        $this->assertFalse($result);
692
    }
693
 
694
    /**
695
     * Ensure that get_next_converter returns false when already on the
696
     * only converter.
697
     */
11 efrain 698
    public function test_get_next_converter_only_converters(): void {
1 efrain 699
        $rcm = new \ReflectionMethod(converter::class, 'get_next_converter');
700
 
701
        $converter = new converter();
702
        $result = $rcm->invoke($converter, ['example'], 'example');
703
        $this->assertFalse($result);
704
    }
705
 
706
    /**
707
     * Ensure that get_next_converter returns false when already on the
708
     * last converter.
709
     */
11 efrain 710
    public function test_get_next_converter_last_converters(): void {
1 efrain 711
        $rcm = new \ReflectionMethod(converter::class, 'get_next_converter');
712
 
713
        $converter = new converter();
714
        $result = $rcm->invoke($converter, ['foo', 'example'], 'example');
715
        $this->assertFalse($result);
716
    }
717
 
718
    /**
719
     * Ensure that get_next_converter returns the next vlaue when in a
720
     * current converter.
721
     */
11 efrain 722
    public function test_get_next_converter_middle_converters(): void {
1 efrain 723
        $rcm = new \ReflectionMethod(converter::class, 'get_next_converter');
724
 
725
        $converter = new converter();
726
        $result = $rcm->invoke($converter, ['foo', 'bar', 'baz', 'example'], 'bar');
727
        $this->assertEquals('baz', $result);
728
    }
729
    /**
730
     *
731
     * Ensure that get_next_converter returns the next vlaue when in a
732
     * current converter.
733
     */
11 efrain 734
    public function test_get_next_converter_first(): void {
1 efrain 735
        $rcm = new \ReflectionMethod(converter::class, 'get_next_converter');
736
 
737
        $converter = new converter();
738
        $result = $rcm->invoke($converter, ['foo', 'bar', 'baz', 'example']);
739
        $this->assertEquals('foo', $result);
740
    }
741
}
742
 
743
class core_file_converter_requirements_base implements \core_files\converter_interface {
744
 
745
    /**
746
     * Whether the plugin is configured and requirements are met.
747
     *
748
     * @return  bool
749
     */
750
    public static function are_requirements_met() {
751
        return false;
752
    }
753
 
754
    /**
755
     * Convert a document to a new format and return a conversion object relating to the conversion in progress.
756
     *
757
     * @param   conversion $conversion The file to be converted
758
     * @return  conversion
759
     */
760
    public function start_document_conversion(conversion $conversion) {
761
    }
762
 
763
    /**
764
     * Poll an existing conversion for status update.
765
     *
766
     * @param   conversion $conversion The file to be converted
767
     * @return  conversion
768
     */
769
    public function poll_conversion_status(conversion $conversion) {
770
    }
771
 
772
    /**
773
     * Whether a file conversion can be completed using this converter.
774
     *
775
     * @param   string $from The source type
776
     * @param   string $to The destination type
777
     * @return  bool
778
     */
779
    public static function supports($from, $to) {
780
        return false;
781
    }
782
 
783
    /**
784
     * A list of the supported conversions.
785
     *
786
     * @return  string
787
     */
788
    public function get_supported_conversions() {
789
        return [];
790
    }
791
 
792
}
793
 
794
/**
795
 * Test class for converter support with requirements are not met.
796
 *
797
 * @package    core_files
798
 * @copyright  2017 Andrew nicols <andrew@nicols.co.uk>
799
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
800
 */
801
class core_file_converter_requirements_not_met extends core_file_converter_requirements_base {
802
}
803
 
804
/**
805
 * Test class for converter support with requirements met and conversion not supported.
806
 *
807
 * @package    core_files
808
 * @copyright  2017 Andrew nicols <andrew@nicols.co.uk>
809
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
810
 */
811
class core_file_converter_type_not_supported extends core_file_converter_requirements_base {
812
 
813
    /**
814
     * Whether the plugin is configured and requirements are met.
815
     *
816
     * @return  bool
817
     */
818
    public static function are_requirements_met() {
819
        return true;
820
    }
821
}
822
 
823
/**
824
 * Test class for converter support with requirements met and conversion supported.
825
 *
826
 * @package    core_files
827
 * @copyright  2017 Andrew nicols <andrew@nicols.co.uk>
828
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
829
 */
830
class core_file_converter_type_supported extends core_file_converter_requirements_base {
831
 
832
    /**
833
     * Whether the plugin is configured and requirements are met.
834
     *
835
     * @return  bool
836
     */
837
    public static function are_requirements_met() {
838
        return true;
839
    }
840
 
841
    /**
842
     * Whether a file conversion can be completed using this converter.
843
     *
844
     * @param   string $from The source type
845
     * @param   string $to The destination type
846
     * @return  bool
847
     */
848
    public static function supports($from, $to) {
849
        return true;
850
    }
851
}
852
 
853
/**
854
 * Test class for converter support with requirements met and successful conversion.
855
 *
856
 * @package    core_files
857
 * @copyright  2017 Andrew nicols <andrew@nicols.co.uk>
858
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
859
 */
860
class core_file_converter_type_successful extends core_file_converter_requirements_base {
861
 
862
    /**
863
     * Convert a document to a new format and return a conversion object relating to the conversion in progress.
864
     *
865
     * @param   conversion $conversion The file to be converted
866
     * @return  conversion
867
     */
868
    public function start_document_conversion(conversion $conversion) {
869
        $conversion->set('status', conversion::STATUS_COMPLETE);
870
 
871
        return $conversion;
872
    }
873
 
874
    /**
875
     * Whether a file conversion can be completed using this converter.
876
     *
877
     * @param   string $from The source type
878
     * @param   string $to The destination type
879
     * @return  bool
880
     */
881
    public static function supports($from, $to) {
882
        return true;
883
    }
884
}
885
 
886
/**
887
 * Test class for converter support with requirements met and failed conversion.
888
 *
889
 * @package    core_files
890
 * @copyright  2017 Andrew nicols <andrew@nicols.co.uk>
891
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
892
 */
893
class core_file_converter_type_failed extends core_file_converter_requirements_base {
894
 
895
    /**
896
     * Whether the plugin is configured and requirements are met.
897
     *
898
     * @return  bool
899
     */
900
    public static function are_requirements_met() {
901
        return true;
902
    }
903
 
904
    /**
905
     * Convert a document to a new format and return a conversion object relating to the conversion in progress.
906
     *
907
     * @param   conversion $conversion The file to be converted
908
     * @return  conversion
909
     */
910
    public function start_document_conversion(conversion $conversion) {
911
        $conversion->set('status', conversion::STATUS_FAILED);
912
 
913
        return $conversion;
914
    }
915
 
916
    /**
917
     * Whether a file conversion can be completed using this converter.
918
     *
919
     * @param   string $from The source type
920
     * @param   string $to The destination type
921
     * @return  bool
922
     */
923
    public static function supports($from, $to) {
924
        return true;
925
    }
926
}