File: app_session_service_unittest.cc

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (251 lines) | stat: -rw-r--r-- 9,615 bytes parent folder | download | duplicates (6)
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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
// Copyright 2021 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/sessions/app_session_service.h"

#include <stddef.h>

#include <vector>

#include "build/build_config.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/buildflags.h"
#include "chrome/browser/sessions/app_session_service_test_helper.h"
#include "chrome/test/base/browser_with_test_window_test.h"
#include "chrome/test/base/testing_profile.h"
#include "components/sessions/content/content_serialized_navigation_builder.h"
#include "components/sessions/content/content_test_helper.h"
#include "components/sessions/core/serialized_navigation_entry_test_helper.h"
#include "content/public/browser/navigation_entry.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/mojom/window_show_state.mojom.h"

using content::NavigationEntry;
using sessions::ContentTestHelper;
using sessions::SerializedNavigationEntry;
using sessions::SerializedNavigationEntryTestHelper;

// Since AppSessionService is mostly based on SessionServiceBase,
// AppSessionService unit tests will aim to test things unique to
// AppSessionService.

// This unit_test suite is relatively spartan compared to SessionService
// unittests because a large portion of SessionService unit tests test
// SessionServiceBase and SessionService together.

// Actual app restoration testing will be in
// app_session_service_browsertests.cc
class AppSessionServiceTest : public BrowserWithTestWindowTest {
 public:
  AppSessionServiceTest() : window_bounds_(0, 1, 2, 3) {}

 protected:
  // SetUp() opens 1 normal window and 1 app window to each of the respective
  // [app]SessionService classes.
  void SetUp() override {
    BrowserWithTestWindowTest::SetUp();

    app_session_service_ =
        std::make_unique<AppSessionService>(browser()->profile());
    app_helper_.SetService(app_session_service_.get());

    app_service()->SetWindowType(app_window_id, Browser::TYPE_APP);
    app_service()->SetWindowBounds(app_window_id, window_bounds_,
                                   ui::mojom::WindowShowState::kNormal);
    app_service()->SetWindowAppName(app_window_id, "TestApp");
    app_service()->SetWindowWorkspace(app_window_id, window_workspace);

    app_nav = ContentTestHelper::CreateNavigation("http://google2.com", "abcd");
    app_helper_.PrepareTabInWindow(app_window_id, app_tab_id, 0, true);
    AppUpdateNavigation(app_window_id, app_tab_id, app_nav, true);
  }

  void TearDown() override {
    DestroyAppSessionService();

    BrowserWithTestWindowTest::TearDown();
  }

  void DestroyAppSessionService() {
    // Destroy the AppSessionService first as it may post tasks.
    ASSERT_TRUE(app_session_service_);
    app_session_service_.reset();
    // This flushes tasks.
    app_helper_.SetService(nullptr);
  }

  void AppUpdateNavigation(SessionID window_session_id,
                           SessionID tab_id,
                           const SerializedNavigationEntry& navigation,
                           bool select) {
    app_service()->UpdateTabNavigation(window_session_id, tab_id, navigation);
    if (select) {
      app_service()->SetSelectedNavigationIndex(window_session_id, tab_id,
                                                navigation.index());
    }
  }

  void AppReadWindows(
      std::vector<std::unique_ptr<sessions::SessionWindow>>* windows,
      SessionID* active_window_id) {
    DestroyAppSessionService();

    app_session_service_ =
        std::make_unique<AppSessionService>(browser()->profile());
    app_helper_.SetService(app_session_service_.get());

    SessionID* non_null_active_window_id = active_window_id;
    SessionID dummy_active_window_id = SessionID::InvalidValue();
    if (!non_null_active_window_id)
      non_null_active_window_id = &dummy_active_window_id;
    app_helper_.ReadWindows(windows, non_null_active_window_id);
  }

  // Gets the pinned state of the app set up in SetUp()
  bool GetPinnedStateOfDefaultApp() {
    std::vector<std::unique_ptr<sessions::SessionWindow>> windows;
    AppReadWindows(&windows, nullptr);

    EXPECT_EQ(1U, windows.size());
    if (HasFatalFailure())
      return false;
    EXPECT_EQ(1U, windows[0]->tabs.size());
    if (HasFatalFailure())
      return false;

    sessions::SessionTab* tab = windows[0]->tabs[0].get();
    return tab->pinned;
  }

  // SetUp already includes one add, add one more.
  void CreateAndWriteSessionWithTwoApps(SessionID app2_id,
                                        SessionID tab1_id,
                                        SerializedNavigationEntry* nav1) {
    *nav1 = ContentTestHelper::CreateNavigation("http://google.com", "abc");

    app_service()->SetWindowType(app2_id, Browser::TYPE_APP);
    app_service()->SetWindowBounds(app2_id, window_bounds_,
                                   ui::mojom::WindowShowState::kNormal);
    app_service()->SetWindowAppName(app2_id, "TestApp");
    app_service()->SetWindowWorkspace(app2_id, window_workspace);

    SerializedNavigationEntry nav =
        ContentTestHelper::CreateNavigation("http://google2.com", "abcd");
    app_helper_.PrepareTabInWindow(app2_id, tab1_id, 0, true);
    AppUpdateNavigation(app2_id, tab1_id, *nav1, true);
  }

  AppSessionService* app_service() { return app_helper_.service(); }

  const gfx::Rect window_bounds_;

  const std::string window_workspace = "abc";

  const SessionID window_id = SessionID::NewUnique();
  const SessionID app_window_id = SessionID::NewUnique();
  const SessionID app_tab_id = SessionID::NewUnique();
  SerializedNavigationEntry app_nav;

  std::unique_ptr<AppSessionService> app_session_service_;

  AppSessionServiceTestHelper app_helper_;
};

TEST_F(AppSessionServiceTest, Basic) {
  SessionID tab_id = SessionID::NewUnique();
  ASSERT_NE(window_id, tab_id);

  // Now verify AppSessionService
  std::vector<std::unique_ptr<sessions::SessionWindow>> app_windows;
  AppReadWindows(&app_windows, nullptr);

  ASSERT_EQ(1U, app_windows.size());
  ASSERT_TRUE(window_bounds_ == app_windows[0]->bounds);
  ASSERT_EQ(window_workspace, app_windows[0]->workspace);
  ASSERT_EQ(0, app_windows[0]->selected_tab_index);
  ASSERT_EQ(app_window_id, app_windows[0]->window_id);
  ASSERT_EQ(1U, app_windows[0]->tabs.size());
  ASSERT_EQ(sessions::SessionWindow::TYPE_APP, app_windows[0]->type);
}

TEST_F(AppSessionServiceTest, BasicRelevancyTest) {
  ASSERT_TRUE(app_service()->ShouldRestoreWindowOfType(
      sessions::SessionWindow::TYPE_APP));
  ASSERT_FALSE(app_service()->ShouldRestoreWindowOfType(
      sessions::SessionWindow::TYPE_NORMAL));
}

// SetUp has one app window written. Add one more and ensure the nav data
// stored matches expectations.
TEST_F(AppSessionServiceTest, TwoApps) {
  SessionID window2_id = SessionID::NewUnique();
  SessionID tab1_id = SessionID::NewUnique();
  SerializedNavigationEntry nav1;

  CreateAndWriteSessionWithTwoApps(window2_id, tab1_id, &nav1);

  std::vector<std::unique_ptr<sessions::SessionWindow>> windows;
  AppReadWindows(&windows, nullptr);

  ASSERT_EQ(2U, windows.size());
  ASSERT_EQ(1U, windows[0]->tabs.size());
  ASSERT_EQ(1U, windows[1]->tabs.size());

  if (windows[0]->window_id == app_window_id) {
    ASSERT_EQ(window2_id, windows[1]->window_id);
  } else {
    ASSERT_EQ(window2_id, windows[0]->window_id);
    ASSERT_EQ(window_id, windows[1]->window_id);
    ASSERT_EQ(ui::mojom::WindowShowState::kMaximized, windows[0]->show_state);
    ASSERT_EQ(ui::mojom::WindowShowState::kNormal, windows[1]->show_state);
  }
}

// Don't set the pinned state and make sure the pinned value is false.
TEST_F(AppSessionServiceTest, PinnedDefaultsToFalse) {
  EXPECT_FALSE(GetPinnedStateOfDefaultApp());
}

TEST_F(AppSessionServiceTest, RestoreAppWithAppSessionService) {
  SessionID window2_id = SessionID::NewUnique();
  SessionID tab2_id = SessionID::NewUnique();
  ASSERT_NE(window2_id, window_id);

  // This unit test checks that the two instances of SessionService
  // do not interfer and are isolated.
  app_helper_.service()->SetWindowType(window2_id, Browser::TYPE_APP);
  app_helper_.service()->SetWindowBounds(window2_id, window_bounds_,
                                         ui::mojom::WindowShowState::kNormal);
  app_helper_.service()->SetWindowAppName(window2_id, "TestApp");

  SerializedNavigationEntry nav1 =
      ContentTestHelper::CreateNavigation("http://google.com", "abc");
  SerializedNavigationEntry nav2 =
      ContentTestHelper::CreateNavigation("http://google2.com", "abcd");

  app_helper_.PrepareTabInWindow(window2_id, tab2_id, 0, false);
  AppUpdateNavigation(window2_id, tab2_id, nav2, true);

  std::vector<std::unique_ptr<sessions::SessionWindow>> app_windows;
  AppReadWindows(&app_windows, nullptr);

  // Now check all the state from AppSessionService
  // We can't predict if app_windows[0] or [1] is the one we opened,
  // so try to figure that out first.
  int our_window_index = 0;
  if (app_windows[0]->window_id != window2_id) {
    // by deduction, it should be [1].
    our_window_index = 1;
  }

  ASSERT_EQ(0, app_windows[our_window_index]->selected_tab_index);
  ASSERT_EQ(window2_id, app_windows[our_window_index]->window_id);
  ASSERT_EQ(1U, app_windows[our_window_index]->tabs.size());
  ASSERT_TRUE(app_windows[our_window_index]->type ==
              sessions::SessionWindow::TYPE_APP);
  ASSERT_EQ("TestApp", app_windows[our_window_index]->app_name);

  auto* tab = app_windows[our_window_index]->tabs[0].get();
  app_helper_.AssertTabEquals(window2_id, tab2_id, 0, 0, 1, *tab);
}