Skip to content

Commit 81a7cee

Browse files
VladyslavTsymbalVladyslav Tsymbal
andauthored
Add Delegate interface for OlpClient (#1709)
Added a delegate interface for OlpClient to allow for better testing and mocking of the client behavior. Implemented a mock version of the delegate to facilitate unit tests. Solves the issue of testing OlpClient without relying on actual network calls. Relates-To: HERESDK-12772 Signed-off-by: Vladyslav Tsymbal <ext-vladyslav.tsymbal@here.com> Co-authored-by: Vladyslav Tsymbal <ext-vladyslav.tsymbal@here.com>
1 parent 317d567 commit 81a7cee

3 files changed

Lines changed: 263 additions & 42 deletions

File tree

olp-cpp-sdk-core/include/olp/core/client/OlpClient.h

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,56 @@ class CORE_API OlpClient {
4545
using RequestBodyType = std::shared_ptr<std::vector<std::uint8_t>>;
4646

4747
OlpClient();
48+
/**
49+
* @brief Abstract delegate interface for the `OlpClient` implementation.
50+
*
51+
* Implement this interface to inject a custom (e.g. test/mock)
52+
* implementation into `OlpClient` via the
53+
* `OlpClient(std::shared_ptr<Delegate>)` constructor. The production
54+
* implementation is created automatically by the other constructors.
55+
*/
56+
class CORE_API Delegate {
57+
public:
58+
virtual ~Delegate() = default;
59+
60+
/// @copydoc OlpClient::SetBaseUrl
61+
virtual void SetBaseUrl(const std::string& base_url) = 0;
62+
/// @copydoc OlpClient::GetBaseUrl
63+
virtual std::string GetBaseUrl() const = 0;
64+
/// @copydoc OlpClient::GetMutableDefaultHeaders
65+
virtual ParametersType& GetMutableDefaultHeaders() = 0;
66+
/// @copydoc OlpClient::GetSettings
67+
virtual const OlpClientSettings& GetSettings() const = 0;
68+
69+
/// @copydoc OlpClient::CallApi(const std::string&, const std::string&,
70+
/// const ParametersType&, const ParametersType&,
71+
/// const ParametersType&, const RequestBodyType&,
72+
/// const std::string&, const NetworkAsyncCallback&)
73+
virtual CancellationToken CallApi(
74+
const std::string& path, const std::string& method,
75+
const ParametersType& query_params, const ParametersType& header_params,
76+
const ParametersType& form_params, const RequestBodyType& post_body,
77+
const std::string& content_type,
78+
const NetworkAsyncCallback& callback) const = 0;
79+
80+
/// @copydoc OlpClient::CallApi(std::string, std::string, ParametersType,
81+
/// ParametersType, ParametersType, RequestBodyType, std::string,
82+
/// CancellationContext)
83+
virtual HttpResponse CallApi(std::string path, std::string method,
84+
ParametersType query_params,
85+
ParametersType header_params,
86+
ParametersType form_params,
87+
RequestBodyType post_body,
88+
std::string content_type,
89+
CancellationContext context) const = 0;
90+
91+
/// @copydoc OlpClient::CallApiStream
92+
virtual HttpResponse CallApiStream(
93+
std::string path, std::string method, ParametersType query_params,
94+
ParametersType header_params, http::Network::DataCallback data_callback,
95+
RequestBodyType post_body, std::string content_type,
96+
CancellationContext context) const = 0;
97+
};
4898

4999
/**
50100
* @brief Creates the `OlpClient` instance.
@@ -53,7 +103,19 @@ class CORE_API OlpClient {
53103
* @param base_url The base URL to be used for all outgoing requests.
54104
*/
55105
OlpClient(const OlpClientSettings& settings, std::string base_url);
56-
virtual ~OlpClient();
106+
107+
/**
108+
* @brief Creates the `OlpClient` instance with a custom delegate.
109+
*
110+
* Use this constructor to inject a test or mock implementation.
111+
* The supplied @p delegate must not be null.
112+
*
113+
* @param delegate A non-null shared pointer to a custom `Delegate`
114+
* implementation.
115+
*/
116+
explicit OlpClient(std::shared_ptr<Delegate> delegate);
117+
118+
~OlpClient();
57119

58120
/// A copy constructor.
59121
OlpClient(const OlpClient&);
@@ -180,8 +242,7 @@ class CORE_API OlpClient {
180242
CancellationContext context) const;
181243

182244
private:
183-
class OlpClientImpl;
184-
std::shared_ptr<OlpClientImpl> impl_;
245+
std::shared_ptr<Delegate> impl_;
185246
};
186247

187248
} // namespace client

olp-cpp-sdk-core/src/client/OlpClient.cpp

Lines changed: 80 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -456,41 +456,57 @@ bool IsPending(const PendingUrlRequestPtr& request) {
456456

457457
} // namespace
458458

459-
class OlpClient::OlpClientImpl {
459+
class OlpClientImpl : public OlpClient::Delegate {
460460
public:
461461
OlpClientImpl();
462+
using ParametersType = OlpClient::ParametersType;
463+
using RequestBodyType = OlpClient::RequestBodyType;
464+
462465
OlpClientImpl(const OlpClientSettings& settings, std::string base_url);
463-
~OlpClientImpl() = default;
466+
~OlpClientImpl() override = default;
464467

465-
void SetBaseUrl(const std::string& base_url);
466-
std::string GetBaseUrl() const;
468+
void SetBaseUrl(const std::string& base_url) override;
469+
std::string GetBaseUrl() const override;
467470

468-
ParametersType& GetMutableDefaultHeaders();
469-
const OlpClientSettings& GetSettings() const { return settings_; }
471+
ParametersType& GetMutableDefaultHeaders() override;
472+
const OlpClientSettings& GetSettings() const override { return settings_; }
470473

471-
CancellationToken CallApi(const std::string& path, const std::string& method,
472-
const ParametersType& query_params,
473-
const ParametersType& header_params,
474-
const ParametersType& form_params,
475-
const RequestBodyType& post_body,
476-
const std::string& content_type,
477-
const NetworkAsyncCallback& callback) const;
474+
CancellationToken CallApi(
475+
const std::string& path, const std::string& method,
476+
const ParametersType& query_params, const ParametersType& header_params,
477+
const ParametersType& form_params, const RequestBodyType& post_body,
478+
const std::string& content_type,
479+
const NetworkAsyncCallback& callback) const override;
478480

479481
HttpResponse CallApi(std::string path, std::string method,
480482
ParametersType query_params,
481-
ParametersType header_params,
482-
http::Network::DataCallback data_callback,
483+
ParametersType header_params, ParametersType form_params,
483484
RequestBodyType post_body, std::string content_type,
484-
CancellationContext context) const;
485+
CancellationContext context) const override;
486+
487+
HttpResponse CallApiStream(std::string path, std::string method,
488+
ParametersType query_params,
489+
ParametersType header_params,
490+
http::Network::DataCallback data_callback,
491+
RequestBodyType post_body,
492+
std::string content_type,
493+
CancellationContext context) const override;
485494

486495
std::shared_ptr<http::NetworkRequest> CreateRequest(
487496
const std::string& path, const std::string& method,
488497
const ParametersType& query_params, const ParametersType& header_params,
489498
const RequestBodyType& post_body, const std::string& content_type) const;
490499

491500
porting::optional<ApiError> AddBearer(bool query_empty,
492-
http::NetworkRequest& request,
493-
CancellationContext& context) const;
501+
http::NetworkRequest& request,
502+
CancellationContext& context) const;
503+
504+
HttpResponse CallApiImpl(std::string path, std::string method,
505+
ParametersType query_params,
506+
ParametersType header_params,
507+
http::Network::DataCallback data_callback,
508+
RequestBodyType post_body, std::string content_type,
509+
CancellationContext context) const;
494510

495511
private:
496512
using MutexType = std::shared_mutex;
@@ -504,29 +520,26 @@ class OlpClient::OlpClientImpl {
504520
bool ValidateBaseUrl() const;
505521
};
506522

507-
OlpClient::OlpClientImpl::OlpClientImpl()
523+
OlpClientImpl::OlpClientImpl()
508524
: pending_requests_{std::make_shared<PendingUrlRequests>()} {}
509525

510-
OlpClient::OlpClientImpl::OlpClientImpl(const OlpClientSettings& settings,
511-
std::string base_url)
526+
OlpClientImpl::OlpClientImpl(const OlpClientSettings& settings,
527+
std::string base_url)
512528
: base_url_{std::move(base_url)},
513529
settings_{settings},
514530
pending_requests_{std::make_shared<PendingUrlRequests>()} {}
515531

516-
void OlpClient::OlpClientImpl::SetBaseUrl(const std::string& base_url) {
532+
void OlpClientImpl::SetBaseUrl(const std::string& base_url) {
517533
base_url_.lockedAssign(base_url);
518534
}
519535

520-
std::string OlpClient::OlpClientImpl::GetBaseUrl() const {
521-
return base_url_.lockedCopy();
522-
}
536+
std::string OlpClientImpl::GetBaseUrl() const { return base_url_.lockedCopy(); }
523537

524-
OlpClient::ParametersType&
525-
OlpClient::OlpClientImpl::GetMutableDefaultHeaders() {
538+
OlpClient::ParametersType& OlpClientImpl::GetMutableDefaultHeaders() {
526539
return default_headers_;
527540
}
528541

529-
porting::optional<client::ApiError> OlpClient::OlpClientImpl::AddBearer(
542+
porting::optional<client::ApiError> OlpClientImpl::AddBearer(
530543
bool query_empty, http::NetworkRequest& request,
531544
CancellationContext& context) const {
532545
const auto& settings = settings_.authentication_settings;
@@ -566,14 +579,14 @@ porting::optional<client::ApiError> OlpClient::OlpClientImpl::AddBearer(
566579
return porting::none;
567580
}
568581

569-
bool OlpClient::OlpClientImpl::ValidateBaseUrl() const {
582+
bool OlpClientImpl::ValidateBaseUrl() const {
570583
return base_url_.locked([](const std::string& base_url) {
571584
return base_url == "" || (base_url.find(kHttpPrefix) != std::string::npos ||
572585
base_url.find(kHttpsPrefix) != std::string::npos);
573586
});
574587
}
575588

576-
std::shared_ptr<http::NetworkRequest> OlpClient::OlpClientImpl::CreateRequest(
589+
std::shared_ptr<http::NetworkRequest> OlpClientImpl::CreateRequest(
577590
const std::string& path, const std::string& method,
578591
const OlpClient::ParametersType& query_params,
579592
const OlpClient::ParametersType& header_params,
@@ -612,7 +625,7 @@ std::shared_ptr<http::NetworkRequest> OlpClient::OlpClientImpl::CreateRequest(
612625
return network_request;
613626
}
614627

615-
CancellationToken OlpClient::OlpClientImpl::CallApi(
628+
CancellationToken OlpClientImpl::CallApi(
616629
const std::string& path, const std::string& method,
617630
const OlpClient::ParametersType& query_params,
618631
const OlpClient::ParametersType& header_params,
@@ -706,7 +719,33 @@ CancellationToken OlpClient::OlpClientImpl::CallApi(
706719
return cancellation_token;
707720
}
708721

709-
HttpResponse OlpClient::OlpClientImpl::CallApi(
722+
HttpResponse OlpClientImpl::CallApi(std::string path, std::string method,
723+
OlpClient::ParametersType query_params,
724+
OlpClient::ParametersType header_params,
725+
OlpClient::ParametersType /*form_params*/,
726+
OlpClient::RequestBodyType post_body,
727+
std::string content_type,
728+
CancellationContext context) const {
729+
return CallApiImpl(std::move(path), std::move(method),
730+
std::move(query_params), std::move(header_params), nullptr,
731+
std::move(post_body), std::move(content_type),
732+
std::move(context));
733+
}
734+
735+
HttpResponse OlpClientImpl::CallApiStream(
736+
std::string path, std::string method,
737+
OlpClient::ParametersType query_params,
738+
OlpClient::ParametersType header_params,
739+
http::Network::DataCallback data_callback,
740+
OlpClient::RequestBodyType post_body, std::string content_type,
741+
CancellationContext context) const {
742+
return CallApiImpl(std::move(path), std::move(method),
743+
std::move(query_params), std::move(header_params),
744+
std::move(data_callback), std::move(post_body),
745+
std::move(content_type), std::move(context));
746+
}
747+
748+
HttpResponse OlpClientImpl::CallApiImpl(
710749
std::string path, std::string method,
711750
OlpClient::ParametersType query_params,
712751
OlpClient::ParametersType header_params,
@@ -831,6 +870,8 @@ HttpResponse OlpClient::OlpClientImpl::CallApi(
831870
OlpClient::OlpClient() : impl_(std::make_shared<OlpClientImpl>()) {}
832871
OlpClient::OlpClient(const OlpClientSettings& settings, std::string base_url)
833872
: impl_(std::make_shared<OlpClientImpl>(settings, std::move(base_url))) {}
873+
OlpClient::OlpClient(std::shared_ptr<Delegate> delegate)
874+
: impl_(std::move(delegate)) {}
834875
OlpClient::~OlpClient() = default;
835876
OlpClient::OlpClient(const OlpClient&) = default;
836877
OlpClient& OlpClient::operator=(const OlpClient&) = default;
@@ -864,14 +905,14 @@ CancellationToken OlpClient::CallApi(
864905
HttpResponse OlpClient::CallApi(std::string path, std::string method,
865906
ParametersType query_params,
866907
ParametersType header_params,
867-
ParametersType /*form_params*/,
908+
ParametersType form_params,
868909
RequestBodyType post_body,
869910
std::string content_type,
870911
CancellationContext context) const {
871912
return impl_->CallApi(std::move(path), std::move(method),
872913
std::move(query_params), std::move(header_params),
873-
nullptr, std::move(post_body), std::move(content_type),
874-
std::move(context));
914+
std::move(form_params), std::move(post_body),
915+
std::move(content_type), std::move(context));
875916
}
876917

877918
HttpResponse OlpClient::CallApiStream(std::string path, std::string method,
@@ -881,10 +922,10 @@ HttpResponse OlpClient::CallApiStream(std::string path, std::string method,
881922
RequestBodyType post_body,
882923
std::string content_type,
883924
CancellationContext context) const {
884-
return impl_->CallApi(std::move(path), std::move(method),
885-
std::move(query_params), std::move(header_params),
886-
std::move(data_callback), std::move(post_body),
887-
std::move(content_type), std::move(context));
925+
return impl_->CallApiStream(std::move(path), std::move(method),
926+
std::move(query_params), std::move(header_params),
927+
std::move(data_callback), std::move(post_body),
928+
std::move(content_type), std::move(context));
888929
}
889930

890931
} // namespace client

0 commit comments

Comments
 (0)