summaryrefslogtreecommitdiff
path: root/chromium/extensions/shell/browser/api/identity/identity_api_unittest.cc
blob: 0af6e4b13bbb46a23cfce6bb9bf41aae453fe5a7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// 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 <string>
#include <utility>

#include "base/memory/scoped_ptr.h"
#include "base/values.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "extensions/browser/api_unittest.h"
#include "extensions/common/extension_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:
  scoped_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();
    // Create an extension with OAuth2 scopes.
    set_extension(
        ExtensionBuilder()
            .SetManifest(
                DictionaryBuilder()
                    .Set("name", "Test")
                    .Set("version", "1.0")
                    .Set("oauth2",
                         DictionaryBuilder()
                             .Set("client_id",
                                  "123456.apps.googleusercontent.com")
                             .Set("scopes",
                                  ListBuilder()
                                      .Append("https://www.googleapis.com/"
                                              "auth/drive")
                                      .Build())
                             .Build())
                    .Build())
            .SetLocation(Manifest::UNPACKED)
            .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).
  scoped_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).
  scoped_ptr<base::Value> result = RunFunctionAndReturnValue(
      new IdentityRemoveCachedAuthTokenFunction, "[{}]");
  EXPECT_FALSE(result.get());
}

}  // namespace shell
}  // namespace extensions