/* * Copyright 2017-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://aws.amazon.com/apache2.0/ * * or in the "license" file accompanying this file. This file is distributed * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing * permissions and limitations under the License. */ #include #include #include #include #include #include #include #include #include #include "PlaylistParser/MockContentFetcher.h" #include "PlaylistParser/IterativePlaylistParser.h" namespace alexaClientSDK { namespace playlistParser { namespace test { using namespace ::testing; using namespace avsCommon::avs; using namespace avsCommon::sdkInterfaces; using namespace avsCommon::utils; using namespace avsCommon::utils::playlistParser; /// A mock factory that creates mock content fetchers class MockContentFetcherFactory : public avsCommon::sdkInterfaces::HTTPContentFetcherInterfaceFactoryInterface { public: MOCK_METHOD1( create, std::unique_ptr(const std::string& url)); }; // namespace test class IterativePlaylistParserTest : public ::testing::Test { protected: /// Configure test instance. void SetUp(); /// Checks that a url is correctly parsed. void testPlaylist( const std::string& url, const std::vector& playlistUrls, const std::vector& durations); /// Checks that a url is correctly parsed but ignore durations. void testPlaylist(const std::string& url, const std::vector& playlistUrls); /// A mock factory to create mock content fetchers std::shared_ptr m_mockFactory; /// Instance of the @c IterativePlaylistParser. std::shared_ptr m_parser; }; void IterativePlaylistParserTest::SetUp() { m_mockFactory = std::make_shared(); EXPECT_CALL(*m_mockFactory, create(_)).WillRepeatedly(Invoke([](const std::string& url) { return avsCommon::utils::memory::make_unique(url); })); m_parser = IterativePlaylistParser::create(m_mockFactory); } void IterativePlaylistParserTest::testPlaylist( const std::string& url, const std::vector& playlistUrls, const std::vector& durations) { ASSERT_EQ(playlistUrls.size(), durations.size()); EXPECT_TRUE(m_parser->initializeParsing(url)); size_t i; for (i = 0; i < playlistUrls.size() - 1; ++i) { auto entry = m_parser->next(); EXPECT_EQ(entry.parseResult, PlaylistParseResult::STILL_ONGOING); EXPECT_EQ(entry.url, playlistUrls[i]); EXPECT_EQ(entry.duration, durations[i]); } auto entry = m_parser->next(); EXPECT_EQ(entry.parseResult, PlaylistParseResult::FINISHED); EXPECT_EQ(entry.url, playlistUrls[i]); EXPECT_EQ(entry.duration, durations[i]); } void IterativePlaylistParserTest::testPlaylist(const std::string& url, const std::vector& playlistUrls) { EXPECT_TRUE(m_parser->initializeParsing(url)); size_t i; for (i = 0; i < playlistUrls.size() - 1; ++i) { auto entry = m_parser->next(); EXPECT_EQ(entry.parseResult, PlaylistParseResult::STILL_ONGOING); EXPECT_EQ(entry.url, playlistUrls[i]); } auto entry = m_parser->next(); EXPECT_EQ(entry.parseResult, PlaylistParseResult::FINISHED); EXPECT_EQ(entry.url, playlistUrls[i]); } /** * Tests initialize failure due to an empty playlist url. */ TEST_F(IterativePlaylistParserTest, testInitializeFailed) { EXPECT_FALSE(m_parser->initializeParsing("")); } /** * Tests successful initialization with non-empty url. */ TEST_F(IterativePlaylistParserTest, testInitializeOk) { EXPECT_TRUE(m_parser->initializeParsing(TEST_M3U_PLAYLIST_URL)); } /** * Tests parsing of a simple M3U playlist. */ TEST_F(IterativePlaylistParserTest, testParsingPlaylist) { testPlaylist(TEST_M3U_PLAYLIST_URL, TEST_M3U_PLAYLIST_URLS, TEST_M3U_DURATIONS); } /** * Tests parsing of an extended M3U/HLS playlist. */ TEST_F(IterativePlaylistParserTest, testParsingHlsPlaylist) { testPlaylist(TEST_HLS_PLAYLIST_URL, TEST_HLS_PLAYLIST_URLS, TEST_HLS_DURATIONS); } /** * Tests parsing of a PLS playlist. */ TEST_F(IterativePlaylistParserTest, testParsingPlsPlaylist) { testPlaylist(TEST_PLS_PLAYLIST_URL, TEST_PLS_PLAYLIST_URLS); } /** * Tests parsing of a simple M3U playlist with relative urls. */ TEST_F(IterativePlaylistParserTest, testParsingRelativePlaylist) { testPlaylist(TEST_M3U_RELATIVE_PLAYLIST_URL, TEST_M3U_RELATIVE_PLAYLIST_URLS); } /** * Tests parsing of a recursive M3U/HLS playlist. */ TEST_F(IterativePlaylistParserTest, testParsingRecursiveHlsPlaylist) { testPlaylist(TEST_HLS_RECURSIVE_PLAYLIST_URL, TEST_HLS_RECURSIVE_PLAYLIST_URLS); } /** * Tests parsing of a live stream HLS playlist. */ TEST_F(IterativePlaylistParserTest, testParsingLiveStreamPlaylist) { testPlaylist(TEST_HLS_LIVE_STREAM_PLAYLIST_URL, TEST_HLS_LIVE_STREAM_PLAYLIST_URLS, TEST_HLS_LIVE_STREAM_DURATIONS); } /** * Test parsing a media url. We expect the media to be the unique url. */ TEST_F(IterativePlaylistParserTest, testParseMediaUrl) { EXPECT_TRUE(m_parser->initializeParsing(TEST_MEDIA_URL)); auto entry = m_parser->next(); EXPECT_EQ(entry.parseResult, PlaylistParseResult::FINISHED); EXPECT_EQ(entry.url, TEST_MEDIA_URL); } /** * Test parsing a invalid url. */ TEST_F(IterativePlaylistParserTest, testParseInvalidUrl) { const std::string invalidUrl = "http://invalid.url"; EXPECT_TRUE(m_parser->initializeParsing(invalidUrl)); auto entry = m_parser->next(); EXPECT_EQ(entry.parseResult, PlaylistParseResult::ERROR); } /** * Test calling @c next() after abort parsing. */ TEST_F(IterativePlaylistParserTest, testNextFailsAfterAbort) { EXPECT_TRUE(m_parser->initializeParsing(TEST_M3U_PLAYLIST_URL)); m_parser->abort(); auto entry = m_parser->next(); auto expectedDuration = PlaylistParserObserverInterface::INVALID_DURATION; EXPECT_EQ(entry.parseResult, PlaylistParseResult::ERROR); EXPECT_EQ(entry.url, ""); EXPECT_EQ(entry.duration, expectedDuration); } } // namespace test } // namespace playlistParser } // namespace alexaClientSDK