summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--battleNetApi/include/apiUrl.hpp7
-rw-r--r--battleNetApi/include/hearthstoneApi.hpp11
-rw-r--r--battleNetApi/include/token.hpp4
-rw-r--r--battleNetApi/src/apiUrl.cpp44
-rw-r--r--battleNetApi/src/hearthstoneApi.cpp56
-rw-r--r--battleNetApi/src/hearthstoneTokenBuilder.cpp3
-rw-r--r--battleNetApi/tests/CMakeLists.txt26
-rw-r--r--battleNetApi/tests/resources/dumb_credentials.json10
-rw-r--r--battleNetApi/tests/src/hearthstoneApiTests.cpp156
-rw-r--r--battleNetApi/tests/src/tests.cpp144
-rw-r--r--battleNetApi/tests/src/tokenTests.cpp2
11 files changed, 248 insertions, 215 deletions
diff --git a/battleNetApi/include/apiUrl.hpp b/battleNetApi/include/apiUrl.hpp
index e936b6c..ece4d17 100644
--- a/battleNetApi/include/apiUrl.hpp
+++ b/battleNetApi/include/apiUrl.hpp
@@ -3,16 +3,18 @@
#include <string>
#include <unordered_map>
+namespace bnet {
+enum class GameMode { constructed, battlegrounds, mercenaries };
+
class ApiUrl {
public:
ApiUrl(const std::string &iContentType, const std::string &iRegion);
void setRegion(const std::string &iRegion);
void setLocale(const std::string &iLocale);
- void setGameMode(const std::string &iGameMode);
+ void setGameMode(const GameMode &iGameMode);
void setPage(const std::string &iPage);
void setPage(uint64_t iPage);
- void setPageSize(const std::string &iPageSize);
void setPageSize(uint64_t iPageSize);
bool hasRegion() const;
@@ -35,3 +37,4 @@ class ApiUrl {
void setValue(const std::string &iKey, const std::string &iValue);
bool hasValue(const std::string &iKey) const;
};
+}; // namespace bnet
diff --git a/battleNetApi/include/hearthstoneApi.hpp b/battleNetApi/include/hearthstoneApi.hpp
index 59cd336..2810204 100644
--- a/battleNetApi/include/hearthstoneApi.hpp
+++ b/battleNetApi/include/hearthstoneApi.hpp
@@ -4,20 +4,25 @@
#include <nlohmann/json.hpp>
#include <string>
+namespace bnet {
using json = nlohmann::json;
class HearthstoneApi {
public:
static json makeApiRequest(const ApiUrl &iApiUrl, const std::string &iTokenText);
- static std::vector<json> makeApiRequest(const std::vector<ApiUrl> &iApiUrls, const std::string &iTokenText);
- static std::vector<json> makeApiRequest(const std::vector<std::string> &iUrls, const std::string &iTokenText);
+ static std::vector<json> makeApiRequest(const std::vector<ApiUrl> &iApiUrls,
+ const std::string &iTokenText);
+ static std::vector<json> makeApiRequest(const std::vector<std::string> &iUrls,
+ const std::string &iTokenText);
static json downloadCards(ApiUrl iApiUrl, const Token &iToken);
private:
static std::string authorizationHeader(const std::string &iTokenText);
- static size_t curlCallbackStringOutput(void *iContent, size_t iSize, size_t iNmemb, std::string *iS);
+ static size_t curlCallbackStringOutput(void *iContent, size_t iSize, size_t iNmemb,
+ std::string *iS);
std::string mAuthorizationHeader; //<! Bearer authorization string for OAuth 2.0 header
friend class HearthstoneApiMock;
};
+}; // namespace bnet
diff --git a/battleNetApi/include/token.hpp b/battleNetApi/include/token.hpp
index f943b81..479cb29 100644
--- a/battleNetApi/include/token.hpp
+++ b/battleNetApi/include/token.hpp
@@ -22,9 +22,9 @@ class Token {
};
namespace {
-auto currentTime = [] {
+auto currentTime = [] -> std::chrono::seconds {
return std::chrono::duration_cast<std::chrono::seconds>(
- std::chrono::steady_clock::now().time_since_epoch());
+ std::chrono::system_clock::now().time_since_epoch());
};
} // namespace
} // namespace bnet
diff --git a/battleNetApi/src/apiUrl.cpp b/battleNetApi/src/apiUrl.cpp
index fa07372..5ef109c 100644
--- a/battleNetApi/src/apiUrl.cpp
+++ b/battleNetApi/src/apiUrl.cpp
@@ -2,6 +2,20 @@
#include <cstdint>
#include <format>
+namespace bnet {
+namespace {
+std::string gamemodeToString(const GameMode &iGameMode) {
+ switch (iGameMode) {
+ case GameMode::constructed:
+ return "constructed";
+ case GameMode::battlegrounds:
+ return "battlegrounds";
+ case GameMode::mercenaries:
+ return "mercenaries";
+ }
+}
+}; // namespace
+
ApiUrl::ApiUrl(const std::string &iContentType, const std::string &iRegion)
: mContentType{iContentType}, mRegion{iRegion} {}
void ApiUrl::setRegion(const std::string &iRegion) {
@@ -16,13 +30,11 @@ void ApiUrl::setLocale(const std::string &iLocale) {
setValue(kLOCALE_KEY, iLocale);
}
}
-void ApiUrl::setGameMode(const std::string &iGameMode) {
- if (not iGameMode.empty()) {
- //!< A recognized game mode, e.g. "constructed"
- //!< @see
- //!< https://community.developer.battle.net/documentation/hearthstone/guides/game-modes
- setValue(kGAME_MODE_KEY, iGameMode);
- }
+void ApiUrl::setGameMode(const GameMode &iGameMode) {
+ //!< A recognized game mode, e.g. "constructed"
+ //!< @see
+ //!< https://community.developer.battle.net/documentation/hearthstone/guides/game-modes
+ setValue(kGAME_MODE_KEY, gamemodeToString(iGameMode));
}
void ApiUrl::setPage(const std::string &iPage) {
if (not iPage.empty()) {
@@ -31,14 +43,8 @@ void ApiUrl::setPage(const std::string &iPage) {
}
}
void ApiUrl::setPage(uint64_t iPage) { setPage(std::to_string(iPage)); }
-void ApiUrl::setPageSize(const std::string &iPageSize) {
- if (not iPageSize.empty()) {
- //!< The number of results to choose per page, e.g. "40"
- setValue(kPAGE_SIZE_KEY, iPageSize);
- }
-}
void ApiUrl::setPageSize(uint64_t iPageSize) {
- return setPageSize(std::to_string(iPageSize));
+ setValue(kPAGE_SIZE_KEY, std::to_string(iPageSize));
}
bool ApiUrl::hasLocale() const { return hasValue(kLOCALE_KEY); }
bool ApiUrl::hasGameMode() const { return hasValue(kGAME_MODE_KEY); }
@@ -47,9 +53,7 @@ bool ApiUrl::hasPageSize() const { return hasValue(kPAGE_SIZE_KEY); }
void ApiUrl::setValue(const std::string &iKey, const std::string &iValue) {
aParameters[iKey] = iValue;
}
-bool ApiUrl::hasValue(const std::string &iKey) const {
- return aParameters.count(iKey) > 0;
-}
+bool ApiUrl::hasValue(const std::string &iKey) const { return aParameters.count(iKey) > 0; }
std::string ApiUrl::text() const {
std::string aFormattedParameters;
for (const auto &[key, value] : aParameters) {
@@ -58,8 +62,8 @@ std::string ApiUrl::text() const {
if (not aFormattedParameters.empty()) {
aFormattedParameters[0] = '?';
}
- aFormattedParameters =
- std::format("https://{}.api.blizzard.com/hearthstone/{}/{}", mRegion,
- mContentType, aFormattedParameters);
+ aFormattedParameters = std::format("https://{}.api.blizzard.com/hearthstone/{}/{}", mRegion,
+ mContentType, aFormattedParameters);
return aFormattedParameters;
}
+}; // namespace bnet
diff --git a/battleNetApi/src/hearthstoneApi.cpp b/battleNetApi/src/hearthstoneApi.cpp
index 1341f74..4dd8fac 100644
--- a/battleNetApi/src/hearthstoneApi.cpp
+++ b/battleNetApi/src/hearthstoneApi.cpp
@@ -5,13 +5,14 @@
#include <curl/multi.h>
#include <format>
#include <iostream>
+#include <stdexcept>
+namespace bnet {
std::string HearthstoneApi::authorizationHeader(const std::string &iTokenText) {
return std::format("Authorization: Bearer {}", iTokenText);
}
-size_t HearthstoneApi::curlCallbackStringOutput(void *iContent, size_t iSize,
- size_t iNmemb,
+size_t HearthstoneApi::curlCallbackStringOutput(void *iContent, size_t iSize, size_t iNmemb,
std::string *iS) {
const size_t kNewLength = iSize * iNmemb;
try {
@@ -23,8 +24,7 @@ size_t HearthstoneApi::curlCallbackStringOutput(void *iContent, size_t iSize,
return kNewLength;
}
-json HearthstoneApi::makeApiRequest(const ApiUrl &iApiUrl,
- const std::string &iTokenText) {
+json HearthstoneApi::makeApiRequest(const ApiUrl &iApiUrl, const std::string &iTokenText) {
CURL *curl = curl_easy_init();
std::string aRequestOutput;
if (curl) {
@@ -34,8 +34,7 @@ json HearthstoneApi::makeApiRequest(const ApiUrl &iApiUrl,
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curlCallbackStringOutput);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &aRequestOutput);
struct curl_slist *chunk = nullptr;
- chunk =
- curl_slist_append(chunk, authorizationHeader(iTokenText).c_str());
+ chunk = curl_slist_append(chunk, authorizationHeader(iTokenText).c_str());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
curl_easy_perform(curl);
curl_easy_cleanup(curl);
@@ -44,34 +43,28 @@ json HearthstoneApi::makeApiRequest(const ApiUrl &iApiUrl,
return aOutputJson;
}
-std::vector<json>
-HearthstoneApi::makeApiRequest(const std::vector<ApiUrl> &iApiUrls,
- const std::string &iTokenText) {
+std::vector<json> HearthstoneApi::makeApiRequest(const std::vector<ApiUrl> &iApiUrls,
+ const std::string &iTokenText) {
std::vector<std::string> aApiUrls(iApiUrls.size());
- std::ranges::transform(
- iApiUrls, aApiUrls.begin(),
- [](const ApiUrl &iApiUrl) { return iApiUrl.text(); });
+ std::ranges::transform(iApiUrls, aApiUrls.begin(),
+ [](const ApiUrl &iApiUrl) { return iApiUrl.text(); });
return makeApiRequest(aApiUrls, iTokenText);
}
-std::vector<json>
-HearthstoneApi::makeApiRequest(const std::vector<std::string> &iUrls,
- const std::string &iTokenText) {
+std::vector<json> HearthstoneApi::makeApiRequest(const std::vector<std::string> &iUrls,
+ const std::string &iTokenText) {
std::vector<std::string> aResponses(iUrls.size());
CURLM *curlm = curl_multi_init();
if (curlm) {
- for (std::vector<std::string>::size_type i{0}; i < aResponses.size();
- ++i) {
+ for (std::vector<std::string>::size_type i{0}; i < aResponses.size(); ++i) {
CURL *curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_URL, iUrls[i].c_str());
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
- curlCallbackStringOutput);
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curlCallbackStringOutput);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &(aResponses[i]));
struct curl_slist *chunk = nullptr;
- chunk = curl_slist_append(chunk,
- authorizationHeader(iTokenText).c_str());
+ chunk = curl_slist_append(chunk, authorizationHeader(iTokenText).c_str());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
curl_multi_add_handle(curlm, curl);
}
@@ -82,8 +75,7 @@ HearthstoneApi::makeApiRequest(const std::vector<std::string> &iUrls,
int numfds = 0;
int res = curl_multi_wait(curlm, NULL, 0, kMaxWaitMs, &numfds);
if (res != CURLM_OK) {
- std::cerr << std::format(
- "error: curl_multi_wait() returned {}\n", res);
+ std::cerr << std::format("error: curl_multi_wait() returned {}\n", res);
}
curl_multi_perform(curlm, &aStillRunning);
} while (aStillRunning);
@@ -98,17 +90,15 @@ HearthstoneApi::makeApiRequest(const std::vector<std::string> &iUrls,
aHandle = aMessage->easy_handle;
aReturnCode = aMessage->data.result;
if (aReturnCode != CURLE_OK) {
- fprintf(stderr, "CURL error code: %d\n",
- aMessage->data.result);
+ fprintf(stderr, "CURL error code: %d\n", aMessage->data.result);
continue;
}
curl_multi_remove_handle(curlm, aHandle);
curl_easy_cleanup(aHandle);
aHandle = nullptr;
} else {
- std::cerr << std::format(
- "error: after curl_multi_info_read(), CURLMsg={}\n",
- static_cast<int>(aMessage->msg));
+ std::cerr << std::format("error: after curl_multi_info_read(), CURLMsg={}\n",
+ static_cast<int>(aMessage->msg));
}
}
curl_multi_cleanup(curlm);
@@ -121,20 +111,23 @@ HearthstoneApi::makeApiRequest(const std::vector<std::string> &iUrls,
}
json HearthstoneApi::downloadCards(ApiUrl iApiUrl, const Token &iToken) {
+ if (!iToken.text().has_value() || iToken.text().value().empty()) {
+ throw std::invalid_argument("Token text does not exist or is empty");
+ }
if (iApiUrl.hasPage()) {
- return makeApiRequest(iApiUrl, iToken.text());
+ return makeApiRequest(iApiUrl, *iToken.text());
}
iApiUrl.setPage("1");
std::vector<std::string> aRequests;
- json aFirstPageJson = makeApiRequest(iApiUrl, iToken.text());
+ json aFirstPageJson = makeApiRequest(iApiUrl, *iToken.text());
int kNumberOfPages{aFirstPageJson["pageCount"]};
for (int i{1}; i < kNumberOfPages; ++i) {
iApiUrl.setPage(std::to_string(i + 1));
aRequests.push_back(iApiUrl.text());
}
json::reference &aOutputJson = aFirstPageJson["cards"];
- std::vector<json> kApiResponses = makeApiRequest(aRequests, iToken.text());
+ std::vector<json> kApiResponses = makeApiRequest(aRequests, *iToken.text());
for (json &aPage : kApiResponses) {
for (json::reference &aCard : aPage["cards"]) {
aOutputJson.push_back(std::move(aCard));
@@ -142,3 +135,4 @@ json HearthstoneApi::downloadCards(ApiUrl iApiUrl, const Token &iToken) {
}
return aOutputJson;
}
+}; // namespace bnet
diff --git a/battleNetApi/src/hearthstoneTokenBuilder.cpp b/battleNetApi/src/hearthstoneTokenBuilder.cpp
index 668aaa5..96e3aa8 100644
--- a/battleNetApi/src/hearthstoneTokenBuilder.cpp
+++ b/battleNetApi/src/hearthstoneTokenBuilder.cpp
@@ -1,3 +1,4 @@
+#include <chrono>
#include <curl/curl.h>
#include <fstream>
#include <hearthstoneTokenBuilder.hpp>
@@ -69,7 +70,7 @@ bool HearthstoneTokenBuilder::isTokenValid(const json &iTokenJson) const {
const std::uint64_t kExpirationTime{iTokenJson["Token"]["ExpirationTime"]};
const std::uint64_t kCurrentTime{
static_cast<std::uint64_t>(std::chrono::duration_cast<std::chrono::seconds>(
- std::chrono::high_resolution_clock::now().time_since_epoch())
+ std::chrono::system_clock::now().time_since_epoch())
.count())};
return kCurrentTime <= kExpirationTime;
}
diff --git a/battleNetApi/tests/CMakeLists.txt b/battleNetApi/tests/CMakeLists.txt
index b59fd8a..6281f6b 100644
--- a/battleNetApi/tests/CMakeLists.txt
+++ b/battleNetApi/tests/CMakeLists.txt
@@ -21,17 +21,21 @@ execute_process(
)
set(BATTLE_NET_API_DIR ${GIT_REPOSITORY_FOLDER_PATH}/battleNetApi)
-#set(SRC_TESTS
-# ${PROJECT_SOURCE_DIR}/src/hearthstoneApi.cpp
-# ${PROJECT_SOURCE_DIR}/src/token.cpp
-# ${PROJECT_SOURCE_DIR}/src/tokenBuilder.cpp
-# ${PROJECT_SOURCE_DIR}/src/hearthstoneTokenBuilder.cpp
-# ${PROJECT_SOURCE_DIR}/src/apiUrl.cpp
-# ${PROJECT_SOURCE_DIR}/tests/src/tests.cpp
-#)
-#add_executable(tests ${SRC_TESTS})
-#target_include_directories(tests PRIVATE ${INCLUDE_DIR})
-#target_link_libraries(tests PRIVATE Catch2::Catch2WithMain curl)
+set(SRC_HEARTHSTONE_API_TESTS
+ ${BATTLE_NET_API_DIR}/src/hearthstoneApi.cpp
+ ${BATTLE_NET_API_DIR}/src/token.cpp
+ ${BATTLE_NET_API_DIR}/src/tokenBuilder.cpp
+ ${BATTLE_NET_API_DIR}/src/hearthstoneTokenBuilder.cpp
+ ${BATTLE_NET_API_DIR}/src/apiUrl.cpp
+ ${BATTLE_NET_API_DIR}/tests/src/hearthstoneApiTests.cpp
+)
+add_executable(hearthstoneApiTests ${SRC_HEARTHSTONE_API_TESTS})
+set(INCLUDE_HEARTHSTONE_API_DIR ${BATTLE_NET_API_DIR}/include)
+target_include_directories(
+ hearthstoneApiTests
+ PRIVATE ${INCLUDE_HEARTHSTONE_API_DIR}
+)
+target_link_libraries(hearthstoneApiTests PRIVATE Catch2::Catch2WithMain curl)
set(INCLUDE_TOKEN_DIR ${BATTLE_NET_API_DIR}/include)
set(SRC_TOKEN_TESTS
diff --git a/battleNetApi/tests/resources/dumb_credentials.json b/battleNetApi/tests/resources/dumb_credentials.json
new file mode 100644
index 0000000..e919770
--- /dev/null
+++ b/battleNetApi/tests/resources/dumb_credentials.json
@@ -0,0 +1,10 @@
+{
+ "Agent": {
+ "Password": "MrMkhVMNdOeqPL4Q4XVQAsRPR14J7Yq6",
+ "Username": "2b50f1123b424d5e9c21971a110fdd04"
+ },
+ "Token": {
+ "Content": "ThisIsTheContentOfTokenContenthehe",
+ "ExpirationTime": 0
+ }
+}
diff --git a/battleNetApi/tests/src/hearthstoneApiTests.cpp b/battleNetApi/tests/src/hearthstoneApiTests.cpp
new file mode 100644
index 0000000..2c39d0c
--- /dev/null
+++ b/battleNetApi/tests/src/hearthstoneApiTests.cpp
@@ -0,0 +1,156 @@
+#include "apiUrl.hpp"
+#include "hearthstoneApi.hpp"
+#include "hearthstoneTokenBuilder.hpp"
+#include <catch2/benchmark/catch_benchmark.hpp>
+#include <catch2/benchmark/catch_chronometer.hpp>
+#include <catch2/benchmark/detail/catch_analyse.hpp>
+#include <catch2/benchmark/detail/catch_benchmark_function.hpp>
+#include <catch2/benchmark/detail/catch_estimate_clock.hpp>
+#include <catch2/catch_approx.hpp>
+#include <catch2/catch_config.hpp>
+#include <catch2/catch_test_macros.hpp>
+#include <cstdint>
+#include <fstream>
+#include <nlohmann/json.hpp>
+#include <string>
+#include <tokenBuilder.hpp>
+
+TEST_CASE("Retrieve number of cards", "[countCards]") {
+ const std::string aContentType{"cards"};
+ const std::string aRegion{"eu"};
+ bnet::ApiUrl aApiUrl(aContentType, aRegion);
+ aApiUrl.setLocale("fr_FR");
+ aApiUrl.setGameMode(bnet::GameMode::constructed);
+ aApiUrl.setPageSize(1);
+ bnet::HearthstoneTokenBuilder aHearthstoneTokenBuilder("resources/credentials.json");
+ const nlohmann::json aResponse = bnet::HearthstoneApi::makeApiRequest(
+ aApiUrl, aHearthstoneTokenBuilder.allowBattleNetApiCall()
+ .allowUpdateSourceFile()
+ .buildToken()
+ .getToken()
+ ->text()
+ .value());
+ REQUIRE(aResponse.size() > 0);
+ REQUIRE(aResponse.contains("pageCount"));
+ std::uint64_t aNumberOfCards{aResponse["pageCount"]};
+ std::uint64_t aExpectedNumberOfCards{6000};
+ REQUIRE(aNumberOfCards >= aExpectedNumberOfCards);
+}
+
+TEST_CASE("Retrieve page once", "[retrievePageOnce]") {
+ const std::string aContentType{"cards"};
+ const std::string aRegion{"eu"};
+ bnet::ApiUrl aApiUrl(aContentType, aRegion);
+ aApiUrl.setLocale("fr_FR");
+ aApiUrl.setGameMode(bnet::GameMode::constructed);
+ aApiUrl.setPageSize(16);
+ bnet::HearthstoneTokenBuilder aHearthstoneTokenBuilder("resources/credentials.json");
+ const std::string aTokenText{aHearthstoneTokenBuilder.allowBattleNetApiCall()
+ .allowUpdateSourceFile()
+ .buildToken()
+ .getToken()
+ ->text()
+ .value()};
+ const nlohmann::json aApiResponse = bnet::HearthstoneApi::makeApiRequest(aApiUrl, aTokenText);
+ REQUIRE(aApiResponse["cards"].size() == 16);
+}
+
+TEST_CASE("Retrieve pages 10 times without parallelization", "[retrievePagesNoParallel]") {
+ const std::string aContentType{"cards"};
+ const std::string aRegion{"eu"};
+ bnet::ApiUrl aApiUrl(aContentType, aRegion);
+ aApiUrl.setLocale("fr_FR");
+ aApiUrl.setGameMode(bnet::GameMode::constructed);
+ aApiUrl.setPageSize(16);
+ aApiUrl.setPage("1");
+ bnet::HearthstoneTokenBuilder aHearthstoneTokenBuilder("resources/credentials.json");
+ const std::string aTokenText{aHearthstoneTokenBuilder.allowBattleNetApiCall()
+ .allowUpdateSourceFile()
+ .buildToken()
+ .getToken()
+ ->text()
+ .value()};
+ bnet::json aApiResponse = bnet::HearthstoneApi::makeApiRequest(aApiUrl, aTokenText);
+
+ // Retrieve number of pages
+ const int aNumberOfRetrievals{10};
+ const int aNumberOfPages{aApiResponse["pageCount"]};
+ REQUIRE(aNumberOfPages >= aNumberOfRetrievals);
+ for (int i{1}; i < aNumberOfRetrievals; ++i) {
+ REQUIRE(aApiResponse["cards"].size() == 16);
+ aApiUrl.setPage(std::to_string(i + 1));
+ aApiResponse = bnet::HearthstoneApi::makeApiRequest(aApiUrl, aTokenText);
+ }
+ REQUIRE(aApiResponse["cards"].size() >= 1);
+ REQUIRE(aApiResponse["cards"].size() <= 16);
+}
+
+TEST_CASE("Retrieve pages 10 times with parallelization", "[retrievePagesParallel]") {
+ const std::string aContentType{"cards"};
+ const std::string aRegion{"eu"};
+ bnet::ApiUrl aApiUrl(aContentType, aRegion);
+ aApiUrl.setLocale("fr_FR");
+ aApiUrl.setGameMode(bnet::GameMode::constructed);
+ aApiUrl.setPageSize(16);
+ aApiUrl.setPage("1");
+ std::vector<std::string> aRequests;
+ bnet::HearthstoneTokenBuilder aHearthstoneTokenBuilder("resources/credentials.json");
+ const std::string aTokenText{aHearthstoneTokenBuilder.allowBattleNetApiCall()
+ .allowUpdateSourceFile()
+ .buildToken()
+ .getToken()
+ ->text()
+ .value()};
+ bnet::json aFirstPageJson = bnet::HearthstoneApi::makeApiRequest(aApiUrl, aTokenText);
+
+ const int aNumberOfPages{aFirstPageJson["pageCount"]};
+ const int aNumberOfRetrievals{10};
+ REQUIRE(aNumberOfPages >= aNumberOfRetrievals);
+ for (int i{1}; i < aNumberOfRetrievals; ++i) {
+ aApiUrl.setPage(std::to_string(i + 1));
+ aRequests.emplace_back(aApiUrl.text());
+ }
+ std::vector<nlohmann::json> aApiResponses =
+ bnet::HearthstoneApi::makeApiRequest(aRequests, aTokenText);
+ aApiResponses.emplace(aApiResponses.begin(), aFirstPageJson);
+ REQUIRE(aApiResponses.size() == aNumberOfRetrievals);
+ for (const nlohmann::json &aApiResponse : aApiResponses) {
+ REQUIRE(aApiResponse["cards"].size() == 16);
+ }
+}
+
+TEST_CASE("Merge two card lists from two page requests", "[Merge pages]") {
+ std::ifstream aFirstPageFile{"resources/page_merge_00.json"};
+ nlohmann::json aFirstPageJson = nlohmann::json::parse(aFirstPageFile);
+ std::ifstream aSecondPageFile{"resources/page_merge_01.json"};
+ const nlohmann::json aSecondPageJson = nlohmann::json::parse(aSecondPageFile);
+
+ nlohmann::json::reference aMergedCards = aFirstPageJson["cards"];
+ for (auto &card : aSecondPageJson["cards"]) {
+ aMergedCards.emplace_back(std::move(card));
+ }
+ REQUIRE(aMergedCards.size() == 32);
+ std::ofstream aOutputJson("build/output_pages_merge.json");
+ aOutputJson << aMergedCards.dump(4);
+}
+
+TEST_CASE("Retrieve a single page with HearthstoneApi::downloadCards",
+ "[retrievePageOnceHearthstoneApi]") {
+ const std::string aContentType{"cards"};
+ const std::string aRegion{"eu"};
+ bnet::ApiUrl aApiUrl(aContentType, aRegion);
+ aApiUrl.setPage(3);
+ bnet::HearthstoneTokenBuilder aHearthstoneTokenBuilder("resources/credentials.json");
+ const std::string aTokenText{aHearthstoneTokenBuilder.allowBattleNetApiCall()
+ .allowUpdateSourceFile()
+ .buildToken()
+ .getToken()
+ ->text()
+ .value()};
+ nlohmann::json aApiResponse = bnet::HearthstoneApi::makeApiRequest(aApiUrl, aTokenText);
+ const nlohmann::json::size_type aExpectedNumberOfCards{aApiResponse["cards"].size()};
+ aApiResponse =
+ bnet::HearthstoneApi::downloadCards(aApiUrl, *aHearthstoneTokenBuilder.getToken());
+ const nlohmann::json::size_type aCurrentNumberOfCards{aApiResponse["cards"].size()};
+ REQUIRE(aCurrentNumberOfCards == aExpectedNumberOfCards);
+}
diff --git a/battleNetApi/tests/src/tests.cpp b/battleNetApi/tests/src/tests.cpp
deleted file mode 100644
index edc0641..0000000
--- a/battleNetApi/tests/src/tests.cpp
+++ /dev/null
@@ -1,144 +0,0 @@
-#include "apiUrl.hpp"
-#include "hearthstoneApi.hpp"
-#include <catch2/benchmark/catch_benchmark.hpp>
-#include <catch2/benchmark/catch_chronometer.hpp>
-#include <catch2/benchmark/detail/catch_analyse.hpp>
-#include <catch2/benchmark/detail/catch_benchmark_function.hpp>
-#include <catch2/benchmark/detail/catch_estimate_clock.hpp>
-#include <catch2/catch_approx.hpp>
-#include <catch2/catch_config.hpp>
-#include <catch2/catch_test_macros.hpp>
-#include <cstdint>
-#include <fstream>
-#include <nlohmann/json.hpp>
-#include <string>
-#include <tokenBuilder.hpp>
-
-TEST_CASE("Retrieve API Token", "[generateApiToken]") {
- const std::string aCredentialsFile{"tests/resources/credentials.json"};
- Token aToken(aCredentialsFile);
- const std::string aTokenContent{aToken.text()};
- const std::string::size_type aTokenSize{aTokenContent.size()};
- REQUIRE(aTokenSize >= 30);
- REQUIRE(aTokenSize <= 40);
-}
-
-TEST_CASE("Retrieve number of cards", "[countCards]") {
- const std::string aCredentialsFile{};
- const std::string aContentType{"cards"};
- const std::string aRegion{"eu"};
- ApiUrl aApiUrl(aContentType, aRegion);
- aApiUrl.setLocale("fr_FR");
- aApiUrl.setGameMode("constructed");
- aApiUrl.setPageSize("1");
- TokenPool::feedTokenSource("tests/resources/credentials.json");
- const json aResponse =
- HearthstoneApi::makeApiRequest(aApiUrl, TokenPool::build().value().text());
- REQUIRE(aResponse.size() > 0);
- REQUIRE(aResponse.contains("pageCount"));
- std::uint64_t aNumberOfCards{aResponse["pageCount"]};
- std::uint64_t aExpectedNumberOfCards{6178};
- REQUIRE(aNumberOfCards == aExpectedNumberOfCards);
-}
-
-TEST_CASE("Retrieve page once", "[retrievePageOnce]") {
- const std::string aCredentialsFile{"tests/resources/credentials.json"};
- Token aToken(kCredentialsFile);
- const std::string aContentType{"cards"};
- const std::string aRegion{"eu"};
- ApiUrl aApiUrl(aContentType, aRegion);
- aApiUrl.setLocale("fr_FR");
- aApiUrl.setGameMode("constructed");
- aApiUrl.setPageSize("16");
- TokenPool::feedTokenSource("tests/resources/credentials.json");
- const json aApiResponse =
- HearthstoneApi::makeApiRequest(aApiUrl, TokenPool::build().value().text());
- REQUIRE(aApiResponse["cards"].size() == 16);
-}
-
-TEST_CASE("Retrieve pages 10 times without parallelization", "[retrievePagesNoParallel]") {
- const std::string aCredentialsFile{"tests/resources/credentials.json"};
- Token aToken(aCredentialsFile);
- const std::string aContentType{"cards"};
- const std::string aRegion{"eu"};
- ApiUrl aApiUrl(aContentType, aRegion);
- aApiUrl.setLocale("fr_FR");
- aApiUrl.setGameMode("constructed");
- aApiUrl.setPageSize("16");
- aApiUrl.setPage("1");
- TokenPool::feedTokenSource("tests/resources/credentials.json");
- std::string aTokenText{TokenPool::build().value().text()};
- json aApiResponse = HearthstoneApi::makeApiRequest(aApiUrl, aTokenText);
-
- // Retrieve number of pages
- const int aNumberOfRetrievals{10};
- const int aNumberOfPages{aApiResponse["pageCount"]};
- REQUIRE(aNumberOfPages >= aNumberOfRetrievals);
- for (int i{1}; i < aNumberOfRetrievals; ++i) {
- REQUIRE(aApiResponse["cards"].size() == 16);
- aApiUrl.setPage(std::to_string(i + 1));
- aApiResponse = HearthstoneApi::makeApiRequest(aApiUrl, aTokenText);
- }
- REQUIRE(aApiResponse["cards"].size() >= 1);
- REQUIRE(aApiResponse["cards"].size() <= 16);
-}
-
-TEST_CASE("Retrieve pages 10 times with parallelization", "[retrievePagesParallel]") {
- const std::string aCredentialsFile{"tests/resources/credentials.json"};
- Token aToken(kCredentialsFile);
- const std::string aContentType{"cards"};
- const std::string aRegion{"eu"};
- ApiUrl aApiUrl(aContentType, aRegion);
- aApiUrl.setLocale("fr_FR");
- aApiUrl.setGameMode("constructed");
- aApiUrl.setPageSize("16");
- aApiUrl.setPage("1");
- std::vector<std::string> aRequests;
- TokenPool::feedTokenSource("tests/resources/credentials.json");
- std::string aTokenText{TokenPool::build().value().text()};
- json aFirstPageJson = HearthstoneApi::makeApiRequest(aApiUrl, aTokenText);
-
- int kNumberOfPages{aFirstPageJson["pageCount"]};
- const int aNumberOfRetrievals{10};
- REQUIRE(aNumberOfPages >= aNumberOfRetrievals);
- for (int i{1}; i < aNumberOfRetrievals; ++i) {
- aApiUrl.setPage(std::to_string(i + 1));
- aRequests.emplace_back(aApiUrl.text());
- }
- std::vector<json> aApiResponses = HearthstoneApi::makeApiRequest(aRequests, aTokenText);
- aApiResponses.emplace(aApiResponses.begin(), aFirstPageJson);
- REQUIRE(aApiResponses.size() == aNumberOfRetrievals);
- for (const json &aApiResponse : aApiResponses) {
- REQUIRE(aApiResponse["cards"].size() == 16);
- }
-}
-
-TEST_CASE("Merge two card lists from two page requests", "[Merge pages]") {
- std::ifstream aFirstPageFile{"tests/resources/page_merge_00.json"};
- json aFirstPageJson = json::parse(aFirstPageFile);
- std::ifstream aSecondPageFile{"tests/resources/page_merge_01.json"};
- const json aSecondPageJson = json::parse(aSecondPageFile);
-
- json::reference aMergedCards = aFirstPageJson["cards"];
- for (auto &card : aSecondPageJson["cards"]) {
- aMergedCards.emplace_back(std::move(card));
- }
- REQUIRE(aMergedCards.size() == 32);
- std::ofstream aOutputJson("build/output_pages_merge.json");
- aOutputJson << aMergedCards.dump(4);
-}
-
-TEST_CASE("Retrieve a single page with HearthstoneApi::downloadCards",
- "[retrievePageOnceHearthstoneApi]") {
- const std::string aContentType{"cards"};
- const std::string aRegion{"eu"};
- ApiUrl aApiUrl(aContentType, aRegion);
- aApiUrl.setPage(3);
- TokenPool::feedTokenSource("tests/resources/credentials.json");
- json aApiResponse = HearthstoneApi::makeApiRequest(aApiUrl, TokenPool::build().value().text());
- const json::size_type aExpectedNumberOfCards{aApiResponse["cards"].size()};
- TokenPool::feedTokenSource("tests/resources/credentials.json");
- aApiResponse = HearthstoneApi::downloadCards(aApiUrl, TokenPool::build().value());
- const json::size_type aCurrentNumberOfCards{aApiResponse["cards"].size()};
- REQUIRE(aCurrentNumberOfCards == aExpectedNumberOfCards);
-}
diff --git a/battleNetApi/tests/src/tokenTests.cpp b/battleNetApi/tests/src/tokenTests.cpp
index b702024..49e8350 100644
--- a/battleNetApi/tests/src/tokenTests.cpp
+++ b/battleNetApi/tests/src/tokenTests.cpp
@@ -35,7 +35,7 @@ TEST_CASE("Token", "[Change token text]") {
}
TEST_CASE("TokenBuilder", "[Retrieve token from JSON]") {
- bnet::HearthstoneTokenBuilder aTokenBuilder{"resources/credentials.json"};
+ bnet::HearthstoneTokenBuilder aTokenBuilder{"resources/dumb_credentials.json"};
REQUIRE(aTokenBuilder.allowExpiredToken().buildToken().getToken());
REQUIRE(aTokenBuilder.getToken()->text() == "ThisIsTheContentOfTokenContenthehe");
}