blob: 67567dc9df8d2b34dff574c392dfceb4e7e83528 [file] [log] [blame]
// Copyright 2014 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 "extensions/shell/browser/api/identity/identity_api.h"
#include <memory>
#include <string>
#include <utility>
#include "base/values.h"
#include "extensions/browser/api_unittest.h"
#include "extensions/common/extension_builder.h"
#include "extensions/common/value_builder.h"
#include "extensions/shell/browser/shell_oauth2_token_service.h"
#include "google_apis/gaia/oauth2_mint_token_flow.h"
namespace extensions {
namespace shell {
// A ShellOAuth2TokenService that does not make network requests.
class MockShellOAuth2TokenService : public ShellOAuth2TokenService {
public:
// The service starts with no account id or refresh token.
MockShellOAuth2TokenService() : ShellOAuth2TokenService(nullptr, "", "") {}
~MockShellOAuth2TokenService() override {}
// OAuth2TokenService:
std::unique_ptr<Request> StartRequest(const std::string& account_id,
const ScopeSet& scopes,
Consumer* consumer) override {
// Immediately return success.
consumer->OnGetTokenSuccess(nullptr, "logged-in-user-token", base::Time());
return nullptr;
}
};
// A mint token flow that immediately returns a known access token when started.
class MockOAuth2MintTokenFlow : public OAuth2MintTokenFlow {
public:
explicit MockOAuth2MintTokenFlow(Delegate* delegate)
: OAuth2MintTokenFlow(delegate, Parameters()), delegate_(delegate) {}
~MockOAuth2MintTokenFlow() override {}
// OAuth2ApiCallFlow:
void Start(net::URLRequestContextGetter* context,
const std::string& access_token) override {
EXPECT_EQ("logged-in-user-token", access_token);
delegate_->OnMintTokenSuccess("app-access-token", 12345);
}
private:
// Cached here so OAuth2MintTokenFlow does not have to expose its delegate.
Delegate* delegate_;
};
class IdentityApiTest : public ApiUnitTest {
public:
IdentityApiTest() {}
~IdentityApiTest() override {}
// testing::Test:
void SetUp() override {
ApiUnitTest::SetUp();
DictionaryBuilder oauth2;
oauth2.Set("client_id", "123456.apps.googleusercontent.com")
.Set("scopes", ListBuilder()
.Append("https://www.googleapis.com/auth/drive")
.Build());
// Create an extension with OAuth2 scopes.
set_extension(
ExtensionBuilder("Test")
.MergeManifest(
DictionaryBuilder().Set("oauth2", oauth2.Build()).Build())
.Build());
}
};
// Verifies that the getAuthToken function exists and can be called without
// crashing.
TEST_F(IdentityApiTest, GetAuthTokenNoRefreshToken) {
MockShellOAuth2TokenService token_service;
// Calling getAuthToken() before a refresh token is available causes an error.
std::string error =
RunFunctionAndReturnError(new IdentityGetAuthTokenFunction, "[{}]");
EXPECT_FALSE(error.empty());
}
// Verifies that getAuthToken() returns an app access token.
TEST_F(IdentityApiTest, GetAuthToken) {
MockShellOAuth2TokenService token_service;
// Simulate a refresh token being set.
token_service.SetRefreshToken("larry@google.com", "refresh-token");
// RunFunctionAndReturnValue takes ownership.
IdentityGetAuthTokenFunction* function = new IdentityGetAuthTokenFunction;
function->SetMintTokenFlowForTesting(new MockOAuth2MintTokenFlow(function));
// Function succeeds and returns a token (for its callback).
std::unique_ptr<base::Value> result =
RunFunctionAndReturnValue(function, "[{}]");
ASSERT_TRUE(result.get());
std::string value;
result->GetAsString(&value);
EXPECT_NE("logged-in-user-token", value);
EXPECT_EQ("app-access-token", value);
}
// Verifies that the removeCachedAuthToken function exists and can be called
// without crashing.
TEST_F(IdentityApiTest, RemoveCachedAuthToken) {
MockShellOAuth2TokenService token_service;
// Function succeeds and returns nothing (for its callback).
std::unique_ptr<base::Value> result = RunFunctionAndReturnValue(
new IdentityRemoveCachedAuthTokenFunction, "[{}]");
EXPECT_FALSE(result.get());
}
} // namespace shell
} // namespace extensions