1 // Copyright 2020 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/ui/ash/holding_space/holding_space_client_impl.h"
6
7 #include <string>
8
9 #include "ash/public/cpp/ash_features.h"
10 #include "ash/public/cpp/holding_space/holding_space_controller.h"
11 #include "ash/public/cpp/holding_space/holding_space_image.h"
12 #include "ash/public/cpp/holding_space/holding_space_item.h"
13 #include "ash/public/cpp/holding_space/holding_space_model.h"
14 #include "base/callback_helpers.h"
15 #include "base/files/file_path.h"
16 #include "base/files/file_util.h"
17 #include "base/path_service.h"
18 #include "base/run_loop.h"
19 #include "base/test/bind.h"
20 #include "base/unguessable_token.h"
21 #include "chrome/browser/chromeos/file_manager/path_util.h"
22 #include "chrome/browser/extensions/component_loader.h"
23 #include "chrome/browser/profiles/profile_manager.h"
24 #include "chrome/browser/ui/ash/holding_space/holding_space_browsertest_base.h"
25 #include "chrome/browser/ui/browser.h"
26 #include "chrome/test/base/in_process_browser_test.h"
27 #include "content/public/test/browser_test.h"
28 #include "storage/browser/file_system/external_mount_points.h"
29 #include "ui/gfx/image/image_skia.h"
30
31 namespace ash {
32
33 namespace {
34
35 // File paths for test data.
36 constexpr char kTestDataDir[] = "chrome/test/data/chromeos/file_manager/";
37 constexpr char kImageFilePath[] = "image.png";
38 constexpr char kTextFilePath[] = "text.txt";
39
40 // Helpers ---------------------------------------------------------------------
41
42 // Copies the file for the `relative_path` in the test data directory to
43 // downloads directory, and returns the path to the copy.
TestFile(Profile * profile,const std::string & relative_path)44 base::FilePath TestFile(Profile* profile, const std::string& relative_path) {
45 base::FilePath source_root;
46 EXPECT_TRUE(base::PathService::Get(base::DIR_SOURCE_ROOT, &source_root));
47 const base::FilePath source_file =
48 source_root.AppendASCII(kTestDataDir).AppendASCII(relative_path);
49
50 base::FilePath target_dir;
51 if (!storage::ExternalMountPoints::GetSystemInstance()->GetRegisteredPath(
52 file_manager::util::GetDownloadsMountPointName(profile),
53 &target_dir)) {
54 ADD_FAILURE() << "Failed to get downloads mount point";
55 return base::FilePath();
56 }
57
58 const base::FilePath target_path = target_dir.Append(source_file.BaseName());
59 base::ScopedAllowBlockingForTesting allow_blocking;
60 if (!base::CopyFile(source_file, target_path)) {
61 ADD_FAILURE() << "Failed to create file.";
62 return base::FilePath();
63 }
64
65 return target_path;
66 }
67
68 } // namespace
69
70 // Tests -----------------------------------------------------------------------
71
72 using HoldingSpaceClientImplTest = HoldingSpaceBrowserTestBase;
73
74 // Verifies that `HoldingSpaceClient::CopyImageToClipboard()` works as intended
75 // when attempting to copy both image backed and non-image backed holding space
76 // items.
IN_PROC_BROWSER_TEST_F(HoldingSpaceClientImplTest,CopyImageToClipboard)77 IN_PROC_BROWSER_TEST_F(HoldingSpaceClientImplTest, CopyImageToClipboard) {
78 ASSERT_TRUE(HoldingSpaceController::Get());
79
80 auto* holding_space_client = HoldingSpaceController::Get()->client();
81 ASSERT_TRUE(holding_space_client);
82
83 {
84 // Create a holding space item backed by a non-image file.
85 auto* holding_space_item =
86 AddItem(GetProfile(), HoldingSpaceItem::Type::kDownload,
87 TestFile(GetProfile(), kTextFilePath));
88
89 // We expect `HoldingSpaceClient::CopyImageToClipboard()` to fail when the
90 // backing file for `holding_space_item` is not an image file.
91 base::RunLoop run_loop;
92 holding_space_client->CopyImageToClipboard(
93 *holding_space_item,
94 base::BindLambdaForTesting([&run_loop](bool success) {
95 EXPECT_FALSE(success);
96 run_loop.Quit();
97 }));
98 run_loop.Run();
99 }
100
101 {
102 // Create a holding space item backed by an image file.
103 auto* holding_space_item =
104 AddItem(GetProfile(), HoldingSpaceItem::Type::kDownload,
105 TestFile(GetProfile(), kImageFilePath));
106
107 // We expect `HoldingSpaceClient::CopyImageToClipboard()` to succeed when
108 // the backing file for `holding_space_item` is an image file.
109 base::RunLoop run_loop;
110 holding_space_client->CopyImageToClipboard(
111 *holding_space_item,
112 base::BindLambdaForTesting([&run_loop](bool success) {
113 EXPECT_TRUE(success);
114 run_loop.Quit();
115 }));
116 run_loop.Run();
117 }
118 }
119
120 // Verifies that `HoldingSpaceClient::OpenDownloads()` works as intended.
121 // TODO(crbug.com/1139299): Flaky.
IN_PROC_BROWSER_TEST_F(HoldingSpaceClientImplTest,DISABLED_OpenDownloads)122 IN_PROC_BROWSER_TEST_F(HoldingSpaceClientImplTest, DISABLED_OpenDownloads) {
123 ASSERT_TRUE(HoldingSpaceController::Get());
124
125 auto* holding_space_client = HoldingSpaceController::Get()->client();
126 ASSERT_TRUE(holding_space_client);
127
128 // We expect `HoldingSpaceClient::OpenDownloads()` to succeed.
129 base::RunLoop run_loop;
130 holding_space_client->OpenDownloads(
131 base::BindLambdaForTesting([&run_loop](bool success) {
132 EXPECT_TRUE(success);
133 run_loop.Quit();
134 }));
135 run_loop.Run();
136 }
137
138 // Verifies that `HoldingSpaceClient::OpenItems()` works as intended when
139 // attempting to open holding space items backed by both non-existing and
140 // existing files.
IN_PROC_BROWSER_TEST_F(HoldingSpaceClientImplTest,OpenItems)141 IN_PROC_BROWSER_TEST_F(HoldingSpaceClientImplTest, OpenItems) {
142 ASSERT_TRUE(HoldingSpaceController::Get());
143
144 auto* holding_space_client = HoldingSpaceController::Get()->client();
145 ASSERT_TRUE(holding_space_client);
146
147 {
148 // Create a holding space item backed by a non-existing file.
149 auto holding_space_item = HoldingSpaceItem::CreateFileBackedItem(
150 HoldingSpaceItem::Type::kDownload, base::FilePath("foo"),
151 GURL("filesystem:fake"),
152 std::make_unique<HoldingSpaceImage>(
153 /*placeholder=*/gfx::ImageSkia(),
154 /*async_bitmap_resolver=*/base::DoNothing()));
155
156 // We expect `HoldingSpaceClient::OpenItems()` to fail when the backing file
157 // for `holding_space_item` does not exist.
158 base::RunLoop run_loop;
159 holding_space_client->OpenItems(
160 {holding_space_item.get()},
161 base::BindLambdaForTesting([&run_loop](bool success) {
162 EXPECT_FALSE(success);
163 run_loop.Quit();
164 }));
165 run_loop.Run();
166 }
167
168 {
169 // Create a holding space item backed by a newly created txt file.
170 HoldingSpaceItem* holding_space_item = AddPinnedFile();
171
172 // We expect `HoldingSpaceClient::OpenItems()` to succeed when the backing
173 // file for `holding_space_item` exists.
174 base::RunLoop run_loop;
175 holding_space_client->OpenItems(
176 {holding_space_item},
177 base::BindLambdaForTesting([&run_loop](bool success) {
178 EXPECT_TRUE(success);
179 run_loop.Quit();
180 }));
181 run_loop.Run();
182 }
183 }
184
185 // Verifies that `HoldingSpaceClient::ShowItemInFolder()` works as intended when
186 // attempting to open holding space items backed by both non-existing and
187 // existing files.
188 // Flaky on linux-chromeos-dbg (https://crbug.com/1130958)
189 #ifdef NDEBUG
190 #define MAYBE_ShowItemInFolder ShowItemInFolder
191 #else
192 #define MAYBE_ShowItemInFolder DISABLED_ShowItemInFolder
193 #endif
IN_PROC_BROWSER_TEST_F(HoldingSpaceClientImplTest,MAYBE_ShowItemInFolder)194 IN_PROC_BROWSER_TEST_F(HoldingSpaceClientImplTest, MAYBE_ShowItemInFolder) {
195 ASSERT_TRUE(HoldingSpaceController::Get());
196
197 auto* holding_space_client = HoldingSpaceController::Get()->client();
198 ASSERT_TRUE(holding_space_client);
199
200 {
201 // Create a holding space item backed by a non-existing file.
202 auto holding_space_item = HoldingSpaceItem::CreateFileBackedItem(
203 HoldingSpaceItem::Type::kDownload, base::FilePath("foo"),
204 GURL("filesystem:fake"),
205 std::make_unique<HoldingSpaceImage>(
206 /*placeholder=*/gfx::ImageSkia(),
207 /*async_bitmap_resolver=*/base::DoNothing()));
208
209 // We expect `HoldingSpaceClient::ShowItemInFolder()` to fail when the
210 // backing file for `holding_space_item` does not exist.
211 base::RunLoop run_loop;
212 holding_space_client->ShowItemInFolder(
213 *holding_space_item,
214 base::BindLambdaForTesting([&run_loop](bool success) {
215 EXPECT_FALSE(success);
216 run_loop.Quit();
217 }));
218 run_loop.Run();
219 }
220
221 {
222 // Create a holding space item backed by a newly created txt file.
223 HoldingSpaceItem* holding_space_item = AddPinnedFile();
224
225 // We expect `HoldingSpaceClient::ShowItemInFolder()` to succeed when the
226 // backing file for `holding_space_item` exists.
227 base::RunLoop run_loop;
228 holding_space_client->ShowItemInFolder(
229 *holding_space_item,
230 base::BindLambdaForTesting([&run_loop](bool success) {
231 EXPECT_TRUE(success);
232 run_loop.Quit();
233 }));
234 run_loop.Run();
235 }
236 }
237
238 // Verifies that `HoldingSpaceClient::PinItems()` works as intended.
IN_PROC_BROWSER_TEST_F(HoldingSpaceClientImplTest,PinItems)239 IN_PROC_BROWSER_TEST_F(HoldingSpaceClientImplTest, PinItems) {
240 ASSERT_TRUE(HoldingSpaceController::Get());
241
242 auto* holding_space_client = HoldingSpaceController::Get()->client();
243 auto* holding_space_model = HoldingSpaceController::Get()->model();
244 ASSERT_TRUE(holding_space_client && holding_space_model);
245
246 // Create a download holding space item.
247 HoldingSpaceItem* download_item = AddDownloadFile();
248 ASSERT_EQ(1u, holding_space_model->items().size());
249
250 // Attempt to pin the download holding space item.
251 holding_space_client->PinItems({download_item});
252 ASSERT_EQ(2u, holding_space_model->items().size());
253
254 // The pinned holding space item should have type `kPinnedFile` but share the
255 // same text and file path as the original download holding space item.
256 HoldingSpaceItem* pinned_file_item = holding_space_model->items()[1].get();
257 EXPECT_EQ(pinned_file_item->type(), HoldingSpaceItem::Type::kPinnedFile);
258 EXPECT_EQ(download_item->text(), pinned_file_item->text());
259 EXPECT_EQ(download_item->file_path(), pinned_file_item->file_path());
260 }
261
262 // Verifies that `HoldingSpaceClient::UnpinItems()` works as intended.
IN_PROC_BROWSER_TEST_F(HoldingSpaceClientImplTest,UnpinItems)263 IN_PROC_BROWSER_TEST_F(HoldingSpaceClientImplTest, UnpinItems) {
264 ASSERT_TRUE(HoldingSpaceController::Get());
265
266 auto* holding_space_client = HoldingSpaceController::Get()->client();
267 auto* holding_space_model = HoldingSpaceController::Get()->model();
268 ASSERT_TRUE(holding_space_client && holding_space_model);
269
270 // Create a pinned file holding space item.
271 HoldingSpaceItem* pinned_file_item = AddPinnedFile();
272 ASSERT_EQ(1u, holding_space_model->items().size());
273
274 // Attempt to unpin the pinned file holding space item.
275 holding_space_client->UnpinItems({pinned_file_item});
276 ASSERT_EQ(0u, holding_space_model->items().size());
277 }
278
279 } // namespace ash
280