blob: 11a11e41e2e9f61483ca4a2506883eacb633e0a1 [file] [log] [blame]
// Copyright 2017 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/base/oauth_token_getter_proxy.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/run_loop.h"
#include "base/test/task_environment.h"
#include "base/threading/thread.h"
#include "base/threading/thread_checker.h"
#include "base/threading/thread_task_runner_handle.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace remoting {
namespace {
OAuthTokenGetter::TokenCallback GetDoNothingTokenCallback() {
return base::DoNothing::Repeatedly<OAuthTokenGetter::Status,
const std::string&, const std::string&>();
}
class FakeOAuthTokenGetter : public OAuthTokenGetter {
public:
FakeOAuthTokenGetter();
~FakeOAuthTokenGetter() override;
void ResolveCallback(Status status,
const std::string& user_email,
const std::string& access_token);
void ExpectInvalidateCache();
// OAuthTokenGetter overrides.
void CallWithToken(TokenCallback on_access_token) override;
void InvalidateCache() override;
base::WeakPtr<FakeOAuthTokenGetter> GetWeakPtr();
private:
TokenCallback on_access_token_;
bool invalidate_cache_expected_ = false;
THREAD_CHECKER(thread_checker_);
base::WeakPtrFactory<FakeOAuthTokenGetter> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(FakeOAuthTokenGetter);
};
FakeOAuthTokenGetter::FakeOAuthTokenGetter() {
DETACH_FROM_THREAD(thread_checker_);
}
FakeOAuthTokenGetter::~FakeOAuthTokenGetter() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(!invalidate_cache_expected_);
}
void FakeOAuthTokenGetter::ResolveCallback(Status status,
const std::string& user_email,
const std::string& access_token) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(!on_access_token_.is_null());
std::move(on_access_token_).Run(status, user_email, access_token);
}
void FakeOAuthTokenGetter::ExpectInvalidateCache() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
ASSERT_FALSE(invalidate_cache_expected_);
invalidate_cache_expected_ = true;
}
void FakeOAuthTokenGetter::CallWithToken(TokenCallback on_access_token) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
on_access_token_ = std::move(on_access_token);
}
void FakeOAuthTokenGetter::InvalidateCache() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
ASSERT_TRUE(invalidate_cache_expected_);
invalidate_cache_expected_ = false;
}
base::WeakPtr<FakeOAuthTokenGetter> FakeOAuthTokenGetter::GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
} // namespace
class OAuthTokenGetterProxyTest : public testing::Test {
public:
OAuthTokenGetterProxyTest() = default;
~OAuthTokenGetterProxyTest() override = default;
// testing::Test overrides.
void SetUp() override;
void TearDown() override;
protected:
void TestCallWithTokenOnRunnerThread(OAuthTokenGetter::Status status,
const std::string& user_email,
const std::string& access_token);
void TestCallWithTokenOnMainThread(OAuthTokenGetter::Status status,
const std::string& user_email,
const std::string& access_token);
void ExpectInvalidateCache();
void InvalidateTokenGetter();
base::Thread runner_thread_{"runner_thread"};
std::unique_ptr<FakeOAuthTokenGetter> token_getter_;
std::unique_ptr<OAuthTokenGetterProxy> proxy_;
private:
struct TokenCallbackResult {
OAuthTokenGetter::Status status;
std::string user_email;
std::string access_token;
};
void TestCallWithTokenImpl(OAuthTokenGetter::Status status,
const std::string& user_email,
const std::string& access_token);
void OnTokenReceived(OAuthTokenGetter::Status status,
const std::string& user_email,
const std::string& access_token);
std::unique_ptr<TokenCallbackResult> expected_callback_result_;
base::test::SingleThreadTaskEnvironment task_environment_;
DISALLOW_COPY_AND_ASSIGN(OAuthTokenGetterProxyTest);
};
void OAuthTokenGetterProxyTest::SetUp() {
token_getter_ = std::make_unique<FakeOAuthTokenGetter>();
runner_thread_.Start();
proxy_ = std::make_unique<OAuthTokenGetterProxy>(
token_getter_->GetWeakPtr(), runner_thread_.task_runner());
}
void OAuthTokenGetterProxyTest::TearDown() {
InvalidateTokenGetter();
proxy_.reset();
runner_thread_.FlushForTesting();
ASSERT_FALSE(expected_callback_result_);
}
void OAuthTokenGetterProxyTest::TestCallWithTokenOnRunnerThread(
OAuthTokenGetter::Status status,
const std::string& user_email,
const std::string& access_token) {
runner_thread_.task_runner()->PostTask(
FROM_HERE,
base::BindOnce(&OAuthTokenGetterProxyTest::TestCallWithTokenImpl,
base::Unretained(this),
OAuthTokenGetter::Status::AUTH_ERROR, "email3", "token3"));
runner_thread_.FlushForTesting();
}
void OAuthTokenGetterProxyTest::TestCallWithTokenOnMainThread(
OAuthTokenGetter::Status status,
const std::string& user_email,
const std::string& access_token) {
TestCallWithTokenImpl(status, user_email, access_token);
runner_thread_.FlushForTesting();
base::RunLoop().RunUntilIdle();
}
void OAuthTokenGetterProxyTest::ExpectInvalidateCache() {
ASSERT_NE(nullptr, token_getter_.get());
runner_thread_.task_runner()->PostTask(
FROM_HERE, base::BindOnce(&FakeOAuthTokenGetter::ExpectInvalidateCache,
token_getter_->GetWeakPtr()));
}
void OAuthTokenGetterProxyTest::InvalidateTokenGetter() {
if (token_getter_) {
runner_thread_.task_runner()->DeleteSoon(FROM_HERE,
token_getter_.release());
}
}
void OAuthTokenGetterProxyTest::TestCallWithTokenImpl(
OAuthTokenGetter::Status status,
const std::string& user_email,
const std::string& access_token) {
ASSERT_FALSE(expected_callback_result_);
expected_callback_result_ = std::make_unique<TokenCallbackResult>();
expected_callback_result_->status = status;
expected_callback_result_->user_email = user_email;
expected_callback_result_->access_token = access_token;
proxy_->CallWithToken(base::BindOnce(
&OAuthTokenGetterProxyTest::OnTokenReceived, base::Unretained(this)));
runner_thread_.task_runner()->PostTask(
FROM_HERE, base::BindOnce(&FakeOAuthTokenGetter::ResolveCallback,
token_getter_->GetWeakPtr(), status, user_email,
access_token));
}
void OAuthTokenGetterProxyTest::OnTokenReceived(
OAuthTokenGetter::Status status,
const std::string& user_email,
const std::string& access_token) {
ASSERT_TRUE(expected_callback_result_);
EXPECT_EQ(expected_callback_result_->status, status);
EXPECT_EQ(expected_callback_result_->user_email, user_email);
EXPECT_EQ(expected_callback_result_->access_token, access_token);
expected_callback_result_.reset();
}
TEST_F(OAuthTokenGetterProxyTest, CallWithTokenOnMainThread) {
TestCallWithTokenOnMainThread(OAuthTokenGetter::Status::SUCCESS, "email1",
"token1");
TestCallWithTokenOnMainThread(OAuthTokenGetter::Status::NETWORK_ERROR,
"email2", "token2");
}
TEST_F(OAuthTokenGetterProxyTest, CallWithTokenOnRunnerThread) {
TestCallWithTokenOnRunnerThread(OAuthTokenGetter::Status::AUTH_ERROR,
"email3", "token3");
TestCallWithTokenOnRunnerThread(OAuthTokenGetter::Status::SUCCESS, "email4",
"token4");
}
TEST_F(OAuthTokenGetterProxyTest, InvalidateCacheOnMainThread) {
ExpectInvalidateCache();
proxy_->InvalidateCache();
runner_thread_.FlushForTesting();
}
TEST_F(OAuthTokenGetterProxyTest, InvalidateCacheOnRunnerThread) {
ExpectInvalidateCache();
runner_thread_.task_runner()->PostTask(
FROM_HERE, base::BindOnce(&OAuthTokenGetterProxy::InvalidateCache,
base::Unretained(proxy_.get())));
runner_thread_.FlushForTesting();
}
TEST_F(
OAuthTokenGetterProxyTest,
CallWithTokenOnMainThreadAfterTokenGetterDestroyed_callsSilentlyDropped) {
InvalidateTokenGetter();
proxy_->CallWithToken(GetDoNothingTokenCallback());
runner_thread_.FlushForTesting();
}
TEST_F(
OAuthTokenGetterProxyTest,
CallWithTokenOnRunnerThreadAfterTokenGetterDestroyed_callsSilentlyDropped) {
InvalidateTokenGetter();
runner_thread_.task_runner()->PostTask(
FROM_HERE, base::BindOnce(&OAuthTokenGetterProxy::CallWithToken,
base::Unretained(proxy_.get()),
GetDoNothingTokenCallback()));
runner_thread_.FlushForTesting();
}
TEST_F(
OAuthTokenGetterProxyTest,
InvalidateCacheOnMainThreadAfterTokenGetterDestroyed_callsSilentlyDropped) {
InvalidateTokenGetter();
proxy_->InvalidateCache();
runner_thread_.FlushForTesting();
}
TEST_F(
OAuthTokenGetterProxyTest,
InvalidateCacheOnRunnerThreadAfterTokenGetterDestroyed_callsSilentlyDropped) {
InvalidateTokenGetter();
runner_thread_.task_runner()->PostTask(
FROM_HERE, base::BindOnce(&OAuthTokenGetterProxy::InvalidateCache,
base::Unretained(proxy_.get())));
runner_thread_.FlushForTesting();
}
} // namespace remoting