File: management_api_non_persistent_apitest.cc

package info (click to toggle)
chromium 138.0.7204.183-1~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 6,080,960 kB
  • sloc: cpp: 34,937,079; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,954; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,811; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (138 lines) | stat: -rw-r--r-- 5,763 bytes parent folder | download | duplicates (5)
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
132
133
134
135
136
137
138
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/strings/stringprintf.h"
#include "chrome/browser/extensions/browsertest_util.h"
#include "chrome/browser/extensions/extension_action_runner.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/test/browser_test.h"
#include "extensions/browser/extension_dialog_auto_confirm.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/test_extension_registry_observer.h"
#include "extensions/test/extension_test_message_listener.h"
#include "extensions/test/result_catcher.h"
#include "extensions/test/test_extension_dir.h"

namespace extensions {

using ContextType = extensions::browser_test_util::ContextType;

// Tests management API from a non-persistent extension (event page or
// Service Worker).
class ManagementApiNonPersistentApiTest
    : public ExtensionApiTest,
      public testing::WithParamInterface<ContextType> {
 public:
  ManagementApiNonPersistentApiTest() : ExtensionApiTest(GetParam()) {}
  ~ManagementApiNonPersistentApiTest() override = default;
  ManagementApiNonPersistentApiTest(const ManagementApiNonPersistentApiTest&) =
      delete;
  ManagementApiNonPersistentApiTest& operator=(
      const ManagementApiNonPersistentApiTest&) = delete;
};

// Tests chrome.management.uninstallSelf API.
IN_PROC_BROWSER_TEST_P(ManagementApiNonPersistentApiTest, UninstallSelf) {
  static constexpr char kEventPageBackgroundScript[] =
      R"({"scripts": ["script.js"], "persistent": false})";
  static constexpr char kServiceWorkerBackgroundScript[] =
      R"({"service_worker": "script.js"})";
  static constexpr char kManifest[] =
      R"({
           "name": "Test Extension",
           "manifest_version": 2,
           "version": "0.1",
           "background": %s
         })";
  std::string manifest =
      base::StringPrintf(kManifest, GetParam() == ContextType::kEventPage
                                        ? kEventPageBackgroundScript
                                        : kServiceWorkerBackgroundScript);

  // This script uninstalls itself.
  static constexpr char kScript[] =
      "chrome.management.uninstallSelf({showConfirmDialog: false});";

  TestExtensionDir test_dir;

  test_dir.WriteManifest(manifest);
  test_dir.WriteFile(FILE_PATH_LITERAL("script.js"), kScript);

  // Construct this before loading the extension, since the extension will
  // immediately uninstall itself when it loads.
  extensions::TestExtensionRegistryObserver observer(
      extensions::ExtensionRegistry::Get(browser()->profile()));

  base::FilePath path = test_dir.Pack();
  // Note: We set LoadOptions::wait_for_renderers to false because the extension
  // uninstalls itself, so the ExtensionHost never fully finishes loading. Since
  // we wait for the uninstall explicitly, this isn't racy.
  scoped_refptr<const Extension> extension =
      LoadExtension(path, {.wait_for_renderers = false,
                           .context_type = ContextType::kFromManifest});

  EXPECT_EQ(extension, observer.WaitForExtensionUninstalled());
}

// Tests chrome.management.uninstall with a real user gesture
// (i.e. browserAction.onClicked event).
IN_PROC_BROWSER_TEST_P(ManagementApiNonPersistentApiTest,
                       UninstallViaBrowserAction) {
  const Extension* extension_b = LoadExtension(test_data_dir_.AppendASCII(
      "management/uninstall_via_browser_action/extension_b"));
  ASSERT_TRUE(extension_b);
  const ExtensionId extension_b_id = extension_b->id();

  ExtensionRegistry* registry = ExtensionRegistry::Get(profile());
  // extension_b should be installed.
  // Note: For the purpose of this test, just checking whether the extension is
  // installed or not (ExtensionRegistry::EVERYTHING)
  // is enough. But for clarity, we check for enabled-ness
  // (ExtensionRegistry::ENABLED) here.
  EXPECT_TRUE(registry->enabled_extensions().GetByID(extension_b_id));

  // Load extension_a and wait for browserAction.onClicked listener
  // registration.
  ExtensionTestMessageListener listener_added("ready");
  const Extension* extension_a = LoadExtension(test_data_dir_.AppendASCII(
      "management/uninstall_via_browser_action/extension_a"));
  ASSERT_TRUE(extension_a);
  EXPECT_TRUE(listener_added.WaitUntilSatisfied());

  // We need to accept uninstallation prompt since this is not a
  // self-uninstallation.
  ScopedTestDialogAutoConfirm auto_confirm_uninstall(
      ScopedTestDialogAutoConfirm::ACCEPT);

  ResultCatcher catcher;
  // Click on browser action to start the test, |extension_a| will uninstall
  // |extension_b|.
  {
    content::WebContents* web_contents =
        browsertest_util::AddTab(browser(), GURL("about:blank"));
    ASSERT_TRUE(web_contents);
    ExtensionActionRunner::GetForWebContents(
        browser()->tab_strip_model()->GetActiveWebContents())
        ->RunAction(extension_a, true);
  }
  EXPECT_TRUE(catcher.GetNextResult()) << message_;

  // extension_b should be gone.
  EXPECT_FALSE(registry->GetExtensionById(extension_b_id,
                                          ExtensionRegistry::EVERYTHING));
}

INSTANTIATE_TEST_SUITE_P(EventPage,
                         ManagementApiNonPersistentApiTest,
                         ::testing::Values(ContextType::kEventPage));

// UninstallViaBrowserAction requires MV2.
INSTANTIATE_TEST_SUITE_P(ServiceWorker,
                         ManagementApiNonPersistentApiTest,
                         ::testing::Values(ContextType::kServiceWorkerMV2));

}  // namespace extensions