diff --git a/partners_api/partners_api_tests/taxi_engine_tests.cpp b/partners_api/partners_api_tests/taxi_engine_tests.cpp index 7856260ebe..ab61f384b2 100644 --- a/partners_api/partners_api_tests/taxi_engine_tests.cpp +++ b/partners_api/partners_api_tests/taxi_engine_tests.cpp @@ -10,13 +10,14 @@ namespace { -std::vector GetUberSynchronous(ms::LatLon const & from, ms::LatLon const & to) +std::vector GetUberSynchronous(ms::LatLon const & from, ms::LatLon const & to, + std::string const & url) { std::string times; std::string prices; - TEST(taxi::uber::RawApi::GetEstimatedTime(from, times), ()); - TEST(taxi::uber::RawApi::GetEstimatedPrice(from, to, prices), ()); + TEST(taxi::uber::RawApi::GetEstimatedTime(from, times, url), ()); + TEST(taxi::uber::RawApi::GetEstimatedPrice(from, to, prices, url), ()); size_t reqId = 0; taxi::uber::ProductMaker maker; @@ -32,24 +33,26 @@ std::vector GetUberSynchronous(ms::LatLon const & from, ms::LatLo return uberProducts; } -std::vector GetYandexSynchronous(ms::LatLon const & from, ms::LatLon const & to) +std::vector GetYandexSynchronous(ms::LatLon const & from, ms::LatLon const & to, + std::string const & url) { std::string yandexAnswer; std::vector yandexProducts; - TEST(taxi::yandex::RawApi::GetTaxiInfo(from, to, yandexAnswer), ()); + TEST(taxi::yandex::RawApi::GetTaxiInfo(from, to, yandexAnswer, url), ()); taxi::yandex::MakeFromJson(yandexAnswer, yandexProducts); return yandexProducts; } -taxi::ProvidersContainer GetProvidersSynchronous(ms::LatLon const & from, ms::LatLon const & to) +taxi::ProvidersContainer GetProvidersSynchronous(ms::LatLon const & from, ms::LatLon const & to, + std::string const & url) { taxi::ProvidersContainer providers; - providers.emplace_back(taxi::Provider::Type::Uber, GetUberSynchronous(from, to)); - providers.emplace_back(taxi::Provider::Type::Yandex, GetYandexSynchronous(from, to)); + providers.emplace_back(taxi::Provider::Type::Uber, GetUberSynchronous(from, to, url)); + providers.emplace_back(taxi::Provider::Type::Yandex, GetYandexSynchronous(from, to, url)); return providers; } @@ -189,12 +192,7 @@ UNIT_TEST(TaxiEngine_Smoke) taxi::ProvidersContainer providersContainer; ms::LatLon const from(38.897724, -77.036531); ms::LatLon const to(38.862416, -76.883316); - - taxi::uber::SetUberUrlForTesting("http://localhost:34568/partners"); - taxi::yandex::SetYandexUrlForTesting("http://localhost:34568/partners"); - - MY_SCOPE_GUARD(cleanupUber, []() { taxi::uber::SetUberUrlForTesting(""); }); - MY_SCOPE_GUARD(cleanupYandex, []() { taxi::yandex::SetYandexUrlForTesting(""); }); + std::string const kTesturl = "http://localhost:34568/partners"; auto const errorCallback = [](taxi::ErrorsContainer const & errors, uint64_t const requestId) { TEST(false, ()); @@ -221,11 +219,11 @@ UNIT_TEST(TaxiEngine_Smoke) testing::StopEventLoop(); }; - taxi::ProvidersContainer const synchronousProviders = GetProvidersSynchronous(from, to); + taxi::ProvidersContainer const synchronousProviders = GetProvidersSynchronous(from, to, kTesturl); { - taxi::Engine engine; - + taxi::Engine engine({{taxi::Provider::Type::Uber, kTesturl}, + {taxi::Provider::Type::Yandex, kTesturl}}); { lock_guard lock(resultsMutex); reqId = engine.GetAvailableProducts( diff --git a/partners_api/partners_api_tests/uber_tests.cpp b/partners_api/partners_api_tests/uber_tests.cpp index e8959c458e..73d67896ae 100644 --- a/partners_api/partners_api_tests/uber_tests.cpp +++ b/partners_api/partners_api_tests/uber_tests.cpp @@ -4,8 +4,6 @@ #include "geometry/latlon.hpp" -#include "base/scope_guard.hpp" - #include "std/algorithm.hpp" #include "std/atomic.hpp" #include "std/mutex.hpp" @@ -167,13 +165,10 @@ UNIT_TEST(Uber_ProductMaker) UNIT_TEST(Uber_GetAvailableProducts) { - taxi::uber::Api api; + taxi::uber::Api api("http://localhost:34568/partners"); ms::LatLon const from(55.796918, 37.537859); ms::LatLon const to(55.758213, 37.616093); - taxi::uber::SetUberUrlForTesting("http://localhost:34568/partners"); - MY_SCOPE_GUARD(cleanup, []() { taxi::uber::SetUberUrlForTesting(""); }); - std::vector resultProducts; api.GetAvailableProducts(from, to, @@ -181,7 +176,10 @@ UNIT_TEST(Uber_GetAvailableProducts) resultProducts = products; testing::StopEventLoop(); }, - [](taxi::ErrorCode const code) { TEST(false, ()); }); + [](taxi::ErrorCode const code) { + LOG(LWARNING, (code)); + testing::StopEventLoop(); + }); testing::RunEventLoop(); diff --git a/partners_api/partners_api_tests/yandex_tests.cpp b/partners_api/partners_api_tests/yandex_tests.cpp index e2b4f999bb..e188997189 100644 --- a/partners_api/partners_api_tests/yandex_tests.cpp +++ b/partners_api/partners_api_tests/yandex_tests.cpp @@ -4,8 +4,6 @@ #include "geometry/latlon.hpp" -#include "base/scope_guard.hpp" - namespace { UNIT_TEST(Yandex_GetTaxiInfo) @@ -21,13 +19,10 @@ UNIT_TEST(Yandex_GetTaxiInfo) UNIT_TEST(Yandex_GetAvailableProducts) { - taxi::yandex::Api api; + taxi::yandex::Api api("http://localhost:34568/partners"); ms::LatLon const from(55.796918, 37.537859); ms::LatLon const to(55.758213, 37.616093); - taxi::yandex::SetYandexUrlForTesting("http://localhost:34568/partners"); - MY_SCOPE_GUARD(cleanup, []() { taxi::yandex::SetYandexUrlForTesting(""); }); - std::vector resultProducts; api.GetAvailableProducts(from, to, @@ -35,7 +30,10 @@ UNIT_TEST(Yandex_GetAvailableProducts) resultProducts = products; testing::StopEventLoop(); }, - [](taxi::ErrorCode const code) { TEST(false, ()); }); + [](taxi::ErrorCode const code) { + LOG(LWARNING, (code)); + testing::StopEventLoop(); + }); testing::RunEventLoop(); diff --git a/partners_api/taxi_engine.cpp b/partners_api/taxi_engine.cpp index b843394722..695f95ef74 100644 --- a/partners_api/taxi_engine.cpp +++ b/partners_api/taxi_engine.cpp @@ -107,13 +107,13 @@ void ResultMaker::DecrementRequestCount() } // Engine ----------------------------------------------------------------------------------------- -Engine::Engine() +Engine::Engine(std::vector urls /* = {} */) { m_enabledCountries = {{Provider::Type::Yandex, {"Russian Federation"}}}; m_disabledCountries = {{Provider::Type::Uber, {"Russian Federation"}}}; - m_apis.emplace_back(Provider::Type::Yandex, my::make_unique()); - m_apis.emplace_back(Provider::Type::Uber, my::make_unique()); + AddApi(urls, Provider::Type::Yandex); + AddApi(urls, Provider::Type::Uber); } /// Requests list of available products. Returns request identificator immediately. @@ -210,4 +210,18 @@ bool Engine::IsAnyCountryEnabled(Provider::Type type, return false; } + +template +void Engine::AddApi(std::vector const & urls, Provider::Type type) +{ + auto const it = std::find_if(urls.cbegin(), urls.cend(), [type](ProviderUrl const & item) + { + return item.m_type == type; + }); + + if (it != urls.cend()) + m_apis.emplace_back(type, my::make_unique(it->m_url)); + else + m_apis.emplace_back(type, my::make_unique()); +} } // namespace taxi diff --git a/partners_api/taxi_engine.hpp b/partners_api/taxi_engine.hpp index 31b494bf86..d7e13bcd44 100644 --- a/partners_api/taxi_engine.hpp +++ b/partners_api/taxi_engine.hpp @@ -47,10 +47,16 @@ private: ProvidersContainer m_providers; }; +struct ProviderUrl +{ + Provider::Type m_type; + std::string m_url; +}; + class Engine final { public: - Engine(); + explicit Engine(std::vector urls = {}); /// Requests list of available products. Returns request identificator immediately. uint64_t GetAvailableProducts(ms::LatLon const & from, ms::LatLon const & to, @@ -66,6 +72,9 @@ private: bool IsAllCountriesDisabled(Provider::Type type, storage::TCountriesVec const & countryIds) const; bool IsAnyCountryEnabled(Provider::Type type, storage::TCountriesVec const & countryIds) const; + template + void AddApi(std::vector const & urls, Provider::Type type); + using ApiPtr = std::unique_ptr; struct ApiContainerItem diff --git a/partners_api/uber_api.cpp b/partners_api/uber_api.cpp index e7c779834d..0214421332 100644 --- a/partners_api/uber_api.cpp +++ b/partners_api/uber_api.cpp @@ -18,9 +18,6 @@ using namespace platform; namespace { -string const kUberEstimatesUrl = "https://api.uber.com/v1/estimates"; -string g_uberUrlForTesting = ""; - bool RunSimpleHttpRequest(string const & url, string & result) { HttpClient request(url); @@ -115,14 +112,6 @@ void MakeFromJson(char const * times, char const * prices, vector products.clear(); } } - -string GetUberURL() -{ - if (!g_uberUrlForTesting.empty()) - return g_uberUrlForTesting; - - return kUberEstimatesUrl; -} } // namespace namespace taxi @@ -130,33 +119,33 @@ namespace taxi namespace uber { // static -bool RawApi::GetProducts(ms::LatLon const & pos, string & result) +bool RawApi::GetProducts(ms::LatLon const & pos, string & result, + std::string const & baseUrl /* = kProductsUrl */) { - stringstream url; - url << fixed << setprecision(6) - << "https://api.uber.com/v1/products?server_token=" << UBER_SERVER_TOKEN + ostringstream url; + url << fixed << setprecision(6) << baseUrl << "?server_token=" << UBER_SERVER_TOKEN << "&latitude=" << pos.lat << "&longitude=" << pos.lon; return RunSimpleHttpRequest(url.str(), result); } // static -bool RawApi::GetEstimatedTime(ms::LatLon const & pos, string & result) +bool RawApi::GetEstimatedTime(ms::LatLon const & pos, string & result, + std::string const & baseUrl /* = kEstimatesUrl */) { - stringstream url; - url << fixed << setprecision(6) - << GetUberURL() << "/time?server_token=" << UBER_SERVER_TOKEN + ostringstream url; + url << fixed << setprecision(6) << baseUrl << "/time?server_token=" << UBER_SERVER_TOKEN << "&start_latitude=" << pos.lat << "&start_longitude=" << pos.lon; return RunSimpleHttpRequest(url.str(), result); } // static -bool RawApi::GetEstimatedPrice(ms::LatLon const & from, ms::LatLon const & to, string & result) +bool RawApi::GetEstimatedPrice(ms::LatLon const & from, ms::LatLon const & to, string & result, + std::string const & baseUrl /* = kEstimatesUrl */) { - stringstream url; - url << fixed << setprecision(6) - << GetUberURL() << "/price?server_token=" << UBER_SERVER_TOKEN + ostringstream url; + url << fixed << setprecision(6) << baseUrl << "/price?server_token=" << UBER_SERVER_TOKEN << "&start_latitude=" << from.lat << "&start_longitude=" << from.lon << "&end_latitude=" << to.lat << "&end_longitude=" << to.lon; @@ -226,13 +215,14 @@ void Api::GetAvailableProducts(ms::LatLon const & from, ms::LatLon const & to, auto const reqId = ++m_requestId; auto const maker = m_maker; + auto const baseUrl = m_baseUrl; maker->Reset(reqId); - threads::SimpleThread([maker, from, reqId, successFn, errorFn]() + threads::SimpleThread([maker, from, reqId, baseUrl, successFn, errorFn]() { string result; - if (!RawApi::GetEstimatedTime(from, result)) + if (!RawApi::GetEstimatedTime(from, result, baseUrl)) { errorFn(ErrorCode::RemoteError); return; @@ -242,10 +232,10 @@ void Api::GetAvailableProducts(ms::LatLon const & from, ms::LatLon const & to, maker->MakeProducts(reqId, successFn, errorFn); }).detach(); - threads::SimpleThread([maker, from, to, reqId, successFn, errorFn]() + threads::SimpleThread([maker, from, to, reqId, baseUrl, successFn, errorFn]() { string result; - if (!RawApi::GetEstimatedPrice(from, to, result)) + if (!RawApi::GetEstimatedPrice(from, to, result, baseUrl)) { errorFn(ErrorCode::RemoteError); return; @@ -267,10 +257,5 @@ RideRequestLinks Api::GetRideRequestLinks(string const & productId, ms::LatLon c return {"uber://" + url.str(), "https://m.uber.com/ul" + url.str()}; } - -void SetUberUrlForTesting(string const & url) -{ - g_uberUrlForTesting = url; -} } // namespace uber } // namespace taxi diff --git a/partners_api/uber_api.hpp b/partners_api/uber_api.hpp index 205f4537aa..ededd975b4 100644 --- a/partners_api/uber_api.hpp +++ b/partners_api/uber_api.hpp @@ -23,6 +23,8 @@ namespace taxi { namespace uber { +string const kEstimatesUrl = "https://api.uber.com/v1/estimates"; +string const kProductsUrl = "https://api.uber.com/v1/products"; /// Uber api wrapper based on synchronous http requests. class RawApi { @@ -31,19 +33,22 @@ public: /// otherwise returns false. The response contains the display name and other details about each /// product, and lists the products in the proper display order. This endpoint does not reflect /// real-time availability of the products. - static bool GetProducts(ms::LatLon const & pos, string & result); + static bool GetProducts(ms::LatLon const & pos, string & result, + std::string const & url = kProductsUrl); /// Returns true when http request was executed successfully and response copied into @result, /// otherwise returns false. The response contains ETAs for all products currently available /// at a given location, with the ETA for each product expressed as integers in seconds. If a /// product returned from GetProducts is not returned from this endpoint for a given /// latitude/longitude pair then there are currently none of that product available to request. /// Call this endpoint every minute to provide the most accurate, up-to-date ETAs. - static bool GetEstimatedTime(ms::LatLon const & pos, string & result); + static bool GetEstimatedTime(ms::LatLon const & pos, string & result, + std::string const & url = kEstimatesUrl); /// Returns true when http request was executed successfully and response copied into @result, /// otherwise returns false. The response contains an estimated price range for each product /// offered at a given location. The price estimate is provided as a formatted string with the /// full price range and the localized currency symbol. - static bool GetEstimatedPrice(ms::LatLon const & from, ms::LatLon const & to, string & result); + static bool GetEstimatedPrice(ms::LatLon const & from, ms::LatLon const & to, string & result, + std::string const & url = kEstimatesUrl); }; /// Class which used for making products from http requests results. @@ -66,6 +71,7 @@ private: class Api : public ApiBase { public: + explicit Api(std::string const & baseUrl = kEstimatesUrl) : m_baseUrl(baseUrl) {} // ApiBase overrides: /// Requests list of available products from Uber. void GetAvailableProducts(ms::LatLon const & from, ms::LatLon const & to, @@ -79,6 +85,7 @@ public: private: shared_ptr m_maker = make_shared(); uint64_t m_requestId = 0; + string const m_baseUrl; }; void SetUberUrlForTesting(string const & url); diff --git a/partners_api/yandex_api.cpp b/partners_api/yandex_api.cpp index b2edc8584d..4c8b5b430c 100644 --- a/partners_api/yandex_api.cpp +++ b/partners_api/yandex_api.cpp @@ -17,9 +17,6 @@ namespace { -std::string const kTaxiInfoUrl = "https://taxi-routeinfo.taxi.yandex.net"; -std::string g_yandexUrlForTesting = ""; - bool RunSimpleHttpRequest(std::string const & url, std::string & result) { platform::HttpClient request(url); @@ -46,27 +43,19 @@ bool CheckYandexResponse(json_t const * answer) return true; } - -std::string GetYandexURL() -{ - if (!g_yandexUrlForTesting.empty()) - return g_yandexUrlForTesting; - - return kTaxiInfoUrl; -} } // namespace namespace taxi { namespace yandex { -bool RawApi::GetTaxiInfo(ms::LatLon const & from, ms::LatLon const & to, std::string & result) +bool RawApi::GetTaxiInfo(ms::LatLon const & from, ms::LatLon const & to, std::string & result, + std::string const & baseUrl /* = kTaxiInfoUrl */) { std::ostringstream url; - url << std::fixed << std::setprecision(6) << GetYandexURL() - << "/taxi_info?clid=" << YANDEX_CLIENT_ID << "&apikey=" << YANDEX_API_KEY - << "&rll=" << from.lon << "," << from.lat << "~" << to.lon << "," << to.lat - << "&class=econom,business,comfortplus,minivan,vip"; + url << std::fixed << std::setprecision(6) << baseUrl << "/taxi_info?clid=" << YANDEX_CLIENT_ID + << "&apikey=" << YANDEX_API_KEY << "&rll=" << from.lon << "," << from.lat << "~" << to.lon + << "," << to.lat << "&class=econom,business,comfortplus,minivan,vip"; return RunSimpleHttpRequest(url.str(), result); } @@ -79,10 +68,12 @@ void Api::GetAvailableProducts(ms::LatLon const & from, ms::LatLon const & to, ASSERT(successFn, ()); ASSERT(errorFn, ()); - threads::SimpleThread([from, to, successFn, errorFn]() + auto const baseUrl = m_baseUrl; + + threads::SimpleThread([from, to, baseUrl, successFn, errorFn]() { std::string result; - if (!RawApi::GetTaxiInfo(from, to, result)) + if (!RawApi::GetTaxiInfo(from, to, result, baseUrl)) { errorFn(ErrorCode::RemoteError); return; @@ -153,10 +144,5 @@ void MakeFromJson(std::string const & src, std::vector & products products.push_back(move(product)); } } - -void SetYandexUrlForTesting(std::string const & url) -{ - g_yandexUrlForTesting = url; -} } // namespace yandex } // namespace taxi diff --git a/partners_api/yandex_api.hpp b/partners_api/yandex_api.hpp index 85d5bcfaf3..06791ebe78 100644 --- a/partners_api/yandex_api.hpp +++ b/partners_api/yandex_api.hpp @@ -13,17 +13,20 @@ namespace taxi { namespace yandex { +std::string const kTaxiInfoUrl = "https://taxi-routeinfo.taxi.yandex.net"; /// Yandex api wrapper based on synchronous http requests. class RawApi { public: - static bool GetTaxiInfo(ms::LatLon const & from, ms::LatLon const & to, std::string & result); + static bool GetTaxiInfo(ms::LatLon const & from, ms::LatLon const & to, std::string & result, + std::string const & url = kTaxiInfoUrl); }; /// Class which used for making products from http requests results. class Api : public ApiBase { public: + explicit Api(std::string const & baseUrl = kTaxiInfoUrl) : m_baseUrl(baseUrl) {} // ApiBase overrides: /// Requests list of available products from Yandex. void GetAvailableProducts(ms::LatLon const & from, ms::LatLon const & to, @@ -33,9 +36,11 @@ public: /// Returns link which allows you to launch the Yandex app. RideRequestLinks GetRideRequestLinks(std::string const & productId, ms::LatLon const & from, ms::LatLon const & to) const override; + +private: + std::string const m_baseUrl; }; void MakeFromJson(std::string const & src, std::vector & products); -void SetYandexUrlForTesting(std::string const & url); } // namespace yandex } // namespace taxi