Index: remoting/test/host_list_fetcher_unittest.cc |
diff --git a/remoting/test/host_list_fetcher_unittest.cc b/remoting/test/host_list_fetcher_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..7f7baf5b6e251c2f88aba7929919a642df5db7fc |
--- /dev/null |
+++ b/remoting/test/host_list_fetcher_unittest.cc |
@@ -0,0 +1,444 @@ |
+// 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/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/host_info.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace { |
+ |
+// Used as a HostListCallback for testing. |
+void OnHostlistRetrieved( |
+ base::Closure done_closure, |
+ std::vector<remoting::test::HostInfo>* hostlist, |
+ const std::vector<remoting::test::HostInfo>& retrieved_hostlist) { |
+ *hostlist = retrieved_hostlist; |
+ |
+ done_closure.Run(); |
+} |
+ |
+const char kAccessTokenValue[] = "test_access_token_value"; |
+const char kHostListReadyResponse[] = |
+"{" |
+" \"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 kHostListMissingParametersResponse[] = |
+"{" |
+" \"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\":\"OFFLINE\"," |
+" \"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\"" |
+" }" |
+" ]" |
+" }" |
+"}"; |
+const char kHostListEmptyTokenUrlPatternsResponse[] = |
+"{" |
+" \"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 kHostListEmptyItemsResponse[] = |
+"{" |
+" \"data\":{" |
+" \"kind\":\"chromoting#hostList\"," |
+" \"items\":[" |
+" ]" |
+" }" |
+"}"; |
+const char kHostListEmptyResponse[] = "{}"; |
+ |
+const unsigned int expected_empty_patterns_host_list_size = 1; |
joedow
2015/07/09 03:09:56
const values should use the kNoUnderscoresNamingSc
tonychun
2015/07/09 17:36:22
Done.
|
+const unsigned int expected_host_list_size = 2; |
+const unsigned int expected_patterns_size = 3; |
+ |
+} // namespace |
+ |
+namespace remoting { |
+namespace test { |
+ |
+// Provides base functionality for the HostListFetcher 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 |
+// HostListFetcher. This fixture also creates an IO MessageLoop |
+// for use by the HostListFetcher. |
+class HostListFetcherTest : public ::testing::Test { |
+ public: |
+ HostListFetcherTest() : url_fetcher_factory_(nullptr) {} |
+ ~HostListFetcherTest() 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(HostListFetcherTest); |
+}; |
+ |
+void HostListFetcherTest::SetUp() { |
+ DCHECK(!message_loop_); |
+ message_loop_.reset(new base::MessageLoopForIO); |
+ |
+ SetFakeResponse(GURL(kHostListProdRequestUrl), |
+ kHostListEmptyResponse, net::HTTP_NOT_FOUND, |
+ net::URLRequestStatus::FAILED); |
+} |
+ |
+void HostListFetcherTest::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(HostListFetcherTest, RetrieveHostListFromProd) { |
+ SetFakeResponse(GURL(kHostListProdRequestUrl), |
+ kHostListReadyResponse, net::HTTP_OK, |
+ net::URLRequestStatus::SUCCESS); |
+ |
+ std::vector<HostInfo> hostlist; |
+ |
+ base::RunLoop run_loop; |
+ HostListFetcher::HostlistCallback host_list_callback = |
+ base::Bind(&OnHostlistRetrieved, run_loop.QuitClosure(), &hostlist); |
+ |
+ HostListFetcher host_list_fetcher; |
+ host_list_fetcher.RetrieveHostlist(kAccessTokenValue, host_list_callback); |
+ |
+ run_loop.Run(); |
+ |
+ EXPECT_EQ(hostlist.size(), expected_host_list_size); |
+ |
+ HostInfo online_host_info = hostlist.at(0); |
+ EXPECT_EQ(online_host_info.token_url_patterns.size(), expected_patterns_size); |
+ EXPECT_FALSE(online_host_info.host_id.empty()); |
+ EXPECT_FALSE(online_host_info.host_jid.empty()); |
+ EXPECT_FALSE(online_host_info.host_name.empty()); |
+ EXPECT_EQ(online_host_info.status, HostStatus::kHostStatusOnline); |
+ EXPECT_TRUE(online_host_info.offline_reason.empty()); |
+ EXPECT_FALSE(online_host_info.public_key.empty()); |
+ |
+ HostInfo offline_host_info = hostlist.at(1); |
+ EXPECT_TRUE(offline_host_info.token_url_patterns.empty()); |
+ EXPECT_FALSE(offline_host_info.host_id.empty()); |
+ EXPECT_FALSE(offline_host_info.host_jid.empty()); |
+ EXPECT_FALSE(offline_host_info.host_name.empty()); |
+ EXPECT_EQ(offline_host_info.status, HostStatus::kHostStatusOffline); |
+ EXPECT_FALSE(offline_host_info.offline_reason.empty()); |
+ EXPECT_FALSE(offline_host_info.public_key.empty()); |
+} |
+ |
+TEST_F(HostListFetcherTest, RetrieveHostListWithEmptyPatterns) { |
+ SetFakeResponse(GURL(kHostListProdRequestUrl), |
+ kHostListEmptyTokenUrlPatternsResponse, net::HTTP_OK, |
+ net::URLRequestStatus::SUCCESS); |
+ |
+ std::vector<HostInfo> hostlist; |
+ |
+ base::RunLoop run_loop; |
+ HostListFetcher::HostlistCallback host_list_callback = |
+ base::Bind(&OnHostlistRetrieved, run_loop.QuitClosure(), &hostlist); |
+ |
+ HostListFetcher host_list_fetcher; |
+ host_list_fetcher.RetrieveHostlist(kAccessTokenValue, host_list_callback); |
+ |
+ run_loop.Run(); |
+ |
+ EXPECT_EQ(hostlist.size(), expected_empty_patterns_host_list_size); |
+ |
+ // While this is unlikely to happen, empty token url patterns are handled. |
+ HostInfo online_host_info = hostlist.at(0); |
+ EXPECT_TRUE(online_host_info.token_url_patterns.empty()); |
+ EXPECT_FALSE(online_host_info.host_id.empty()); |
+ EXPECT_FALSE(online_host_info.host_jid.empty()); |
+ EXPECT_FALSE(online_host_info.host_name.empty()); |
+ EXPECT_EQ(online_host_info.status, HostStatus::kHostStatusOnline); |
+ EXPECT_TRUE(online_host_info.offline_reason.empty()); |
+ EXPECT_FALSE(online_host_info.public_key.empty()); |
+} |
+ |
+TEST_F(HostListFetcherTest, |
+ RetrieveHostListMissingParametersResponse) { |
+ SetFakeResponse(GURL(kHostListProdRequestUrl), |
+ kHostListMissingParametersResponse, net::HTTP_OK, |
+ net::URLRequestStatus::SUCCESS); |
+ |
+ std::vector<HostInfo> hostlist; |
+ |
+ base::RunLoop run_loop; |
+ HostListFetcher::HostlistCallback host_list_callback = |
+ base::Bind(&OnHostlistRetrieved, run_loop.QuitClosure(), &hostlist); |
+ |
+ HostListFetcher host_list_fetcher; |
+ host_list_fetcher.RetrieveHostlist(kAccessTokenValue, host_list_callback); |
+ run_loop.Run(); |
+ |
+ EXPECT_EQ(hostlist.size(), expected_host_list_size); |
+ |
+ HostInfo no_jid_host_info = hostlist.at(0); |
+ EXPECT_EQ(no_jid_host_info.token_url_patterns.size(), expected_patterns_size); |
+ EXPECT_FALSE(no_jid_host_info.host_id.empty()); |
+ EXPECT_TRUE(no_jid_host_info.host_jid.empty()); |
+ EXPECT_FALSE(no_jid_host_info.host_name.empty()); |
+ EXPECT_EQ(no_jid_host_info.status, HostStatus::kHostStatusOffline); |
+ EXPECT_TRUE(no_jid_host_info.offline_reason.empty()); |
+ EXPECT_FALSE(no_jid_host_info.public_key.empty()); |
+ |
+ HostInfo no_offline_reason_host_info = hostlist.at(1); |
+ EXPECT_TRUE(no_offline_reason_host_info.token_url_patterns.empty()); |
+ EXPECT_FALSE(no_offline_reason_host_info.host_id.empty()); |
+ EXPECT_FALSE(no_offline_reason_host_info.host_jid.empty()); |
+ EXPECT_FALSE(no_offline_reason_host_info.host_name.empty()); |
+ EXPECT_EQ(no_offline_reason_host_info.status, HostStatus::kHostStatusOffline); |
+ EXPECT_TRUE(no_offline_reason_host_info.offline_reason.empty()); |
+ EXPECT_FALSE(no_offline_reason_host_info.public_key.empty()); |
+} |
+ |
+ |
+TEST_F(HostListFetcherTest, RetrieveHostListNetworkError) { |
+ base::RunLoop run_loop; |
+ |
+ std::vector<HostInfo> hostlist; |
+ |
+ HostListFetcher::HostlistCallback host_list_callback = |
+ base::Bind(&OnHostlistRetrieved, run_loop.QuitClosure(), &hostlist); |
+ |
+ HostListFetcher host_list_fetcher; |
+ host_list_fetcher.RetrieveHostlist(kAccessTokenValue, host_list_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(HostListFetcherTest, RetrieveHostListEmptyItemsResponse) { |
+ SetFakeResponse(GURL(kHostListProdRequestUrl), |
+ kHostListEmptyItemsResponse, net::HTTP_OK, |
+ net::URLRequestStatus::SUCCESS); |
+ |
+ base::RunLoop run_loop; |
+ |
+ std::vector<HostInfo> hostlist; |
+ |
+ HostListFetcher::HostlistCallback host_list_callback = |
+ base::Bind(&OnHostlistRetrieved, run_loop.QuitClosure(), &hostlist); |
+ |
+ HostListFetcher host_list_fetcher; |
+ host_list_fetcher.RetrieveHostlist(kAccessTokenValue, host_list_callback); |
+ run_loop.Run(); |
+ |
+ // If we received an empty items response, then host list should be empty. |
+ EXPECT_TRUE(hostlist.empty()); |
+} |
+ |
+TEST_F(HostListFetcherTest, RetrieveHostListEmptyResponse) { |
+ SetFakeResponse(GURL(kHostListProdRequestUrl), |
+ kHostListEmptyResponse, net::HTTP_OK, |
+ net::URLRequestStatus::SUCCESS); |
+ |
+ base::RunLoop run_loop; |
+ |
+ std::vector<HostInfo> hostlist; |
+ |
+ HostListFetcher::HostlistCallback host_list_callback = |
+ base::Bind(&OnHostlistRetrieved, run_loop.QuitClosure(), &hostlist); |
+ |
+ HostListFetcher host_list_fetcher; |
+ host_list_fetcher.RetrieveHostlist(kAccessTokenValue, host_list_callback); |
+ run_loop.Run(); |
+ |
+ // If we received an empty response, then host list should be empty. |
+ EXPECT_TRUE(hostlist.empty()); |
+} |
+ |
+TEST_F(HostListFetcherTest, MultipleRetrieveHostListRequests) { |
+ // First, we will retrieve a valid response from the directory service. |
+ SetFakeResponse(GURL(kHostListProdRequestUrl), |
+ kHostListReadyResponse, net::HTTP_OK, |
+ net::URLRequestStatus::SUCCESS); |
+ |
+ std::vector<HostInfo> ready_hostlist; |
+ |
+ base::RunLoop ready_run_loop; |
+ HostListFetcher::HostlistCallback ready_host_list_callback = |
+ base::Bind(&OnHostlistRetrieved, |
+ ready_run_loop.QuitClosure(), |
+ &ready_hostlist); |
+ |
+ HostListFetcher host_list_fetcher; |
+ host_list_fetcher.RetrieveHostlist(kAccessTokenValue, |
+ ready_host_list_callback); |
+ |
+ ready_run_loop.Run(); |
+ |
+ EXPECT_EQ(ready_hostlist.size(), expected_host_list_size); |
+ |
+ HostInfo online_host_info = ready_hostlist.at(0); |
+ EXPECT_EQ(online_host_info.token_url_patterns.size(), expected_patterns_size); |
+ EXPECT_FALSE(online_host_info.host_id.empty()); |
+ EXPECT_FALSE(online_host_info.host_jid.empty()); |
+ EXPECT_FALSE(online_host_info.host_name.empty()); |
+ EXPECT_EQ(online_host_info.status, HostStatus::kHostStatusOnline); |
+ EXPECT_TRUE(online_host_info.offline_reason.empty()); |
+ EXPECT_FALSE(online_host_info.public_key.empty()); |
+ |
+ HostInfo offline_host_info = ready_hostlist.at(1); |
+ EXPECT_TRUE(offline_host_info.token_url_patterns.empty()); |
+ EXPECT_FALSE(offline_host_info.host_id.empty()); |
+ EXPECT_FALSE(offline_host_info.host_jid.empty()); |
+ EXPECT_FALSE(offline_host_info.host_name.empty()); |
+ EXPECT_EQ(offline_host_info.status, HostStatus::kHostStatusOffline); |
+ EXPECT_FALSE(offline_host_info.offline_reason.empty()); |
+ EXPECT_FALSE(offline_host_info.public_key.empty()); |
+ |
+ // Next, we will retrieve an empty items response from the directory service. |
+ SetFakeResponse(GURL(kHostListProdRequestUrl), |
+ kHostListEmptyItemsResponse, net::HTTP_OK, |
+ net::URLRequestStatus::SUCCESS); |
+ |
+ std::vector<HostInfo> empty_items_hostlist; |
+ |
+ base::RunLoop empty_items_run_loop; |
+ |
+ HostListFetcher::HostlistCallback empty_host_list_callback = |
+ base::Bind(&OnHostlistRetrieved, |
+ empty_items_run_loop.QuitClosure(), |
+ &empty_items_hostlist); |
+ |
+ // Re-use the same host_list_fetcher. |
+ host_list_fetcher.RetrieveHostlist(kAccessTokenValue, |
+ empty_host_list_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 |