Chromium Code Reviews| Index: remoting/test/chromoting_host_list_fetcher_unittest.cc |
| diff --git a/remoting/test/chromoting_host_list_fetcher_unittest.cc b/remoting/test/chromoting_host_list_fetcher_unittest.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..9cac2e08564795c96cc68174d4020ad039a90b7e |
| --- /dev/null |
| +++ b/remoting/test/chromoting_host_list_fetcher_unittest.cc |
| @@ -0,0 +1,462 @@ |
| +// Copyright 2015 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "remoting/test/chromoting_host_list_fetcher.h" |
| + |
| +#include "base/bind.h" |
| +#include "base/message_loop/message_loop.h" |
| +#include "base/run_loop.h" |
| +#include "base/strings/stringprintf.h" |
| +#include "net/url_request/test_url_fetcher_factory.h" |
| +#include "remoting/test/chromoting_host_info.h" |
| +#include "testing/gtest/include/gtest/gtest.h" |
| + |
| +namespace { |
| +// Used as a ChromotingHostListCallback for testing. |
| +void OnHostlistRetrieved( |
| + base::Closure done_closure, |
| + std::vector<remoting::test::ChromotingHostInfo>* hostlist, |
| + const std::vector<remoting::test::ChromotingHostInfo>& retrieved_hostlist, |
| + bool request_success) { |
|
joedow
2015/07/08 17:19:08
What is request_success used for? Can you remove
tonychun
2015/07/08 22:38:16
Done.
|
| + *hostlist = retrieved_hostlist; |
| + |
| + done_closure.Run(); |
| +} |
| + |
| +const char kAccessTokenValue[] = "test_access_token_value"; |
| +const char kChromotingHostListReadyResponse[] = |
| +"{" |
| +" \"data\":{" |
| +" \"kind\":\"chromoting#hostList\"," |
| +" \"items\":[" |
| +" {" |
| +" \"tokenUrlPatterns\":[" |
| +" \"tokenUrlPattern_1A\"," |
| +" \"tokenUrlPattern_1B\"," |
| +" \"tokenUrlPattern_1C\"" |
| +" ]," |
| +" \"kind\":\"chromoting#host\"," |
| +" \"hostId\":\"test_host_id_1\"," |
| +" \"hostName\":\"test_host_name_1\"," |
| +" \"publicKey\":\"test_public_key_1\"," |
| +" \"jabberId\":\"test_jabber_id_1\"," |
| +" \"createdTime\":\"test_created_time_1\"," |
| +" \"updatedTime\":\"test_updated_time_1\"," |
| +" \"status\":\"ONLINE\"," |
| +" \"hostOfflineReason\":\"\"," |
| +" \"hostVersion\":\"test_host_version_1\"" |
| +" }," |
| +" {" |
| +" \"kind\":\"chromoting#host\"," |
| +" \"hostId\":\"test_host_id_2\"," |
| +" \"hostName\":\"test_host_name_2\"," |
| +" \"publicKey\":\"test_public_key_2\"," |
| +" \"jabberId\":\"test_jabber_id_2\"," |
| +" \"createdTime\":\"test_created_time_2\"," |
| +" \"updatedTime\":\"test_updated_time_2\"," |
| +" \"status\":\"OFFLINE\"," |
| +" \"hostOfflineReason\":\"test_host_offline_reason_2\"," |
| +" \"hostVersion\":\"test_host_version_2\"" |
| +" }" |
| +" ]" |
| +" }" |
| +"}"; |
| +const char kChromotingHostListMissingParametersResponse[] = |
| +"{" |
| +" \"data\":{" |
| +" \"kind\":\"chromoting#hostList\"," |
| +" \"items\":[" |
| +" {" |
| +" \"tokenUrlPatterns\":[" |
| +" \"tokenUrlPattern_1A\"," |
| +" \"tokenUrlPattern_1B\"," |
| +" \"tokenUrlPattern_1C\"" |
| +" ]," |
| +" \"kind\":\"chromoting#host\"," |
| +" \"hostId\":\"test_host_id_1\"," |
| +" \"hostName\":\"test_host_name_1\"," |
| +" \"publicKey\":\"test_public_key_1\"," |
| +" \"createdTime\":\"test_created_time_1\"," |
| +" \"updatedTime\":\"test_updated_time_1\"," |
| +" \"status\":\"ONLINE\"," |
| +" \"hostOfflineReason\":\"\"," |
| +" \"hostVersion\":\"test_host_version_1\"" |
| +" }," |
| +" {" |
| +" \"kind\":\"chromoting#host\"," |
| +" \"hostName\":\"test_host_name_2\"," |
| +" \"publicKey\":\"test_public_key_2\"," |
| +" \"jabberId\":\"test_jabber_id_2\"," |
| +" \"createdTime\":\"test_created_time_2\"," |
| +" \"updatedTime\":\"test_updated_time_2\"," |
| +" \"status\":\"ONLINE\"," |
| +" \"hostOfflineReason\":\"\"," |
| +" \"hostVersion\":\"test_host_version_2\"" |
| +" }," |
| +" {" |
| +" \"kind\":\"chromoting#host\"," |
| +" \"hostId\":\"test_host_id_3\"," |
| +" \"publicKey\":\"test_public_key_3\"," |
| +" \"jabberId\":\"test_jabber_id_3\"," |
| +" \"createdTime\":\"test_created_time_3\"," |
| +" \"updatedTime\":\"test_updated_time_3\"," |
| +" \"status\":\"ONLINE\"," |
| +" \"hostOfflineReason\":\"\"," |
| +" \"hostVersion\":\"test_host_version_3\"" |
| +" }," |
| +" {" |
| +" \"kind\":\"chromoting#host\"," |
| +" \"hostId\":\"test_host_id_4\"," |
| +" \"hostName\":\"test_host_name_4\"," |
| +" \"jabberId\":\"test_jabber_id_4\"," |
| +" \"createdTime\":\"test_created_time_4\"," |
| +" \"updatedTime\":\"test_updated_time_4\"," |
| +" \"status\":\"ONLINE\"," |
| +" \"hostOfflineReason\":\"\"," |
| +" \"hostVersion\":\"test_host_version_4\"" |
| +" }," |
| +" {" |
| +" \"kind\":\"chromoting#host\"," |
| +" \"hostId\":\"test_host_id_5\"," |
| +" \"hostName\":\"test_host_name_5\"," |
| +" \"publicKey\":\"test_public_key_5\"," |
| +" \"jabberId\":\"test_jabber_id_5\"," |
| +" \"createdTime\":\"test_created_time_5\"," |
| +" \"updatedTime\":\"test_updated_time_5\"," |
| +" \"status\":\"OFFLINE\"," |
| +" \"hostVersion\":\"test_host_version_5\"" |
| +" }" |
| +" ]" |
| +" }" |
| +"}"; |
|
joedow
2015/07/08 17:19:08
Good mixture of data for testing, thanks for addin
tonychun
2015/07/08 22:38:16
Acknowledged.
|
| +const char kChromotingHostListEmptyTokenUrlPatternsResponse[] = |
| +"{" |
| +" \"data\":{" |
| +" \"kind\":\"chromoting#hostList\"," |
| +" \"items\":[" |
| +" {" |
| +" \"tokenUrlPatterns\":[" |
| +" ]," |
| +" \"kind\":\"chromoting#host\"," |
| +" \"hostId\":\"test_host_id_1\"," |
| +" \"hostName\":\"test_host_name_1\"," |
| +" \"publicKey\":\"test_public_key_1\"," |
| +" \"jabberId\":\"test_jabber_id_1\"," |
| +" \"createdTime\":\"test_created_time_1\"," |
| +" \"updatedTime\":\"test_updated_time_1\"," |
| +" \"status\":\"ONLINE\"," |
| +" \"hostOfflineReason\":\"\"," |
| +" \"hostVersion\":\"test_host_version_1\"" |
| +" }" |
| +" ]" |
| +" }" |
| +"}"; |
| +const char kChromotingHostListEmptyItemsResponse[] = |
| +"{" |
| +" \"data\":{" |
| +" \"kind\":\"chromoting#hostList\"," |
| +" \"items\":[" |
| +" ]" |
| +" }" |
| +"}"; |
| +const char kChromotingHostListEmptyResponse[] = "{}"; |
| +} // namespace |
| + |
| +namespace remoting { |
| +namespace test { |
| + |
| +// Provides base functionality for the ChromotingHostListFetcher Tests below. |
| +// The FakeURLFetcherFactory allows us to override the response data and payload |
| +// for specified URLs. We use this to stub out network calls made by the |
| +// ChromotingHostListFetcher. This fixture also creates an IO MessageLoop |
|
joedow
2015/07/08 17:19:08
nit: You can just say MessageLoop here, you don't
tonychun
2015/07/08 22:38:16
Done.
|
| +// for use by the ChromotingHostListFetcher. |
| +class ChromotingHostListFetcherTest : public ::testing::Test { |
| + public: |
| + ChromotingHostListFetcherTest() : url_fetcher_factory_(nullptr) {} |
| + ~ChromotingHostListFetcherTest() override {} |
| + |
| + protected: |
| + // testing::Test interface. |
| + void SetUp() override; |
| + |
| + // Sets the HTTP status and data returned for a specified URL. |
| + void SetFakeResponse(const GURL& url, |
| + const std::string& data, |
| + net::HttpStatusCode code, |
| + net::URLRequestStatus::Status status); |
| + |
| + private: |
| + net::FakeURLFetcherFactory url_fetcher_factory_; |
| + scoped_ptr<base::MessageLoopForIO> message_loop_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(ChromotingHostListFetcherTest); |
| +}; |
| + |
| +void ChromotingHostListFetcherTest::SetUp() { |
| + DCHECK(!message_loop_); |
| + message_loop_.reset(new base::MessageLoopForIO); |
| + |
| + SetFakeResponse(GURL(kChromotingHostListProdRequestUrl), |
| + kChromotingHostListEmptyResponse, net::HTTP_NOT_FOUND, |
| + net::URLRequestStatus::FAILED); |
| +} |
| + |
| +void ChromotingHostListFetcherTest::SetFakeResponse( |
| + const GURL& url, |
| + const std::string& data, |
| + net::HttpStatusCode code, |
| + net::URLRequestStatus::Status status) { |
| + url_fetcher_factory_.SetFakeResponse(url, data, code, status); |
| +} |
| + |
| +TEST_F(ChromotingHostListFetcherTest, RetrieveHostListFromProd) { |
| + SetFakeResponse(GURL(kChromotingHostListProdRequestUrl), |
| + kChromotingHostListReadyResponse, net::HTTP_OK, |
| + net::URLRequestStatus::SUCCESS); |
| + |
| + std::vector<ChromotingHostInfo> hostlist; |
| + |
| + base::RunLoop run_loop; |
| + ChromotingHostListFetcher::HostlistCallback hostlist_fetch_callback = |
| + base::Bind(&OnHostlistRetrieved, run_loop.QuitClosure(), &hostlist); |
| + |
| + ChromotingHostListFetcher chromoting_host_list_fetcher; |
| + chromoting_host_list_fetcher.RetrieveHostlist(kAccessTokenValue, |
| + hostlist_fetch_callback); |
| + |
| + run_loop.Run(); |
| + |
| + const unsigned int expected_host_list_size = 2; |
| + EXPECT_EQ(hostlist.size(), expected_host_list_size); |
| + |
| + ChromotingHostInfo online_chromoting_host_info = hostlist.at(0); |
| + const unsigned int expected_patterns_size = 3; |
| + EXPECT_EQ(online_chromoting_host_info.token_url_patterns.size(), |
| + expected_patterns_size); |
| + EXPECT_FALSE(online_chromoting_host_info.host_id.empty()); |
| + EXPECT_FALSE(online_chromoting_host_info.host_jid.empty()); |
| + EXPECT_FALSE(online_chromoting_host_info.host_name.empty()); |
| + EXPECT_EQ(online_chromoting_host_info.status, |
| + ChromotingHostStatus::kChromotingHostStatusOnline); |
|
joedow
2015/07/08 17:19:08
nit: this line would look better if the params wer
tonychun
2015/07/08 22:38:16
Done.
|
| + EXPECT_TRUE(online_chromoting_host_info.offline_reason.empty()); |
| + EXPECT_FALSE(online_chromoting_host_info.public_key.empty()); |
| + |
| + ChromotingHostInfo offline_chromoting_host_info = hostlist.at(1); |
| + EXPECT_TRUE(offline_chromoting_host_info.token_url_patterns.empty()); |
| + EXPECT_FALSE(offline_chromoting_host_info.host_id.empty()); |
| + EXPECT_FALSE(offline_chromoting_host_info.host_jid.empty()); |
| + EXPECT_FALSE(offline_chromoting_host_info.host_name.empty()); |
| + EXPECT_EQ(offline_chromoting_host_info.status, |
| + ChromotingHostStatus::kChromotingHostStatusOffline); |
| + EXPECT_FALSE(offline_chromoting_host_info.offline_reason.empty()); |
| + EXPECT_FALSE(offline_chromoting_host_info.public_key.empty()); |
| +} |
| + |
| +TEST_F(ChromotingHostListFetcherTest, RetrieveHostListWithEmptyPatterns) { |
| + SetFakeResponse( |
| + GURL(kChromotingHostListProdRequestUrl), |
| + kChromotingHostListEmptyTokenUrlPatternsResponse, net::HTTP_OK, |
| + net::URLRequestStatus::SUCCESS); |
| + |
| + std::vector<ChromotingHostInfo> hostlist; |
| + |
| + base::RunLoop run_loop; |
| + ChromotingHostListFetcher::HostlistCallback hostlist_fetch_callback = |
| + base::Bind(&OnHostlistRetrieved, run_loop.QuitClosure(), &hostlist); |
| + |
| + ChromotingHostListFetcher chromoting_host_list_fetcher; |
| + chromoting_host_list_fetcher.RetrieveHostlist(kAccessTokenValue, |
| + hostlist_fetch_callback); |
| + |
| + run_loop.Run(); |
| + |
| + const unsigned int expected_host_list_size = 1; |
| + EXPECT_EQ(hostlist.size(), expected_host_list_size); |
| + |
| + // While this is unlikely to happen, empty token url patterns are handled. |
| + ChromotingHostInfo online_chromoting_host_info = hostlist.at(0); |
| + EXPECT_TRUE(online_chromoting_host_info.token_url_patterns.empty()); |
| + EXPECT_FALSE(online_chromoting_host_info.host_id.empty()); |
| + EXPECT_FALSE(online_chromoting_host_info.host_jid.empty()); |
| + EXPECT_FALSE(online_chromoting_host_info.host_name.empty()); |
| + EXPECT_EQ(online_chromoting_host_info.status, |
| + ChromotingHostStatus::kChromotingHostStatusOnline); |
| + EXPECT_TRUE(online_chromoting_host_info.offline_reason.empty()); |
| + EXPECT_FALSE(online_chromoting_host_info.public_key.empty()); |
| +} |
| + |
| +TEST_F(ChromotingHostListFetcherTest, |
| + RetrieveHostListMissingParametersResponse) { |
| + SetFakeResponse(GURL(kChromotingHostListProdRequestUrl), |
| + kChromotingHostListMissingParametersResponse, net::HTTP_OK, |
| + net::URLRequestStatus::SUCCESS); |
| + |
| + std::vector<ChromotingHostInfo> hostlist; |
| + |
| + base::RunLoop run_loop; |
| + ChromotingHostListFetcher::HostlistCallback hostlist_fetch_callback = |
| + base::Bind(&OnHostlistRetrieved, run_loop.QuitClosure(), &hostlist); |
| + |
| + ChromotingHostListFetcher chromoting_host_list_fetcher; |
| + chromoting_host_list_fetcher.RetrieveHostlist(kAccessTokenValue, |
| + hostlist_fetch_callback); |
| + run_loop.Run(); |
| + |
| + const unsigned int expected_host_list_size = 2; |
| + EXPECT_EQ(hostlist.size(), expected_host_list_size); |
| + |
| + ChromotingHostInfo missing_jabber_id_host_info = hostlist.at(0); |
| + const unsigned int expected_patterns_size = 3; |
| + EXPECT_EQ(missing_jabber_id_host_info.token_url_patterns.size(), |
| + expected_patterns_size); |
| + EXPECT_FALSE(missing_jabber_id_host_info.host_id.empty()); |
| + EXPECT_TRUE(missing_jabber_id_host_info.host_jid.empty()); |
| + EXPECT_FALSE(missing_jabber_id_host_info.host_name.empty()); |
| + EXPECT_EQ(missing_jabber_id_host_info.status, |
| + ChromotingHostStatus::kChromotingHostStatusOnline); |
| + EXPECT_TRUE(missing_jabber_id_host_info.offline_reason.empty()); |
| + EXPECT_FALSE(missing_jabber_id_host_info.public_key.empty()); |
| + |
| + ChromotingHostInfo missing_offline_reason_host_info = hostlist.at(1); |
| + EXPECT_TRUE(missing_offline_reason_host_info.token_url_patterns.empty()); |
| + EXPECT_FALSE(missing_offline_reason_host_info.host_id.empty()); |
| + EXPECT_FALSE(missing_offline_reason_host_info.host_jid.empty()); |
| + EXPECT_FALSE(missing_offline_reason_host_info.host_name.empty()); |
| + EXPECT_EQ(missing_offline_reason_host_info.status, |
| + ChromotingHostStatus::kChromotingHostStatusOffline); |
| + EXPECT_TRUE(missing_offline_reason_host_info.offline_reason.empty()); |
| + EXPECT_FALSE(missing_offline_reason_host_info.public_key.empty()); |
| +} |
| + |
| + |
| +TEST_F(ChromotingHostListFetcherTest, RetrieveHostListNetworkError) { |
| + base::RunLoop run_loop; |
| + |
| + std::vector<ChromotingHostInfo> hostlist; |
| + |
| + ChromotingHostListFetcher::HostlistCallback hostlist_fetch_callback = |
| + base::Bind(&OnHostlistRetrieved, run_loop.QuitClosure(), &hostlist); |
| + |
| + ChromotingHostListFetcher chromoting_host_list_fetcher; |
| + chromoting_host_list_fetcher.RetrieveHostlist(kAccessTokenValue, |
| + hostlist_fetch_callback); |
| + run_loop.Run(); |
| + |
| + // If there was a network error retrieving the host list, then the host list |
| + // should be empty. |
| + EXPECT_TRUE(hostlist.empty()); |
| +} |
| + |
| +TEST_F(ChromotingHostListFetcherTest, RetrieveHostListEmptyItemsResponse) { |
| + SetFakeResponse(GURL(kChromotingHostListProdRequestUrl), |
| + kChromotingHostListEmptyItemsResponse, net::HTTP_OK, |
| + net::URLRequestStatus::SUCCESS); |
| + |
| + base::RunLoop run_loop; |
| + |
| + std::vector<ChromotingHostInfo> hostlist; |
| + |
| + ChromotingHostListFetcher::HostlistCallback hostlist_fetch_callback = |
| + base::Bind(&OnHostlistRetrieved, run_loop.QuitClosure(), &hostlist); |
| + |
| + ChromotingHostListFetcher chromoting_host_list_fetcher; |
| + chromoting_host_list_fetcher.RetrieveHostlist(kAccessTokenValue, |
| + hostlist_fetch_callback); |
| + run_loop.Run(); |
| + |
| + // If we received an empty items response, then host list should be empty. |
| + EXPECT_TRUE(hostlist.empty()); |
| +} |
| + |
| +TEST_F(ChromotingHostListFetcherTest, RetrieveHostListEmptyResponse) { |
| + SetFakeResponse(GURL(kChromotingHostListProdRequestUrl), |
| + kChromotingHostListEmptyResponse, net::HTTP_OK, |
| + net::URLRequestStatus::SUCCESS); |
| + |
| + base::RunLoop run_loop; |
| + |
| + std::vector<ChromotingHostInfo> hostlist; |
| + |
| + ChromotingHostListFetcher::HostlistCallback hostlist_fetch_callback = |
| + base::Bind(&OnHostlistRetrieved, run_loop.QuitClosure(), &hostlist); |
| + |
| + ChromotingHostListFetcher chromoting_host_list_fetcher; |
| + chromoting_host_list_fetcher.RetrieveHostlist(kAccessTokenValue, |
| + hostlist_fetch_callback); |
| + run_loop.Run(); |
| + |
| + // If we received an empty response, then host list should be empty. |
| + EXPECT_TRUE(hostlist.empty()); |
| +} |
| + |
| +TEST_F(ChromotingHostListFetcherTest, MultipleRetrieveHostListRequests) { |
| + // First, we will retrieve a valid response from the Directory |
| + SetFakeResponse(GURL(kChromotingHostListProdRequestUrl), |
| + kChromotingHostListReadyResponse, net::HTTP_OK, |
| + net::URLRequestStatus::SUCCESS); |
| + |
| + std::vector<ChromotingHostInfo> ready_hostlist; |
| + |
| + base::RunLoop ready_run_loop; |
| + ChromotingHostListFetcher::HostlistCallback ready_hostlist_fetch_callback = |
| + base::Bind(&OnHostlistRetrieved, |
| + ready_run_loop.QuitClosure(), |
| + &ready_hostlist); |
| + |
| + ChromotingHostListFetcher chromoting_host_list_fetcher; |
| + chromoting_host_list_fetcher.RetrieveHostlist(kAccessTokenValue, |
| + ready_hostlist_fetch_callback); |
| + |
| + ready_run_loop.Run(); |
| + |
| + const unsigned int expected_host_list_size = 2; |
| + EXPECT_EQ(ready_hostlist.size(), expected_host_list_size); |
| + |
| + ChromotingHostInfo online_chromoting_host_info = ready_hostlist.at(0); |
| + const unsigned int expected_patterns_size = 3; |
| + EXPECT_EQ(online_chromoting_host_info.token_url_patterns.size(), |
| + expected_patterns_size); |
| + EXPECT_FALSE(online_chromoting_host_info.host_id.empty()); |
| + EXPECT_FALSE(online_chromoting_host_info.host_jid.empty()); |
| + EXPECT_FALSE(online_chromoting_host_info.host_name.empty()); |
| + EXPECT_EQ(online_chromoting_host_info.status, |
| + ChromotingHostStatus::kChromotingHostStatusOnline); |
| + EXPECT_TRUE(online_chromoting_host_info.offline_reason.empty()); |
| + EXPECT_FALSE(online_chromoting_host_info.public_key.empty()); |
| + |
| + ChromotingHostInfo offline_chromoting_host_info = ready_hostlist.at(1); |
| + EXPECT_TRUE(offline_chromoting_host_info.token_url_patterns.empty()); |
| + EXPECT_FALSE(offline_chromoting_host_info.host_id.empty()); |
| + EXPECT_FALSE(offline_chromoting_host_info.host_jid.empty()); |
| + EXPECT_FALSE(offline_chromoting_host_info.host_name.empty()); |
| + EXPECT_EQ(offline_chromoting_host_info.status, |
| + ChromotingHostStatus::kChromotingHostStatusOffline); |
| + EXPECT_FALSE(offline_chromoting_host_info.offline_reason.empty()); |
| + EXPECT_FALSE(offline_chromoting_host_info.public_key.empty()); |
| + |
| + // Next, we will retrieve an empty items response from the Directory |
| + SetFakeResponse(GURL(kChromotingHostListProdRequestUrl), |
| + kChromotingHostListEmptyItemsResponse, net::HTTP_OK, |
| + net::URLRequestStatus::SUCCESS); |
| + |
| + std::vector<ChromotingHostInfo> empty_items_hostlist; |
| + |
| + base::RunLoop empty_items_run_loop; |
| + |
| + ChromotingHostListFetcher::HostlistCallback empty_hostlist_fetch_callback = |
| + base::Bind(&OnHostlistRetrieved, |
| + empty_items_run_loop.QuitClosure(), |
| + &empty_items_hostlist); |
| + |
| + // Re-use the same chromoting_host_list_fetcher |
| + chromoting_host_list_fetcher.RetrieveHostlist(kAccessTokenValue, |
| + empty_hostlist_fetch_callback); |
| + |
| + empty_items_run_loop.Run(); |
| + // If we received an empty items response, then host list should be empty. |
| + EXPECT_TRUE(empty_items_hostlist.empty()); |
| +} |
| + |
| +} // namespace test |
| +} // namespace remoting |