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