avs-device-sdk/CapabilityAgents/ExternalMediaPlayer/test/ExternalMediaPlayerTest.cpp

2153 lines
89 KiB
C++

/*
* Copyright 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.
*/
/// @file ExternalMediaPlayerTest.cpp
#include <chrono>
#include <future>
#include <map>
#include <memory>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <rapidjson/document.h>
#include <rapidjson/error/en.h>
#include <rapidjson/stringbuffer.h>
#include <rapidjson/writer.h>
#include <AVSCommon/AVS/Attachment/AttachmentManager.h>
#include <AVSCommon/SDKInterfaces/MockExceptionEncounteredSender.h>
#include <AVSCommon/SDKInterfaces/MockChannelVolumeInterface.h>
#include <AVSCommon/SDKInterfaces/MockContextManager.h>
#include <AVSCommon/SDKInterfaces/MockDirectiveHandlerResult.h>
#include <AVSCommon/SDKInterfaces/MockDirectiveSequencer.h>
#include <AVSCommon/SDKInterfaces/MockExceptionEncounteredSender.h>
#include <AVSCommon/SDKInterfaces/MockFocusManager.h>
#include <AVSCommon/SDKInterfaces/MockMessageSender.h>
#include <AVSCommon/SDKInterfaces/MockPlaybackRouter.h>
#include <AVSCommon/SDKInterfaces/MockRenderPlayerInfoCardsObserverInterface.h>
#include <AVSCommon/SDKInterfaces/MockSpeakerManager.h>
#include <AVSCommon/Utils/JSON/JSONUtils.h>
#include <AVSCommon/Utils/Logger/ConsoleLogger.h>
#include <AVSCommon/Utils/MediaPlayer/MockMediaPlayer.h>
#include <AVSCommon/Utils/Memory/Memory.h>
#include <AVSCommon/Utils/Metrics/MockMetricRecorder.h>
#include <MockCertifiedSender.h>
#include "ExternalMediaPlayer/ExternalMediaPlayer.h"
namespace alexaClientSDK {
namespace capabilityAgents {
namespace externalMediaPlayer {
namespace test {
using namespace avsCommon::utils;
using namespace avsCommon::utils::json::jsonUtils;
using namespace avsCommon;
using namespace avsCommon::avs;
using namespace avsCommon::avs::attachment;
using namespace avsCommon::sdkInterfaces;
using namespace avsCommon::sdkInterfaces::externalMediaPlayer;
using namespace avsCommon::sdkInterfaces::test;
using namespace avsCommon::utils::mediaPlayer;
using namespace avsCommon::utils::memory;
using namespace avsCommon::utils::mediaPlayer::test;
using namespace avsCommon::utils::metrics::test;
using namespace capabilityAgents::externalMediaPlayer;
using namespace ::testing;
using namespace rapidjson;
/// Provide State Token for testing.
static const unsigned int PROVIDE_STATE_TOKEN_TEST{1};
/// Plenty of time for a test to complete.
static std::chrono::milliseconds MY_WAIT_TIMEOUT(1000);
// The namespaces used in the context.
static const std::string EXTERNALMEDIAPLAYER_STATE_NAMESPACE = "ExternalMediaPlayer";
static const std::string PLAYBACKSTATEREPORTER_STATE_NAMESPACE = "Alexa.PlaybackStateReporter";
// The names used in the context.
static const std::string EXTERNALMEDIAPLAYER_NAME = "ExternalMediaPlayerState";
static const std::string PLAYBACKSTATEREPORTER_NAME = "playbackState";
static const std::string EXTERNALMEDIAPLAYER_NAMESPACE = "ExternalMediaPlayer";
static const std::string PLAYBACKCONTROLLER_NAMESPACE = "Alexa.PlaybackController";
static const std::string PLAYLISTCONTROLLER_NAMESPACE = "Alexa.PlaylistController";
static const std::string SEEKCONTROLLER_NAMESPACE = "Alexa.SeekController";
static const std::string FAVORITESCONTROLLER_NAMESPACE = "Alexa.FavoritesController";
// field values used in Adapter State response
static const std::string PLAYER_USER_NAME = "userName";
static const std::string PLAYER_ID = "testPlayerId";
static const std::string PLAYER_TRACK = "testTrack";
static const std::string PLAYER_STATE = "IDLE";
// The @c External media player play directive signature.
static const NamespaceAndName PLAY_DIRECTIVE{EXTERNALMEDIAPLAYER_NAMESPACE, "Play"};
static const NamespaceAndName LOGIN_DIRECTIVE{EXTERNALMEDIAPLAYER_NAMESPACE, "Login"};
static const NamespaceAndName LOGOUT_DIRECTIVE{EXTERNALMEDIAPLAYER_NAMESPACE, "Logout"};
static const NamespaceAndName AUTHORIZEDISCOVEREDPLAYERS_DIRECTIVE{EXTERNALMEDIAPLAYER_NAMESPACE,
"AuthorizeDiscoveredPlayers"};
// The @c Transport control directive signatures.
static const NamespaceAndName RESUME_DIRECTIVE{PLAYBACKCONTROLLER_NAMESPACE, "Play"};
static const NamespaceAndName PAUSE_DIRECTIVE{PLAYBACKCONTROLLER_NAMESPACE, "Pause"};
static const NamespaceAndName STOP_DIRECTIVE{PLAYBACKCONTROLLER_NAMESPACE, "Stop"};
static const NamespaceAndName NEXT_DIRECTIVE{PLAYBACKCONTROLLER_NAMESPACE, "Next"};
static const NamespaceAndName PREVIOUS_DIRECTIVE{PLAYBACKCONTROLLER_NAMESPACE, "Previous"};
static const NamespaceAndName STARTOVER_DIRECTIVE{PLAYBACKCONTROLLER_NAMESPACE, "StartOver"};
static const NamespaceAndName REWIND_DIRECTIVE{PLAYBACKCONTROLLER_NAMESPACE, "Rewind"};
static const NamespaceAndName FASTFORWARD_DIRECTIVE{PLAYBACKCONTROLLER_NAMESPACE, "FastForward"};
// The @c PlayList control directive signature.
static const NamespaceAndName ENABLEREPEATONE_DIRECTIVE{PLAYLISTCONTROLLER_NAMESPACE, "EnableRepeatOne"};
static const NamespaceAndName ENABLEREPEAT_DIRECTIVE{PLAYLISTCONTROLLER_NAMESPACE, "EnableRepeat"};
static const NamespaceAndName DISABLEREPEAT_DIRECTIVE{PLAYLISTCONTROLLER_NAMESPACE, "DisableRepeat"};
static const NamespaceAndName ENABLESHUFFLE_DIRECTIVE{PLAYLISTCONTROLLER_NAMESPACE, "EnableShuffle"};
static const NamespaceAndName DISABLESHUFFLE_DIRECTIVE{PLAYLISTCONTROLLER_NAMESPACE, "DisableShuffle"};
// The @c Seek control directive signature.
static const NamespaceAndName SEEK_DIRECTIVE{SEEKCONTROLLER_NAMESPACE, "SetSeekPosition"};
static const NamespaceAndName ADJUSTSEEK_DIRECTIVE{SEEKCONTROLLER_NAMESPACE, "AdjustSeekPosition"};
// The @c favorites control directive signature.
static const NamespaceAndName FAVORITE_DIRECTIVE{FAVORITESCONTROLLER_NAMESPACE, "Favorite"};
static const NamespaceAndName UNFAVORITE_DIRECTIVE{FAVORITESCONTROLLER_NAMESPACE, "Unfavorite"};
// The @c ExternalMediaPlayer context state signatures.
static const NamespaceAndName SESSION_STATE{EXTERNALMEDIAPLAYER_STATE_NAMESPACE, EXTERNALMEDIAPLAYER_NAME};
static const NamespaceAndName PLAYBACK_STATE{PLAYBACKSTATEREPORTER_STATE_NAMESPACE, PLAYBACKSTATEREPORTER_NAME};
// @c ExternalMediaPlayer events.
static const NamespaceAndName REPORT_DISCOVERED_PLAYERS{EXTERNALMEDIAPLAYER_NAMESPACE, "ReportDiscoveredPlayers"};
static const NamespaceAndName AUTHORIZATION_COMPLETE{EXTERNALMEDIAPLAYER_NAMESPACE, "AuthorizationComplete"};
// A playRequestor for testing
static const PlayRequestor testPlayRequestor{.type = "ALERT", .id = "123"};
// clang-format off
static const std::string IDLE_PLAYBACK_STATE =
R"({
"state":"IDLE",
"supportedOperations":[],
"shuffle":"NOT_SHUFFLED",
"repeat":"NOT_REPEATED",
"favorite":"NOT_RATED",
"positionMilliseconds":0,
"players":[{
"playerId":"",
"state":"IDLE",
"supportedOperations":[],
"positionMilliseconds":0,
"shuffle":"NOT_SHUFFLED",
"repeat":"NOT_REPEATED",
"favorite":"NOT_RATED",
"media":{
"type":"",
"value":{
"playbackSource":"",
"playbackSourceId":"",
"trackName":"",
"trackId":"",
"trackNumber":"",
"artist":"",
"artistId":"",
"album":"",
"albumId":"",
"coverUrls":{"tiny":"","small":"","medium":"","large":""},
"coverId":"",
"mediaProvider":"",
"mediaType":"TRACK",
"durationInMilliseconds":0
}
}
}]
})";
// clang-format on
/**
* Method to create an adapter state struct response to getState();
*
* @return an adpater state partially filled with test values
*/
static AdapterState createAdapterState() {
AdapterSessionState sessionState;
sessionState.loggedIn = false;
sessionState.userName = PLAYER_USER_NAME;
sessionState.playerId = PLAYER_ID;
AdapterPlaybackState playbackState;
playbackState.state = PLAYER_STATE;
playbackState.trackName = PLAYER_TRACK;
playbackState.playRequestor = testPlayRequestor;
AdapterState adapterState;
adapterState.sessionState = sessionState;
adapterState.playbackState = playbackState;
return adapterState;
}
/// Message Id for testing.
static const std::string MESSAGE_ID_TEST("MessageId_Test");
static const std::string MESSAGE_ID_TEST2("MessageId_Test2");
/// Dialog Request Id for testing.
static const std::string DIALOG_REQUEST_ID_TEST("DialogId_Test");
/// String to identify log entries originating from this file.
static const std::string TAG("ExternalMediaPlayerTest");
/// Music service provider id 1.
static const std::string MSP1_LOCAL_PLAYER_ID("MSP1_LOCAL_PLAYER_ID");
/// Cloud assigned playerId for this MSP.
static const std::string MSP1_PLAYER_ID("MSP1_PLAYERID");
/// Associated skillToken for this MSP.
static const std::string MSP1_SKILLTOKEN("MSP1_SKILLTOKEN");
/// Music service provider id 2.
static const std::string MSP2_LOCAL_PLAYER_ID("MSP2_LOCAL_PLAYER_ID");
/// Cloud assigned playerId for this MSP.
static const std::string MSP2_PLAYER_ID("MSP2_PLAYERID");
/// Associated skillToken for this MSP.
static const std::string MSP2_SKILLTOKEN("MSP2_SKILLTOKEN");
/**
* Create a LogEntry using this file's TAG and the specified event string.
*
* @param The event string for this @c LogEntry.
*/
#define LX(event) alexaClientSDK::avsCommon::utils::logger::LogEntry(TAG, event)
/// Mock class of ExternalMediaAdapterInterface.
class MockExternalMediaPlayerAdapter : public ExternalMediaAdapterInterface {
public:
/*
* Method that adheres to the AdapterCreateFunc interface to create an adapter. This method create a mock
* instances and assigns it to a class static to keep the mock class simple.
*
* @param metricRecorder The metricRecorder instance to be used to record metrics
* @param mediaPlayer The mediaPlayer instance to be used to play Spotify content.
* @param speakerManager A @c SpeakerManagerInterface to perform volume changes requested by ESDK.
* @param messageSender The object to use for sending events.
* @param focusManager The focusManager used to acquire/release channel.
* @param contextManager The AVS Context manager used to generate system context for events.
* @param externalMediaPlayer The instance of the @c ExternalMediaPlayer managing the adapter.
* @return A @c std::shared_ptr to the new @c ExternalMediaAdapter instance.
*/
static std::shared_ptr<avsCommon::sdkInterfaces::externalMediaPlayer::ExternalMediaAdapterInterface> getInstance(
std::shared_ptr<alexaClientSDK::avsCommon::utils::metrics::MetricRecorderInterface> metricRecorder,
std::shared_ptr<avsCommon::utils::mediaPlayer::MediaPlayerInterface> mediaPlayer,
std::shared_ptr<avsCommon::sdkInterfaces::ChannelVolumeInterface> speaker,
std::shared_ptr<avsCommon::sdkInterfaces::SpeakerManagerInterface> speakerManager,
std::shared_ptr<avsCommon::sdkInterfaces::MessageSenderInterface> messageSender,
std::shared_ptr<avsCommon::sdkInterfaces::FocusManagerInterface> focusManager,
std::shared_ptr<avsCommon::sdkInterfaces::ContextManagerInterface> contextManager,
std::shared_ptr<avsCommon::sdkInterfaces::ExternalMediaPlayerInterface> externalMediaPlayer);
static std::shared_ptr<MockExternalMediaPlayerAdapter> m_currentActiveMediaPlayerAdapter;
MOCK_METHOD0(doShutdown, void());
MOCK_METHOD0(init, void());
MOCK_METHOD0(deInit, void());
MOCK_METHOD4(
handleLogin,
void(
const std::string& accessToken,
const std::string& userName,
bool forceLogin,
std::chrono::milliseconds tokenRefreshInterval));
MOCK_METHOD0(handleLogout, void());
MOCK_METHOD8(
handlePlay,
void(
std::string& playContextToken,
int64_t index,
std::chrono::milliseconds offset,
const std::string& skillToken,
const std::string& playbackSessionId,
const std::string& navigation,
bool preload,
const avsCommon::avs::PlayRequestor& playRequestor));
MOCK_METHOD1(handlePlayControl, void(RequestType requestType));
MOCK_METHOD1(handleSeek, void(std::chrono::milliseconds offset));
MOCK_METHOD1(handleAdjustSeek, void(std::chrono::milliseconds deltaOffset));
MOCK_METHOD3(
handleAuthorized,
void(bool authorized, const std::string& playerId, const std::string& defaultSkillToken));
MOCK_METHOD1(handleSetVolume, void(int8_t volume));
MOCK_METHOD1(handleSetMute, void(bool));
MOCK_METHOD0(getState, AdapterState());
MOCK_METHOD0(getOffset, std::chrono::milliseconds());
private:
/// MockExternalMediaPlayerAdapter private constructor.
MockExternalMediaPlayerAdapter();
};
/// Static instance of MockMediaPlayerAdapter.
std::shared_ptr<MockExternalMediaPlayerAdapter> MockExternalMediaPlayerAdapter::m_currentActiveMediaPlayerAdapter;
MockExternalMediaPlayerAdapter::MockExternalMediaPlayerAdapter() :
RequiresShutdown("MockExternalMediaPlayerAdapter"),
ExternalMediaAdapterInterface("MockExternalMediaPlayerAdapter") {
}
std::shared_ptr<avsCommon::sdkInterfaces::externalMediaPlayer::ExternalMediaAdapterInterface>
MockExternalMediaPlayerAdapter::getInstance(
std::shared_ptr<alexaClientSDK::avsCommon::utils::metrics::MetricRecorderInterface> metricRecorder,
std::shared_ptr<avsCommon::utils::mediaPlayer::MediaPlayerInterface> mediaPlayer,
std::shared_ptr<avsCommon::sdkInterfaces::ChannelVolumeInterface> speaker,
std::shared_ptr<avsCommon::sdkInterfaces::SpeakerManagerInterface> speakerManager,
std::shared_ptr<avsCommon::sdkInterfaces::MessageSenderInterface> messageSender,
std::shared_ptr<avsCommon::sdkInterfaces::FocusManagerInterface> focusManager,
std::shared_ptr<avsCommon::sdkInterfaces::ContextManagerInterface> contextManager,
std::shared_ptr<avsCommon::sdkInterfaces::ExternalMediaPlayerInterface> externalMediaPlayer) {
MockExternalMediaPlayerAdapter::m_currentActiveMediaPlayerAdapter =
std::shared_ptr<MockExternalMediaPlayerAdapter>(new MockExternalMediaPlayerAdapter());
return MockExternalMediaPlayerAdapter::m_currentActiveMediaPlayerAdapter;
}
class MockExternalMediaPlayerObserver : public ExternalMediaPlayerObserverInterface {
public:
static std::shared_ptr<MockExternalMediaPlayerObserver> getInstance();
MOCK_METHOD2(
onLoginStateProvided,
void(const std::string&, const avsCommon::sdkInterfaces::externalMediaPlayer::ObservableSessionProperties));
MOCK_METHOD2(
onPlaybackStateProvided,
void(
const std::string&,
const avsCommon::sdkInterfaces::externalMediaPlayer::ObservablePlaybackStateProperties));
private:
/**
* Constructor
*/
MockExternalMediaPlayerObserver();
};
std::shared_ptr<MockExternalMediaPlayerObserver> MockExternalMediaPlayerObserver::getInstance() {
return std::shared_ptr<MockExternalMediaPlayerObserver>(new MockExternalMediaPlayerObserver());
}
MockExternalMediaPlayerObserver::MockExternalMediaPlayerObserver() {
}
/**
* Method to create AuthorizeDiscoveredPlayers payload.
*
* @param players A set of players JSON objects.
*
* @return A string representation of the payload.
*/
static std::string createAuthorizeDiscoveredPlayersPayload(
std::unordered_set<std::string> players = std::unordered_set<std::string>()) {
// clang-format off
std::string payload = R"(
{
"players" : [
)";
for (auto it = players.begin(); it != players.end(); it++) {
if (it != players.begin()) {
payload += ",";
}
payload += *it;
}
payload += R"(]})";
// clang-format on
return payload;
}
/**
* Create the players json object.
*
* @param localPlayerId The localPlayerId.
* @param authorized Whether the player is authorized.
* @param playerId The cloud assigned playerId.
* @param skillToken The skillToken.
*
* @return A string representation of the payload.
*/
static std::string createPlayerJson(
const std::string& localPlayerId,
bool authorized,
const std::string& playerId,
const std::string& skillToken) {
// clang-format off
return
R"({
"localPlayerId" : ")" + localPlayerId + R"(",
"authorized" : )" + (authorized ? "true" : "false") + R"(,
"metadata" : {
"playerId" : ")" + playerId + R"(",
"skillToken" : ")" + skillToken + R"("
}
})";
// clang-format on
}
/**
* Get idle session state json object
*
* @return A string representation of idle session state json object
*/
static std::string getIdleSessionStateJson(std::string agent) {
// clang-format off
std::string idle_session_state =
R"({
"agent":")" + std::string(agent) + R"(",
"spiVersion":")" + std::string(ExternalMediaPlayer::SPI_VERSION) + R"(",
"playerInFocus":"",
"players":[{
"playerId":"",
"endpointId":"",
"loggedIn":false,
"username":"",
"isGuest":false,
"launched":false,
"active":false,
"spiVersion":"",
"playerCookie":"",
"skillToken":"",
"playbackSessionId":""
}]
})";
// clang-format on
return idle_session_state;
}
/**
* Method to create payload with parse error.
*
* @param playContext Play context {Track/playlist/album/artist/station/podcast} identifier.
* @param index The index of the media item in the container, if the container is indexable.
* @param offsetInMilliseconds The offset position within media item, in milliseconds.
* @param playerId The business name of the player.
* @return A string representation of the payload.
*/
static std::string createPlayPayloadWithParseError(
const std::string& playContext,
int index,
int64_t offsetInMilliseconds,
const std::string& playerId,
const std::string& skillToken,
const std::string& playbackSessionId,
const std::string& navigation,
bool preload) {
// clang-format off
const std::string PLAY_PAYLOAD_TEST =
"{"
"\"playbackContextToken\":\"" + playContext + "\","
"\"offsetInMilliseconds\":" + std::to_string(offsetInMilliseconds) + "\","
"\"playerId\":\"" + playerId + "\","
"\"index\":\"" + std::to_string(index) + "\","
"\"skillToken\":\"" + skillToken + "\","
"\"playbackSessionId\":\"" + playbackSessionId + "\","
"\"navigation\":\"" + navigation + "\","
"\"preload\":" + (preload ? "true" : "false") + ""
"}";
// clang-format on
return PLAY_PAYLOAD_TEST;
}
/**
* Method to create payload with only playerId.
*
* @param playerId The business name of the player.
* @return A string representation of the payload.
*/
static std::string createPayloadWithPlayerId(const std::string& playerId) {
// clang-format off
const std::string PLAYERID_PAYLOAD_TEST =
"{"
"\"playerId\":\"" + playerId + "\""
"}";
// clang-format on
return PLAYERID_PAYLOAD_TEST;
}
/**
* Method to create a Play payload with playContext, index, offsetInMilliseconds, playerId.
*
* @param playContext Play context {Track/playlist/album/artist/station/podcast} identifier.
* @param index The index of the media item in the container, if the container is indexable.
* @param offsetInMilliseconds The offset position within media item, in milliseconds.
* @param playerId The business name of the player.
* @return A string representation of the payload.
*/
static std::string createPlayPayload(
const std::string& playContext,
int index,
int64_t offsetInMilliseconds,
const std::string& playerId,
const std::string& skillToken,
const std::string& playbackSessionId,
const std::string& navigation,
bool preload) {
// clang-format off
const std::string PLAY_PAYLOAD_TEST =
"{"
"\"playbackContextToken\":\"" + playContext + "\","
"\"offsetInMilliseconds\":\"" + std::to_string(offsetInMilliseconds) + "\","
"\"playerId\":\"" + playerId + "\","
"\"index\":\"" + std::to_string(index) + "\","
"\"skillToken\":\"" + skillToken + "\","
"\"playbackSessionId\":\"" + playbackSessionId + "\","
"\"navigation\":\"" + navigation + "\","
"\"preload\":" + (preload ? "true" : "false") + ""
"}";
// clang-format on
return PLAY_PAYLOAD_TEST;
}
/**
* Method to create a Play payload with playContext, index, offsetInMilliseconds, playerId, and playRequestor.
*
* @param playContext Play context {Track/playlist/album/artist/station/podcast} identifier.
* @param index The index of the media item in the container, if the container is indexable.
* @param offsetInMilliseconds The offset position within media item, in milliseconds.
* @param playerId The business name of the player.
* @param skillToken The token identifying the domain or skill associated with this player.
* @param playbackSessionId A UUID associated with the most recent @c Play directive.
* @param navigation Communicates desired visual display behavior for the app associated with playback.
* @param preload Indicates if @c Play directive is intended to preload the identified content only but not begin
* playback.
* @param playRequestor The playRequestor object of the @c play directive.
*
* @return A string representation of the payload.
*/
static std::string createPlayPayloadWithPlayRequestor(
const std::string& playContext,
int index,
int64_t offsetInMilliseconds,
const std::string& playerId,
const std::string& skillToken,
const std::string& playbackSessionId,
const std::string& navigation,
bool preload,
const PlayRequestor& playRequestor) {
// clang-format off
const std::string PLAY_PAYLOAD_TEST =
"{"
"\"playbackContextToken\":\"" + playContext + "\","
"\"offsetInMilliseconds\":\"" + std::to_string(offsetInMilliseconds) + "\","
"\"playerId\":\"" + playerId + "\","
"\"index\":\"" + std::to_string(index) + "\","
"\"skillToken\":\"" + skillToken + "\","
"\"playbackSessionId\":\"" + playbackSessionId + "\","
"\"navigation\":\"" + navigation + "\","
"\"preload\":" + (preload ? "true" : "false") + ","
"\"playRequestor\":{"
"\"type\":\"" + playRequestor.type + "\","
"\"id\":\"" + playRequestor.id + "\""
"}"
"}";
// clang-format on
return PLAY_PAYLOAD_TEST;
}
/**
* Method to create a Play payload with only index, offsetInMilliseconds, playerId.
*
* @param index The index of the media item in the container, if the container is indexable.
* @param offsetInMilliseconds The offset position within media item, in milliseconds.
* @param playerId The business name of the player.
* @return A string representation of the payload.
*/
static std::string createPlayPayloadNoContext(
int index,
int64_t offsetInMilliseconds,
const std::string& playerId,
const std::string& skillToken,
const std::string& playbackSessionId,
const std::string& navigation,
bool preload) {
// clang-format off
const std::string PLAY_PAYLOAD_TEST =
"{"
"\"offsetInMilliseconds\":\"" + std::to_string(offsetInMilliseconds) + "\","
"\"playerId\":\"" + playerId + "\","
"\"index\":\"" + std::to_string(index) + "\","
"\"skillToken\":\"" + skillToken + "\","
"\"playbackSessionId\":\"" + playbackSessionId + "\","
"\"navigation\":\"" + navigation + "\","
"\"preload\":" + (preload ? "true" : "false") + ""
"}";
// clang-format on
return PLAY_PAYLOAD_TEST;
}
/**
* Method to create a Play payload with only playContext, index, offsetInMilliseconds.
*
* @param playContext Play context {Track/playlist/album/artist/station/podcast} identifier.
* @param index The index of the media item in the container, if the container is indexable.
* @param offsetInMilliseconds The offset position within media item, in milliseconds.
* @return A string representation of the payload.
*/
static std::string createPlayPayloadNoPlayerId(
const std::string& playContext,
int index,
int64_t offsetInMilliseconds,
const std::string& skillToken,
const std::string& playbackSessionId,
const std::string& navigation,
bool preload) {
// clang-format off
const std::string PLAY_PAYLOAD_TEST =
"{"
"\"playbackContextToken\":\"" + playContext + "\","
"\"offsetInMilliseconds\":\"" + std::to_string(offsetInMilliseconds) + "\","
"\"index\":\"" + std::to_string(index) + "\","
"\"skillToken\":\"" + skillToken + "\","
"\"playbackSessionId\":\"" + playbackSessionId + "\","
"\"navigation\":\"" + navigation + "\","
"\"preload\":" + (preload ? "true" : "false") + ""
"}";
// clang-format on
return PLAY_PAYLOAD_TEST;
}
/**
* Method to create a Play payload with only playContext, offsetInMilliseconds and playerId.
*
* @param playContext Play context {Track/playlist/album/artist/station/podcast} identifier.
* @param offsetInMilliseconds The offset position within media item, in milliseconds.
* @param playerId The business name of the player.
* @return A string representation of the payload.
*/
static std::string createPlayPayloadNoIndex(
const std::string& playContext,
int64_t offsetInMilliseconds,
const std::string& playerId,
const std::string& skillToken,
const std::string& playbackSessionId,
const std::string& navigation,
bool preload) {
// clang-format off
const std::string PLAY_PAYLOAD_TEST =
"{"
"\"playbackContextToken\":\"" + playContext + "\","
"\"offsetInMilliseconds\":" + std::to_string(offsetInMilliseconds) + ","
"\"playerId\":\"" + playerId + "\","
"\"skillToken\":\"" + skillToken + "\","
"\"playbackSessionId\":\"" + playbackSessionId + "\","
"\"navigation\":\"" + navigation + "\","
"\"preload\":" + (preload ? "true" : "false") + ""
"}";
// clang-format on
return PLAY_PAYLOAD_TEST;
}
/**
* Method to create a Play payload with only playContext, index, playerId.
*
* @param playContext Play context {Track/playlist/album/artist/station/podcast} identifier.
* @param index The index of the media item in the container, if the container is indexable.
* @param playerId The business name of the player.
* @return A string representation of the payload.
*/
static std::string createPlayPayloadNoOffset(
const std::string& playContext,
int index,
const std::string& playerId,
const std::string& skillToken,
const std::string& playbackSessionId,
const std::string& navigation,
bool preload) {
// clang-format off
const std::string PLAY_PAYLOAD_TEST =
"{"
"\"playbackContextToken\":\"" + playContext + "\","
"\"playerId\":\"" + playerId + "\","
"\"index\":\"" + std::to_string(index) + "\","
"\"skillToken\":\"" + skillToken + "\","
"\"playbackSessionId\":\"" + playbackSessionId + "\","
"\"navigation\":\"" + navigation + "\","
"\"preload\":" + (preload ? "true" : "false") + ""
"}";
// clang-format on
return PLAY_PAYLOAD_TEST;
}
/**
* Method to create a Login payload with accessToken, userName, refresh interval, forceLogin, playerId.
*
* @param accessToken The access context of the user identifier.
* @param userName The userName of the user logging in.
* @param refreshInterval The duration in milliseconds for which the accessToken is valid.
* @param forceLogin bool which signifies if the adapter has to a force a login or merely cache the access token.
* @param playerId The business name of the player.
* @return A string representation of the payload.
*/
static std::string createLoginPayload(
const std::string& accessToken,
const std::string& userName,
int64_t refreshInterval,
bool forceLogin,
const std::string& playerId) {
// clang-format off
const std::string LOGIN_PAYLOAD_TEST =
"{"
"\"playerId\":\"" + playerId + "\","
"\"accessToken\":\"" + accessToken + "\","
"\"tokenRefreshIntervalInMilliseconds\":" + std::to_string(refreshInterval) + ","
"\"forceLogin\": true" + ","
"\"username\":\"" + userName + "\""
"}";
// clang-format on
return LOGIN_PAYLOAD_TEST;
}
/**
* Method to create a Seek payload.
*
* @param timeOffset The offset to seek to.
* @param playerId The business name of the player.
* @param adjustSeek @c true offset adjusts seek relative to current position
* @c false offset is interpreted as an absolute offset.
* @return A string representation of the payload.
*/
static std::string createSeekPayload(int64_t timeOffset, const std::string& playerId, bool adjustSeek) {
std::string SEEK_PAYLOAD_TEST;
// clang-format off
if (adjustSeek) {
SEEK_PAYLOAD_TEST = "{\"playerId\":\"" + playerId + "\",\"deltaPositionMilliseconds\":" +
std::to_string(timeOffset) + "}";
}
else {
SEEK_PAYLOAD_TEST = "{\"playerId\":\"" + playerId + "\",\"positionMilliseconds\":" +
std::to_string(timeOffset) + "}";
}
// clang-format on
return SEEK_PAYLOAD_TEST;
}
class ExternalMediaPlayerTest : public ::testing::Test {
public:
ExternalMediaPlayerTest();
void SetUp() override;
void TearDown() override;
/**
* Verify that the provided state matches the expected state
*
* @param jsonState The state to verify
* @param expectedState The expected state
*/
void verifyState(const std::string& providedState, const std::string& expectedState);
/**
* Helper method to authorize a set of players.
*
* @param payload The payload for an AuthorizeDiscoveredPlayers directive.
* @param resultHandler A result handler associated with the directive upon which expectations can be set.
*/
void sendAuthorizeDiscoveredPlayersDirective(
const std::string& payload,
std::unique_ptr<DirectiveHandlerResultInterface> resultHandler = nullptr);
/**
* This is invoked in response to a @c setState call.
*
* @return @c SUCCESS.
*/
SetStateResult wakeOnSetState();
/**
* This is is invoked to clear the promise set by a setState call for repeat testing
*
* @return @c SUCCESS.
*/
SetStateResult resetWakeOnSetState();
/// The map of adapters to @c MediaPlayerInterface.
ExternalMediaPlayer::AdapterMediaPlayerMap m_adapterMediaPlayerMap;
/// The map of adapters to @c SpeakerInterface.
ExternalMediaPlayer::AdapterSpeakerMap m_adapterSpeakerMap;
/// The map of adapter creation functions.
ExternalMediaPlayer::AdapterCreationMap m_adapterMap;
/// @c ExternalMediaPlayer to test
std::shared_ptr<ExternalMediaPlayer> m_externalMediaPlayer;
/// Player to send the audio to.
std::shared_ptr<MockMediaPlayer> m_mockMediaPlayer;
/// @c SpeakerInterface to manage volume changes of individual speakers.
std::shared_ptr<MockChannelVolumeInterface> m_mockSpeakerInterface;
/// @c SpeakerManager to manage volume changes across speakers.
std::shared_ptr<MockSpeakerManager> m_mockSpeakerManager;
/// @c MetricRecorder to send metrics
std::shared_ptr<MockMetricRecorder> m_metricRecorder;
/// @c ContextManager to provide state and update state.
std::shared_ptr<MockContextManager> m_mockContextManager;
/// @c FocusManager to request focus to the DIALOG channel.
std::shared_ptr<MockFocusManager> m_mockFocusManager;
/// A directive handler result to send the result to.
std::unique_ptr<MockDirectiveHandlerResult> m_mockDirectiveHandlerResult;
/// A message sender used to send events to AVS.
std::shared_ptr<MockMessageSender> m_mockMessageSender;
std::shared_ptr<certifiedSender::test::MockCertifiedSender> m_mockCertifiedSender;
/// An exception sender used to send exception encountered events to AVS.
std::shared_ptr<MockExceptionEncounteredSender> m_mockExceptionSender;
/// A playback router to notify when @c ExternalMediaPlayer becomes active.
std::shared_ptr<MockPlaybackRouter> m_mockPlaybackRouter;
/// Attachment manager used to create a reader.
std::shared_ptr<AttachmentManager> m_attachmentManager;
/// Promise to be fulfilled when @c setState is called.
std::promise<void> m_wakeSetStatePromise;
/// Future to notify when @c setState is called.
std::future<void> m_wakeSetStateFuture;
};
ExternalMediaPlayerTest::ExternalMediaPlayerTest() :
m_wakeSetStatePromise{},
m_wakeSetStateFuture{m_wakeSetStatePromise.get_future()} {
}
void ExternalMediaPlayerTest::SetUp() {
m_mockSpeakerInterface = std::make_shared<NiceMock<MockChannelVolumeInterface>>();
m_mockSpeakerManager = std::make_shared<NiceMock<MockSpeakerManager>>();
m_metricRecorder = std::make_shared<NiceMock<MockMetricRecorder>>();
m_mockMessageSender = std::make_shared<NiceMock<MockMessageSender>>();
m_mockFocusManager = std::make_shared<NiceMock<MockFocusManager>>();
m_mockContextManager = std::make_shared<NiceMock<MockContextManager>>();
m_mockExceptionSender = std::make_shared<NiceMock<MockExceptionEncounteredSender>>();
m_mockMediaPlayer = MockMediaPlayer::create();
m_mockPlaybackRouter = std::make_shared<NiceMock<MockPlaybackRouter>>();
m_attachmentManager = std::make_shared<AttachmentManager>(AttachmentManager::AttachmentType::IN_PROCESS);
m_mockCertifiedSender = std::make_shared<certifiedSender::test::MockCertifiedSender>();
m_adapterMediaPlayerMap.insert(std::make_pair(MSP1_LOCAL_PLAYER_ID, m_mockMediaPlayer));
m_adapterSpeakerMap.insert(std::make_pair(MSP1_LOCAL_PLAYER_ID, m_mockSpeakerInterface));
m_adapterMap.insert(std::make_pair(MSP1_LOCAL_PLAYER_ID, &MockExternalMediaPlayerAdapter::getInstance));
m_externalMediaPlayer = ExternalMediaPlayer::create(
m_adapterMediaPlayerMap,
m_adapterSpeakerMap,
m_adapterMap,
m_mockSpeakerManager,
m_mockMessageSender,
m_mockCertifiedSender->get(),
m_mockFocusManager,
m_mockContextManager,
m_mockExceptionSender,
m_mockPlaybackRouter,
m_metricRecorder);
m_mockDirectiveHandlerResult = std::unique_ptr<MockDirectiveHandlerResult>(new MockDirectiveHandlerResult);
ASSERT_TRUE(m_externalMediaPlayer);
// Authorize Players.
const std::string playersJson = createPlayerJson(MSP1_LOCAL_PLAYER_ID, true, MSP1_PLAYER_ID, MSP1_SKILLTOKEN);
sendAuthorizeDiscoveredPlayersDirective(createAuthorizeDiscoveredPlayersPayload({playersJson}));
}
void ExternalMediaPlayerTest::TearDown() {
EXPECT_CALL(*(MockExternalMediaPlayerAdapter::m_currentActiveMediaPlayerAdapter), doShutdown());
m_externalMediaPlayer->shutdown();
m_mockMediaPlayer->shutdown();
MockExternalMediaPlayerAdapter::m_currentActiveMediaPlayerAdapter.reset();
}
SetStateResult ExternalMediaPlayerTest::wakeOnSetState() {
m_wakeSetStatePromise.set_value();
return SetStateResult::SUCCESS;
}
SetStateResult ExternalMediaPlayerTest::resetWakeOnSetState() {
m_wakeSetStatePromise = std::promise<void>();
m_wakeSetStateFuture = m_wakeSetStatePromise.get_future();
return SetStateResult::SUCCESS;
}
void ExternalMediaPlayerTest::verifyState(const std::string& providedState, const std::string& expectedState) {
rapidjson::Document providedStateParsed;
providedStateParsed.Parse(providedState);
rapidjson::Document expectedStateParsed;
expectedStateParsed.Parse(expectedState);
EXPECT_EQ(providedStateParsed, expectedStateParsed);
}
/**
* Test create() with nullptrs
*/
TEST_F(ExternalMediaPlayerTest, test_createWithNullPointers) {
/// Have an empty map of adapters and mediaPlayers
ExternalMediaPlayer::AdapterCreationMap adapterMap;
ExternalMediaPlayer::AdapterMediaPlayerMap adapterMediaPlayerMap;
ExternalMediaPlayer::AdapterSpeakerMap adapterSpeakerMap;
auto testExternalMediaPlayer = ExternalMediaPlayer::create(
adapterMediaPlayerMap,
adapterSpeakerMap,
adapterMap,
nullptr,
m_mockMessageSender,
m_mockCertifiedSender->get(),
m_mockFocusManager,
m_mockContextManager,
m_mockExceptionSender,
m_mockPlaybackRouter,
m_metricRecorder);
EXPECT_EQ(testExternalMediaPlayer, nullptr);
testExternalMediaPlayer = ExternalMediaPlayer::create(
adapterMediaPlayerMap,
adapterSpeakerMap,
adapterMap,
m_mockSpeakerManager,
nullptr,
m_mockCertifiedSender->get(),
m_mockFocusManager,
m_mockContextManager,
m_mockExceptionSender,
m_mockPlaybackRouter,
m_metricRecorder);
EXPECT_EQ(testExternalMediaPlayer, nullptr);
testExternalMediaPlayer = ExternalMediaPlayer::create(
adapterMediaPlayerMap,
adapterSpeakerMap,
adapterMap,
m_mockSpeakerManager,
m_mockMessageSender,
m_mockCertifiedSender->get(),
nullptr,
m_mockContextManager,
m_mockExceptionSender,
m_mockPlaybackRouter,
m_metricRecorder);
EXPECT_EQ(testExternalMediaPlayer, nullptr);
testExternalMediaPlayer = ExternalMediaPlayer::create(
adapterMediaPlayerMap,
adapterSpeakerMap,
adapterMap,
m_mockSpeakerManager,
m_mockMessageSender,
m_mockCertifiedSender->get(),
m_mockFocusManager,
nullptr,
m_mockExceptionSender,
m_mockPlaybackRouter,
m_metricRecorder);
EXPECT_EQ(testExternalMediaPlayer, nullptr);
testExternalMediaPlayer = ExternalMediaPlayer::create(
adapterMediaPlayerMap,
adapterSpeakerMap,
adapterMap,
m_mockSpeakerManager,
m_mockMessageSender,
m_mockCertifiedSender->get(),
m_mockFocusManager,
m_mockContextManager,
nullptr,
m_mockPlaybackRouter,
m_metricRecorder);
EXPECT_EQ(testExternalMediaPlayer, nullptr);
testExternalMediaPlayer = ExternalMediaPlayer::create(
adapterMediaPlayerMap,
adapterSpeakerMap,
adapterMap,
m_mockSpeakerManager,
m_mockMessageSender,
m_mockCertifiedSender->get(),
m_mockFocusManager,
m_mockContextManager,
m_mockExceptionSender,
nullptr,
m_metricRecorder);
EXPECT_EQ(testExternalMediaPlayer, nullptr);
}
/**
* Method to test successful creation of ExternalMediaPlayer capability agent
* even if the creation of adapters fails.
*/
TEST_F(ExternalMediaPlayerTest, test_createWithAdapterCreationFailures) {
/// Have an empty map of adapters and mediaPlayers
ExternalMediaPlayer::AdapterCreationMap adapterMap;
ExternalMediaPlayer::AdapterMediaPlayerMap adapterMediaPlayerMap;
ExternalMediaPlayer::AdapterSpeakerMap adapterSpeakerMap;
auto testExternalMediaPlayer = ExternalMediaPlayer::create(
adapterMediaPlayerMap,
adapterSpeakerMap,
adapterMap,
m_mockSpeakerManager,
m_mockMessageSender,
m_mockCertifiedSender->get(),
m_mockFocusManager,
m_mockContextManager,
m_mockExceptionSender,
m_mockPlaybackRouter,
m_metricRecorder);
ASSERT_TRUE(testExternalMediaPlayer);
testExternalMediaPlayer->shutdown();
// Create an adapter MSP_PROVIDER2 but do not create a mediaPlayer for it.
adapterMap.clear();
adapterMediaPlayerMap.clear();
adapterMediaPlayerMap.insert(std::make_pair(MSP1_LOCAL_PLAYER_ID, m_mockMediaPlayer));
adapterMap.insert(std::make_pair(MSP2_LOCAL_PLAYER_ID, &MockExternalMediaPlayerAdapter::getInstance));
testExternalMediaPlayer = ExternalMediaPlayer::create(
adapterMediaPlayerMap,
adapterSpeakerMap,
adapterMap,
m_mockSpeakerManager,
m_mockMessageSender,
m_mockCertifiedSender->get(),
m_mockFocusManager,
m_mockContextManager,
m_mockExceptionSender,
m_mockPlaybackRouter,
m_metricRecorder);
ASSERT_TRUE(testExternalMediaPlayer);
testExternalMediaPlayer->shutdown();
}
/**
* Test getConfiguration on an ExternalMediaPlayer. The operation succeeds.
*/
TEST_F(ExternalMediaPlayerTest, test_getConfiguration) {
auto configuration = m_externalMediaPlayer->getConfiguration();
auto audioNonBlockingPolicy = BlockingPolicy(BlockingPolicy::MEDIUM_AUDIO, false);
auto neitherNonBlockingPolicy = BlockingPolicy(BlockingPolicy::MEDIUMS_NONE, false);
// TODO: ARC-227 Verify default values
ASSERT_EQ(configuration[PLAY_DIRECTIVE], audioNonBlockingPolicy);
ASSERT_EQ(configuration[AUTHORIZEDISCOVEREDPLAYERS_DIRECTIVE], audioNonBlockingPolicy);
ASSERT_EQ(configuration[LOGIN_DIRECTIVE], neitherNonBlockingPolicy);
ASSERT_EQ(configuration[LOGOUT_DIRECTIVE], neitherNonBlockingPolicy);
ASSERT_EQ(configuration[RESUME_DIRECTIVE], audioNonBlockingPolicy);
ASSERT_EQ(configuration[PAUSE_DIRECTIVE], audioNonBlockingPolicy);
ASSERT_EQ(configuration[STOP_DIRECTIVE], audioNonBlockingPolicy);
ASSERT_EQ(configuration[NEXT_DIRECTIVE], audioNonBlockingPolicy);
ASSERT_EQ(configuration[PREVIOUS_DIRECTIVE], audioNonBlockingPolicy);
ASSERT_EQ(configuration[STARTOVER_DIRECTIVE], audioNonBlockingPolicy);
ASSERT_EQ(configuration[REWIND_DIRECTIVE], audioNonBlockingPolicy);
ASSERT_EQ(configuration[FASTFORWARD_DIRECTIVE], audioNonBlockingPolicy);
ASSERT_EQ(configuration[ENABLEREPEATONE_DIRECTIVE], neitherNonBlockingPolicy);
ASSERT_EQ(configuration[ENABLEREPEAT_DIRECTIVE], neitherNonBlockingPolicy);
ASSERT_EQ(configuration[DISABLEREPEAT_DIRECTIVE], neitherNonBlockingPolicy);
ASSERT_EQ(configuration[ENABLESHUFFLE_DIRECTIVE], neitherNonBlockingPolicy);
ASSERT_EQ(configuration[DISABLESHUFFLE_DIRECTIVE], neitherNonBlockingPolicy);
ASSERT_EQ(configuration[SEEK_DIRECTIVE], audioNonBlockingPolicy);
ASSERT_EQ(configuration[ADJUSTSEEK_DIRECTIVE], audioNonBlockingPolicy);
ASSERT_EQ(configuration[FAVORITE_DIRECTIVE], neitherNonBlockingPolicy);
ASSERT_EQ(configuration[UNFAVORITE_DIRECTIVE], neitherNonBlockingPolicy);
}
void ExternalMediaPlayerTest::sendAuthorizeDiscoveredPlayersDirective(
const std::string& payload,
std::unique_ptr<DirectiveHandlerResultInterface> resultHandler) {
if (!resultHandler) {
resultHandler = std::unique_ptr<MockDirectiveHandlerResult>(new MockDirectiveHandlerResult);
}
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(
AUTHORIZEDISCOVEREDPLAYERS_DIRECTIVE.nameSpace, AUTHORIZEDISCOVEREDPLAYERS_DIRECTIVE.name, MESSAGE_ID_TEST2);
std::shared_ptr<AVSDirective> directive =
AVSDirective::create("", avsMessageHeader, payload, m_attachmentManager, "");
m_externalMediaPlayer->CapabilityAgent::preHandleDirective(directive, std::move(resultHandler));
m_externalMediaPlayer->CapabilityAgent::handleDirective(MESSAGE_ID_TEST2);
}
/**
* Test session state information on an ExternalMediaPlayer .
*/
TEST_F(ExternalMediaPlayerTest, test_callingProvideSessionState) {
EXPECT_CALL(
*(m_mockContextManager.get()), setState(SESSION_STATE, _, StateRefreshPolicy::ALWAYS, PROVIDE_STATE_TOKEN_TEST))
.Times(1)
.WillOnce(DoAll(
// need to include all four arguments, but only care about jsonState
Invoke([this](
const avs::NamespaceAndName& namespaceAndName,
const std::string& jsonState,
const avs::StateRefreshPolicy& refreshPolicy,
const unsigned int stateRequestToken) {
std::string agent = "";
verifyState(jsonState, getIdleSessionStateJson(agent));
}),
InvokeWithoutArgs(this, &ExternalMediaPlayerTest::wakeOnSetState)));
EXPECT_CALL(*(MockExternalMediaPlayerAdapter::m_currentActiveMediaPlayerAdapter), getState());
m_externalMediaPlayer->provideState(SESSION_STATE, PROVIDE_STATE_TOKEN_TEST);
ASSERT_TRUE(std::future_status::ready == m_wakeSetStateFuture.wait_for(MY_WAIT_TIMEOUT));
}
/**
* Test playback state information on an ExternalMediaPlayer.
*/
TEST_F(ExternalMediaPlayerTest, test_callingProvidePlaybackState) {
EXPECT_CALL(
*(m_mockContextManager.get()),
setState(PLAYBACK_STATE, _, StateRefreshPolicy::ALWAYS, PROVIDE_STATE_TOKEN_TEST))
.Times(1)
.WillOnce(DoAll(
// need to include all four arguments, but only care about jsonState
Invoke([this](
const avs::NamespaceAndName& namespaceAndName,
const std::string& jsonState,
const avs::StateRefreshPolicy& refreshPolicy,
const unsigned int stateRequestToken) { verifyState(jsonState, IDLE_PLAYBACK_STATE); }),
InvokeWithoutArgs(this, &ExternalMediaPlayerTest::wakeOnSetState)));
EXPECT_CALL(*(MockExternalMediaPlayerAdapter::m_currentActiveMediaPlayerAdapter), getState()).Times(AtLeast(1));
m_externalMediaPlayer->provideState(PLAYBACK_STATE, PROVIDE_STATE_TOKEN_TEST);
ASSERT_TRUE(std::future_status::ready == m_wakeSetStateFuture.wait_for(MY_WAIT_TIMEOUT));
}
/**
* Test payload with parse error in ExternalMediaPlayer. This should fail.
*/
TEST_F(ExternalMediaPlayerTest, test_playParserError) {
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(
PLAY_DIRECTIVE.nameSpace, PLAY_DIRECTIVE.name, MESSAGE_ID_TEST, DIALOG_REQUEST_ID_TEST);
std::shared_ptr<AVSDirective> directive = AVSDirective::create(
"",
avsMessageHeader,
createPlayPayloadWithParseError("XXX", 0, 0, "Adapter", "YYY", "ZZZ", "DEFAULT", false),
m_attachmentManager,
"");
EXPECT_CALL(*(m_mockExceptionSender.get()), sendExceptionEncountered(_, _, _));
EXPECT_CALL(*m_mockDirectiveHandlerResult, setFailed(_));
m_externalMediaPlayer->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
m_externalMediaPlayer->CapabilityAgent::handleDirective(MESSAGE_ID_TEST);
}
/**
* Test PLAY payload without an adapter in ExternalMediaPlayer. This should fail.
*/
TEST_F(ExternalMediaPlayerTest, test_playNoAdapter) {
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(
PLAY_DIRECTIVE.nameSpace, PLAY_DIRECTIVE.name, MESSAGE_ID_TEST, DIALOG_REQUEST_ID_TEST);
std::shared_ptr<AVSDirective> directive = AVSDirective::create(
"",
avsMessageHeader,
createPlayPayload("XXX", 0, 0, "Adapter", "YYY", "ZZZ", "DEFAULT", false),
m_attachmentManager,
"");
EXPECT_CALL(*(m_mockExceptionSender.get()), sendExceptionEncountered(_, _, _));
EXPECT_CALL(*m_mockDirectiveHandlerResult, setFailed(_));
m_externalMediaPlayer->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
m_externalMediaPlayer->CapabilityAgent::handleDirective(MESSAGE_ID_TEST);
}
/**
* Test PLAY payload without play context in ExternalMediaPlayer. This should fail.
*/
TEST_F(ExternalMediaPlayerTest, test_playNoPlayContext) {
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(
PLAY_DIRECTIVE.nameSpace, PLAY_DIRECTIVE.name, MESSAGE_ID_TEST, DIALOG_REQUEST_ID_TEST);
std::shared_ptr<AVSDirective> directive = AVSDirective::create(
"",
avsMessageHeader,
createPlayPayloadNoContext(0, 0, MSP1_PLAYER_ID, "YYY", "ZZZ", "DEFAULT", false),
m_attachmentManager,
"");
EXPECT_CALL(*(m_mockExceptionSender.get()), sendExceptionEncountered(_, _, _));
EXPECT_CALL(*m_mockDirectiveHandlerResult, setFailed(_));
m_externalMediaPlayer->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
m_externalMediaPlayer->CapabilityAgent::handleDirective(MESSAGE_ID_TEST);
}
/**
* Test PLAY payload without playerId in ExternalMediaPlayer. This should fail.
*/
TEST_F(ExternalMediaPlayerTest, test_playNoPlayerId) {
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(
PLAY_DIRECTIVE.nameSpace, PLAY_DIRECTIVE.name, MESSAGE_ID_TEST, DIALOG_REQUEST_ID_TEST);
std::shared_ptr<AVSDirective> directive = AVSDirective::create(
"",
avsMessageHeader,
createPlayPayloadNoPlayerId("XXX", 0, 0, "YYY", "ZZZ", "DEFAULT", false),
m_attachmentManager,
"");
EXPECT_CALL(*(m_mockExceptionSender.get()), sendExceptionEncountered(_, _, _));
EXPECT_CALL(*m_mockDirectiveHandlerResult, setFailed(_));
m_externalMediaPlayer->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
m_externalMediaPlayer->CapabilityAgent::handleDirective(MESSAGE_ID_TEST);
}
/**
* Test PLAY payload without offsetin ExternalMediaPlayer. This should succeed.
*/
TEST_F(ExternalMediaPlayerTest, test_playNoOffset) {
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(
PLAY_DIRECTIVE.nameSpace, PLAY_DIRECTIVE.name, MESSAGE_ID_TEST, DIALOG_REQUEST_ID_TEST);
std::shared_ptr<AVSDirective> directive = AVSDirective::create(
"",
avsMessageHeader,
createPlayPayloadNoOffset("XXX", 0, MSP1_PLAYER_ID, "YYY", "ZZZ", "DEFAULT", false),
m_attachmentManager,
"");
EXPECT_CALL(
*(MockExternalMediaPlayerAdapter::m_currentActiveMediaPlayerAdapter),
handlePlay(_, _, _, _, _, _, _, PlayRequestor{}));
EXPECT_CALL(*m_mockDirectiveHandlerResult, setCompleted());
m_externalMediaPlayer->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
m_externalMediaPlayer->CapabilityAgent::handleDirective(MESSAGE_ID_TEST);
}
/**
* Test PLAY payload with playRequestor in ExternalMediaPlayer. This should succeed.
*/
TEST_F(ExternalMediaPlayerTest, testPlaywithPlayRequestor) {
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(
PLAY_DIRECTIVE.nameSpace, PLAY_DIRECTIVE.name, MESSAGE_ID_TEST, DIALOG_REQUEST_ID_TEST);
std::shared_ptr<AVSDirective> directive = AVSDirective::create(
"",
avsMessageHeader,
createPlayPayloadWithPlayRequestor(
"XXX", 0, 0, MSP1_PLAYER_ID, "YYY", "ZZZ", "DEFAULT", false, testPlayRequestor),
m_attachmentManager,
"");
EXPECT_CALL(
*(MockExternalMediaPlayerAdapter::m_currentActiveMediaPlayerAdapter),
handlePlay(_, _, _, _, _, _, _, testPlayRequestor));
EXPECT_CALL(*m_mockDirectiveHandlerResult, setCompleted());
m_externalMediaPlayer->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
m_externalMediaPlayer->CapabilityAgent::handleDirective(MESSAGE_ID_TEST);
}
/**
* Test PLAY payload without index in ExternalMediaPlayer. This should succeed.
*/
TEST_F(ExternalMediaPlayerTest, test_playNoIndex) {
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(
PLAY_DIRECTIVE.nameSpace, PLAY_DIRECTIVE.name, MESSAGE_ID_TEST, DIALOG_REQUEST_ID_TEST);
std::shared_ptr<AVSDirective> directive = AVSDirective::create(
"",
avsMessageHeader,
createPlayPayloadNoIndex("XXX", 0, MSP1_PLAYER_ID, "YYY", "ZZZ", "DEFAULT", false),
m_attachmentManager,
"");
EXPECT_CALL(
*(MockExternalMediaPlayerAdapter::m_currentActiveMediaPlayerAdapter), handlePlay(_, _, _, _, _, _, _, _));
EXPECT_CALL(*m_mockDirectiveHandlerResult, setCompleted());
m_externalMediaPlayer->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
m_externalMediaPlayer->CapabilityAgent::handleDirective(MESSAGE_ID_TEST);
}
/**
* Test successful logout.
*/
TEST_F(ExternalMediaPlayerTest, test_logout) {
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(
LOGOUT_DIRECTIVE.nameSpace, LOGOUT_DIRECTIVE.name, MESSAGE_ID_TEST, DIALOG_REQUEST_ID_TEST);
std::shared_ptr<AVSDirective> directive =
AVSDirective::create("", avsMessageHeader, createPayloadWithPlayerId(MSP1_PLAYER_ID), m_attachmentManager, "");
EXPECT_CALL(*(MockExternalMediaPlayerAdapter::m_currentActiveMediaPlayerAdapter), handleLogout());
EXPECT_CALL(*m_mockDirectiveHandlerResult, setCompleted());
m_externalMediaPlayer->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
m_externalMediaPlayer->CapabilityAgent::handleDirective(MESSAGE_ID_TEST);
}
/**
* Test successful login.
*/
TEST_F(ExternalMediaPlayerTest, test_login) {
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(
LOGIN_DIRECTIVE.nameSpace, LOGIN_DIRECTIVE.name, MESSAGE_ID_TEST, DIALOG_REQUEST_ID_TEST);
std::shared_ptr<AVSDirective> directive = AVSDirective::create(
"",
avsMessageHeader,
createLoginPayload("XXX", "msploginuser", 1000, false, MSP1_PLAYER_ID),
m_attachmentManager,
"");
EXPECT_CALL(*(MockExternalMediaPlayerAdapter::m_currentActiveMediaPlayerAdapter), handleLogin(_, _, _, _));
EXPECT_CALL(*m_mockDirectiveHandlerResult, setCompleted());
m_externalMediaPlayer->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
m_externalMediaPlayer->CapabilityAgent::handleDirective(MESSAGE_ID_TEST);
}
/**
* Test observers of session state are correctly notified
*/
TEST_F(ExternalMediaPlayerTest, test_loginStateChangeObserverIsNotified) {
// add a mock observer
auto observer = MockExternalMediaPlayerObserver::getInstance();
m_externalMediaPlayer->addObserver(observer);
EXPECT_CALL(
*(m_mockContextManager.get()), setState(SESSION_STATE, _, StateRefreshPolicy::ALWAYS, PROVIDE_STATE_TOKEN_TEST))
.Times(1)
.WillOnce(InvokeWithoutArgs(this, &ExternalMediaPlayerTest::wakeOnSetState));
EXPECT_CALL(*(MockExternalMediaPlayerAdapter::m_currentActiveMediaPlayerAdapter), getState())
.WillRepeatedly(Return(createAdapterState()));
ObservableSessionProperties observableSessionProperties{false, PLAYER_USER_NAME};
EXPECT_CALL(*(observer), onLoginStateProvided(PLAYER_ID, observableSessionProperties)).Times(1);
m_externalMediaPlayer->provideState(SESSION_STATE, PROVIDE_STATE_TOKEN_TEST);
ASSERT_TRUE(std::future_status::ready == m_wakeSetStateFuture.wait_for(MY_WAIT_TIMEOUT));
}
/**
* Test observers of playback state are correctly notified
*/
TEST_F(ExternalMediaPlayerTest, test_playbackStateChangeObserverIsNotified) {
// add a mock observer
auto observer = MockExternalMediaPlayerObserver::getInstance();
m_externalMediaPlayer->addObserver(observer);
EXPECT_CALL(
*(m_mockContextManager.get()),
setState(PLAYBACK_STATE, _, StateRefreshPolicy::ALWAYS, PROVIDE_STATE_TOKEN_TEST))
.Times(1)
.WillRepeatedly(InvokeWithoutArgs(this, &ExternalMediaPlayerTest::wakeOnSetState));
EXPECT_CALL(*(MockExternalMediaPlayerAdapter::m_currentActiveMediaPlayerAdapter), getState())
.WillRepeatedly(Return(createAdapterState()));
ObservablePlaybackStateProperties observablePlaybackStateProperties{PLAYER_STATE, PLAYER_TRACK, testPlayRequestor};
EXPECT_CALL(*(observer), onPlaybackStateProvided(PLAYER_ID, observablePlaybackStateProperties)).Times(1);
m_externalMediaPlayer->provideState(PLAYBACK_STATE, PROVIDE_STATE_TOKEN_TEST);
ASSERT_TRUE(std::future_status::ready == m_wakeSetStateFuture.wait_for(MY_WAIT_TIMEOUT));
}
/**
* Test that after removal login observers are not called anymore
*/
TEST_F(ExternalMediaPlayerTest, test_loginStateChangeObserverRemoval) {
// add a mock observer
auto observer = MockExternalMediaPlayerObserver::getInstance();
m_externalMediaPlayer->addObserver(observer);
EXPECT_CALL(
*(m_mockContextManager.get()), setState(SESSION_STATE, _, StateRefreshPolicy::ALWAYS, PROVIDE_STATE_TOKEN_TEST))
.Times(2)
.WillRepeatedly(InvokeWithoutArgs(this, &ExternalMediaPlayerTest::wakeOnSetState));
EXPECT_CALL(*(MockExternalMediaPlayerAdapter::m_currentActiveMediaPlayerAdapter), getState())
.WillRepeatedly(Return(createAdapterState()));
EXPECT_CALL(*(observer), onLoginStateProvided(_, _)).Times(1);
m_externalMediaPlayer->provideState(SESSION_STATE, PROVIDE_STATE_TOKEN_TEST);
ASSERT_TRUE(std::future_status::ready == m_wakeSetStateFuture.wait_for(MY_WAIT_TIMEOUT));
this->resetWakeOnSetState();
m_externalMediaPlayer->removeObserver(observer);
EXPECT_CALL(*(observer), onLoginStateProvided(_, _)).Times(0);
m_externalMediaPlayer->provideState(SESSION_STATE, PROVIDE_STATE_TOKEN_TEST);
ASSERT_TRUE(std::future_status::ready == m_wakeSetStateFuture.wait_for(MY_WAIT_TIMEOUT));
}
/**
* Test that after removal playback state observers are not called anymore
*/
TEST_F(ExternalMediaPlayerTest, test_playbackStateChangeObserverRemoval) {
// add a mock observer
auto observer = MockExternalMediaPlayerObserver::getInstance();
m_externalMediaPlayer->addObserver(observer);
EXPECT_CALL(
*(m_mockContextManager.get()),
setState(PLAYBACK_STATE, _, StateRefreshPolicy::ALWAYS, PROVIDE_STATE_TOKEN_TEST))
.Times(2)
.WillRepeatedly(InvokeWithoutArgs(this, &ExternalMediaPlayerTest::wakeOnSetState));
EXPECT_CALL(*(MockExternalMediaPlayerAdapter::m_currentActiveMediaPlayerAdapter), getState())
.WillRepeatedly(Return(createAdapterState()));
EXPECT_CALL(*(observer), onPlaybackStateProvided(_, _)).Times(1);
m_externalMediaPlayer->provideState(PLAYBACK_STATE, PROVIDE_STATE_TOKEN_TEST);
ASSERT_TRUE(std::future_status::ready == m_wakeSetStateFuture.wait_for(MY_WAIT_TIMEOUT));
this->resetWakeOnSetState();
m_externalMediaPlayer->removeObserver(observer);
EXPECT_CALL(*(observer), onPlaybackStateProvided(_, _)).Times(0);
m_externalMediaPlayer->provideState(PLAYBACK_STATE, PROVIDE_STATE_TOKEN_TEST);
ASSERT_TRUE(std::future_status::ready == m_wakeSetStateFuture.wait_for(MY_WAIT_TIMEOUT));
}
/**
* Test successful resume.
*/
TEST_F(ExternalMediaPlayerTest, test_play) {
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(
RESUME_DIRECTIVE.nameSpace, RESUME_DIRECTIVE.name, MESSAGE_ID_TEST, DIALOG_REQUEST_ID_TEST);
std::shared_ptr<AVSDirective> directive =
AVSDirective::create("", avsMessageHeader, createPayloadWithPlayerId(MSP1_PLAYER_ID), m_attachmentManager, "");
EXPECT_CALL(*m_mockDirectiveHandlerResult, setCompleted());
EXPECT_CALL(*(MockExternalMediaPlayerAdapter::m_currentActiveMediaPlayerAdapter), handlePlayControl(_));
m_externalMediaPlayer->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
m_externalMediaPlayer->CapabilityAgent::handleDirective(MESSAGE_ID_TEST);
}
/**
* Test successful pause.
*/
TEST_F(ExternalMediaPlayerTest, test_pause) {
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(
PAUSE_DIRECTIVE.nameSpace, PAUSE_DIRECTIVE.name, MESSAGE_ID_TEST, DIALOG_REQUEST_ID_TEST);
std::shared_ptr<AVSDirective> directive =
AVSDirective::create("", avsMessageHeader, createPayloadWithPlayerId(MSP1_PLAYER_ID), m_attachmentManager, "");
EXPECT_CALL(*(MockExternalMediaPlayerAdapter::m_currentActiveMediaPlayerAdapter), handlePlayControl(_));
EXPECT_CALL(*m_mockDirectiveHandlerResult, setCompleted());
m_externalMediaPlayer->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
m_externalMediaPlayer->CapabilityAgent::handleDirective(MESSAGE_ID_TEST);
}
/**
* Test successful stop.
*/
TEST_F(ExternalMediaPlayerTest, testStop) {
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(
STOP_DIRECTIVE.nameSpace, STOP_DIRECTIVE.name, MESSAGE_ID_TEST, DIALOG_REQUEST_ID_TEST);
std::shared_ptr<AVSDirective> directive =
AVSDirective::create("", avsMessageHeader, createPayloadWithPlayerId(MSP1_PLAYER_ID), m_attachmentManager, "");
EXPECT_CALL(*(MockExternalMediaPlayerAdapter::m_currentActiveMediaPlayerAdapter), handlePlayControl(_));
EXPECT_CALL(*m_mockDirectiveHandlerResult, setCompleted());
m_externalMediaPlayer->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
m_externalMediaPlayer->CapabilityAgent::handleDirective(MESSAGE_ID_TEST);
}
/**
* Test successful stop.
*/
TEST_F(ExternalMediaPlayerTest, test_stop) {
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(
STOP_DIRECTIVE.nameSpace, STOP_DIRECTIVE.name, MESSAGE_ID_TEST, DIALOG_REQUEST_ID_TEST);
std::shared_ptr<AVSDirective> directive =
AVSDirective::create("", avsMessageHeader, createPayloadWithPlayerId(MSP1_PLAYER_ID), m_attachmentManager, "");
EXPECT_CALL(*(MockExternalMediaPlayerAdapter::m_currentActiveMediaPlayerAdapter), handlePlayControl(_));
EXPECT_CALL(*m_mockDirectiveHandlerResult, setCompleted());
m_externalMediaPlayer->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
m_externalMediaPlayer->CapabilityAgent::handleDirective(MESSAGE_ID_TEST);
}
/**
* Test successful next.
*/
TEST_F(ExternalMediaPlayerTest, test_next) {
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(
NEXT_DIRECTIVE.nameSpace, NEXT_DIRECTIVE.name, MESSAGE_ID_TEST, DIALOG_REQUEST_ID_TEST);
std::shared_ptr<AVSDirective> directive =
AVSDirective::create("", avsMessageHeader, createPayloadWithPlayerId(MSP1_PLAYER_ID), m_attachmentManager, "");
EXPECT_CALL(*(MockExternalMediaPlayerAdapter::m_currentActiveMediaPlayerAdapter), handlePlayControl(_));
EXPECT_CALL(*m_mockDirectiveHandlerResult, setCompleted());
m_externalMediaPlayer->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
m_externalMediaPlayer->CapabilityAgent::handleDirective(MESSAGE_ID_TEST);
}
/**
* Test successful previous.
*/
TEST_F(ExternalMediaPlayerTest, test_previous) {
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(
PREVIOUS_DIRECTIVE.nameSpace, PREVIOUS_DIRECTIVE.name, MESSAGE_ID_TEST, DIALOG_REQUEST_ID_TEST);
std::shared_ptr<AVSDirective> directive =
AVSDirective::create("", avsMessageHeader, createPayloadWithPlayerId(MSP1_PLAYER_ID), m_attachmentManager, "");
EXPECT_CALL(*(MockExternalMediaPlayerAdapter::m_currentActiveMediaPlayerAdapter), handlePlayControl(_));
EXPECT_CALL(*m_mockDirectiveHandlerResult, setCompleted());
m_externalMediaPlayer->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
m_externalMediaPlayer->CapabilityAgent::handleDirective(MESSAGE_ID_TEST);
}
/**
* Test successful StarOver.
*/
TEST_F(ExternalMediaPlayerTest, test_startOver) {
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(
STARTOVER_DIRECTIVE.nameSpace, STARTOVER_DIRECTIVE.name, MESSAGE_ID_TEST, DIALOG_REQUEST_ID_TEST);
std::shared_ptr<AVSDirective> directive =
AVSDirective::create("", avsMessageHeader, createPayloadWithPlayerId(MSP1_PLAYER_ID), m_attachmentManager, "");
EXPECT_CALL(*(MockExternalMediaPlayerAdapter::m_currentActiveMediaPlayerAdapter), handlePlayControl(_));
EXPECT_CALL(*m_mockDirectiveHandlerResult, setCompleted());
m_externalMediaPlayer->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
m_externalMediaPlayer->CapabilityAgent::handleDirective(MESSAGE_ID_TEST);
}
/**
* Test successful rewind.
*/
TEST_F(ExternalMediaPlayerTest, test_rewind) {
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(
REWIND_DIRECTIVE.nameSpace, REWIND_DIRECTIVE.name, MESSAGE_ID_TEST, DIALOG_REQUEST_ID_TEST);
std::shared_ptr<AVSDirective> directive =
AVSDirective::create("", avsMessageHeader, createPayloadWithPlayerId(MSP1_PLAYER_ID), m_attachmentManager, "");
EXPECT_CALL(*(MockExternalMediaPlayerAdapter::m_currentActiveMediaPlayerAdapter), handlePlayControl(_));
EXPECT_CALL(*m_mockDirectiveHandlerResult, setCompleted());
m_externalMediaPlayer->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
m_externalMediaPlayer->CapabilityAgent::handleDirective(MESSAGE_ID_TEST);
}
/**
* Test successful fast-forward.
*/
TEST_F(ExternalMediaPlayerTest, test_fastForward) {
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(
FASTFORWARD_DIRECTIVE.nameSpace, FASTFORWARD_DIRECTIVE.name, MESSAGE_ID_TEST, DIALOG_REQUEST_ID_TEST);
std::shared_ptr<AVSDirective> directive =
AVSDirective::create("", avsMessageHeader, createPayloadWithPlayerId(MSP1_PLAYER_ID), m_attachmentManager, "");
EXPECT_CALL(*(MockExternalMediaPlayerAdapter::m_currentActiveMediaPlayerAdapter), handlePlayControl(_));
EXPECT_CALL(*m_mockDirectiveHandlerResult, setCompleted());
m_externalMediaPlayer->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
m_externalMediaPlayer->CapabilityAgent::handleDirective(MESSAGE_ID_TEST);
}
/**
* Test successful EnableRepeatOne.
*/
TEST_F(ExternalMediaPlayerTest, test_enableRepeatOne) {
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(
ENABLEREPEATONE_DIRECTIVE.nameSpace, ENABLEREPEATONE_DIRECTIVE.name, MESSAGE_ID_TEST, DIALOG_REQUEST_ID_TEST);
std::shared_ptr<AVSDirective> directive =
AVSDirective::create("", avsMessageHeader, createPayloadWithPlayerId(MSP1_PLAYER_ID), m_attachmentManager, "");
EXPECT_CALL(*(MockExternalMediaPlayerAdapter::m_currentActiveMediaPlayerAdapter), handlePlayControl(_));
EXPECT_CALL(*m_mockDirectiveHandlerResult, setCompleted());
m_externalMediaPlayer->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
m_externalMediaPlayer->CapabilityAgent::handleDirective(MESSAGE_ID_TEST);
}
/**
* Test successful EnableRepeat.
*/
TEST_F(ExternalMediaPlayerTest, test_enableRepeat) {
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(
ENABLEREPEAT_DIRECTIVE.nameSpace, ENABLEREPEAT_DIRECTIVE.name, MESSAGE_ID_TEST, DIALOG_REQUEST_ID_TEST);
std::shared_ptr<AVSDirective> directive =
AVSDirective::create("", avsMessageHeader, createPayloadWithPlayerId(MSP1_PLAYER_ID), m_attachmentManager, "");
EXPECT_CALL(*(MockExternalMediaPlayerAdapter::m_currentActiveMediaPlayerAdapter), handlePlayControl(_));
EXPECT_CALL(*m_mockDirectiveHandlerResult, setCompleted());
m_externalMediaPlayer->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
m_externalMediaPlayer->CapabilityAgent::handleDirective(MESSAGE_ID_TEST);
}
/**
* Test successful DisableRepeat.
*/
TEST_F(ExternalMediaPlayerTest, test_disableRepeat) {
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(
DISABLEREPEAT_DIRECTIVE.nameSpace, DISABLEREPEAT_DIRECTIVE.name, MESSAGE_ID_TEST, DIALOG_REQUEST_ID_TEST);
std::shared_ptr<AVSDirective> directive =
AVSDirective::create("", avsMessageHeader, createPayloadWithPlayerId(MSP1_PLAYER_ID), m_attachmentManager, "");
EXPECT_CALL(*(MockExternalMediaPlayerAdapter::m_currentActiveMediaPlayerAdapter), handlePlayControl(_));
EXPECT_CALL(*m_mockDirectiveHandlerResult, setCompleted());
m_externalMediaPlayer->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
m_externalMediaPlayer->CapabilityAgent::handleDirective(MESSAGE_ID_TEST);
}
/**
* Test successful EnableShuffle.
*/
TEST_F(ExternalMediaPlayerTest, test_enableShuffle) {
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(
ENABLESHUFFLE_DIRECTIVE.nameSpace, ENABLESHUFFLE_DIRECTIVE.name, MESSAGE_ID_TEST, DIALOG_REQUEST_ID_TEST);
std::shared_ptr<AVSDirective> directive =
AVSDirective::create("", avsMessageHeader, createPayloadWithPlayerId(MSP1_PLAYER_ID), m_attachmentManager, "");
EXPECT_CALL(*(MockExternalMediaPlayerAdapter::m_currentActiveMediaPlayerAdapter), handlePlayControl(_));
EXPECT_CALL(*m_mockDirectiveHandlerResult, setCompleted());
m_externalMediaPlayer->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
m_externalMediaPlayer->CapabilityAgent::handleDirective(MESSAGE_ID_TEST);
}
/**
* Test successful DisableRepeat.
*/
TEST_F(ExternalMediaPlayerTest, test_disableShuffle) {
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(
DISABLESHUFFLE_DIRECTIVE.nameSpace, DISABLESHUFFLE_DIRECTIVE.name, MESSAGE_ID_TEST, DIALOG_REQUEST_ID_TEST);
std::shared_ptr<AVSDirective> directive =
AVSDirective::create("", avsMessageHeader, createPayloadWithPlayerId(MSP1_PLAYER_ID), m_attachmentManager, "");
EXPECT_CALL(*(MockExternalMediaPlayerAdapter::m_currentActiveMediaPlayerAdapter), handlePlayControl(_));
EXPECT_CALL(*m_mockDirectiveHandlerResult, setCompleted());
m_externalMediaPlayer->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
m_externalMediaPlayer->CapabilityAgent::handleDirective(MESSAGE_ID_TEST);
}
/**
* Test successful Favorite.
*/
TEST_F(ExternalMediaPlayerTest, test_favorite) {
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(
FAVORITE_DIRECTIVE.nameSpace, FAVORITE_DIRECTIVE.name, MESSAGE_ID_TEST, DIALOG_REQUEST_ID_TEST);
std::shared_ptr<AVSDirective> directive =
AVSDirective::create("", avsMessageHeader, createPayloadWithPlayerId(MSP1_PLAYER_ID), m_attachmentManager, "");
EXPECT_CALL(*(MockExternalMediaPlayerAdapter::m_currentActiveMediaPlayerAdapter), handlePlayControl(_));
EXPECT_CALL(*m_mockDirectiveHandlerResult, setCompleted());
m_externalMediaPlayer->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
m_externalMediaPlayer->CapabilityAgent::handleDirective(MESSAGE_ID_TEST);
}
/**
* Test successful UnFavorite.
*/
TEST_F(ExternalMediaPlayerTest, test_unfavorite) {
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(
UNFAVORITE_DIRECTIVE.nameSpace, UNFAVORITE_DIRECTIVE.name, MESSAGE_ID_TEST, DIALOG_REQUEST_ID_TEST);
std::shared_ptr<AVSDirective> directive =
AVSDirective::create("", avsMessageHeader, createPayloadWithPlayerId(MSP1_PLAYER_ID), m_attachmentManager, "");
EXPECT_CALL(*(MockExternalMediaPlayerAdapter::m_currentActiveMediaPlayerAdapter), handlePlayControl(_));
EXPECT_CALL(*m_mockDirectiveHandlerResult, setCompleted());
m_externalMediaPlayer->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
m_externalMediaPlayer->CapabilityAgent::handleDirective(MESSAGE_ID_TEST);
}
/**
* Test incorrect directive.
*/
TEST_F(ExternalMediaPlayerTest, test_incorrectDirective) {
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(
FAVORITE_DIRECTIVE.nameSpace, PREVIOUS_DIRECTIVE.name, MESSAGE_ID_TEST, DIALOG_REQUEST_ID_TEST);
std::shared_ptr<AVSDirective> directive =
AVSDirective::create("", avsMessageHeader, createPayloadWithPlayerId(MSP1_PLAYER_ID), m_attachmentManager, "");
EXPECT_CALL(*(m_mockExceptionSender.get()), sendExceptionEncountered(_, _, _));
EXPECT_CALL(*m_mockDirectiveHandlerResult, setFailed(_));
m_externalMediaPlayer->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
m_externalMediaPlayer->CapabilityAgent::handleDirective(MESSAGE_ID_TEST);
}
/**
* Test Seek failure passing incorrect field in payload.
*/
TEST_F(ExternalMediaPlayerTest, test_seekFailure) {
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(
SEEK_DIRECTIVE.nameSpace, SEEK_DIRECTIVE.name, MESSAGE_ID_TEST, DIALOG_REQUEST_ID_TEST);
std::shared_ptr<AVSDirective> directive = AVSDirective::create(
"", avsMessageHeader, createSeekPayload(100, MSP1_PLAYER_ID, true), m_attachmentManager, "");
EXPECT_CALL(*(m_mockExceptionSender.get()), sendExceptionEncountered(_, _, _));
EXPECT_CALL(*m_mockDirectiveHandlerResult, setFailed(_));
m_externalMediaPlayer->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
m_externalMediaPlayer->CapabilityAgent::handleDirective(MESSAGE_ID_TEST);
}
/**
* Test successful Seek.
*/
TEST_F(ExternalMediaPlayerTest, test_seekSuccess) {
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(
SEEK_DIRECTIVE.nameSpace, SEEK_DIRECTIVE.name, MESSAGE_ID_TEST, DIALOG_REQUEST_ID_TEST);
std::shared_ptr<AVSDirective> directive = AVSDirective::create(
"", avsMessageHeader, createSeekPayload(100, MSP1_PLAYER_ID, false), m_attachmentManager, "");
EXPECT_CALL(*(MockExternalMediaPlayerAdapter::m_currentActiveMediaPlayerAdapter), handleSeek(_));
EXPECT_CALL(*m_mockDirectiveHandlerResult, setCompleted());
m_externalMediaPlayer->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
m_externalMediaPlayer->CapabilityAgent::handleDirective(MESSAGE_ID_TEST);
}
/**
* Test AdjustSeek failure incorrect field in payload.
*/
TEST_F(ExternalMediaPlayerTest, test_adjustSeekFailure) {
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(
ADJUSTSEEK_DIRECTIVE.nameSpace, ADJUSTSEEK_DIRECTIVE.name, MESSAGE_ID_TEST, DIALOG_REQUEST_ID_TEST);
std::shared_ptr<AVSDirective> directive = AVSDirective::create(
"", avsMessageHeader, createSeekPayload(100, MSP1_PLAYER_ID, false), m_attachmentManager, "");
EXPECT_CALL(*(m_mockExceptionSender.get()), sendExceptionEncountered(_, _, _));
EXPECT_CALL(*m_mockDirectiveHandlerResult, setFailed(_));
m_externalMediaPlayer->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
m_externalMediaPlayer->CapabilityAgent::handleDirective(MESSAGE_ID_TEST);
}
/**
* Test AdjustSeek failure passing in an incorrect offset.
*/
TEST_F(ExternalMediaPlayerTest, test_adjustSeekFailure2) {
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(
ADJUSTSEEK_DIRECTIVE.nameSpace, ADJUSTSEEK_DIRECTIVE.name, MESSAGE_ID_TEST, DIALOG_REQUEST_ID_TEST);
std::shared_ptr<AVSDirective> directive = AVSDirective::create(
"", avsMessageHeader, createSeekPayload(86400014, MSP1_PLAYER_ID, true), m_attachmentManager, "");
EXPECT_CALL(*(m_mockExceptionSender.get()), sendExceptionEncountered(_, _, _));
EXPECT_CALL(*m_mockDirectiveHandlerResult, setFailed(_));
m_externalMediaPlayer->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
m_externalMediaPlayer->CapabilityAgent::handleDirective(MESSAGE_ID_TEST);
}
/**
* Test AdjustSeek successful passing in correct payload and offset.
*/
TEST_F(ExternalMediaPlayerTest, test_adjustSeekSuccess) {
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(
ADJUSTSEEK_DIRECTIVE.nameSpace, ADJUSTSEEK_DIRECTIVE.name, MESSAGE_ID_TEST, DIALOG_REQUEST_ID_TEST);
std::shared_ptr<AVSDirective> directive = AVSDirective::create(
"", avsMessageHeader, createSeekPayload(86400000, MSP1_PLAYER_ID, true), m_attachmentManager, "");
EXPECT_CALL(*(MockExternalMediaPlayerAdapter::m_currentActiveMediaPlayerAdapter), handleAdjustSeek(_));
EXPECT_CALL(*m_mockDirectiveHandlerResult, setCompleted());
m_externalMediaPlayer->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
m_externalMediaPlayer->CapabilityAgent::handleDirective(MESSAGE_ID_TEST);
}
/**
* Custom matcher to check an event of a certain name is sent.
* Returns true if the event with that name is sent.
* */
MATCHER_P2(
EventNamed,
/* std::string */ expectedNameSpace,
/* std::string */ expectedName,
"") {
// Throw obvious compile error if not a MessageRequest.
std::shared_ptr<MessageRequest> request = arg;
if (!request) {
return false;
}
rapidjson::Document document;
ParseResult result = document.Parse(request->getJsonContent());
if (!result) {
return false;
}
rapidjson::Value::ConstMemberIterator eventIt;
rapidjson::Value::ConstMemberIterator headerIt;
if (!json::jsonUtils::findNode(document, "event", &eventIt) ||
!json::jsonUtils::findNode(eventIt->value, "header", &headerIt)) {
return false;
}
std::string name;
std::string nameSpace;
if (!json::jsonUtils::retrieveValue(headerIt->value, "name", &name) ||
!json::jsonUtils::retrieveValue(headerIt->value, "namespace", &nameSpace) || nameSpace != expectedNameSpace ||
name != expectedName) {
return false;
}
return true;
}
/**
* Checks that the AuthorizationComplete event contains the expected authorized and deauthorized fields.
*
* @param request The AuthorizationComplete event sent.
* @param expectedAuthorized The expected list of @c playerId to @c skillToken pairs to verify against.
* @param expectedDeauthorized The expected list of @c deauthorized localPlayerId the verify against.
*/
static void veryifyAuthorizationCompletePayload(
std::shared_ptr<MessageRequest> request,
std::unordered_map<std::string, std::string> expectedAuthorized,
std::unordered_set<std::string> expectedDeauthorized = std::unordered_set<std::string>()) {
rapidjson::Document document;
ParseResult result = document.Parse(request->getJsonContent());
if (!result) {
FAIL();
}
rapidjson::Value::ConstMemberIterator eventIt;
rapidjson::Value::ConstMemberIterator payloadIt;
rapidjson::Value::ConstMemberIterator authorizedIt;
rapidjson::Value::ConstMemberIterator deauthorizedIt;
if (!findNode(document, "event", &eventIt) || !findNode(eventIt->value, "payload", &payloadIt) ||
!findNode(payloadIt->value, "authorized", &authorizedIt) ||
!findNode(payloadIt->value, "deauthorized", &deauthorizedIt)) {
FAIL();
}
std::unordered_map<std::string, std::string> authorized;
std::unordered_set<std::string> deauthorized;
for (rapidjson::Value::ConstValueIterator it = authorizedIt->value.Begin(); it != authorizedIt->value.End(); it++) {
std::string playerId;
std::string skillToken;
if (!retrieveValue(*it, "playerId", &playerId) || !retrieveValue(*it, "skillToken", &skillToken)) {
FAIL();
}
authorized[playerId] = skillToken;
}
for (rapidjson::Value::ConstValueIterator it = deauthorizedIt->value.Begin(); it != deauthorizedIt->value.End();
it++) {
std::string localPlayerId;
if (!retrieveValue(*it, "localPlayerId", &localPlayerId)) {
FAIL();
}
deauthorized.insert(localPlayerId);
}
ASSERT_THAT(authorized, ContainerEq(expectedAuthorized));
ASSERT_THAT(deauthorized, ContainerEq(expectedDeauthorized));
}
/**
* Test that ReportDiscoveredPlayers is sent.
*/
TEST_F(ExternalMediaPlayerTest, testReportDiscoveredPlayers) {
std::promise<void> eventPromise;
std::future<void> eventFuture = eventPromise.get_future();
// Initialize the CertifiedSender
auto mockCertifiedSender = std::make_shared<certifiedSender::test::MockCertifiedSender>();
std::shared_ptr<avsCommon::sdkInterfaces::ConnectionStatusObserverInterface> connectionObserver =
std::static_pointer_cast<avsCommon::sdkInterfaces::ConnectionStatusObserverInterface>(
mockCertifiedSender->get());
connectionObserver->onConnectionStatusChanged(
ConnectionStatusObserverInterface::Status::CONNECTED,
ConnectionStatusObserverInterface::ChangedReason::SUCCESS);
// Set expectation on m_mockCertifiedSender's @c MessageSenderInterface
// because @c MockCertifiedSender isn't a gmock mock.
EXPECT_CALL(
*(mockCertifiedSender->getMockMessageSender()),
sendMessage(EventNamed(REPORT_DISCOVERED_PLAYERS.nameSpace, REPORT_DISCOVERED_PLAYERS.name)))
.Times(1)
.WillOnce(InvokeWithoutArgs([&eventPromise]() { eventPromise.set_value(); }));
auto messageSender = std::make_shared<NiceMock<MockMessageSender>>();
m_externalMediaPlayer = ExternalMediaPlayer::create(
m_adapterMediaPlayerMap,
m_adapterSpeakerMap,
m_adapterMap,
m_mockSpeakerManager,
m_mockMessageSender,
mockCertifiedSender->get(),
m_mockFocusManager,
m_mockContextManager,
m_mockExceptionSender,
m_mockPlaybackRouter,
m_metricRecorder);
ASSERT_TRUE(std::future_status::ready == eventFuture.wait_for(MY_WAIT_TIMEOUT));
}
/**
* Test successful AuthorizeDiscoveredPlayers directive processing.
*/
TEST_F(ExternalMediaPlayerTest, testTimer_AuthorizeDiscoveredPlayersSuccess) {
std::promise<void> authorizationCompletePromise;
std::future<void> authorizationCompleteFuture = authorizationCompletePromise.get_future();
ON_CALL(*m_mockContextManager, getContext(_, _, _)).WillByDefault(InvokeWithoutArgs([this]() {
m_externalMediaPlayer->onContextAvailable("");
return 0;
}));
// Use another instance to avoid SetUp() interferring with the test.
auto messageSender = std::make_shared<NiceMock<MockMessageSender>>();
m_externalMediaPlayer = ExternalMediaPlayer::create(
m_adapterMediaPlayerMap,
m_adapterSpeakerMap,
m_adapterMap,
m_mockSpeakerManager,
messageSender,
m_mockCertifiedSender->get(),
m_mockFocusManager,
m_mockContextManager,
m_mockExceptionSender,
m_mockPlaybackRouter,
m_metricRecorder);
EXPECT_CALL(*m_mockDirectiveHandlerResult, setCompleted());
EXPECT_CALL(*messageSender, sendMessage(EventNamed(AUTHORIZATION_COMPLETE.nameSpace, AUTHORIZATION_COMPLETE.name)))
.Times(1)
.WillOnce(Invoke([&authorizationCompletePromise](std::shared_ptr<MessageRequest> request) {
veryifyAuthorizationCompletePayload(request, {{MSP1_PLAYER_ID, MSP1_SKILLTOKEN}});
authorizationCompletePromise.set_value();
}));
EXPECT_CALL(
*(MockExternalMediaPlayerAdapter::m_currentActiveMediaPlayerAdapter),
handleAuthorized(true, MSP1_PLAYER_ID, MSP1_SKILLTOKEN));
const std::string playersJson = createPlayerJson(MSP1_LOCAL_PLAYER_ID, true, MSP1_PLAYER_ID, MSP1_SKILLTOKEN);
sendAuthorizeDiscoveredPlayersDirective(
createAuthorizeDiscoveredPlayersPayload({playersJson}), std::move(m_mockDirectiveHandlerResult));
ASSERT_TRUE(std::future_status::ready == authorizationCompleteFuture.wait_for(MY_WAIT_TIMEOUT));
}
/**
* Test successful AuthorizeDiscoveredPlayers directive processing of multiple directives.
*/
TEST_F(ExternalMediaPlayerTest, testMultipleAuthorizeDiscoveredPlayersSuccess) {
ON_CALL(*m_mockContextManager, getContext(_, _, _)).WillByDefault(InvokeWithoutArgs([this]() {
m_externalMediaPlayer->onContextAvailable("");
return 0;
}));
// Use another instance to avoid SetUp() interferring with the test.
auto messageSender = std::make_shared<NiceMock<MockMessageSender>>();
m_externalMediaPlayer = ExternalMediaPlayer::create(
m_adapterMediaPlayerMap,
m_adapterSpeakerMap,
m_adapterMap,
m_mockSpeakerManager,
messageSender,
m_mockCertifiedSender->get(),
m_mockFocusManager,
m_mockContextManager,
m_mockExceptionSender,
m_mockPlaybackRouter,
m_metricRecorder);
std::promise<void> authorizationCompletePromise;
std::future<void> authorizationCompleteFuture = authorizationCompletePromise.get_future();
auto mockDirectiveHandlerResult = std::unique_ptr<MockDirectiveHandlerResult>(new MockDirectiveHandlerResult);
EXPECT_CALL(*mockDirectiveHandlerResult, setCompleted());
EXPECT_CALL(
*(MockExternalMediaPlayerAdapter::m_currentActiveMediaPlayerAdapter),
handleAuthorized(true, MSP1_PLAYER_ID, MSP1_SKILLTOKEN));
std::promise<void> authorizationCompletePromise2;
std::future<void> authorizationCompleteFuture2 = authorizationCompletePromise2.get_future();
auto mockDirectiveHandlerResult2 = std::unique_ptr<MockDirectiveHandlerResult>(new MockDirectiveHandlerResult);
EXPECT_CALL(*mockDirectiveHandlerResult2, setCompleted());
EXPECT_CALL(*(MockExternalMediaPlayerAdapter::m_currentActiveMediaPlayerAdapter), handleAuthorized(false, "", ""));
{
InSequence s;
EXPECT_CALL(
*messageSender, sendMessage(EventNamed(AUTHORIZATION_COMPLETE.nameSpace, AUTHORIZATION_COMPLETE.name)))
.Times(1)
.WillOnce(Invoke([&authorizationCompletePromise](std::shared_ptr<MessageRequest> request) {
veryifyAuthorizationCompletePayload(request, {{MSP1_PLAYER_ID, MSP1_SKILLTOKEN}});
authorizationCompletePromise.set_value();
}));
EXPECT_CALL(
*messageSender, sendMessage(EventNamed(AUTHORIZATION_COMPLETE.nameSpace, AUTHORIZATION_COMPLETE.name)))
.Times(1)
.WillOnce(Invoke([&authorizationCompletePromise2](std::shared_ptr<MessageRequest> request) {
veryifyAuthorizationCompletePayload(
request, std::unordered_map<std::string, std::string>(), {MSP1_LOCAL_PLAYER_ID});
authorizationCompletePromise2.set_value();
}));
}
const std::string playersJson = createPlayerJson(MSP1_LOCAL_PLAYER_ID, true, MSP1_PLAYER_ID, MSP1_SKILLTOKEN);
sendAuthorizeDiscoveredPlayersDirective(
createAuthorizeDiscoveredPlayersPayload({playersJson}), std::move(mockDirectiveHandlerResult));
sendAuthorizeDiscoveredPlayersDirective(
createAuthorizeDiscoveredPlayersPayload(), std::move(mockDirectiveHandlerResult2));
ASSERT_TRUE(std::future_status::ready == authorizationCompleteFuture.wait_for(MY_WAIT_TIMEOUT));
ASSERT_TRUE(std::future_status::ready == authorizationCompleteFuture2.wait_for(MY_WAIT_TIMEOUT));
}
/**
* Test setPlayerInFocus succeeds for authorized players.
*/
TEST_F(ExternalMediaPlayerTest, testSetPlayerInFocusSucceedsForAuthorized) {
EXPECT_CALL(*m_mockContextManager, setState(SESSION_STATE, _, _, _))
.WillOnce(Invoke([this](
const avs::NamespaceAndName& namespaceAndName,
const std::string& jsonState,
const avs::StateRefreshPolicy& refreshPolicy,
const unsigned int stateRequestToken) {
rapidjson::Document document;
ParseResult result = document.Parse(jsonState);
if (!result) {
return SetStateResult::SUCCESS;
}
std::string playerInFocus;
if (!retrieveValue(document, "playerInFocus", &playerInFocus)) {
return SetStateResult::SUCCESS;
}
if (MSP1_PLAYER_ID == playerInFocus) {
wakeOnSetState();
}
return SetStateResult::SUCCESS;
}));
// Authorized from SetUp().
m_externalMediaPlayer->setPlayerInFocus(MSP1_PLAYER_ID);
m_externalMediaPlayer->provideState(SESSION_STATE, PROVIDE_STATE_TOKEN_TEST);
ASSERT_TRUE(std::future_status::ready == m_wakeSetStateFuture.wait_for(MY_WAIT_TIMEOUT));
}
/**
* Test setPlayerInFocus fails for unauthorized players.
*/
TEST_F(ExternalMediaPlayerTest, testSetPlayerInFocusFailsForAuthorized) {
const std::string INVALID_ID = "invalidPlayerId";
EXPECT_CALL(*m_mockPlaybackRouter, setHandler(_)).Times(0);
EXPECT_CALL(*m_mockContextManager, setState(_, Not(HasSubstr(INVALID_ID)), _, _))
.WillOnce(InvokeWithoutArgs(this, &ExternalMediaPlayerTest::wakeOnSetState));
m_externalMediaPlayer->setPlayerInFocus(INVALID_ID);
m_externalMediaPlayer->provideState(SESSION_STATE, PROVIDE_STATE_TOKEN_TEST);
ASSERT_TRUE(std::future_status::ready == m_wakeSetStateFuture.wait_for(MY_WAIT_TIMEOUT));
}
/**
* Test setPlayerInFocus notifies any RenderPlayerInfoCardsObservers.
*/
TEST_F(ExternalMediaPlayerTest, testSetPlayerInFocusNotfiesTemplateRuntimeObserver) {
std::promise<void> promise;
std::future<void> future = promise.get_future();
auto renderCardObserver = std::make_shared<MockRenderPlayerInfoCardsObserver>();
m_externalMediaPlayer->setObserver(renderCardObserver);
EXPECT_CALL(*renderCardObserver, onRenderPlayerCardsInfoChanged(_, _))
.WillOnce(Invoke([&promise](
avsCommon::avs::PlayerActivity state,
const RenderPlayerInfoCardsObserverInterface::Context& context) { promise.set_value(); }));
// Authorized from SetUp().
m_externalMediaPlayer->setPlayerInFocus(MSP1_PLAYER_ID);
m_externalMediaPlayer->provideState(PLAYBACK_STATE, PROVIDE_STATE_TOKEN_TEST);
ASSERT_TRUE(std::future_status::ready == future.wait_for(MY_WAIT_TIMEOUT));
}
} // namespace test
} // namespace externalMediaPlayer
} // namespace capabilityAgents
} // namespace alexaClientSDK