1// Copyright 2014 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 "chrome/browser/apps/app_browsertest_util.h"
6#include "chrome/browser/extensions/api/management/management_api.h"
7#include "chrome/browser/extensions/extension_apitest.h"
8#include "chrome/browser/extensions/extension_function_test_utils.h"
9#include "chrome/browser/extensions/test_extension_dir.h"
10#include "chrome/test/base/ui_test_utils.h"
11#include "content/public/browser/notification_service.h"
12#include "extensions/browser/api/runtime/runtime_api.h"
13#include "extensions/browser/extension_registry.h"
14#include "extensions/test/result_catcher.h"
15#include "net/test/embedded_test_server/embedded_test_server.h"
16
17// Tests the privileged components of chrome.runtime.
18IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ChromeRuntimePrivileged) {
19  ASSERT_TRUE(RunExtensionTest("runtime/privileged")) << message_;
20}
21
22// Tests the unprivileged components of chrome.runtime.
23IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ChromeRuntimeUnprivileged) {
24  ASSERT_TRUE(StartEmbeddedTestServer());
25  ASSERT_TRUE(
26      LoadExtension(test_data_dir_.AppendASCII("runtime/content_script")));
27
28  // The content script runs on webpage.html.
29  extensions::ResultCatcher catcher;
30  ui_test_utils::NavigateToURL(browser(),
31                               embedded_test_server()->GetURL("/webpage.html"));
32  EXPECT_TRUE(catcher.GetNextResult()) << message_;
33}
34
35IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ChromeRuntimeUninstallURL) {
36  // Auto-confirm the uninstall dialog.
37  extensions::ManagementUninstallFunction::SetAutoConfirmForTest(true);
38  ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("runtime")
39                                .AppendASCII("uninstall_url")
40                                .AppendASCII("sets_uninstall_url")));
41  ASSERT_TRUE(RunExtensionTest("runtime/uninstall_url")) << message_;
42}
43
44namespace extensions {
45
46IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ChromeRuntimeGetPlatformInfo) {
47  scoped_ptr<base::Value> result(
48      extension_function_test_utils::RunFunctionAndReturnSingleResult(
49          new RuntimeGetPlatformInfoFunction(), "[]", browser()));
50  ASSERT_TRUE(result.get() != NULL);
51  base::DictionaryValue* dict =
52      extension_function_test_utils::ToDictionary(result.get());
53  ASSERT_TRUE(dict != NULL);
54  EXPECT_TRUE(dict->HasKey("os"));
55  EXPECT_TRUE(dict->HasKey("arch"));
56  EXPECT_TRUE(dict->HasKey("nacl_arch"));
57}
58
59// Tests chrome.runtime.getPackageDirectory with an app.
60IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,
61                       ChromeRuntimeGetPackageDirectoryEntryApp) {
62  ClearCommandLineArgs();
63  ASSERT_TRUE(RunPlatformAppTest("api_test/runtime/get_package_directory/app"))
64      << message_;
65}
66
67// Tests chrome.runtime.getPackageDirectory with an extension.
68IN_PROC_BROWSER_TEST_F(ExtensionApiTest,
69                       ChromeRuntimeGetPackageDirectoryEntryExtension) {
70  ASSERT_TRUE(RunExtensionTest("runtime/get_package_directory/extension"))
71      << message_;
72}
73
74// Tests chrome.runtime.reload
75// This test is flaky: crbug.com/366181
76IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DISABLED_ChromeRuntimeReload) {
77  ExtensionRegistry* registry = ExtensionRegistry::Get(profile());
78  const char kManifest[] =
79      "{"
80      "  \"name\": \"reload\","
81      "  \"version\": \"1.0\","
82      "  \"background\": {"
83      "    \"scripts\": [\"background.js\"]"
84      "  },"
85      "  \"manifest_version\": 2"
86      "}";
87
88  TestExtensionDir dir;
89  dir.WriteManifest(kManifest);
90  dir.WriteFile(FILE_PATH_LITERAL("background.js"), "console.log('loaded');");
91
92  const Extension* extension = LoadExtension(dir.unpacked_path());
93  ASSERT_TRUE(extension);
94  const std::string extension_id = extension->id();
95
96  // Somewhat arbitrary upper limit of 30 iterations. If the extension manages
97  // to reload itself that often without being terminated, the test fails
98  // anyway.
99  for (int i = 0; i < 30; i++) {
100    content::WindowedNotificationObserver unload_observer(
101        extensions::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED,
102        content::NotificationService::AllSources());
103    content::WindowedNotificationObserver load_observer(
104        extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED,
105        content::NotificationService::AllSources());
106
107    ASSERT_TRUE(ExecuteScriptInBackgroundPageNoWait(
108        extension_id, "chrome.runtime.reload();"));
109    unload_observer.Wait();
110
111    if (registry->GetExtensionById(extension_id,
112                                   ExtensionRegistry::TERMINATED)) {
113      break;
114    } else {
115      load_observer.Wait();
116      WaitForExtensionViewsToLoad();
117    }
118  }
119  ASSERT_TRUE(
120      registry->GetExtensionById(extension_id, ExtensionRegistry::TERMINATED));
121}
122
123}  // namespace extensions
124