123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292 |
- // Copyright 2018 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.
- #if !defined(__has_feature) || !__has_feature(objc_arc)
- #error "This file requires ARC support."
- #endif
- #include "remoting/ios/facade/host_list_service.h"
- #import <Foundation/Foundation.h>
- #import "remoting/ios/facade/remoting_authentication.h"
- #import "remoting/ios/facade/remoting_service.h"
- #import "third_party/ocmock/OCMock/OCMock.h"
- #include "base/bind.h"
- #include "base/run_loop.h"
- #include "base/test/task_environment.h"
- #include "base/threading/sequenced_task_runner_handle.h"
- #include "net/http/http_status_code.h"
- #include "remoting/base/directory_service_client.h"
- #include "remoting/base/fake_oauth_token_getter.h"
- #include "remoting/base/protobuf_http_status.h"
- #include "remoting/base/protobuf_http_test_responder.h"
- #include "services/network/public/cpp/shared_url_loader_factory.h"
- #include "testing/gtest/include/gtest/gtest.h"
- #include "testing/gtest_mac.h"
- #include "testing/platform_test.h"
- #include "ui/base/l10n/l10n_util.h"
- #include "ui/base/resource/resource_bundle.h"
- #include "ui/display/screen.h"
- #define EXPECT_HOST_LIST_STATE(expected) \
- EXPECT_EQ(expected, host_list_service_.state())
- #define EXPECT_NO_FETCH_FAILURE() \
- EXPECT_TRUE(host_list_service_.last_fetch_failure() == nullptr)
- namespace remoting {
- namespace {
- apis::v1::HostInfo CreateFakeHost(const std::string& host_id) {
- apis::v1::HostInfo fake_host;
- fake_host.set_host_id(host_id);
- return fake_host;
- }
- apis::v1::GetHostListResponse CreateFakeHostListResponse(
- const std::string& host_id = "fake_host") {
- apis::v1::GetHostListResponse response;
- *response.add_hosts() = CreateFakeHost(host_id);
- return response;
- }
- } // namespace
- class HostListServiceTest : public PlatformTest {
- public:
- HostListServiceTest();
- ~HostListServiceTest() override;
- protected:
- // Respond to a GetHostList request and block until the host list state is
- // changed.
- void BlockAndRespondGetHostList(
- const ProtobufHttpStatus& status,
- const apis::v1::GetHostListResponse& response);
- void NotifyUserUpdate(bool is_signed_in);
- base::test::TaskEnvironment task_environment_;
- ProtobufHttpTestResponder test_responder_;
- FakeOAuthTokenGetter oauth_token_getter_{OAuthTokenGetter::Status::SUCCESS,
- "", ""};
- HostListService host_list_service_;
- int on_fetch_failed_call_count_ = 0;
- int on_host_list_state_changed_call_count_ = 0;
- id remoting_authentication_mock_;
- id remoting_service_mock_;
- private:
- base::CallbackListSubscription host_list_state_subscription_;
- base::CallbackListSubscription fetch_failure_subscription_;
- display::ScopedNativeScreen screen_;
- };
- HostListServiceTest::HostListServiceTest()
- : host_list_service_(base::SequenceBound<DirectoryServiceClient>(
- task_environment_.GetMainThreadTaskRunner(),
- &oauth_token_getter_,
- test_responder_.GetUrlLoaderFactory())) {
- static const char use_cocoa_locale[] = "";
- l10n_util::OverrideLocaleWithCocoaLocale();
- ui::ResourceBundle::InitSharedInstanceWithLocale(
- use_cocoa_locale, NULL, ui::ResourceBundle::DO_NOT_LOAD_COMMON_RESOURCES);
- on_fetch_failed_call_count_ = 0;
- on_host_list_state_changed_call_count_ = 0;
- remoting_authentication_mock_ =
- OCMProtocolMock(@protocol(RemotingAuthentication));
- remoting_service_mock_ = OCMClassMock([RemotingService class]);
- OCMStub([remoting_service_mock_ instance]).andReturn(remoting_service_mock_);
- OCMStub([remoting_service_mock_ authentication])
- .andReturn(remoting_authentication_mock_);
- host_list_state_subscription_ =
- host_list_service_.RegisterHostListStateCallback(base::BindRepeating(
- [](HostListServiceTest* that) {
- that->on_host_list_state_changed_call_count_++;
- },
- base::Unretained(this)));
- fetch_failure_subscription_ =
- host_list_service_.RegisterFetchFailureCallback(base::BindRepeating(
- [](HostListServiceTest* that) {
- that->on_fetch_failed_call_count_++;
- },
- base::Unretained(this)));
- }
- HostListServiceTest::~HostListServiceTest() {
- ui::ResourceBundle::CleanupSharedInstance();
- }
- void HostListServiceTest::BlockAndRespondGetHostList(
- const ProtobufHttpStatus& status,
- const apis::v1::GetHostListResponse& response) {
- base::RunLoop run_loop;
- auto subscription =
- host_list_service_.RegisterHostListStateCallback(run_loop.QuitClosure());
- if (status.ok()) {
- test_responder_.AddResponseToMostRecentRequestUrl(response);
- } else {
- test_responder_.AddErrorToMostRecentRequestUrl(status);
- }
- run_loop.Run();
- }
- void HostListServiceTest::NotifyUserUpdate(bool is_signed_in) {
- NSDictionary* user_info =
- is_signed_in ? @{kUserInfo : [[UserInfo alloc] init]} : @{};
- [NSNotificationCenter.defaultCenter postNotificationName:kUserDidUpdate
- object:nil
- userInfo:user_info];
- }
- TEST_F(HostListServiceTest, SuccessfullyFetchedOneHost) {
- EXPECT_HOST_LIST_STATE(HostListService::State::NOT_FETCHED);
- EXPECT_NO_FETCH_FAILURE();
- host_list_service_.RequestFetch();
- EXPECT_HOST_LIST_STATE(HostListService::State::FETCHING);
- EXPECT_NO_FETCH_FAILURE();
- BlockAndRespondGetHostList(ProtobufHttpStatus::OK(),
- CreateFakeHostListResponse("fake_host_1"));
- EXPECT_HOST_LIST_STATE(HostListService::State::FETCHED);
- EXPECT_NO_FETCH_FAILURE();
- EXPECT_EQ(1u, host_list_service_.hosts().size());
- EXPECT_EQ("fake_host_1", host_list_service_.hosts()[0].host_id());
- EXPECT_EQ(2, on_host_list_state_changed_call_count_);
- EXPECT_EQ(0, on_fetch_failed_call_count_);
- }
- TEST_F(HostListServiceTest, SuccessfullyFetchedTwoHosts_HostListSorted) {
- EXPECT_HOST_LIST_STATE(HostListService::State::NOT_FETCHED);
- EXPECT_NO_FETCH_FAILURE();
- host_list_service_.RequestFetch();
- EXPECT_HOST_LIST_STATE(HostListService::State::FETCHING);
- EXPECT_NO_FETCH_FAILURE();
- apis::v1::GetHostListResponse response;
- response.add_hosts()->set_host_name("Host 2");
- response.add_hosts()->set_host_name("Host 1");
- BlockAndRespondGetHostList(ProtobufHttpStatus::OK(), response);
- EXPECT_HOST_LIST_STATE(HostListService::State::FETCHED);
- EXPECT_NO_FETCH_FAILURE();
- EXPECT_EQ(2u, host_list_service_.hosts().size());
- EXPECT_EQ("Host 1", host_list_service_.hosts()[0].host_name());
- EXPECT_EQ("Host 2", host_list_service_.hosts()[1].host_name());
- EXPECT_EQ(2, on_host_list_state_changed_call_count_);
- EXPECT_EQ(0, on_fetch_failed_call_count_);
- }
- TEST_F(HostListServiceTest, FetchHostListRequestFailed) {
- EXPECT_HOST_LIST_STATE(HostListService::State::NOT_FETCHED);
- EXPECT_NO_FETCH_FAILURE();
- host_list_service_.RequestFetch();
- EXPECT_HOST_LIST_STATE(HostListService::State::FETCHING);
- EXPECT_NO_FETCH_FAILURE();
- BlockAndRespondGetHostList(
- ProtobufHttpStatus(ProtobufHttpStatus::Code::INTERNAL, "Internal error"),
- {});
- EXPECT_HOST_LIST_STATE(HostListService::State::NOT_FETCHED);
- EXPECT_EQ(HostListService::FetchFailureReason::UNKNOWN_ERROR,
- host_list_service_.last_fetch_failure()->reason);
- EXPECT_EQ("Internal error",
- host_list_service_.last_fetch_failure()->localized_description);
- EXPECT_TRUE(host_list_service_.hosts().empty());
- EXPECT_EQ(2, on_host_list_state_changed_call_count_);
- EXPECT_EQ(1, on_fetch_failed_call_count_);
- }
- TEST_F(HostListServiceTest, FetchHostListRequestUnauthenticated_signOut) {
- EXPECT_HOST_LIST_STATE(HostListService::State::NOT_FETCHED);
- EXPECT_NO_FETCH_FAILURE();
- host_list_service_.RequestFetch();
- EXPECT_HOST_LIST_STATE(HostListService::State::FETCHING);
- EXPECT_NO_FETCH_FAILURE();
- OCMExpect([remoting_authentication_mock_ logout]);
- BlockAndRespondGetHostList(
- ProtobufHttpStatus(ProtobufHttpStatus::Code::UNAUTHENTICATED,
- "Unauthenticated"),
- {});
- EXPECT_HOST_LIST_STATE(HostListService::State::NOT_FETCHED);
- [remoting_authentication_mock_ verifyAtLocation:nil];
- EXPECT_EQ(2, on_host_list_state_changed_call_count_);
- EXPECT_EQ(1, on_fetch_failed_call_count_);
- }
- TEST_F(HostListServiceTest, RequestFetchWhileFetching_ignoreSecondRequest) {
- EXPECT_HOST_LIST_STATE(HostListService::State::NOT_FETCHED);
- host_list_service_.RequestFetch();
- EXPECT_HOST_LIST_STATE(HostListService::State::FETCHING);
- host_list_service_.RequestFetch();
- EXPECT_HOST_LIST_STATE(HostListService::State::FETCHING);
- EXPECT_EQ(1, on_host_list_state_changed_call_count_);
- EXPECT_EQ(0, on_fetch_failed_call_count_);
- }
- TEST_F(HostListServiceTest, UserLogOut_cancelFetch) {
- EXPECT_HOST_LIST_STATE(HostListService::State::NOT_FETCHED);
- host_list_service_.RequestFetch();
- EXPECT_HOST_LIST_STATE(HostListService::State::FETCHING);
- NotifyUserUpdate(false);
- EXPECT_HOST_LIST_STATE(HostListService::State::NOT_FETCHED);
- EXPECT_EQ(2, on_host_list_state_changed_call_count_);
- EXPECT_EQ(0, on_fetch_failed_call_count_);
- }
- TEST_F(HostListServiceTest, UserSwitchAccount_cancelThenRequestNewFetch) {
- EXPECT_HOST_LIST_STATE(HostListService::State::NOT_FETCHED);
- host_list_service_.RequestFetch();
- EXPECT_HOST_LIST_STATE(HostListService::State::FETCHING);
- ASSERT_EQ(1, test_responder_.GetNumPending());
- NotifyUserUpdate(true);
- // The HostListService should have cancelled the previous request and created
- // a new request.
- ASSERT_EQ(2, test_responder_.GetNumPending());
- ASSERT_FALSE(test_responder_.GetPendingRequest(0).client.is_connected());
- ASSERT_TRUE(test_responder_.GetPendingRequest(1).client.is_connected());
- EXPECT_HOST_LIST_STATE(HostListService::State::FETCHING);
- BlockAndRespondGetHostList(ProtobufHttpStatus::OK(),
- CreateFakeHostListResponse("fake_host_id"));
- EXPECT_HOST_LIST_STATE(HostListService::State::FETCHED);
- EXPECT_EQ(1u, host_list_service_.hosts().size());
- EXPECT_EQ("fake_host_id", host_list_service_.hosts()[0].host_id());
- // Note that there is an extra FETCHING->NOT_FETCH change during
- // NotifyUserUpdate(true).
- EXPECT_EQ(4, on_host_list_state_changed_call_count_);
- EXPECT_EQ(0, on_fetch_failed_call_count_);
- }
- } // namespace remoting
|