blob: fe8416052c8a1f80b68f68ad2188f67d1f5ce698 [file] [log] [blame]
// 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/app_remoting_test_driver_environment.h"
#include <stddef.h>
#include <algorithm>
#include <utility>
#include "base/files/file_path.h"
#include "base/macros.h"
#include "remoting/test/fake_access_token_fetcher.h"
#include "remoting/test/fake_app_remoting_report_issue_request.h"
#include "remoting/test/fake_refresh_token_store.h"
#include "remoting/test/fake_remote_host_info_fetcher.h"
#include "remoting/test/mock_access_token_fetcher.h"
#include "remoting/test/refresh_token_store.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
const char kAuthCodeValue[] = "4/892379827345jkefvkdfbv";
const char kUserNameValue[] = "remoting_user@gmail.com";
const char kTestApplicationId[] = "sadlkjlsjgadjfgoajdfgagb";
const char kAnotherTestApplicationId[] = "waklgoisdhfnvjkdsfbljn";
const char kTestHostId1[] = "awesome_test_host_id";
const char kTestHostId2[] = "super_awesome_test_host_id";
const char kTestHostId3[] = "uber_awesome_test_host_id";
}
namespace remoting {
namespace test {
using testing::_;
class AppRemotingTestDriverEnvironmentTest : public ::testing::Test {
public:
AppRemotingTestDriverEnvironmentTest();
~AppRemotingTestDriverEnvironmentTest() override;
FakeAccessTokenFetcher* fake_access_token_fetcher() const {
return fake_access_token_fetcher_;
}
protected:
void Initialize();
void Initialize(
const AppRemotingTestDriverEnvironment::EnvironmentOptions& options);
FakeAccessTokenFetcher* fake_access_token_fetcher_;
FakeAppRemotingReportIssueRequest fake_report_issue_request_;
FakeRefreshTokenStore fake_token_store_;
FakeRemoteHostInfoFetcher fake_remote_host_info_fetcher_;
MockAccessTokenFetcher mock_access_token_fetcher_;
std::unique_ptr<AppRemotingTestDriverEnvironment> environment_object_;
private:
DISALLOW_COPY_AND_ASSIGN(AppRemotingTestDriverEnvironmentTest);
};
AppRemotingTestDriverEnvironmentTest::AppRemotingTestDriverEnvironmentTest()
: fake_access_token_fetcher_(nullptr) {
}
AppRemotingTestDriverEnvironmentTest::~AppRemotingTestDriverEnvironmentTest() =
default;
void AppRemotingTestDriverEnvironmentTest::Initialize() {
AppRemotingTestDriverEnvironment::EnvironmentOptions options;
options.user_name = kUserNameValue;
options.service_environment = kDeveloperEnvironment;
Initialize(options);
}
void AppRemotingTestDriverEnvironmentTest::Initialize(
const AppRemotingTestDriverEnvironment::EnvironmentOptions& options) {
environment_object_.reset(new AppRemotingTestDriverEnvironment(options));
std::unique_ptr<FakeAccessTokenFetcher> fake_access_token_fetcher(
new FakeAccessTokenFetcher());
fake_access_token_fetcher_ = fake_access_token_fetcher.get();
mock_access_token_fetcher_.SetAccessTokenFetcher(
std::move(fake_access_token_fetcher));
environment_object_->SetAccessTokenFetcherForTest(
&mock_access_token_fetcher_);
environment_object_->SetAppRemotingReportIssueRequestForTest(
&fake_report_issue_request_);
environment_object_->SetRefreshTokenStoreForTest(&fake_token_store_);
environment_object_->SetRemoteHostInfoFetcherForTest(
&fake_remote_host_info_fetcher_);
}
TEST_F(AppRemotingTestDriverEnvironmentTest, InitializeObjectWithAuthCode) {
Initialize();
EXPECT_CALL(mock_access_token_fetcher_, GetAccessTokenFromAuthCode(_, _));
EXPECT_CALL(mock_access_token_fetcher_, GetAccessTokenFromRefreshToken(_, _))
.Times(0);
EXPECT_TRUE(environment_object_->Initialize(kAuthCodeValue));
EXPECT_TRUE(fake_token_store_.refresh_token_write_attempted());
EXPECT_EQ(fake_token_store_.stored_refresh_token_value(),
kFakeAccessTokenFetcherRefreshTokenValue);
EXPECT_EQ(environment_object_->user_name(), kUserNameValue);
EXPECT_EQ(environment_object_->access_token(),
kFakeAccessTokenFetcherAccessTokenValue);
// Attempt to init again, we should not see any additional calls or errors.
EXPECT_TRUE(environment_object_->Initialize(kAuthCodeValue));
}
TEST_F(AppRemotingTestDriverEnvironmentTest,
InitializeObjectWithAuthCodeFailed) {
Initialize();
fake_access_token_fetcher()->set_fail_access_token_from_auth_code(true);
EXPECT_CALL(mock_access_token_fetcher_, GetAccessTokenFromAuthCode(_, _));
EXPECT_CALL(mock_access_token_fetcher_, GetAccessTokenFromRefreshToken(_, _))
.Times(0);
EXPECT_FALSE(environment_object_->Initialize(kAuthCodeValue));
EXPECT_FALSE(fake_token_store_.refresh_token_write_attempted());
}
TEST_F(AppRemotingTestDriverEnvironmentTest, InitializeObjectWithRefreshToken) {
Initialize();
EXPECT_CALL(mock_access_token_fetcher_, GetAccessTokenFromRefreshToken(_, _));
EXPECT_CALL(mock_access_token_fetcher_, GetAccessTokenFromAuthCode(_, _))
.Times(0);
// Pass in an empty auth code since we are using a refresh token.
EXPECT_TRUE(environment_object_->Initialize(std::string()));
// We should not write the refresh token a second time if we read from the
// disk originally.
EXPECT_FALSE(fake_token_store_.refresh_token_write_attempted());
// Verify the object was initialized correctly.
EXPECT_EQ(environment_object_->user_name(), kUserNameValue);
EXPECT_EQ(environment_object_->access_token(),
kFakeAccessTokenFetcherAccessTokenValue);
// Attempt to init again, we should not see any additional calls or errors.
EXPECT_TRUE(environment_object_->Initialize(std::string()));
}
TEST_F(AppRemotingTestDriverEnvironmentTest, TearDownAfterInitializeSucceeds) {
Initialize();
EXPECT_CALL(mock_access_token_fetcher_, GetAccessTokenFromRefreshToken(_, _));
EXPECT_CALL(mock_access_token_fetcher_, GetAccessTokenFromAuthCode(_, _))
.Times(0);
// Pass in an empty auth code since we are using a refresh token.
EXPECT_TRUE(environment_object_->Initialize(std::string()));
// Note: We are using a static cast here because the TearDown() method is
// private as it is an interface method that we only want to call
// directly in tests or by the GTEST framework.
static_cast<testing::Environment*>(environment_object_.get())->TearDown();
}
TEST_F(AppRemotingTestDriverEnvironmentTest,
InitializeObjectWithRefreshTokenFailed) {
Initialize();
fake_access_token_fetcher()->set_fail_access_token_from_refresh_token(true);
EXPECT_CALL(mock_access_token_fetcher_, GetAccessTokenFromRefreshToken(_, _));
EXPECT_CALL(mock_access_token_fetcher_, GetAccessTokenFromAuthCode(_, _))
.Times(0);
// Pass in an empty auth code since we are using a refresh token.
EXPECT_FALSE(environment_object_->Initialize(std::string()));
EXPECT_FALSE(fake_token_store_.refresh_token_write_attempted());
}
TEST_F(AppRemotingTestDriverEnvironmentTest,
InitializeObjectNoAuthCodeOrRefreshToken) {
Initialize();
// Neither method should be called in this scenario.
EXPECT_CALL(mock_access_token_fetcher_, GetAccessTokenFromAuthCode(_, _))
.Times(0);
EXPECT_CALL(mock_access_token_fetcher_, GetAccessTokenFromRefreshToken(_, _))
.Times(0);
// Clear out the 'stored' refresh token value.
fake_token_store_.set_refresh_token_value(std::string());
// With no auth code or refresh token, then the initialization should fail.
EXPECT_FALSE(environment_object_->Initialize(std::string()));
EXPECT_FALSE(fake_token_store_.refresh_token_write_attempted());
}
TEST_F(AppRemotingTestDriverEnvironmentTest,
InitializeObjectWithAuthCodeWriteFailed) {
Initialize();
EXPECT_CALL(mock_access_token_fetcher_, GetAccessTokenFromAuthCode(_, _));
EXPECT_CALL(mock_access_token_fetcher_, GetAccessTokenFromRefreshToken(_, _))
.Times(0);
// Simulate a failure writing the token to the disk.
fake_token_store_.set_refresh_token_write_succeeded(false);
EXPECT_FALSE(environment_object_->Initialize(kAuthCodeValue));
EXPECT_TRUE(fake_token_store_.refresh_token_write_attempted());
}
TEST_F(AppRemotingTestDriverEnvironmentTest,
RefreshAccessTokenAfterUsingAuthCode) {
Initialize();
{
testing::InSequence call_sequence;
EXPECT_CALL(mock_access_token_fetcher_, GetAccessTokenFromAuthCode(_, _));
EXPECT_CALL(mock_access_token_fetcher_,
GetAccessTokenFromRefreshToken(_, _));
}
EXPECT_TRUE(environment_object_->Initialize(kAuthCodeValue));
EXPECT_TRUE(fake_token_store_.refresh_token_write_attempted());
EXPECT_EQ(fake_token_store_.stored_refresh_token_value(),
kFakeAccessTokenFetcherRefreshTokenValue);
EXPECT_EQ(environment_object_->user_name(), kUserNameValue);
EXPECT_EQ(environment_object_->access_token(),
kFakeAccessTokenFetcherAccessTokenValue);
// Attempt to init again, we should not see any additional calls or errors.
EXPECT_TRUE(environment_object_->RefreshAccessToken());
}
TEST_F(AppRemotingTestDriverEnvironmentTest, RefreshAccessTokenFailure) {
Initialize();
{
testing::InSequence call_sequence;
// Mock is set up for this call to succeed.
EXPECT_CALL(mock_access_token_fetcher_, GetAccessTokenFromAuthCode(_, _));
// Mock is set up for this call to fail.
EXPECT_CALL(mock_access_token_fetcher_,
GetAccessTokenFromRefreshToken(_, _));
}
EXPECT_TRUE(environment_object_->Initialize(kAuthCodeValue));
EXPECT_TRUE(fake_token_store_.refresh_token_write_attempted());
EXPECT_EQ(fake_token_store_.stored_refresh_token_value(),
kFakeAccessTokenFetcherRefreshTokenValue);
EXPECT_EQ(environment_object_->user_name(), kUserNameValue);
EXPECT_EQ(environment_object_->access_token(),
kFakeAccessTokenFetcherAccessTokenValue);
fake_access_token_fetcher()->set_fail_access_token_from_refresh_token(true);
// We expect the refresh to have failed, the user name to remain valid,
// and the access token to have been cleared.
EXPECT_FALSE(environment_object_->RefreshAccessToken());
EXPECT_TRUE(environment_object_->access_token().empty());
EXPECT_EQ(environment_object_->user_name(), kUserNameValue);
}
TEST_F(AppRemotingTestDriverEnvironmentTest, GetRemoteHostInfoSuccess) {
Initialize();
// Pass in an empty auth code since we are using a refresh token.
EXPECT_TRUE(environment_object_->Initialize(std::string()));
RemoteHostInfo remote_host_info;
EXPECT_TRUE(environment_object_->GetRemoteHostInfoForApplicationId(
kTestApplicationId, &remote_host_info));
EXPECT_TRUE(remote_host_info.IsReadyForConnection());
}
TEST_F(AppRemotingTestDriverEnvironmentTest, GetRemoteHostInfoFailure) {
Initialize();
// Pass in an empty auth code since we are using a refresh token.
EXPECT_TRUE(environment_object_->Initialize(std::string()));
fake_remote_host_info_fetcher_.set_fail_retrieve_remote_host_info(true);
RemoteHostInfo remote_host_info;
EXPECT_FALSE(environment_object_->GetRemoteHostInfoForApplicationId(
kTestApplicationId, &remote_host_info));
}
TEST_F(AppRemotingTestDriverEnvironmentTest,
GetRemoteHostInfoWithoutInitializing) {
Initialize();
RemoteHostInfo remote_host_info;
EXPECT_FALSE(environment_object_->GetRemoteHostInfoForApplicationId(
kTestApplicationId, &remote_host_info));
}
TEST_F(AppRemotingTestDriverEnvironmentTest, NoRemoteHostsReleasedOnTearDown) {
// Use the default options as the flag to release the remote hosts is not
// enabled by default.
Initialize();
// Pass in an empty auth code since we are using a refresh token.
EXPECT_TRUE(environment_object_->Initialize(std::string()));
RemoteHostInfo remote_host_info;
EXPECT_TRUE(environment_object_->GetRemoteHostInfoForApplicationId(
kTestApplicationId, &remote_host_info));
EXPECT_TRUE(remote_host_info.IsReadyForConnection());
EXPECT_EQ(fake_report_issue_request_.get_host_ids_released().size(), 0UL);
environment_object_->AddHostToReleaseList(kTestApplicationId, kTestHostId1);
// Note: We are using a static cast here because the TearDown() method is
// private as it is an interface method that we only want to call
// directly in tests or by the GTEST framework.
static_cast<testing::Environment*>(environment_object_.get())->TearDown();
// Verify no hosts were released via a report issue request.
EXPECT_EQ(fake_report_issue_request_.get_host_ids_released().size(), 0UL);
}
TEST_F(AppRemotingTestDriverEnvironmentTest, OneRemoteHostReleasedOnTearDown) {
AppRemotingTestDriverEnvironment::EnvironmentOptions options;
options.user_name = kUserNameValue;
options.release_hosts_when_done = true;
options.service_environment = kDeveloperEnvironment;
Initialize(options);
// Pass in an empty auth code since we are using a refresh token.
EXPECT_TRUE(environment_object_->Initialize(std::string()));
RemoteHostInfo remote_host_info;
EXPECT_TRUE(environment_object_->GetRemoteHostInfoForApplicationId(
kTestApplicationId, &remote_host_info));
EXPECT_TRUE(remote_host_info.IsReadyForConnection());
EXPECT_EQ(fake_report_issue_request_.get_host_ids_released().size(), 0UL);
environment_object_->AddHostToReleaseList(kTestApplicationId, kTestHostId1);
// Note: We are using a static cast here because the TearDown() method is
// private as it is an interface method that we only want to call
// directly in tests or by the GTEST framework.
static_cast<testing::Environment*>(environment_object_.get())->TearDown();
std::string expected_host(
MakeFormattedStringForReleasedHost(kTestApplicationId, kTestHostId1));
std::vector<std::string> actual_host_list =
fake_report_issue_request_.get_host_ids_released();
EXPECT_EQ(actual_host_list.size(), 1UL);
EXPECT_EQ(actual_host_list[0], expected_host);
}
TEST_F(AppRemotingTestDriverEnvironmentTest, RemoteHostsReleasedOnTearDown) {
AppRemotingTestDriverEnvironment::EnvironmentOptions options;
options.user_name = kUserNameValue;
options.release_hosts_when_done = true;
options.service_environment = kDeveloperEnvironment;
Initialize(options);
// Pass in an empty auth code since we are using a refresh token.
EXPECT_TRUE(environment_object_->Initialize(std::string()));
RemoteHostInfo remote_host_info;
EXPECT_TRUE(environment_object_->GetRemoteHostInfoForApplicationId(
kTestApplicationId, &remote_host_info));
EXPECT_TRUE(remote_host_info.IsReadyForConnection());
std::vector<std::string> expected_host_list;
environment_object_->AddHostToReleaseList(kTestApplicationId, kTestHostId1);
expected_host_list.push_back(
MakeFormattedStringForReleasedHost(kTestApplicationId, kTestHostId1));
environment_object_->AddHostToReleaseList(kAnotherTestApplicationId,
kTestHostId2);
expected_host_list.push_back(MakeFormattedStringForReleasedHost(
kAnotherTestApplicationId, kTestHostId2));
environment_object_->AddHostToReleaseList(kTestApplicationId, kTestHostId3);
expected_host_list.push_back(
MakeFormattedStringForReleasedHost(kTestApplicationId, kTestHostId3));
// Note: We are using a static cast here because the TearDown() method is
// private as it is an interface method that we only want to call
// directly in tests or by the GTEST framework.
static_cast<testing::Environment*>(environment_object_.get())->TearDown();
std::vector<std::string> actual_host_list =
fake_report_issue_request_.get_host_ids_released();
std::sort(actual_host_list.begin(), actual_host_list.end());
std::sort(expected_host_list.begin(), expected_host_list.end());
EXPECT_EQ(actual_host_list.size(), expected_host_list.size());
for (size_t i = 0; i < actual_host_list.size(); ++i) {
EXPECT_EQ(actual_host_list[i], expected_host_list[i]);
}
}
TEST_F(AppRemotingTestDriverEnvironmentTest, RemoteHostsReleasedOnce) {
AppRemotingTestDriverEnvironment::EnvironmentOptions options;
options.user_name = kUserNameValue;
options.release_hosts_when_done = true;
options.service_environment = kDeveloperEnvironment;
Initialize(options);
// Pass in an empty auth code since we are using a refresh token.
EXPECT_TRUE(environment_object_->Initialize(std::string()));
RemoteHostInfo remote_host_info;
EXPECT_TRUE(environment_object_->GetRemoteHostInfoForApplicationId(
kTestApplicationId, &remote_host_info));
EXPECT_TRUE(remote_host_info.IsReadyForConnection());
std::vector<std::string> expected_host_list;
environment_object_->AddHostToReleaseList(kTestApplicationId, kTestHostId1);
expected_host_list.push_back(
MakeFormattedStringForReleasedHost(kTestApplicationId, kTestHostId1));
environment_object_->AddHostToReleaseList(kAnotherTestApplicationId,
kTestHostId2);
expected_host_list.push_back(MakeFormattedStringForReleasedHost(
kAnotherTestApplicationId, kTestHostId2));
environment_object_->AddHostToReleaseList(kTestApplicationId, kTestHostId3);
expected_host_list.push_back(
MakeFormattedStringForReleasedHost(kTestApplicationId, kTestHostId3));
// Attempt to add the previous hosts again, they should not be added since
// they will already exist in the list of hosts to release.
environment_object_->AddHostToReleaseList(kTestApplicationId, kTestHostId1);
environment_object_->AddHostToReleaseList(kAnotherTestApplicationId,
kTestHostId2);
environment_object_->AddHostToReleaseList(kTestApplicationId, kTestHostId3);
// Note: We are using a static cast here because the TearDown() method is
// private as it is an interface method that we only want to call
// directly in tests or by the GTEST framework.
static_cast<testing::Environment*>(environment_object_.get())->TearDown();
std::vector<std::string> actual_host_list =
fake_report_issue_request_.get_host_ids_released();
std::sort(actual_host_list.begin(), actual_host_list.end());
std::sort(expected_host_list.begin(), expected_host_list.end());
EXPECT_EQ(actual_host_list.size(), expected_host_list.size());
for (size_t i = 0; i < actual_host_list.size(); ++i) {
EXPECT_EQ(actual_host_list[i], expected_host_list[i]);
}
}
} // namespace test
} // namespace remoting