Remove web::uri usage from public API (#7834)

This commit is contained in:
BrennanConroy 2019-02-23 13:35:37 -08:00 committed by GitHub
parent f1b188611a
commit f8368097a9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 110 additions and 293 deletions

View File

@ -80,13 +80,13 @@ namespace signalr
m_disconnect_cts = pplx::cancellation_token_source();
m_start_completed_event.reset();
m_message_id = m_groups_token = m_connection_id = _XPLATSTR("");
m_connection_id = _XPLATSTR("");
}
return start_negotiate(m_base_url, 0);
}
pplx::task<void> connection_impl::start_negotiate(const web::uri& url, int redirect_count)
pplx::task<void> connection_impl::start_negotiate(const utility::string_t& url, int redirect_count)
{
if (redirect_count >= MAX_NEGOTIATE_REDIRECTS)
{
@ -214,7 +214,7 @@ namespace signalr
return pplx::create_task(start_tce);
}
pplx::task<std::shared_ptr<transport>> connection_impl::start_transport(const web::uri& url)
pplx::task<std::shared_ptr<transport>> connection_impl::start_transport(const utility::string_t& url)
{
auto connection = shared_from_this();
@ -294,7 +294,7 @@ namespace signalr
.then([transport](){ return pplx::task_from_result(transport); });
}
pplx::task<void> connection_impl::send_connect_request(const std::shared_ptr<transport>& transport, const web::uri& url, const pplx::task_completion_event<void>& connect_request_tce)
pplx::task<void> connection_impl::send_connect_request(const std::shared_ptr<transport>& transport, const utility::string_t& url, const pplx::task_completion_event<void>& connect_request_tce)
{
auto logger = m_logger;
auto query_string = _XPLATSTR("id=" + m_connection_id);
@ -479,7 +479,7 @@ namespace signalr
return m_connection_state.load();
}
utility::string_t connection_impl::get_connection_id() const
utility::string_t connection_impl::get_connection_id() const noexcept
{
if (m_connection_state.load() == connection_state::connecting)
{
@ -507,7 +507,7 @@ namespace signalr
m_disconnected = disconnected;
}
void connection_impl::ensure_disconnected(const utility::string_t& error_message)
void connection_impl::ensure_disconnected(const utility::string_t& error_message) const
{
const auto state = get_connection_state();
if (state != connection_state::disconnected)

View File

@ -41,14 +41,14 @@ namespace signalr
pplx::task<void> stop();
connection_state get_connection_state() const noexcept;
utility::string_t get_connection_id() const;
utility::string_t get_connection_id() const noexcept;
void set_message_received(const std::function<void(const utility::string_t&)>& message_received);
void set_disconnected(const std::function<void()>& disconnected);
void set_client_config(const signalr_client_config& config);
private:
web::uri m_base_url;
utility::string_t m_base_url;
std::atomic<connection_state> m_connection_state;
logger m_logger;
std::shared_ptr<transport> m_transport;
@ -63,17 +63,14 @@ namespace signalr
std::mutex m_stop_lock;
event m_start_completed_event;
utility::string_t m_connection_id;
utility::string_t m_connection_data;
utility::string_t m_message_id;
utility::string_t m_groups_token;
connection_impl(const utility::string_t& url, trace_level trace_level, const std::shared_ptr<log_writer>& log_writer,
std::unique_ptr<web_request_factory> web_request_factory, std::unique_ptr<transport_factory> transport_factory);
pplx::task<std::shared_ptr<transport>> start_transport(const web::uri& url);
pplx::task<std::shared_ptr<transport>> start_transport(const utility::string_t& url);
pplx::task<void> send_connect_request(const std::shared_ptr<transport>& transport,
const web::uri& url, const pplx::task_completion_event<void>& connect_request_tce);
pplx::task<void> start_negotiate(const web::uri& url, int redirect_count);
const utility::string_t& url, const pplx::task_completion_event<void>& connect_request_tce);
pplx::task<void> start_negotiate(const utility::string_t& url, int redirect_count);
void process_response(const utility::string_t& response);
@ -85,6 +82,6 @@ namespace signalr
void invoke_message_received(const utility::string_t& message);
static utility::string_t translate_connection_state(connection_state state);
void ensure_disconnected(const utility::string_t& error_message);
void ensure_disconnected(const utility::string_t& error_message) const;
};
}

View File

@ -3,9 +3,6 @@
#pragma once
#include "cpprest/details/basic_types.h"
#define SIGNALR_VERSION _XPLATSTR("0.1.0-alpha0")
#define PROTOCOL _XPLATSTR("1.4")
#define USER_AGENT _XPLATSTR("SignalR.Client.Cpp/") SIGNALR_VERSION
#define MAX_NEGOTIATE_REDIRECTS 100

View File

@ -10,7 +10,7 @@ namespace signalr
{
namespace http_sender
{
pplx::task<utility::string_t> get(web_request_factory& request_factory, const web::uri& url,
pplx::task<utility::string_t> get(web_request_factory& request_factory, const utility::string_t& url,
const signalr_client_config& signalr_client_config)
{
auto request = request_factory.create_web_request(url);
@ -32,7 +32,7 @@ namespace signalr
});
}
pplx::task<utility::string_t> post(web_request_factory& request_factory, const web::uri& url,
pplx::task<utility::string_t> post(web_request_factory& request_factory, const utility::string_t& url,
const signalr_client_config& signalr_client_config)
{
auto request = request_factory.create_web_request(url);
@ -54,4 +54,4 @@ namespace signalr
});
}
}
}
}

View File

@ -12,10 +12,10 @@ namespace signalr
{
namespace http_sender
{
pplx::task<utility::string_t> get(web_request_factory& request_factory, const web::uri& url,
pplx::task<utility::string_t> get(web_request_factory& request_factory, const utility::string_t& url,
const signalr_client_config& client_config = signalr_client_config{});
pplx::task<utility::string_t> post(web_request_factory& request_factory, const web::uri& url,
pplx::task<utility::string_t> post(web_request_factory& request_factory, const utility::string_t& url,
const signalr_client_config& client_config = signalr_client_config{});
}
}
}

View File

@ -43,7 +43,7 @@ namespace signalr
const std::shared_ptr<log_writer>& log_writer, std::unique_ptr<web_request_factory> web_request_factory,
std::unique_ptr<transport_factory> transport_factory)
: m_connection(connection_impl::create(url, trace_level, log_writer,
std::move(web_request_factory), std::move(transport_factory))),m_logger(log_writer, trace_level),
std::move(web_request_factory), std::move(transport_factory))), m_logger(log_writer, trace_level),
m_callback_manager(json::value::parse(_XPLATSTR("{ \"error\" : \"connection went out of scope before invocation result was received\"}"))),
m_disconnected([]() noexcept {}), m_handshakeReceived(false)
{ }

View File

@ -11,7 +11,7 @@ namespace signalr
{
namespace request_sender
{
pplx::task<negotiation_response> negotiate(web_request_factory& request_factory, const web::uri& base_url,
pplx::task<negotiation_response> negotiate(web_request_factory& request_factory, const utility::string_t& base_url,
const signalr_client_config& signalr_client_config)
{
auto negotiate_url = url_builder::build_negotiate(base_url);

View File

@ -14,7 +14,7 @@ namespace signalr
{
namespace request_sender
{
pplx::task<negotiation_response> negotiate(web_request_factory& request_factory, const web::uri &base_url,
pplx::task<negotiation_response> negotiate(web_request_factory& request_factory, const utility::string_t& base_url,
const signalr_client_config& signalr_client_config = signalr::signalr_client_config{});
}
}

View File

@ -13,7 +13,7 @@ namespace signalr
class transport
{
public:
virtual pplx::task<void> connect(const web::uri &url) = 0;
virtual pplx::task<void> connect(const utility::string_t &url) = 0;
virtual pplx::task<void> send(const utility::string_t &data) = 0;
@ -37,4 +37,4 @@ namespace signalr
std::function<void(const std::exception&)> m_error_callback;
};
}
}

View File

@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#include "stdafx.h"
#include "constants.h"
#include "cpprest/http_client.h"
#include "signalrclient/transport_type.h"
@ -10,55 +9,6 @@ namespace signalr
{
namespace url_builder
{
utility::string_t get_transport_name(transport_type transport)
{
_ASSERTE(transport == transport_type::websockets || transport == transport_type::long_polling);
return transport == transport_type::websockets
? utility::string_t(_XPLATSTR("webSockets"))
: utility::string_t(_XPLATSTR("longPolling"));
}
void append_transport(web::uri_builder &builder, transport_type transport)
{
if (transport > static_cast<transport_type>(-1))
{
builder.append_query(_XPLATSTR("transport"), get_transport_name(transport));
}
}
void append_connection_token(web::uri_builder &builder, const utility::string_t &connection_token)
{
if (connection_token.length() > 0)
{
builder.append_query(_XPLATSTR("connectionToken"), connection_token, /* do_encoding */ true);
}
}
void append_connection_data(web::uri_builder& builder, const utility::string_t& connection_data)
{
if (connection_data.length() > 0)
{
builder.append_query(_XPLATSTR("connectionData"), connection_data, /* do_encoding */ true);
}
}
void append_message_id(web::uri_builder& builder, const utility::string_t& message_id)
{
if (message_id.length() > 0)
{
builder.append_query(_XPLATSTR("messageId"), message_id, /* do_encoding */ true);
}
}
void append_groups_token(web::uri_builder& builder, const utility::string_t& groups_token)
{
if (groups_token.length() > 0)
{
builder.append_query(_XPLATSTR("groupsToken"), groups_token, /* do_encoding */ true);
}
}
web::uri_builder &convert_to_websocket_url(web::uri_builder &builder, transport_type transport)
{
if (transport == transport_type::websockets)
@ -89,22 +39,20 @@ namespace signalr
return builder.append_path(command);
}
web::uri build_negotiate(const web::uri& base_url)
utility::string_t build_negotiate(const utility::string_t& base_url)
{
return build_uri(base_url, _XPLATSTR("negotiate")).to_uri();
return build_uri(base_url, _XPLATSTR("negotiate")).to_string();
}
web::uri build_connect(const web::uri& base_url, transport_type transport, const utility::string_t& query_string)
utility::string_t build_connect(const utility::string_t& base_url, transport_type transport, const utility::string_t& query_string)
{
auto builder = build_uri(base_url, _XPLATSTR(""), query_string);
return convert_to_websocket_url(builder, transport).to_uri();
//auto builder = build_uri(base_url, _XPLATSTR("connect"), transport, connection_data, query_string);
//return convert_to_websocket_url(builder, transport).to_uri();
return convert_to_websocket_url(builder, transport).to_string();
}
web::uri build_start(const web::uri &base_url, const utility::string_t &query_string)
utility::string_t build_start(const utility::string_t& base_url, const utility::string_t &query_string)
{
return build_uri(base_url, _XPLATSTR(""), query_string).to_uri();
return build_uri(base_url, _XPLATSTR(""), query_string).to_string();
}
}
}

View File

@ -10,8 +10,8 @@ namespace signalr
{
namespace url_builder
{
web::uri build_negotiate(const web::uri& base_url);
web::uri build_connect(const web::uri& base_url, transport_type transport, const utility::string_t& query_string);
web::uri build_start(const web::uri& base_url, const utility::string_t& query_string);
utility::string_t build_negotiate(const utility::string_t& base_url);
utility::string_t build_connect(const utility::string_t& base_url, transport_type transport, const utility::string_t& query_string);
utility::string_t build_start(const utility::string_t& base_url, const utility::string_t& query_string);
}
}

View File

@ -7,7 +7,7 @@
namespace signalr
{
web_request::web_request(const web::uri &url)
web_request::web_request(const utility::string_t& url)
: m_url(url)
{ }
@ -49,4 +49,4 @@ namespace signalr
}
web_request::~web_request() = default;
}
}

View File

@ -11,7 +11,7 @@ namespace signalr
class web_request
{
public:
explicit web_request(const web::uri &url);
explicit web_request(const utility::string_t& url);
virtual void set_method(const utility::string_t &method);
virtual void set_user_agent(const utility::string_t &user_agent_string);
@ -24,9 +24,9 @@ namespace signalr
virtual ~web_request();
private:
const web::uri m_url;
const utility::string_t m_url;
web::http::http_request m_request;
utility::string_t m_user_agent_string;
signalr_client_config m_signalr_client_config;
};
}
}

View File

@ -7,7 +7,7 @@
namespace signalr
{
std::unique_ptr<web_request> web_request_factory::create_web_request(const web::uri &url)
std::unique_ptr<web_request> web_request_factory::create_web_request(const utility::string_t& url)
{
return std::make_unique<web_request>(url);
}

View File

@ -11,8 +11,8 @@ namespace signalr
class web_request_factory
{
public:
virtual std::unique_ptr<web_request> create_web_request(const web::uri &url);
virtual std::unique_ptr<web_request> create_web_request(const utility::string_t& url);
virtual ~web_request_factory();
};
}
}

View File

@ -41,9 +41,10 @@ namespace signalr
return transport_type::websockets;
}
pplx::task<void> websocket_transport::connect(const web::uri &url)
pplx::task<void> websocket_transport::connect(const utility::string_t& url)
{
_ASSERTE(url.scheme() == _XPLATSTR("ws") || url.scheme() == _XPLATSTR("wss"));
web::uri uri(url);
_ASSERTE(uri.scheme() == _XPLATSTR("ws") || uri.scheme() == _XPLATSTR("wss"));
{
std::lock_guard<std::mutex> stop_lock(m_start_stop_lock);
@ -55,7 +56,7 @@ namespace signalr
m_logger.log(trace_level::info,
utility::string_t(_XPLATSTR("[websocket transport] connecting to: "))
.append(url.to_string()));
.append(url));
auto websocket_client = m_websocket_client_factory();

View File

@ -25,7 +25,7 @@ namespace signalr
websocket_transport& operator=(const websocket_transport&) = delete;
pplx::task<void> connect(const web::uri &url) override;
pplx::task<void> connect(const utility::string_t& url) override;
pplx::task<void> send(const utility::string_t &data) override;

View File

@ -93,9 +93,6 @@
<PackageReference Include="cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn" Version="2.9.1" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<Target Name="AfterBuild">
<Exec Command="copy /y &quot;$(SolutionDir)bin\Desktop\$(Platform)\$(Configuration)\dll\$(SignalrClientTargetName).dll&quot; &quot;$(SolutionDir)bin\Desktop\$(Platform)\$(Configuration)\$(SignalrClientTargetName).dll&quot;" />
</Target>
<PropertyGroup>
<IsTestProject>true</IsTestProject>
</PropertyGroup>

View File

@ -111,6 +111,28 @@ TEST(connection_impl_start, connection_state_is_disconnected_when_connection_can
ASSERT_EQ(connection->get_connection_state(), connection_state::disconnected);
}
TEST(connection_impl_start, throws_for_invalid_uri)
{
std::shared_ptr<log_writer> writer(std::make_shared<memory_log_writer>());
auto websocket_client = create_test_websocket_client(
/* receive function */ []() { return pplx::task_from_result(std::string("{ }\x1e")); });
auto connection = connection_impl::create(_XPLATSTR(":1\t ä bad_uri&a=b"), trace_level::errors, writer, create_test_web_request_factory(), std::make_unique<test_transport_factory>(websocket_client));
try
{
connection->start().get();
ASSERT_TRUE(false);
}
catch (const std::exception&)
{
// We shouldn't check the exact exception as it would be specific to the http library being used
}
ASSERT_EQ(connection->get_connection_state(), connection_state::disconnected);
}
TEST(connection_impl_start, start_sets_id_query_string)
{
std::shared_ptr<log_writer> writer(std::make_shared<memory_log_writer>());
@ -246,35 +268,6 @@ TEST(connection_impl_start, start_fails_if_transport_connect_throws)
ASSERT_EQ(_XPLATSTR("[error ] transport could not connect due to: connecting failed\n"), entry);
}
// TODO
TEST(connection_impl_start, DISABLED_start_fails_if_no_available_transports)
{
auto web_request_factory = std::make_unique<test_web_request_factory>([](const web::uri &) -> std::unique_ptr<web_request>
{
auto response_body =
_XPLATSTR("{ \"connectionId\" : \"f7707523-307d-4cba-9abf-3eef701241e8\", ")
_XPLATSTR("\"availableTransports\" : [] }");
return std::unique_ptr<web_request>(new web_request_stub((unsigned short)200, _XPLATSTR("OK"), response_body));
});
auto websocket_client = std::make_shared<test_websocket_client>();
auto connection =
connection_impl::create(create_uri(), trace_level::errors, std::make_shared<trace_log_writer>(),
std::move(web_request_factory), std::make_unique<test_transport_factory>(websocket_client));
try
{
connection->start().get();
ASSERT_TRUE(false); // exception not thrown
}
catch (const std::exception &e)
{
ASSERT_EQ(_XPLATSTR("websockets not supported on the server and there is no fallback transport"),
utility::conversions::to_string_t(e.what()));
}
}
#if defined(_WIN32) // https://github.com/aspnet/SignalR-Client-Cpp/issues/131
TEST(connection_impl_send, send_fails_if_transport_fails_when_receiving_messages)
@ -984,86 +977,6 @@ TEST(connection_impl_set_message_received, non_std_exception_from_callback_caugh
ASSERT_EQ(_XPLATSTR("[error ] message_received callback threw an unknown exception\n"), entry);
}
TEST(connection_impl_set_message_received, DISABLED_error_logged_for_malformed_payload)
{
int call_number = -1;
auto websocket_client = create_test_websocket_client(
/* receive function */ [call_number]()
mutable {
std::string responses[]
{
"{ }\x1e",
"{ 42\x1e",
"{ \"type\": 1, \"target\": \"something\", \"arguments\" : [\"release\"] }\x1e",
"{}"
};
call_number = std::min(call_number + 1, 3);
return pplx::task_from_result(responses[call_number]);
});
std::shared_ptr<log_writer> writer(std::make_shared<memory_log_writer>());
auto connection = create_connection(websocket_client, writer, trace_level::errors);
auto message_received_event = std::make_shared<event>();
connection->set_message_received([message_received_event](const utility::string_t&)
{
// this is called only once because we have just one response with a message
message_received_event->set();
});
connection->start().get();
ASSERT_FALSE(message_received_event->wait(5000));
auto log_entries = std::dynamic_pointer_cast<memory_log_writer>(writer)->get_log_entries();
ASSERT_FALSE(log_entries.empty());
auto entry = remove_date_from_log_entry(log_entries[0]);
ASSERT_EQ(_XPLATSTR("[error ] error occured when parsing response: * Line 1, Column 4 Syntax error: Malformed object literal. response: { 42\x1e\n"), entry);
}
TEST(connection_impl_set_message_received, DISABLED_unexpected_responses_logged)
{
int call_number = -1;
auto websocket_client = create_test_websocket_client(
/* receive function */ [call_number]()
mutable {
std::string responses[]
{
"{ }\x1e",
"42\x1e",
"{ \"type\": 1, \"target\": \"something\", \"arguments\" : [\"release\"] }\x1e",
"{}"
};
call_number = std::min(call_number + 1, 3);
return pplx::task_from_result(responses[call_number]);
});
std::shared_ptr<log_writer> writer(std::make_shared<memory_log_writer>());
auto connection = create_connection(websocket_client, writer, trace_level::info);
auto message_received_event = std::make_shared<event>();
connection->set_message_received([message_received_event](const utility::string_t&)
{
// this is called only once because we have just one response with a message
message_received_event->set();
});
connection->start().get();
ASSERT_FALSE(message_received_event->wait(5000));
auto log_entries = std::dynamic_pointer_cast<memory_log_writer>(writer)->get_log_entries();
ASSERT_TRUE(log_entries.size() >= 1);
auto entry = remove_date_from_log_entry(log_entries[1]);
ASSERT_EQ(_XPLATSTR("[info ] unexpected response received from the server: 42\n"), entry);
}
void can_be_set_only_in_disconnected_state(std::function<void(connection_impl *)> callback, const char* expected_exception_message)
{
auto websocket_client = create_test_websocket_client(
@ -1299,7 +1212,7 @@ TEST(connection_impl_stop, ongoing_start_request_canceled_if_connection_stopped_
auto response_body =
url.path() == _XPLATSTR("/negotiate")
? _XPLATSTR("{ \"connectionId\" : \"f7707523-307d-4cba-9abf-3eef701241e8\", ")
_XPLATSTR("\"availableTransports\" : [] }")
_XPLATSTR("\"availableTransports\" : [ { \"transport\": \"WebSockets\", \"transferFormats\": [ \"Text\", \"Binary\" ] } ] }")
: _XPLATSTR("");
return std::unique_ptr<web_request>(new web_request_stub((unsigned short)200, _XPLATSTR("OK"), response_body));

View File

@ -470,7 +470,7 @@ TEST(invoke, invoke_returns_value_returned_from_the_server)
ASSERT_EQ(_XPLATSTR("\"abc\""), result.serialize());
}
TEST(invoke, invoke_propagates_hub_errors_from_server_as_hub_exceptions)
TEST(invoke, invoke_propagates_errors_from_server_as_hub_exceptions)
{
auto callback_registered_event = std::make_shared<event>();
@ -562,7 +562,7 @@ TEST(receive, logs_if_callback_for_given_id_not_found)
std::string responses[]
{
"{ }\x1e",
"{ \"type\": 3, \"invocationId\": \"0\" }\x1e"
"{ \"type\": 3, \"invocationId\": \"0\" }\x1e",
"{}"
};
@ -596,53 +596,7 @@ TEST(receive, logs_if_callback_for_given_id_not_found)
ASSERT_EQ(_XPLATSTR("[info ] no callback found for id: 0\n"), entry) << dump_vector(log_entries);
}
// TODO Flaky until hub_connection.start waits for handshake response
TEST(invoke, DISABLED_invoke_propagates_errors_from_server_as_exceptions)
{
auto callback_registered_event = std::make_shared<event>();
int call_number = -1;
auto websocket_client = create_test_websocket_client(
/* receive function */ [call_number, callback_registered_event]()
mutable {
std::string responses[]
{
"{ }\x1e",
"{ \"type\": 3, \"invocationId\": \"0\", \"error\": \"Ooops\" }\x1e"
"{}"
};
call_number = std::min(call_number + 1, 2);
if (call_number > 0)
{
callback_registered_event->wait();
}
return pplx::task_from_result(responses[call_number]);
});
auto hub_connection = create_hub_connection(websocket_client);
try
{
hub_connection->start()
.then([hub_connection, callback_registered_event]()
{
auto t = hub_connection->invoke(_XPLATSTR("method"), json::value::array());
callback_registered_event->set();
return t;
}).get();
ASSERT_TRUE(false); // exception expected but not thrown
}
catch (const std::runtime_error& e)
{
ASSERT_STREQ("\"Ooops\"", e.what());
}
}
// TODO Flaky until hub_connection.start waits for handshake response
TEST(invoke_void, DISABLED_invoke_creates_runtime_error)
TEST(invoke_void, invoke_creates_runtime_error)
{
auto callback_registered_event = std::make_shared<event>();
@ -679,10 +633,10 @@ TEST(invoke_void, DISABLED_invoke_creates_runtime_error)
ASSERT_TRUE(false); // exception expected but not thrown
}
catch (const signalr_exception& e)
catch (const hub_exception & e)
{
ASSERT_STREQ("\"Ooops\"", e.what());
ASSERT_TRUE(dynamic_cast<const hub_exception *>(&e) == nullptr);
ASSERT_FALSE(callback_registered_event->wait(0));
}
}

View File

@ -13,8 +13,8 @@ using namespace signalr;
TEST(request_sender_negotiate, request_created_with_correct_url)
{
web::uri requested_url;
auto request_factory = test_web_request_factory([&requested_url](const web::uri &url) -> std::unique_ptr<web_request>
utility::string_t requested_url;
auto request_factory = test_web_request_factory([&requested_url](const utility::string_t& url) -> std::unique_ptr<web_request>
{
utility::string_t response_body(
_XPLATSTR("{ \"connectionId\" : \"f7707523-307d-4cba-9abf-3eef701241e8\", ")
@ -24,24 +24,30 @@ TEST(request_sender_negotiate, request_created_with_correct_url)
return std::unique_ptr<web_request>(new web_request_stub((unsigned short)200, _XPLATSTR("OK"), response_body));
});
request_sender::negotiate(request_factory, web::uri{ _XPLATSTR("http://fake/signalr") }).get();
request_sender::negotiate(request_factory, _XPLATSTR("http://fake/signalr")).get();
ASSERT_EQ(web::uri(_XPLATSTR("http://fake/signalr/negotiate")), requested_url);
ASSERT_EQ(_XPLATSTR("http://fake/signalr/negotiate"), requested_url);
}
TEST(request_sender_negotiate, negotiation_request_sent_and_response_serialized)
{
auto request_factory = test_web_request_factory([](const web::uri&) -> std::unique_ptr<web_request>
auto request_factory = test_web_request_factory([](const utility::string_t&) -> std::unique_ptr<web_request>
{
utility::string_t response_body(
_XPLATSTR("{\"connectionId\" : \"f7707523-307d-4cba-9abf-3eef701241e8\", ")
_XPLATSTR("\"availableTransports\" : [] }"));
_XPLATSTR("\"availableTransports\" : [ { \"transport\": \"WebSockets\", \"transferFormats\": [ \"Text\", \"Binary\" ] },")
_XPLATSTR("{ \"transport\": \"ServerSentEvents\", \"transferFormats\": [ \"Text\" ] } ] }"));
return std::unique_ptr<web_request>(new web_request_stub((unsigned short)200, _XPLATSTR("OK"), response_body));
});
auto response = request_sender::negotiate(request_factory, web::uri{ _XPLATSTR("http://fake/signalr") }).get();
auto response = request_sender::negotiate(request_factory, _XPLATSTR("http://fake/signalr")).get();
ASSERT_EQ(_XPLATSTR("f7707523-307d-4cba-9abf-3eef701241e8"), response.connectionId);
// TODO: response.availableTransports
ASSERT_EQ(2u, response.availableTransports.size());
ASSERT_EQ(2u, response.availableTransports[0].transfer_formats.size());
ASSERT_EQ(_XPLATSTR("Text"), response.availableTransports[0].transfer_formats[0]);
ASSERT_EQ(_XPLATSTR("Binary"), response.availableTransports[0].transfer_formats[1]);
ASSERT_EQ(1u, response.availableTransports[1].transfer_formats.size());
ASSERT_EQ(_XPLATSTR("Text"), response.availableTransports[1].transfer_formats[0]);
}

View File

@ -6,11 +6,11 @@
using namespace signalr;
test_web_request_factory::test_web_request_factory(std::function<std::unique_ptr<web_request>(const web::uri &url)> create_web_request_fn)
test_web_request_factory::test_web_request_factory(std::function<std::unique_ptr<web_request>(const utility::string_t& url)> create_web_request_fn)
: m_create_web_request_fn(create_web_request_fn)
{ }
std::unique_ptr<web_request> test_web_request_factory::create_web_request(const web::uri &url)
std::unique_ptr<web_request> test_web_request_factory::create_web_request(const utility::string_t& url)
{
return m_create_web_request_fn(url);
}

View File

@ -11,10 +11,10 @@ using namespace signalr;
class test_web_request_factory : public web_request_factory
{
public:
explicit test_web_request_factory(std::function<std::unique_ptr<web_request>(const web::uri &url)> create_web_request_fn);
explicit test_web_request_factory(std::function<std::unique_ptr<web_request>(const utility::string_t& url)> create_web_request_fn);
virtual std::unique_ptr<web_request> create_web_request(const web::uri &url) override;
virtual std::unique_ptr<web_request> create_web_request(const utility::string_t& url) override;
private:
std::function<std::unique_ptr<web_request>(const web::uri &url)> m_create_web_request_fn;
std::function<std::unique_ptr<web_request>(const utility::string_t& url)> m_create_web_request_fn;
};

View File

@ -9,20 +9,20 @@ using namespace signalr;
TEST(url_builder_negotiate, url_correct_if_query_string_empty)
{
ASSERT_EQ(
web::uri(_XPLATSTR("http://fake/negotiate")),
url_builder::build_negotiate(web::uri{ _XPLATSTR("http://fake/") }));
_XPLATSTR("http://fake/negotiate"),
url_builder::build_negotiate(_XPLATSTR("http://fake/")));
}
TEST(url_builder_negotiate, url_correct_if_query_string_not_empty)
{
ASSERT_EQ(
web::uri(_XPLATSTR("http://fake/negotiate?q1=1&q2=2")),
url_builder::build_negotiate(web::uri{ _XPLATSTR("http://fake/?q1=1&q2=2") }));
_XPLATSTR("http://fake/negotiate?q1=1&q2=2"),
url_builder::build_negotiate(_XPLATSTR("http://fake/?q1=1&q2=2")));
}
TEST(url_builder_connect_webSockets, url_correct_if_query_string_not_empty)
{
ASSERT_EQ(
web::uri(_XPLATSTR("ws://fake/?q1=1&q2=2")),
url_builder::build_connect(web::uri{ _XPLATSTR("http://fake/") }, transport_type::websockets, _XPLATSTR("q1=1&q2=2")));
_XPLATSTR("ws://fake/?q1=1&q2=2"),
url_builder::build_connect(_XPLATSTR("http://fake/"), transport_type::websockets, _XPLATSTR("q1=1&q2=2")));
}

View File

@ -5,7 +5,7 @@
#include "web_request_stub.h"
web_request_stub::web_request_stub(unsigned short status_code, const utility::string_t& reason_phrase, const utility::string_t& response_body)
: web_request(web::uri(_XPLATSTR(""))), m_status_code(status_code), m_reason_phrase(reason_phrase), m_response_body(response_body)
: web_request(_XPLATSTR("")), m_status_code(status_code), m_reason_phrase(reason_phrase), m_response_body(response_body)
{ }
void web_request_stub::set_method(const utility::string_t &method)
@ -29,4 +29,4 @@ pplx::task<web_response> web_request_stub::get_response()
return pplx::task_from_result<web_response>(
web_response{ m_status_code, m_reason_phrase, pplx::task_from_result<utility::string_t>(m_response_body) });
}
}

View File

@ -10,7 +10,7 @@ using namespace signalr;
TEST(web_request_get_response, DISABLED_sends_request_receives_response)
{
web::uri url(_XPLATSTR("http://localhost:56000/web_request_test"));
utility::string_t url(_XPLATSTR("http://localhost:56000/web_request_test"));
auto request_received = false;
utility::string_t user_agent_string;
@ -41,4 +41,4 @@ TEST(web_request_get_response, DISABLED_sends_request_receives_response)
ASSERT_TRUE(request_received);
ASSERT_EQ(_XPLATSTR("007"), user_agent_string);
}
}

View File

@ -97,8 +97,7 @@ TEST(websocket_transport_connect, connect_logs_exceptions)
entry);
}
// Flaky test: crashes test process
TEST(websocket_transport_connect, DISABLED_cannot_call_connect_on_already_connected_transport)
TEST(websocket_transport_connect, cannot_call_connect_on_already_connected_transport)
{
auto client = std::make_shared<test_websocket_client>();
auto ws_transport = websocket_transport::create([&](){ return client; }, logger(std::make_shared<trace_log_writer>(), trace_level::none),
@ -237,9 +236,10 @@ TEST(websocket_transport_disconnect, receive_not_called_after_disconnect)
auto client = std::make_shared<test_websocket_client>();
pplx::task_completion_event<std::string> receive_task_tce;
pplx::task_completion_event<void> receive_task_started_tce;
// receive_task_tce is captured by reference since we assign it a new value after the first disconnect. This is
// safe here because we are blocking on disconnect and therefore we won't get into a state were we would be using
// safe here because we are blocking on disconnect and therefore we won't get into a state where we would be using
// an invalid reference because the tce went out of scope and was destroyed.
client->set_close_function([&receive_task_tce]()
{
@ -250,9 +250,10 @@ TEST(websocket_transport_disconnect, receive_not_called_after_disconnect)
int num_called = 0;
client->set_receive_function([&receive_task_tce, &num_called]() -> pplx::task<std::string>
client->set_receive_function([&receive_task_tce, &receive_task_started_tce, &num_called]() -> pplx::task<std::string>
{
num_called++;
receive_task_started_tce.set();
return pplx::create_task(receive_task_tce);
});
@ -260,10 +261,13 @@ TEST(websocket_transport_disconnect, receive_not_called_after_disconnect)
[](const utility::string_t&){}, [](const std::exception&){});
ws_transport->connect(_XPLATSTR("ws://fakeuri.org")).get();
pplx::create_task(receive_task_started_tce).get();
ws_transport->disconnect().get();
receive_task_tce = pplx::task_completion_event<std::string>();
receive_task_started_tce = pplx::task_completion_event<void>();
ws_transport->connect(_XPLATSTR("ws://fakeuri.org")).get();
pplx::create_task(receive_task_started_tce).get();
ws_transport->disconnect().get();
ASSERT_EQ(2, num_called);