OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "base/string_number_conversions.h" | |
6 #include "base/utf_string_conversions.h" | |
7 #include "chrome/browser/browser_process.h" | |
8 #include "chrome/browser/browser_signin.h" | |
9 #include "chrome/browser/extensions/extension_browsertest.h" | |
10 #include "chrome/browser/extensions/extension_test_message_listener.h" | |
11 #include "chrome/browser/extensions/extension_webstore_private_api.h" | |
12 #include "chrome/browser/net/gaia/token_service.h" | |
13 #include "chrome/browser/profiles/profile_manager.h" | |
14 #include "chrome/browser/sync/profile_sync_service.h" | |
15 #include "chrome/browser/sync/signin_manager.h" | |
16 #include "chrome/browser/ui/browser.h" | |
17 #include "chrome/common/chrome_switches.h" | |
18 #include "chrome/common/net/gaia/gaia_constants.h" | |
19 #include "chrome/common/url_constants.h" | |
20 #include "chrome/test/base/ui_test_utils.h" | |
21 #include "content/browser/tab_contents/tab_contents.h" | |
22 #include "googleurl/src/gurl.h" | |
23 #include "net/base/mock_host_resolver.h" | |
24 | |
25 using chrome::kHttpScheme; | |
26 using chrome::kStandardSchemeSeparator; | |
27 | |
28 namespace { | |
29 | |
30 const char kTestUrlHostname[] = "www.example.com"; | |
31 | |
32 } // namespace | |
33 | |
34 // A fake version of ProfileSyncService used for testing. | |
35 class FakeProfileSyncService : public ProfileSyncService { | |
36 public: | |
37 FakeProfileSyncService() | |
38 : ProfileSyncService(NULL, NULL, new SigninManager(), ""), | |
39 setup_(false) { | |
40 } | |
41 virtual ~FakeProfileSyncService() {} | |
42 | |
43 // Overrides of virtual methods in ProfileSyncService. | |
44 virtual bool HasSyncSetupCompleted() const { | |
45 return setup_; | |
46 } | |
47 virtual void ChangePreferredDataTypes(const syncable::ModelTypeSet& types) { | |
48 types_ = types; | |
49 } | |
50 virtual void GetPreferredDataTypes(syncable::ModelTypeSet* types) const { | |
51 *types = types_; | |
52 } | |
53 virtual void SetSyncSetupCompleted() { | |
54 setup_ = true; | |
55 } | |
56 | |
57 private: | |
58 bool setup_; | |
59 syncable::ModelTypeSet types_; | |
60 }; | |
61 | |
62 class FakeBrowserSignin : public BrowserSignin { | |
63 public: | |
64 // The |username_after_login| parameter determines what this fake | |
65 // BrowserSignin will set the username to when ShowLoginDialog is called. | |
66 FakeBrowserSignin(bool should_succeed, | |
67 const std::string& initial_username, | |
68 const std::string& username_after_login) | |
69 : BrowserSignin(NULL), | |
70 should_succeed_(should_succeed), | |
71 username_(initial_username), | |
72 username_after_login_(username_after_login) { | |
73 } | |
74 virtual ~FakeBrowserSignin() {} | |
75 | |
76 virtual std::string GetSignedInUsername() const { | |
77 return username_; | |
78 } | |
79 | |
80 virtual void RequestSignin(TabContents* tab_contents, | |
81 const string16& preferred_email, | |
82 const string16& message, | |
83 SigninDelegate* delegate) { | |
84 if (should_succeed_) { | |
85 // Simulate valid login. | |
86 username_ = username_after_login_; | |
87 delegate->OnLoginSuccess(); | |
88 | |
89 // Fake a token available notification. | |
90 Profile* profile = Profile::FromBrowserContext( | |
91 tab_contents->browser_context())->GetOriginalProfile(); | |
92 TokenService* token_service = profile->GetTokenService(); | |
93 token_service->IssueAuthTokenForTest(GaiaConstants::kGaiaService, | |
94 "new_token"); | |
95 } else { | |
96 delegate->OnLoginFailure(GoogleServiceAuthError( | |
97 GoogleServiceAuthError::REQUEST_CANCELED)); | |
98 } | |
99 } | |
100 | |
101 private: | |
102 bool should_succeed_; | |
103 std::string username_; | |
104 std::string username_after_login_; | |
105 }; | |
106 | |
107 class ExtensionWebstorePrivateBrowserTest : public ExtensionBrowserTest { | |
108 public: | |
109 ExtensionWebstorePrivateBrowserTest() { | |
110 test_url_base_ = std::string() + kHttpScheme + kStandardSchemeSeparator + | |
111 kTestUrlHostname; | |
112 } | |
113 | |
114 void SetUpCommandLine(CommandLine* command_line) { | |
115 ExtensionBrowserTest::SetUpCommandLine(command_line); | |
116 command_line->AppendSwitchASCII(switches::kAppsGalleryURL, test_url_base_); | |
117 } | |
118 | |
119 // This generates a regular test server url pointing to a test file at | |
120 // |relative_path|, but replaces the hostname with kTestUrlHostname so that | |
121 // we get the webstore private APIs injected (this happens because of the | |
122 // command line switch we added in SetupCommandLine). | |
123 GURL GetUrl(const std::string& relative_path) { | |
124 GURL base_url = test_server()->GetURL( | |
125 "files/extensions/webstore_private/" + relative_path); | |
126 GURL::Replacements replacements; | |
127 std::string replacement_host = std::string(kTestUrlHostname); | |
128 replacements.SetHostStr(replacement_host); | |
129 return base_url.ReplaceComponents(replacements); | |
130 } | |
131 | |
132 void RunLoginTestImpl(bool incognito, | |
133 const std::string& relative_path, | |
134 const std::string& initial_login, | |
135 bool login_succeeds, | |
136 const std::string& login_result) { | |
137 // Clear the token service so previous tests don't affect things. | |
138 TokenService* token_service = browser()->profile()->GetTokenService(); | |
139 token_service->ResetCredentialsInMemory(); | |
140 if (!initial_login.empty()) { | |
141 // Initialize the token service with an existing token. | |
142 token_service->IssueAuthTokenForTest(GaiaConstants::kGaiaService, | |
143 "existing_token"); | |
144 } | |
145 | |
146 FakeProfileSyncService sync_service; | |
147 FakeBrowserSignin signin(login_succeeds, initial_login, login_result); | |
148 WebstorePrivateApi::SetTestingProfileSyncService(&sync_service); | |
149 WebstorePrivateApi::SetTestingBrowserSignin(&signin); | |
150 | |
151 ExtensionTestMessageListener listener("success", false); | |
152 GURL url = GetUrl(relative_path); | |
153 if (incognito) { | |
154 ui_test_utils::OpenURLOffTheRecord(browser()->profile(), url); | |
155 } else { | |
156 ui_test_utils::NavigateToURL(browser(), url); | |
157 } | |
158 EXPECT_TRUE(listener.WaitUntilSatisfied()); | |
159 | |
160 WebstorePrivateApi::SetTestingBrowserSignin(NULL); | |
161 WebstorePrivateApi::SetTestingProfileSyncService(NULL); | |
162 } | |
163 | |
164 void RunLoginTest(const std::string& relative_path, | |
165 const std::string& initial_login, | |
166 bool login_succeeds, | |
167 const std::string& login_result) { | |
168 RunLoginTestImpl(true, | |
169 relative_path, | |
170 initial_login, | |
171 login_succeeds, | |
172 login_result); | |
173 RunLoginTestImpl(false, | |
174 relative_path, | |
175 initial_login, | |
176 login_succeeds, | |
177 login_result); | |
178 } | |
179 | |
180 protected: | |
181 std::string test_url_base_; | |
182 }; | |
183 | |
184 // TODO(asargent) I've added some extra logging to this test since we've seen a | |
185 // few failures on the bots lately. See crbug.com/91753 for details. | |
186 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateBrowserTest, BrowserLogin) { | |
187 LOG(INFO) << "Adding rule to host resolver"; | |
188 host_resolver()->AddRule(kTestUrlHostname, "127.0.0.1"); | |
189 | |
190 LOG(INFO) << "Starting test server"; | |
191 ASSERT_TRUE(test_server()->Start()); | |
192 | |
193 LOG(INFO) << "expect_nonempty.html"; | |
194 RunLoginTest("browser_login/expect_nonempty.html", | |
195 "foo@bar.com", false, ""); | |
196 | |
197 LOG(INFO) << "prompt_no_preferred.html"; | |
198 RunLoginTest("browser_login/prompt_no_preferred.html", "", true, ""); | |
199 | |
200 LOG(INFO) << "prompt_preferred.html"; | |
201 RunLoginTest("browser_login/prompt_preferred.html", "", true, "foo@bar.com"); | |
202 | |
203 LOG(INFO) << "prompt_login_fails.html"; | |
204 RunLoginTest("browser_login/prompt_login_fails.html", | |
205 "", false, "foo@bar.com"); | |
206 } | |
OLD | NEW |