Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / extensions / api / debugger / debugger_apitest.cc
blob0d8185877dca9065fd5f7378edad1dd406f31110
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/sessions/session_tab_helper.h"
15 #include "chrome/browser/ui/tabs/tab_strip_model.h"
16 #include "chrome/common/chrome_paths.h"
17 #include "chrome/common/chrome_switches.h"
18 #include "chrome/test/base/ui_test_utils.h"
19 #include "extensions/browser/extension_function.h"
20 #include "extensions/common/extension.h"
21 #include "extensions/common/extension_builder.h"
22 #include "extensions/common/manifest_constants.h"
23 #include "extensions/common/switches.h"
24 #include "extensions/common/value_builder.h"
26 namespace extensions {
28 class DebuggerApiTest : public ExtensionApiTest {
29 protected:
30 ~DebuggerApiTest() override {}
32 void SetUpCommandLine(base::CommandLine* command_line) override;
33 void SetUpOnMainThread() override;
35 // Run the attach function. If |expected_error| is not empty, then the
36 // function should fail with the error. Otherwise, the function is expected
37 // to succeed.
38 testing::AssertionResult RunAttachFunction(const GURL& url,
39 const std::string& expected_error);
41 const Extension* extension() const { return extension_.get(); }
42 base::CommandLine* command_line() const { return command_line_; }
44 private:
45 testing::AssertionResult RunAttachFunctionOnTarget(
46 const std::string& debuggee_target, const std::string& expected_error);
48 // The command-line for the test process, preserved in order to modify
49 // mid-test.
50 base::CommandLine* command_line_;
52 // A basic extension with the debugger permission.
53 scoped_refptr<const Extension> extension_;
56 void DebuggerApiTest::SetUpCommandLine(base::CommandLine* command_line) {
57 ExtensionApiTest::SetUpCommandLine(command_line);
58 // We need to hold onto |command_line| in order to modify it during the test.
59 command_line_ = command_line;
62 void DebuggerApiTest::SetUpOnMainThread() {
63 ExtensionApiTest::SetUpOnMainThread();
64 extension_ =
65 ExtensionBuilder().SetManifest(
66 DictionaryBuilder().Set("name", "debugger")
67 .Set("version", "0.1")
68 .Set("manifest_version", 2)
69 .Set("permissions",
70 ListBuilder().Append("debugger"))).Build();
73 testing::AssertionResult DebuggerApiTest::RunAttachFunction(
74 const GURL& url, const std::string& expected_error) {
75 ui_test_utils::NavigateToURL(browser(), url);
76 content::WebContents* web_contents =
77 browser()->tab_strip_model()->GetActiveWebContents();
79 // Attach by tabId.
80 int tab_id = SessionTabHelper::IdForTab(web_contents);
81 std::string debugee_by_tab = base::StringPrintf("{\"tabId\": %d}", tab_id);
82 testing::AssertionResult result =
83 RunAttachFunctionOnTarget(debugee_by_tab, expected_error);
84 if (!result)
85 return result;
87 // Attach by targetId.
88 scoped_refptr<DebuggerGetTargetsFunction> get_targets_function =
89 new DebuggerGetTargetsFunction();
90 scoped_ptr<base::Value> value(
91 extension_function_test_utils::RunFunctionAndReturnSingleResult(
92 get_targets_function.get(), "[]", browser()));
93 base::ListValue* targets = nullptr;
94 EXPECT_TRUE(value->GetAsList(&targets));
96 std::string debugger_target_id;
97 for (size_t i = 0; i < targets->GetSize(); ++i) {
98 base::DictionaryValue* target_dict = nullptr;
99 EXPECT_TRUE(targets->GetDictionary(i, &target_dict));
100 int id = -1;
101 if (target_dict->GetInteger("tabId", &id) && id == tab_id) {
102 EXPECT_TRUE(target_dict->GetString("id", &debugger_target_id));
103 break;
106 EXPECT_TRUE(!debugger_target_id.empty());
108 std::string debugee_by_target_id =
109 base::StringPrintf("{\"targetId\": \"%s\"}", debugger_target_id.c_str());
110 return RunAttachFunctionOnTarget(debugee_by_target_id, expected_error);
113 testing::AssertionResult DebuggerApiTest::RunAttachFunctionOnTarget(
114 const std::string& debuggee_target, const std::string& expected_error) {
115 scoped_refptr<DebuggerAttachFunction> attach_function =
116 new DebuggerAttachFunction();
117 attach_function->set_extension(extension_.get());
119 std::string actual_error;
120 if (!RunFunction(attach_function.get(),
121 base::StringPrintf("[%s, \"1.1\"]", debuggee_target.c_str()),
122 browser(),
123 extension_function_test_utils::NONE)) {
124 actual_error = attach_function->GetError();
125 } else {
126 // Clean up and detach.
127 scoped_refptr<DebuggerDetachFunction> detach_function =
128 new DebuggerDetachFunction();
129 detach_function->set_extension(extension_.get());
130 if (!RunFunction(detach_function.get(),
131 base::StringPrintf("[%s]", debuggee_target.c_str()),
132 browser(),
133 extension_function_test_utils::NONE)) {
134 return testing::AssertionFailure() << "Could not detach from "
135 << debuggee_target << " : " << detach_function->GetError();
139 if (expected_error.empty() && !actual_error.empty()) {
140 return testing::AssertionFailure() << "Could not attach to "
141 << debuggee_target << " : " << actual_error;
142 } else if (actual_error != expected_error) {
143 return testing::AssertionFailure() << "Did not get correct error upon "
144 << "attach to " << debuggee_target << " : "
145 << "expected: " << expected_error << ", found: " << actual_error;
147 return testing::AssertionSuccess();
150 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, Debugger) {
151 ASSERT_TRUE(RunExtensionTest("debugger")) << message_;
154 IN_PROC_BROWSER_TEST_F(DebuggerApiTest,
155 DebuggerNotAllowedOnOtherExtensionPages) {
156 // Load another arbitrary extension with an associated resource (popup.html).
157 base::FilePath path;
158 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path));
159 path = path.AppendASCII("extensions").AppendASCII("good_unpacked");
160 const Extension* another_extension = LoadExtension(path);
161 ASSERT_TRUE(another_extension);
163 GURL other_ext_url =
164 GURL(base::StringPrintf("chrome-extension://%s/popup.html",
165 another_extension->id().c_str()));
167 // This extension should not be able to access another extension.
168 EXPECT_TRUE(RunAttachFunction(
169 other_ext_url, manifest_errors::kCannotAccessExtensionUrl));
171 // This extension *should* be able to debug itself.
172 EXPECT_TRUE(RunAttachFunction(
173 GURL(base::StringPrintf("chrome-extension://%s/foo.html",
174 extension()->id().c_str())),
175 std::string()));
177 // Append extensions on chrome urls switch. The extension should now be able
178 // to debug any extension.
179 command_line()->AppendSwitch(switches::kExtensionsOnChromeURLs);
180 EXPECT_TRUE(RunAttachFunction(other_ext_url, std::string()));
183 } // namespace extensions