From f72eb8765848cd1ec05981abf7eee8b11fefb709 Mon Sep 17 00:00:00 2001 From: Alexander Stehlik Date: Mon, 3 Jul 2023 21:23:15 +0200 Subject: [PATCH] [TASK] Enhance functional test for videos Use symfony/crawler for parsing HTML. Add test for tracks. --- .../Controller/MediaController/VideoTest.php | 90 ++++++++++++++++--- Tests/Functional/Fixtures/Database/common.csv | 2 + .../Fixtures/Database/media/video.csv | 14 +-- composer.json | 1 + 4 files changed, 89 insertions(+), 18 deletions(-) diff --git a/Tests/Functional/Controller/MediaController/VideoTest.php b/Tests/Functional/Controller/MediaController/VideoTest.php index d5d39dc3..c3981acb 100644 --- a/Tests/Functional/Controller/MediaController/VideoTest.php +++ b/Tests/Functional/Controller/MediaController/VideoTest.php @@ -4,8 +4,27 @@ namespace Sto\Html5mediakit\Tests\Functional\Controller\MediaController; +use Symfony\Component\DomCrawler\Crawler; + class VideoTest extends AbstractMediaControllerTestCase { + private array $expectedTracks = [ + [ + 'src' => '/tracks/subtitles-en.vtt', + 'kind' => 'subtitles', + 'srclang' => 'en', + 'label' => 'English', + 'default' => true, + ], + [ + 'src' => '/tracks/subtitles-de.vtt', + 'kind' => 'subtitles', + 'srclang' => 'de', + 'label' => 'German', + 'default' => false, + ], + ]; + private array $formats = [ 'webm' => 'webm', 'mp4' => 'mp4', @@ -16,28 +35,75 @@ public function testMediaControllerShowsVideo(): void { $responseBody = $this->loadFixturesAndGetResponseBody('media/video'); - $this->assertResponseContainsSources($responseBody); - $this->assertResponseContainsFallbackLinks($responseBody); - self::assertStringContainsString('Testcaption', $responseBody); - self::assertStringContainsString('Testdescription', $responseBody); - self::assertStringContainsString('poster="/video/poster.png"', $responseBody); + $crawler = new Crawler($responseBody); + + $videoContent = $this->getSingleElement($crawler, 'div.tx-html5mediakit-media-container'); + + $videoElement = $this->getSingleElement($videoContent, 'video'); + + self::assertSame('/video/poster.png', $videoElement->attr('poster')); + + $this->assertVideoContainsSources($videoElement); + + $fallbackText = $this->getSingleElement($videoContent, '.tx-html5mediakit-video-fallbacktext'); + $this->assertFallbacktextContainsFallbackLinks($fallbackText); + + $this->assertValidMetaData($this->getSingleElement($videoContent, '.tx-html5mediakit-media-metadata')); + + $this->assertVideoContainsTracks($videoElement); } - private function assertResponseContainsFallbackLinks(string $responseBody): void + private function assertFallbacktextContainsFallbackLinks(Crawler $fallbackText): void { foreach ($this->formats as $extension) { /** @noinspection HtmlUnknownTarget */ - $expectedSource = sprintf('media.%1$s', $extension); - self::assertStringContainsString($expectedSource, $responseBody); + $fallbackLink = $fallbackText->filter(sprintf('a[href="/video/media.%s"]', $extension)); + self::assertCount(1, $fallbackLink); + self::assertSame('media.' . $extension, $fallbackLink->text()); } } - private function assertResponseContainsSources(string $responseBody): void + private function assertValidMetaData(Crawler $metaDataElement): void + { + self::assertStringContainsString( + 'Testcaption', + $this->getSingleElement($metaDataElement, '.tx-html5mediakit-media-caption')->text() + ); + + self::assertStringContainsString( + 'Testdescription', + $this->getSingleElement($metaDataElement, '.tx-html5mediakit-media-description')->text() + ); + } + + private function assertVideoContainsSources(Crawler $videoElement): void { foreach ($this->formats as $mimeType => $extension) { - /** @noinspection HtmlUnknownTarget */ - $expectedSource = sprintf('', $extension, $mimeType); - self::assertStringContainsString($expectedSource, $responseBody); + $source = $videoElement->filter(sprintf('source[type="video/%s"]', $mimeType)); + self::assertCount(1, $source); + self::assertSame('/video/media.' . $extension, $source->attr('src')); + } + } + + private function assertVideoContainsTracks(Crawler $videoElement): void + { + foreach ($this->expectedTracks as $expectedTrack) { + $track = $this->getSingleElement($videoElement, sprintf('track[src="%s"]', $expectedTrack['src'])); + self::assertSame($expectedTrack['kind'], $track->attr('kind')); + self::assertSame($expectedTrack['srclang'], $track->attr('srclang')); + self::assertSame($expectedTrack['label'], $track->attr('label')); + + $expectedDefault = $expectedTrack['default'] ? '' : null; + self::assertSame($expectedDefault, $track->attr('default')); } } + + private function getSingleElement(Crawler $crawler, string $selector): Crawler + { + $elements = $crawler->filter($selector); + + self::assertCount(1, $elements, 'Expected exactly one element matching selector "' . $selector . '"'); + + return $elements->first(); + } } diff --git a/Tests/Functional/Fixtures/Database/common.csv b/Tests/Functional/Fixtures/Database/common.csv index bd5e2bfa..93895e0b 100644 --- a/Tests/Functional/Fixtures/Database/common.csv +++ b/Tests/Functional/Fixtures/Database/common.csv @@ -6,3 +6,5 @@ sys_file,,,,,, ,4,0,0,video/media.ogv,media.ogv,4 ,5,0,0,video/media.webm,media.webm,4 ,6,0,0,video/poster.png,poster.png,2 +,7,0,0,tracks/subtitles-en.vtt,subtitles-en.vtt,1 +,8,0,0,tracks/subtitles-de.vtt,subtitles-de.vtt,1 diff --git a/Tests/Functional/Fixtures/Database/media/video.csv b/Tests/Functional/Fixtures/Database/media/video.csv index c5f37e7d..a25849b1 100644 --- a/Tests/Functional/Fixtures/Database/media/video.csv +++ b/Tests/Functional/Fixtures/Database/media/video.csv @@ -7,9 +7,11 @@ tt_content,,,,,,, tx_html5mediakit_domain_model_media,,,,,,,,,,, ,uid,pid,content_element,type,caption,description,h264,ogv,web_m,poster,deleted ,1,1,1,video,Testcaption,Testdescription,1,1,1,1,0 -sys_file_reference,,,,,,,, -,uid,pid,uid_local,uid_foreign,tablenames,fieldname,l10n_diffsource -,1,0,3,1,tx_html5mediakit_domain_model_media,h264, -,2,0,4,1,tx_html5mediakit_domain_model_media,ogv, -,3,0,5,1,tx_html5mediakit_domain_model_media,web_m, -,4,0,6,1,tx_html5mediakit_domain_model_media,poster, +sys_file_reference,,,,,,,,,, +,uid,pid,uid_local,uid_foreign,tablenames,fieldname,tx_html5mediakit_track_kind,tx_html5mediakit_track_label,tx_html5mediakit_track_srclang +,1,0,3,1,tx_html5mediakit_domain_model_media,h264,,, +,2,0,4,1,tx_html5mediakit_domain_model_media,ogv,,, +,3,0,5,1,tx_html5mediakit_domain_model_media,web_m,,, +,4,0,6,1,tx_html5mediakit_domain_model_media,poster,,, +,5,0,7,1,tx_html5mediakit_domain_model_media,tracks,subtitles,English,en +,6,0,8,1,tx_html5mediakit_domain_model_media,tracks,subtitles,German,de diff --git a/composer.json b/composer.json index 7c001402..dbb21128 100644 --- a/composer.json +++ b/composer.json @@ -16,6 +16,7 @@ "friendsofphp/php-cs-fixer": "^3.14", "michielroos/typo3scan": "^1.7", "squizlabs/php_codesniffer": "^3.7", + "symfony/dom-crawler": "^6.3", "typo3/cms-fluid-styled-content": "*" }, "replace": {