xref: /plugin/totext/_test/PptxExtractorTest.php (revision e3bf24fb9dfc9f06d2338a5c5cb7500e628e4f71)
1<?php
2
3namespace dokuwiki\plugin\totext\test;
4
5use dokuwiki\plugin\totext\Exception\ExtractionException;
6use dokuwiki\plugin\totext\Extractor\PptxExtractor;
7use DokuWikiTest;
8
9/**
10 * Tests for the PPTX extractor.
11 *
12 * @group plugin_totext
13 */
14class PptxExtractorTest extends DokuWikiTest
15{
16    /** @var string[] */
17    protected $pluginsEnabled = ['totext'];
18
19    /** @var string temp working directory */
20    private $tmp = '';
21
22    /** @var string fixture path */
23    private $fixture = '';
24
25    /** @inheritDoc */
26    public function setUp(): void
27    {
28        parent::setUp();
29        $this->tmp = FixtureBuilder::tempDir();
30        $this->fixture = $this->tmp . '/sample.pptx';
31        FixtureBuilder::buildPptx($this->fixture);
32    }
33
34    /** @inheritDoc */
35    public function tearDown(): void
36    {
37        FixtureBuilder::cleanup($this->tmp);
38        parent::tearDown();
39    }
40
41    public function testExtractsBothSlides()
42    {
43        $text = (new PptxExtractor())->extract($this->fixture);
44        $this->assertStringContainsString('First slide title', $text);
45        $this->assertStringContainsString('Second slide', $text);
46    }
47
48    public function testHonoursSldIdLstOrder()
49    {
50        // Fixture's sldIdLst points rId2 (slide1.xml = "First slide title") FIRST,
51        // then rId1 (slide2.xml = "Second slide"). Display order must reflect that.
52        $text = (new PptxExtractor())->extract($this->fixture);
53        $posFirst = strpos($text, 'First slide title');
54        $posSecond = strpos($text, 'Second slide');
55        $this->assertNotFalse($posFirst);
56        $this->assertNotFalse($posSecond);
57        $this->assertLessThan($posSecond, $posFirst);
58    }
59
60    public function testSlideHeaders()
61    {
62        $text = (new PptxExtractor())->extract($this->fixture);
63        $this->assertStringContainsString('=== Slide 1 ===', $text);
64        $this->assertStringContainsString('=== Slide 2 ===', $text);
65    }
66
67    public function testExtractsSpeakerNotes()
68    {
69        $path = $this->tmp . '/notes.pptx';
70        FixtureBuilder::buildPptxWithNotes($path);
71        $text = (new PptxExtractor())->extract($path);
72        $this->assertStringContainsString('Visible slide body', $text);
73        $this->assertStringContainsString('--- Notes ---', $text);
74        $this->assertStringContainsString('These are the speaker notes.', $text);
75        // notes follow the slide they belong to
76        $this->assertLessThan(
77            strpos($text, 'These are the speaker notes.'),
78            strpos($text, 'Visible slide body'),
79        );
80    }
81
82    public function testNoSlidesThrows()
83    {
84        // a valid ZIP with neither presentation parts nor slide parts
85        $path = $this->tmp . '/empty.pptx';
86        FixtureBuilder::zip($path, ['[Content_Types].xml' => '<Types/>']);
87        $this->expectException(ExtractionException::class);
88        (new PptxExtractor())->extract($path);
89    }
90
91    /**
92     * @return array<string, array{0: string, 1: bool}>
93     */
94    public function provideSupports(): array
95    {
96        return [
97            'pptx' => ['foo.pptx', true],
98            'uppercase' => ['foo.PPTX', true],
99            'xlsx' => ['foo.xlsx', false],
100            'legacy ppt' => ['foo.ppt', false],
101        ];
102    }
103
104    /**
105     * @dataProvider provideSupports
106     */
107    public function testSupports(string $path, bool $expected)
108    {
109        $this->assertSame($expected, (new PptxExtractor())->supports($path));
110    }
111}
112