-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
252 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
#include "xapi/Exceptions.hpp" | ||
#include "xapi/XStationClient.hpp" | ||
#include <gtest/gtest.h> | ||
#include <string> | ||
|
||
using namespace xapi; | ||
|
||
class XStationClientTest : public testing::Test | ||
{ | ||
protected: | ||
void SetUp() override | ||
{ | ||
} | ||
|
||
void TearDown() override | ||
{ | ||
} | ||
|
||
public: | ||
boost::asio::io_context &getIoContext() | ||
{ | ||
return m_context; | ||
} | ||
|
||
template <typename Awaitable> auto runAwaitable(Awaitable &&awaitable) | ||
{ | ||
std::exception_ptr eptr; | ||
using result_type = typename Awaitable::value_type; | ||
result_type result; | ||
|
||
boost::asio::co_spawn( | ||
m_context, | ||
[&]() -> boost::asio::awaitable<void> { | ||
try | ||
{ | ||
result = co_await std::forward<Awaitable>(awaitable); | ||
} | ||
catch (...) | ||
{ | ||
eptr = std::current_exception(); | ||
} | ||
}, | ||
boost::asio::detached); | ||
|
||
m_context.run(); | ||
|
||
if (eptr) | ||
{ | ||
std::rethrow_exception(eptr); | ||
} | ||
|
||
return result; | ||
} | ||
|
||
template <typename Awaitable> auto runAwaitableVoid(Awaitable &&awaitable) | ||
{ | ||
std::exception_ptr eptr; | ||
boost::asio::co_spawn( | ||
m_context, | ||
[&]() -> boost::asio::awaitable<void> { | ||
try | ||
{ | ||
co_await std::forward<Awaitable>(awaitable); | ||
} | ||
catch (...) | ||
{ | ||
eptr = std::current_exception(); | ||
} | ||
}, | ||
boost::asio::detached); | ||
|
||
m_context.run(); | ||
|
||
if (eptr) | ||
{ | ||
std::rethrow_exception(eptr); | ||
} | ||
} | ||
|
||
private: | ||
boost::asio::io_context m_context; | ||
}; | ||
|
||
TEST_F(XStationClientTest, XStationClient_string_constructor) | ||
{ | ||
EXPECT_NO_THROW(auto client = std::make_unique<XStationClient>(getIoContext(), "test", "test", "demo")); | ||
} | ||
|
||
TEST_F(XStationClientTest, XStationClient_json_constructor) | ||
{ | ||
const boost::json::object accountCredentials = { | ||
{"accountId", "test"}, | ||
{"password", "test"}, | ||
{"accountType", "demo"} | ||
}; | ||
|
||
EXPECT_NO_THROW(auto client = std::make_unique<XStationClient>(getIoContext(), accountCredentials)); | ||
} | ||
|
||
TEST_F(XStationClientTest, XStationClient_getSocket_exception) | ||
{ | ||
const boost::json::object accountCredentials = { | ||
{"accountId", "test"}, | ||
{"password", "test"}, | ||
{"accountType", "demo"} | ||
}; | ||
|
||
std::unique_ptr<XStationClient> client; | ||
EXPECT_NO_THROW(client = std::make_unique<XStationClient>(getIoContext(), accountCredentials)); | ||
EXPECT_THROW(runAwaitable(client->getSocket()), exception::LoginFailed); | ||
} | ||
|
||
TEST_F(XStationClientTest, XStationClient_getStream_exception) | ||
{ | ||
const boost::json::object accountCredentials = { | ||
{"accountId", "test"}, | ||
{"password", "test"}, | ||
{"accountType", "demo"} | ||
}; | ||
|
||
std::unique_ptr<XStationClient> client; | ||
EXPECT_NO_THROW(client = std::make_unique<XStationClient>(getIoContext(), accountCredentials)); | ||
EXPECT_THROW(runAwaitable(client->getStream()), exception::LoginFailed); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
#include "XStationClient.hpp" | ||
#include "Exceptions.hpp" | ||
|
||
namespace xapi | ||
{ | ||
|
||
XStationClient::XStationClient(boost::asio::io_context &ioContext, const std::string &accountId, | ||
const std::string &password, const std::string &accountType) | ||
: m_ioContext(ioContext), m_accountId(accountId), m_password(password), m_accountType(accountType), | ||
m_streamSessionId("") | ||
{ | ||
} | ||
|
||
XStationClient::XStationClient(boost::asio::io_context &ioContext, const boost::json::object &accountCredentials) | ||
: m_ioContext(ioContext), m_accountId(accountCredentials.at("accountId").as_string()), | ||
m_password(accountCredentials.at("password").as_string()), | ||
m_accountType(accountCredentials.at("accountType").as_string()), m_streamSessionId("") | ||
{ | ||
} | ||
|
||
boost::asio::awaitable<std::shared_ptr<xapi::Socket>> XStationClient::getSocket() | ||
{ | ||
auto socket = std::make_shared<xapi::Socket>(m_ioContext); | ||
co_await socket->initSession(m_accountType); | ||
m_streamSessionId = co_await socket->login(m_accountId, m_password); | ||
co_return socket; | ||
} | ||
|
||
boost::asio::awaitable<std::shared_ptr<xapi::Stream>> XStationClient::getStream() const | ||
{ | ||
if (m_streamSessionId.empty()) | ||
{ | ||
throw xapi::exception::LoginFailed("No stream session ID, get Socket to establish a session first"); | ||
} | ||
auto stream = std::make_shared<xapi::Stream>(m_ioContext); | ||
co_await stream->initSession(m_accountType, m_streamSessionId); | ||
co_return stream; | ||
} | ||
|
||
} // namespace xapi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
#pragma once | ||
|
||
/** | ||
* @file XStationClient.hpp | ||
* @brief Defines the XStationClient class for managing xStation client. | ||
* | ||
* This file contains the definition of the XStationClient class, which provides | ||
* an interface for managing xStation client and retreiving Socket and Stream objects. | ||
*/ | ||
|
||
#include "Socket.hpp" | ||
#include "Stream.hpp" | ||
|
||
namespace xapi | ||
{ | ||
/** | ||
* @brief Provides an interface for managing xStation client and retreiving Socket and Stream objects. | ||
* | ||
* The XStationClient class provides a high-level interface for managing xStation client and retreiving xapi::Socket and | ||
* xapi::Stream objects that can be used to interact with xAPI. | ||
*/ | ||
class XStationClient | ||
{ | ||
public: | ||
XStationClient() = delete; | ||
|
||
/** | ||
* @brief Constructs a new XStationClient object. | ||
* @param ioContext The IO context for asynchronous operations. | ||
* @param accountId The account ID to use for the client. | ||
* @param password The password to use for the client. | ||
* @param accountType The type of account to use for the client. | ||
* Possible values are: | ||
* | ||
* - `"demo"` for a demo account. | ||
* | ||
* - `"real"` for a real money account. | ||
*/ | ||
XStationClient(boost::asio::io_context &ioContext, const std::string &accountId, | ||
const std::string &password, const std::string &accountType = "demo"); | ||
|
||
/** | ||
* @brief Constructs a new XStationClient object. | ||
* | ||
* Initializes the client with the provided IO context and account credentials. | ||
* | ||
* @param ioContext The IO context for managing asynchronous operations. | ||
* @param accountCredentials A boost::json::object containing the account credentials required for the client. | ||
* The map should include the following keys: | ||
* | ||
* - `accountId`: The account ID as a string. | ||
* | ||
* - `password`: The account password as a string. | ||
* | ||
* - `accountType`: The type of account. Possible values are: `"demo"` or `"real"` | ||
* | ||
*/ | ||
XStationClient(boost::asio::io_context &ioContext, const boost::json::object &accountCredentials); | ||
|
||
~XStationClient() = default; | ||
|
||
/** | ||
* @brief Retrieves a configured Socket object for the client. | ||
* @return An awaitable std::shared_ptr<xapi::Socket> object. | ||
*/ | ||
boost::asio::awaitable<std::shared_ptr<xapi::Socket>> getSocket(); | ||
|
||
/** | ||
* @brief Retrieves a configured Stream object for the client. | ||
* @return An awaitable std::shared_ptr<xapi::Stream> object. | ||
*/ | ||
boost::asio::awaitable<std::shared_ptr<xapi::Stream>> getStream() const; | ||
|
||
private: | ||
boost::asio::io_context &m_ioContext; | ||
|
||
const std::string m_accountId; | ||
const std::string m_password; | ||
const std::string m_accountType; | ||
|
||
std::string m_streamSessionId; | ||
}; | ||
|
||
} // namespace xapi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,3 +7,4 @@ | |
#include "Connection.hpp" | ||
#include "Socket.hpp" | ||
#include "Stream.hpp" | ||
#include "XStationClient.hpp" |