File: toolbar_actions_model_browsertest.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 (150 lines) | stat: -rw-r--r-- 6,137 bytes parent folder | download | duplicates (4)
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
139
140
141
142
143
144
145
146
147
148
149
150
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/toolbar/toolbar_actions_model.h"

#include "base/memory/raw_ptr.h"
#include "base/test/metrics/histogram_tester.h"
#include "chrome/browser/extensions/extension_browsertest.h"
#include "chrome/browser/profiles/profile.h"
#include "content/public/test/browser_test.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/extension_set.h"
#include "testing/gmock/include/gmock/gmock.h"

namespace {

// We use some arbitrary extensions. Use constants for more clarity.
constexpr char kExtension1Path[] = "simple_with_file";
constexpr char kExtension1Name[] = "foo";
constexpr char kExtension2Path[] = "simple_with_icon";
constexpr char kExtension2Name[] = "Simple Extension with icon";
constexpr char kExtension3Path[] = "simple_with_host";
constexpr char kExtension3Name[] = "bar";

}  // namespace

class ToolbarActionsModelBrowserTest : public extensions::ExtensionBrowserTest {
 public:
  ToolbarActionsModelBrowserTest() = default;
  ~ToolbarActionsModelBrowserTest() override = default;

  void SetUpOnMainThread() override {
    extensions::ExtensionBrowserTest::SetUpOnMainThread();
    toolbar_model_ = ToolbarActionsModel::Get(profile());
    ASSERT_TRUE(toolbar_model_);
  }

  void TearDownOnMainThread() override {
    toolbar_model_ = nullptr;
    extensions::ExtensionBrowserTest::TearDownOnMainThread();
  }

  ToolbarActionsModel* toolbar_model() { return toolbar_model_; }
  base::HistogramTester* histogram_tester() { return &histogram_tester_; }

 private:
  raw_ptr<ToolbarActionsModel> toolbar_model_ = nullptr;
  base::HistogramTester histogram_tester_;
};

IN_PROC_BROWSER_TEST_F(ToolbarActionsModelBrowserTest, PRE_PinnedStateMetrics) {
  const extensions::Extension* extension1 =
      LoadExtension(test_data_dir_.AppendASCII("simple_with_file"));
  ASSERT_TRUE(extension1);

  const extensions::Extension* extension2 =
      LoadExtension(test_data_dir_.AppendASCII("simple_with_icon"));
  ASSERT_TRUE(extension2);

  EXPECT_EQ(2u, toolbar_model()->action_ids().size());

  EXPECT_FALSE(toolbar_model()->IsActionPinned(extension1->id()));
  EXPECT_FALSE(toolbar_model()->IsActionPinned(extension2->id()));
  toolbar_model()->SetActionVisibility(extension1->id(), true);
  EXPECT_TRUE(toolbar_model()->IsActionPinned(extension1->id()));
  EXPECT_FALSE(toolbar_model()->IsActionPinned(extension2->id()));
}

IN_PROC_BROWSER_TEST_F(ToolbarActionsModelBrowserTest, PinnedStateMetrics) {
  EXPECT_EQ(2u, toolbar_model()->action_ids().size());
  EXPECT_EQ(1u, toolbar_model()->pinned_action_ids().size());

  histogram_tester()->ExpectUniqueSample(
      "Extensions.Toolbar.PinnedExtensionPercentage3", 50, 1);
  histogram_tester()->ExpectUniqueSample(
      "Extensions.Toolbar.PinnedExtensionCount2", 1, 1);
}

// Test that a user's pinned extensions and ordering persist across sessions. We
// exercise this in a two-step browser test, which most closely reflects a
// "real world" multi-session scenario.
IN_PROC_BROWSER_TEST_F(ToolbarActionsModelBrowserTest,
                       PRE_PinnedStatePersistence) {
  const extensions::Extension* const extension1 =
      LoadExtension(test_data_dir_.AppendASCII(kExtension1Path));
  ASSERT_TRUE(extension1);

  const extensions::Extension* const extension2 =
      LoadExtension(test_data_dir_.AppendASCII(kExtension2Path));
  ASSERT_TRUE(extension2);

  const extensions::Extension* const extension3 =
      LoadExtension(test_data_dir_.AppendASCII(kExtension3Path));
  ASSERT_TRUE(extension3);

  EXPECT_THAT(toolbar_model()->action_ids(),
              ::testing::UnorderedElementsAre(
                  extension1->id(), extension2->id(), extension3->id()));
  EXPECT_THAT(toolbar_model()->pinned_action_ids(), ::testing::IsEmpty());

  // Pin extension 3, followed by 2. The pinned extensions should be in the
  // order 3, 2.
  // TODO(devlin): The order of ToolbarActionsModel::action_ids() is not updated
  // as a result of pinning, but is updated as a result of moving extensions
  // around. Since pinned extensions are now the sorted order (and the rest are
  // displayed in alphabetical order in the menu), we can likely get rid of
  // sorting in action_ids() entirely. We should at least be consistent.
  toolbar_model()->SetActionVisibility(extension3->id(), true);
  toolbar_model()->SetActionVisibility(extension2->id(), true);

  EXPECT_THAT(toolbar_model()->action_ids(),
              ::testing::UnorderedElementsAre(
                  extension1->id(), extension2->id(), extension3->id()));
  EXPECT_THAT(toolbar_model()->pinned_action_ids(),
              ::testing::ElementsAre(extension3->id(), extension2->id()));
}

IN_PROC_BROWSER_TEST_F(ToolbarActionsModelBrowserTest, PinnedStatePersistence) {
  // Re-look-up the extensions. (Note that we can't use ID, since unpacked
  // extensions' ids are based on their absolute file path.)
  extensions::ExtensionRegistry* const registry =
      extensions::ExtensionRegistry::Get(profile());
  auto get_extension_by_name =
      [registry](const char* name) -> const extensions::Extension* {
    for (const auto& extension : registry->enabled_extensions()) {
      if (extension->name() == name) {
        return extension.get();
      }
    }
    return nullptr;
  };

  const extensions::Extension* const extension1 =
      get_extension_by_name(kExtension1Name);
  ASSERT_TRUE(extension1);
  const extensions::Extension* const extension2 =
      get_extension_by_name(kExtension2Name);
  ASSERT_TRUE(extension2);
  const extensions::Extension* const extension3 =
      get_extension_by_name(kExtension3Name);
  ASSERT_TRUE(extension3);

  // Pin state should have been persisted across sessions.
  EXPECT_THAT(toolbar_model()->action_ids(),
              ::testing::UnorderedElementsAre(
                  extension1->id(), extension2->id(), extension3->id()));
  EXPECT_THAT(toolbar_model()->pinned_action_ids(),
              ::testing::ElementsAre(extension3->id(), extension2->id()));
}