summaryrefslogtreecommitdiff
path: root/subprojects/battleNetApi
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/battleNetApi')
-rw-r--r--subprojects/battleNetApi/include/apiUrl.hpp3
-rw-r--r--subprojects/battleNetApi/include/hearthstoneApi.hpp26
-rw-r--r--subprojects/battleNetApi/src/apiUrl.cpp22
-rw-r--r--subprojects/battleNetApi/src/hearthstoneApi.cpp7
-rw-r--r--subprojects/battleNetApi/tests/tests.cpp20
5 files changed, 64 insertions, 14 deletions
diff --git a/subprojects/battleNetApi/include/apiUrl.hpp b/subprojects/battleNetApi/include/apiUrl.hpp
index 12124c6..509b248 100644
--- a/subprojects/battleNetApi/include/apiUrl.hpp
+++ b/subprojects/battleNetApi/include/apiUrl.hpp
@@ -9,7 +9,8 @@ class ApiUrl {
void setRegion(const std::string &iRegion);
void setLocale(const std::string &iLocale);
void setGameMode(const std::string &iGameMode);
- std::string operator()();
+ void setPageSize(const std::string &iPageSize);
+ std::string operator()() const;
private:
std::string mContentType;
diff --git a/subprojects/battleNetApi/include/hearthstoneApi.hpp b/subprojects/battleNetApi/include/hearthstoneApi.hpp
index bbcc8c7..c11acc7 100644
--- a/subprojects/battleNetApi/include/hearthstoneApi.hpp
+++ b/subprojects/battleNetApi/include/hearthstoneApi.hpp
@@ -1,17 +1,41 @@
#pragma once
#include "token.hpp"
+#include <iostream>
+#include <regex>
#include <string>
class HearthstoneApi {
public:
HearthstoneApi(Token &&iToken);
- std::uint64_t numberOfCards();
+ std::uint64_t numberOfCards(const std::string &iApiResponse) const;
private:
std::string authorizationHeader();
std::string makeApiRequest(const std::string &iUrl) const;
static size_t curlCallbackStringOutput(void *iContent, size_t iSize, size_t iNmemb, std::string *iS);
+ /**
+ * @brief
+ * @param[in] iJsonContent The std::string which contains Json (Battle.net API response for instance)
+ * @param[in] iKeyValueRegex The regex used to retrieve value from (key, value) pair
+ * An example: "\"cardCount\":(\\d+)"
+ */
+ template <typename T> T valueInJson(const std::string &iJsonContent, const std::string &iKeyValueRegex) const {
+ const std::regex iRegex{iKeyValueRegex};
+ std::smatch aMatches;
+ if (std::regex_search(iJsonContent, aMatches, iRegex)) {
+ const std::string kValueString{aMatches[1].str()};
+ T aValue;
+ const auto kConversionStatus =
+ std::from_chars(kValueString.data(), kValueString.data() + kValueString.size(), aValue);
+ if (kConversionStatus.ec == std::errc{}) {
+ return aValue;
+ }
+ }
+ std::cerr << std::format("Unable to find value with regex: '{}'\n", iKeyValueRegex);
+ return 0;
+ }
+
Token mToken;
std::string mAuthorizationHeader; //<! Bearer authorization string for OAuth 2.0 header
diff --git a/subprojects/battleNetApi/src/apiUrl.cpp b/subprojects/battleNetApi/src/apiUrl.cpp
index e08c8c7..3de13cd 100644
--- a/subprojects/battleNetApi/src/apiUrl.cpp
+++ b/subprojects/battleNetApi/src/apiUrl.cpp
@@ -4,15 +4,29 @@
ApiUrl::ApiUrl(const std::string &iContentType, const std::string &iRegion)
: mContentType{iContentType}, mRegion{iRegion} {}
void ApiUrl::setRegion(const std::string &iRegion) {
- mRegion = iRegion; //<! eu
+ if (not iRegion.empty()) {
+ mRegion = iRegion; //!< The region of the data to receive, e.g. "eu"
+ }
}
void ApiUrl::setLocale(const std::string &iLocale) {
- aParameters["locale"] = iLocale; //<! fr_FR, ko_KR
+ if (not iLocale.empty()) {
+ aParameters["locale"] = iLocale; //!< The locale to reflect in localized data, e.g. "fr_FR" or "ko_KR"
+ //!< If you do not supply a value, all translations are returned.
+ }
}
void ApiUrl::setGameMode(const std::string &iGameMode) {
- aParameters["gameMode"] = iGameMode; //<! constructed
+ if (not iGameMode.empty()) {
+ aParameters["gameMode"] =
+ iGameMode; //!< A recognized game mode, e.g. "constructed"
+ //!< @see https://community.developer.battle.net/documentation/hearthstone/guides/game-modes
+ }
+}
+void ApiUrl::setPageSize(const std::string &iPageSize) {
+ if (not iPageSize.empty()) {
+ aParameters["pageSize"] = iPageSize; //!< The number of results to choose per page, e.g. "40"
+ }
}
-std::string ApiUrl::operator()() {
+std::string ApiUrl::operator()() const {
std::string aFormattedParameters;
for (const auto &[key, value] : aParameters) {
aFormattedParameters += std::format("&{}={}", key, value);
diff --git a/subprojects/battleNetApi/src/hearthstoneApi.cpp b/subprojects/battleNetApi/src/hearthstoneApi.cpp
index b6eaf71..c34e6ad 100644
--- a/subprojects/battleNetApi/src/hearthstoneApi.cpp
+++ b/subprojects/battleNetApi/src/hearthstoneApi.cpp
@@ -4,11 +4,10 @@
HearthstoneApi::HearthstoneApi(Token &&iToken) : mToken(iToken), mAuthorizationHeader(authorizationHeader()) {}
-std::uint64_t HearthstoneApi::numberOfCards() {
- // TODO: implement logic
- return 123456;
+std::uint64_t HearthstoneApi::numberOfCards(const std::string &iApiResponse) const {
+ const std::string aCardCountRegex{"\"cardCount\":(\\d+)"};
+ return valueInJson<std::uint64_t>(iApiResponse, aCardCountRegex);
}
-
std::string HearthstoneApi::authorizationHeader() { return std::format("Authorization: Bearer {}", mToken.toString()); }
size_t HearthstoneApi::curlCallbackStringOutput(void *iContent, size_t iSize, size_t iNmemb, std::string *iS) {
diff --git a/subprojects/battleNetApi/tests/tests.cpp b/subprojects/battleNetApi/tests/tests.cpp
index 368a767..6513301 100644
--- a/subprojects/battleNetApi/tests/tests.cpp
+++ b/subprojects/battleNetApi/tests/tests.cpp
@@ -22,7 +22,10 @@ class TokenMock {
class HearthstoneApiMock {
public:
HearthstoneApiMock() : mHearthstoneApi(std::move(mToken.getToken())) {};
- std::string makeApiRequest(const std::string &iCardsUrl) { return mHearthstoneApi.makeApiRequest(iCardsUrl); }
+ std::string makeApiRequest(const std::string &iUrl) { return mHearthstoneApi.makeApiRequest(iUrl); }
+ std::uint64_t numberOfCards(const std::string &iApiResponse) {
+ return mHearthstoneApi.numberOfCards(iApiResponse);
+ };
private:
TokenMock mToken;
@@ -38,9 +41,16 @@ TEST_CASE("Retrieve API Token", "[getApiToken]") {
REQUIRE(kTokenSize <= 40);
}
-TEST_CASE("Retrieve number of pages", "[getPagesCount]") {
+TEST_CASE("Retrieve number of cards", "[getCardsCount]") {
HearthstoneApiMock aHearthstoneApi;
- // std::cout << aHearthstoneApi.numberOfCards() << '\n';
+ const std::string kContentType{"cards"};
+ const std::string kRegion{"eu"};
+ ApiUrl aApiUrl(kContentType, kRegion);
+ aApiUrl.setLocale("fr_FR");
+ aApiUrl.setGameMode("constructed");
+ aApiUrl.setPageSize("1");
+ std::uint64_t kNumberOfCards{aHearthstoneApi.numberOfCards(aHearthstoneApi.makeApiRequest(aApiUrl()))};
+ std::cout << std::format("Number of cards: {}", kNumberOfCards) << '\n';
}
TEST_CASE("Retrieve cards", "[retrieveCards]") {
@@ -50,5 +60,7 @@ TEST_CASE("Retrieve cards", "[retrieveCards]") {
ApiUrl aApiUrl(kContentType, kRegion);
aApiUrl.setLocale("fr_FR");
aApiUrl.setGameMode("constructed");
- std::cout << aHearthstoneApi.makeApiRequest(aApiUrl()) << '\n';
+ aApiUrl.setPageSize("10");
+ const std::string kApiResponse{aHearthstoneApi.makeApiRequest(aApiUrl())};
+ REQUIRE(kApiResponse.size() > 300);
}