Add new certificateProvider extension API.
[chromium-blink-merge.git] / chrome / browser / extensions / api / debugger / debugger_apitest.cc
blob82c24e263b57a9289ed297c2e2550a13ba7701f2
1 // Copyright (c) 2012 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.
5 #include <string>
7 #include "base/command_line.h"
8 #include "base/memory/ref_counted.h"
9 #include "base/path_service.h"
10 #include "base/strings/stringprintf.h"
11 #include "chrome/browser/extensions/api/debugger/debugger_api.h"
12 #include "chrome/browser/extensions/extension_apitest.h"
13 #include "chrome/browser/extensions/extension_function_test_utils.h"
14 #include "chrome/browser/infobars/infobar_service.h"
15 #include "chrome/browser/sessions/session_tab_helper.h"
16 #include "chrome/browser/ui/tabs/tab_strip_model.h"
17 #include "chrome/common/chrome_paths.h"
18 #include "chrome/common/chrome_switches.h"
19 #include "chrome/test/base/ui_test_utils.h"
20 #include "components/infobars/core/infobar.h"
21 #include "components/infobars/core/infobar_delegate.h"
22 #include "extensions/browser/extension_function.h"
23 #include "extensions/common/extension.h"
24 #include "extensions/common/extension_builder.h"
25 #include "extensions/common/manifest_constants.h"
26 #include "extensions/common/switches.h"
27 #include "extensions/common/value_builder.h"
29 namespace extensions {
31 class DebuggerApiTest : public ExtensionApiTest {
32 protected:
33 ~DebuggerApiTest() override {}
35 void SetUpCommandLine(base::CommandLine* command_line) override;
36 void SetUpOnMainThread() override;
38 // Run the attach function. If |expected_error| is not empty, then the
39 // function should fail with the error. Otherwise, the function is expected
40 // to succeed.
41 testing::AssertionResult RunAttachFunction(const GURL& url,
42 const std::string& expected_error);
44 const Extension* extension() const { return extension_.get(); }
45 base::CommandLine* command_line() const { return command_line_; }
47 private:
48 testing::AssertionResult RunAttachFunctionOnTarget(
49 const std::string& debuggee_target, const std::string& expected_error);
51 // The command-line for the test process, preserved in order to modify
52 // mid-test.
53 base::CommandLine* command_line_;
55 // A basic extension with the debugger permission.
56 scoped_refptr<const Extension> extension_;
59 void DebuggerApiTest::SetUpCommandLine(base::CommandLine* command_line) {
60 ExtensionApiTest::SetUpCommandLine(command_line);
61 // We need to hold onto |command_line| in order to modify it during the test.
62 command_line_ = command_line;
65 void DebuggerApiTest::SetUpOnMainThread() {
66 ExtensionApiTest::SetUpOnMainThread();
67 extension_ =
68 ExtensionBuilder().SetManifest(
69 DictionaryBuilder().Set("name", "debugger")
70 .Set("version", "0.1")
71 .Set("manifest_version", 2)
72 .Set("permissions",
73 ListBuilder().Append("debugger"))).Build();
76 testing::AssertionResult DebuggerApiTest::RunAttachFunction(
77 const GURL& url, const std::string& expected_error) {
78 ui_test_utils::NavigateToURL(browser(), url);
79 content::WebContents* web_contents =
80 browser()->tab_strip_model()->GetActiveWebContents();
82 // Attach by tabId.
83 int tab_id = SessionTabHelper::IdForTab(web_contents);
84 std::string debugee_by_tab = base::StringPrintf("{\"tabId\": %d}", tab_id);
85 testing::AssertionResult result =
86 RunAttachFunctionOnTarget(debugee_by_tab, expected_error);
87 if (!result)
88 return result;
90 // Attach by targetId.
91 scoped_refptr<DebuggerGetTargetsFunction> get_targets_function =
92 new DebuggerGetTargetsFunction();
93 scoped_ptr<base::Value> value(
94 extension_function_test_utils::RunFunctionAndReturnSingleResult(
95 get_targets_function.get(), "[]", browser()));
96 base::ListValue* targets = nullptr;
97 EXPECT_TRUE(value->GetAsList(&targets));
99 std::string debugger_target_id;
100 for (size_t i = 0; i < targets->GetSize(); ++i) {
101 base::DictionaryValue* target_dict = nullptr;
102 EXPECT_TRUE(targets->GetDictionary(i, &target_dict));
103 int id = -1;
104 if (target_dict->GetInteger("tabId", &id) && id == tab_id) {
105 EXPECT_TRUE(target_dict->GetString("id", &debugger_target_id));
106 break;
109 EXPECT_TRUE(!debugger_target_id.empty());
111 std::string debugee_by_target_id =
112 base::StringPrintf("{\"targetId\": \"%s\"}", debugger_target_id.c_str());
113 return RunAttachFunctionOnTarget(debugee_by_target_id, expected_error);
116 testing::AssertionResult DebuggerApiTest::RunAttachFunctionOnTarget(
117 const std::string& debuggee_target, const std::string& expected_error) {
118 scoped_refptr<DebuggerAttachFunction> attach_function =
119 new DebuggerAttachFunction();
120 attach_function->set_extension(extension_.get());
122 std::string actual_error;
123 if (!RunFunction(attach_function.get(),
124 base::StringPrintf("[%s, \"1.1\"]", debuggee_target.c_str()),
125 browser(),
126 extension_function_test_utils::NONE)) {
127 actual_error = attach_function->GetError();
128 } else {
129 // Clean up and detach.
130 scoped_refptr<DebuggerDetachFunction> detach_function =
131 new DebuggerDetachFunction();
132 detach_function->set_extension(extension_.get());
133 if (!RunFunction(detach_function.get(),
134 base::StringPrintf("[%s]", debuggee_target.c_str()),
135 browser(),
136 extension_function_test_utils::NONE)) {
137 return testing::AssertionFailure() << "Could not detach from "
138 << debuggee_target << " : " << detach_function->GetError();
142 if (expected_error.empty() && !actual_error.empty()) {
143 return testing::AssertionFailure() << "Could not attach to "
144 << debuggee_target << " : " << actual_error;
145 } else if (actual_error != expected_error) {
146 return testing::AssertionFailure() << "Did not get correct error upon "
147 << "attach to " << debuggee_target << " : "
148 << "expected: " << expected_error << ", found: " << actual_error;
150 return testing::AssertionSuccess();
153 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, Debugger) {
154 ASSERT_TRUE(RunExtensionTest("debugger")) << message_;
157 IN_PROC_BROWSER_TEST_F(DebuggerApiTest,
158 DebuggerNotAllowedOnOtherExtensionPages) {
159 // Load another arbitrary extension with an associated resource (popup.html).
160 base::FilePath path;
161 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path));
162 path = path.AppendASCII("extensions").AppendASCII("good_unpacked");
163 const Extension* another_extension = LoadExtension(path);
164 ASSERT_TRUE(another_extension);
166 GURL other_ext_url =
167 GURL(base::StringPrintf("chrome-extension://%s/popup.html",
168 another_extension->id().c_str()));
170 // This extension should not be able to access another extension.
171 EXPECT_TRUE(RunAttachFunction(
172 other_ext_url, manifest_errors::kCannotAccessExtensionUrl));
174 // This extension *should* be able to debug itself.
175 EXPECT_TRUE(RunAttachFunction(
176 GURL(base::StringPrintf("chrome-extension://%s/foo.html",
177 extension()->id().c_str())),
178 std::string()));
180 // Append extensions on chrome urls switch. The extension should now be able
181 // to debug any extension.
182 command_line()->AppendSwitch(switches::kExtensionsOnChromeURLs);
183 EXPECT_TRUE(RunAttachFunction(other_ext_url, std::string()));
186 IN_PROC_BROWSER_TEST_F(DebuggerApiTest, InfoBar) {
187 int tab_id = SessionTabHelper::IdForTab(
188 browser()->tab_strip_model()->GetActiveWebContents());
189 scoped_refptr<DebuggerAttachFunction> attach_function;
190 scoped_refptr<DebuggerDetachFunction> detach_function;
192 Browser* another_browser =
193 new Browser(Browser::CreateParams(profile(), chrome::GetActiveDesktop()));
194 AddBlankTabAndShow(another_browser);
195 AddBlankTabAndShow(another_browser);
197 InfoBarService* service1 = InfoBarService::FromWebContents(
198 browser()->tab_strip_model()->GetActiveWebContents());
199 InfoBarService* service2 = InfoBarService::FromWebContents(
200 another_browser->tab_strip_model()->GetWebContentsAt(0));
201 InfoBarService* service3 = InfoBarService::FromWebContents(
202 another_browser->tab_strip_model()->GetWebContentsAt(1));
204 // Attach should create infobars in both browsers.
205 attach_function = new DebuggerAttachFunction();
206 attach_function->set_extension(extension());
207 ASSERT_TRUE(
208 RunFunction(attach_function.get(),
209 base::StringPrintf("[{\"tabId\": %d}, \"1.1\"]", tab_id),
210 browser(), extension_function_test_utils::NONE));
211 EXPECT_EQ(1u, service1->infobar_count());
212 EXPECT_EQ(1u, service2->infobar_count());
213 EXPECT_EQ(1u, service3->infobar_count());
215 // Detach should remove all infobars.
216 detach_function = new DebuggerDetachFunction();
217 detach_function->set_extension(extension());
218 ASSERT_TRUE(RunFunction(detach_function.get(),
219 base::StringPrintf("[{\"tabId\": %d}]", tab_id),
220 browser(), extension_function_test_utils::NONE));
221 EXPECT_EQ(0u, service1->infobar_count());
222 EXPECT_EQ(0u, service2->infobar_count());
223 EXPECT_EQ(0u, service3->infobar_count());
225 // Attach again.
226 attach_function = new DebuggerAttachFunction();
227 attach_function->set_extension(extension());
228 ASSERT_TRUE(
229 RunFunction(attach_function.get(),
230 base::StringPrintf("[{\"tabId\": %d}, \"1.1\"]", tab_id),
231 browser(), extension_function_test_utils::NONE));
232 EXPECT_EQ(1u, service1->infobar_count());
233 EXPECT_EQ(1u, service2->infobar_count());
234 EXPECT_EQ(1u, service3->infobar_count());
236 // Closing infobar should cause detach and remove all infobars.
237 service2->infobar_at(0)->delegate()->InfoBarDismissed();
238 EXPECT_EQ(0u, service1->infobar_count());
239 EXPECT_EQ(0u, service2->infobar_count());
240 EXPECT_EQ(0u, service3->infobar_count());
241 detach_function = new DebuggerDetachFunction();
242 detach_function->set_extension(extension());
243 // Cannot detach again.
244 ASSERT_FALSE(RunFunction(detach_function.get(),
245 base::StringPrintf("[{\"tabId\": %d}]", tab_id),
246 browser(), extension_function_test_utils::NONE));
248 // And again...
249 attach_function = new DebuggerAttachFunction();
250 attach_function->set_extension(extension());
251 ASSERT_TRUE(
252 RunFunction(attach_function.get(),
253 base::StringPrintf("[{\"tabId\": %d}, \"1.1\"]", tab_id),
254 browser(), extension_function_test_utils::NONE));
255 EXPECT_EQ(1u, service1->infobar_count());
256 EXPECT_EQ(1u, service2->infobar_count());
257 EXPECT_EQ(1u, service3->infobar_count());
259 // Closing tab should not affect anything.
260 ASSERT_TRUE(another_browser->tab_strip_model()->CloseWebContentsAt(1, 0));
261 service3 = nullptr;
262 EXPECT_EQ(1u, service1->infobar_count());
263 EXPECT_EQ(1u, service2->infobar_count());
265 // Closing browser should not affect anything.
266 CloseBrowserSynchronously(another_browser);
267 service2 = nullptr;
268 another_browser = nullptr;
269 EXPECT_EQ(1u, service1->infobar_count());
271 // Detach should remove the remaining infobar.
272 detach_function = new DebuggerDetachFunction();
273 detach_function->set_extension(extension());
274 ASSERT_TRUE(RunFunction(detach_function.get(),
275 base::StringPrintf("[{\"tabId\": %d}]", tab_id),
276 browser(), extension_function_test_utils::NONE));
277 EXPECT_EQ(0u, service1->infobar_count());
280 } // namespace extensions