[M120][Tizen][Onscreen] Fix build errors for TV profile
[platform/framework/web/chromium-efl.git] / chrome / browser / platform_util_unittest.cc
1 // Copyright 2015 The Chromium Authors
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/platform_util.h"
6
7 #include <memory>
8
9 #include "base/files/file_util.h"
10 #include "base/files/scoped_temp_dir.h"
11 #include "base/functional/bind.h"
12 #include "base/functional/callback.h"
13 #include "base/memory/raw_ptr.h"
14 #include "base/run_loop.h"
15 #include "build/build_config.h"
16 #include "build/chromeos_buildflags.h"
17 #include "chrome/browser/platform_util_internal.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19
20 #if BUILDFLAG(IS_CHROMEOS_ASH)
21 #include "base/json/json_string_value_serializer.h"
22 #include "base/values.h"
23 #include "chrome/browser/apps/app_service/app_service_proxy.h"
24 #include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
25 #include "chrome/browser/apps/app_service/app_service_test.h"
26 #include "chrome/browser/apps/app_service/intent_util.h"
27 #include "chrome/browser/ash/file_manager/app_id.h"
28 #include "chrome/browser/ash/fileapi/file_system_backend.h"
29 #include "chrome/browser/ash/fileapi/file_system_backend_delegate.h"
30 #include "chrome/browser/chrome_content_browser_client.h"
31 #include "chrome/browser/extensions/extension_special_storage_policy.h"
32 #include "chrome/test/base/browser_with_test_window_test.h"
33 #include "components/services/app_service/public/cpp/app_types.h"
34 #include "components/services/app_service/public/cpp/intent_filter.h"
35 #include "content/public/browser/browser_context.h"
36 #include "content/public/common/content_client.h"
37 #include "extensions/browser/extension_registry.h"
38 #include "extensions/common/extension.h"
39 #include "storage/browser/file_system/external_mount_points.h"
40 #include "storage/browser/test/mock_special_storage_policy.h"
41 #include "storage/common/file_system/file_system_types.h"
42 #else
43 #include "content/public/test/browser_task_environment.h"
44 #endif
45
46 namespace platform_util {
47
48 namespace {
49
50 #if BUILDFLAG(IS_CHROMEOS_ASH)
51
52 // ChromeContentBrowserClient subclass that sets up a custom file system backend
53 // that allows the test to grant file access to the file manager extension ID
54 // without having to install the extension.
55 class PlatformUtilTestContentBrowserClient : public ChromeContentBrowserClient {
56  public:
57   void GetAdditionalFileSystemBackends(
58       content::BrowserContext* browser_context,
59       const base::FilePath& storage_partition_path,
60       std::vector<std::unique_ptr<storage::FileSystemBackend>>*
61           additional_backends) override {
62     storage::ExternalMountPoints* external_mount_points =
63         browser_context->GetMountPoints();
64
65     // New FileSystemBackend that uses our MockSpecialStoragePolicy.
66     additional_backends->push_back(std::make_unique<ash::FileSystemBackend>(
67         nullptr,  // profile
68         nullptr,  // file_system_provider_delegate
69         nullptr,  // mtp_delegate
70         nullptr,  // arc_content_delegate
71         nullptr,  // arc_documents_provider_delegate
72         nullptr,  // drivefs_delegate
73         nullptr,  // smbfs_delegate
74         external_mount_points,
75         storage::ExternalMountPoints::GetSystemInstance()));
76   }
77 };
78
79 // Base test fixture class to be used on Chrome OS.
80 class PlatformUtilTestBase : public BrowserWithTestWindowTest {
81  protected:
82   void SetUpPlatformFixture(const base::FilePath& test_directory) {
83     content_browser_client_ =
84         std::make_unique<PlatformUtilTestContentBrowserClient>();
85     old_content_browser_client_ =
86         content::SetBrowserClientForTesting(content_browser_client_.get());
87
88     app_service_test_.SetUp(GetProfile());
89     app_service_proxy_ =
90         apps::AppServiceProxyFactory::GetForProfile(GetProfile());
91     ASSERT_TRUE(app_service_proxy_);
92
93     // The test_directory needs to be mounted for it to be accessible.
94     GetProfile()->GetMountPoints()->RegisterFileSystem(
95         "test", storage::kFileSystemTypeLocal, storage::FileSystemMountOption(),
96         test_directory);
97
98     // To test opening a file, we are going to register a mock extension that
99     // handles .txt files. The extension doesn't actually need to exist due to
100     // the DisableShellOperationsForTesting() call which prevents the extension
101     // from being invoked.
102     std::string error;
103     int error_code = 0;
104
105     std::string json_manifest =
106         "{"
107         "  \"manifest_version\": 2,"
108         "  \"name\": \"Test extension\","
109         "  \"version\": \"0\","
110         "  \"app\": { \"background\": { \"scripts\": [\"main.js\"] }},"
111         "  \"file_handlers\": {"
112         "    \"text\": {"
113         "      \"extensions\": [ \"txt\" ],"
114         "      \"title\": \"Text\""
115         "      }"
116         "    }"
117         "}";
118     JSONStringValueDeserializer json_string_deserializer(json_manifest);
119     std::unique_ptr<base::Value> manifest =
120         json_string_deserializer.Deserialize(&error_code, &error);
121     base::Value::Dict* manifest_dictionary = manifest->GetIfDict();
122     ASSERT_TRUE(manifest_dictionary);
123
124     scoped_refptr<extensions::Extension> extension =
125         extensions::Extension::Create(
126             test_directory.AppendASCII("invalid-extension"),
127             extensions::mojom::ManifestLocation::kInvalidLocation,
128             *manifest_dictionary, extensions::Extension::NO_FLAGS, &error);
129     ASSERT_TRUE(error.empty()) << error;
130
131     std::vector<apps::AppPtr> apps;
132     auto app = std::make_unique<apps::App>(apps::AppType::kChromeApp,
133                                            "invalid-chrome-app");
134     app->handles_intents = true;
135     app->readiness = apps::Readiness::kReady;
136     app->intent_filters =
137         apps_util::CreateIntentFiltersForChromeApp(extension.get());
138     apps.push_back(std::move(app));
139     app_service_proxy_->OnApps(std::move(apps), apps::AppType::kChromeApp,
140                                /*should_notify_initialized=*/false);
141   }
142
143   void SetUp() override {
144     BrowserWithTestWindowTest::SetUp();
145     base::RunLoop().RunUntilIdle();
146   }
147
148   void TearDown() override {
149     content::ContentBrowserClient* content_browser_client =
150         content::SetBrowserClientForTesting(old_content_browser_client_);
151     old_content_browser_client_ = nullptr;
152     DCHECK_EQ(static_cast<content::ContentBrowserClient*>(
153                   content_browser_client_.get()),
154               content_browser_client)
155         << "ContentBrowserClient changed during test.";
156     BrowserWithTestWindowTest::TearDown();
157   }
158
159  private:
160   std::unique_ptr<content::ContentBrowserClient> content_browser_client_;
161   raw_ptr<content::ContentBrowserClient, ExperimentalAsh>
162       old_content_browser_client_ = nullptr;
163   apps::AppServiceTest app_service_test_;
164   raw_ptr<apps::AppServiceProxy, DanglingUntriaged | ExperimentalAsh>
165       app_service_proxy_ = nullptr;
166 };
167
168 #else
169
170 // Test fixture used by all desktop platforms other than Chrome OS.
171 class PlatformUtilTestBase : public testing::Test {
172  protected:
173   Profile* GetProfile() { return nullptr; }
174   void SetUpPlatformFixture(const base::FilePath&) {}
175
176  private:
177   content::BrowserTaskEnvironment task_environment_;
178 };
179
180 #endif
181
182 class PlatformUtilTest : public PlatformUtilTestBase {
183  public:
184   void SetUp() override {
185     ASSERT_NO_FATAL_FAILURE(PlatformUtilTestBase::SetUp());
186
187     static const char kTestFileData[] = "Cow says moo!";
188
189     // This prevents platform_util from invoking any shell or external APIs
190     // during tests. Doing so may result in external applications being launched
191     // and intefering with tests.
192     internal::DisableShellOperationsForTesting();
193
194     ASSERT_TRUE(directory_.CreateUniqueTempDir());
195
196     // A valid file.
197     existing_file_ = directory_.GetPath().AppendASCII("test_file.txt");
198     ASSERT_TRUE(base::WriteFile(existing_file_, kTestFileData));
199
200     // A valid folder.
201     existing_folder_ = directory_.GetPath().AppendASCII("test_folder");
202     ASSERT_TRUE(base::CreateDirectory(existing_folder_));
203
204     // A non-existent path.
205     nowhere_ = directory_.GetPath().AppendASCII("nowhere");
206
207     SetUpPlatformFixture(directory_.GetPath());
208   }
209
210   OpenOperationResult CallOpenItem(const base::FilePath& path,
211                                    OpenItemType item_type) {
212     base::RunLoop run_loop;
213     OpenOperationResult result = OPEN_SUCCEEDED;
214     OpenOperationCallback callback =
215         base::BindOnce(&OnOpenOperationDone, run_loop.QuitClosure(), &result);
216     OpenItem(GetProfile(), path, item_type, std::move(callback));
217     run_loop.Run();
218     return result;
219   }
220
221   base::FilePath existing_file_;
222   base::FilePath existing_folder_;
223   base::FilePath nowhere_;
224
225  protected:
226   base::ScopedTempDir directory_;
227
228  private:
229   std::unique_ptr<base::RunLoop> run_loop_;
230
231   static void OnOpenOperationDone(base::OnceClosure closure,
232                                   OpenOperationResult* store_result,
233                                   OpenOperationResult result) {
234     *store_result = result;
235     std::move(closure).Run();
236   }
237 };
238
239 }  // namespace
240
241 TEST_F(PlatformUtilTest, OpenFile) {
242   EXPECT_EQ(OPEN_SUCCEEDED, CallOpenItem(existing_file_, OPEN_FILE));
243   EXPECT_EQ(OPEN_FAILED_INVALID_TYPE,
244             CallOpenItem(existing_folder_, OPEN_FILE));
245   EXPECT_EQ(OPEN_FAILED_PATH_NOT_FOUND, CallOpenItem(nowhere_, OPEN_FILE));
246 }
247
248 TEST_F(PlatformUtilTest, OpenFolder) {
249   EXPECT_EQ(OPEN_SUCCEEDED, CallOpenItem(existing_folder_, OPEN_FOLDER));
250   EXPECT_EQ(OPEN_FAILED_INVALID_TYPE,
251             CallOpenItem(existing_file_, OPEN_FOLDER));
252   EXPECT_EQ(OPEN_FAILED_PATH_NOT_FOUND, CallOpenItem(nowhere_, OPEN_FOLDER));
253 }
254
255 #if BUILDFLAG(IS_POSIX)
256 // Symbolic links are currently only supported on Posix. Windows technically
257 // supports it as well, but not on Windows XP.
258 class PlatformUtilPosixTest : public PlatformUtilTest {
259  public:
260   void SetUp() override {
261     ASSERT_NO_FATAL_FAILURE(PlatformUtilTest::SetUp());
262
263     symlink_to_file_ = directory_.GetPath().AppendASCII("l_file.txt");
264     ASSERT_TRUE(base::CreateSymbolicLink(existing_file_, symlink_to_file_));
265     symlink_to_folder_ = directory_.GetPath().AppendASCII("l_folder");
266     ASSERT_TRUE(base::CreateSymbolicLink(existing_folder_, symlink_to_folder_));
267     symlink_to_nowhere_ = directory_.GetPath().AppendASCII("l_nowhere");
268     ASSERT_TRUE(base::CreateSymbolicLink(nowhere_, symlink_to_nowhere_));
269   }
270
271  protected:
272   base::FilePath symlink_to_file_;
273   base::FilePath symlink_to_folder_;
274   base::FilePath symlink_to_nowhere_;
275 };
276 #endif  // BUILDFLAG(IS_POSIX)
277
278 #if BUILDFLAG(IS_CHROMEOS_ASH)
279 // ChromeOS doesn't follow symbolic links in sandboxed filesystems. So all the
280 // symbolic link tests should return PATH_NOT_FOUND.
281
282 TEST_F(PlatformUtilPosixTest, OpenFileWithPosixSymlinksChromeOS) {
283   EXPECT_EQ(OPEN_FAILED_PATH_NOT_FOUND,
284             CallOpenItem(symlink_to_file_, OPEN_FILE));
285   EXPECT_EQ(OPEN_FAILED_PATH_NOT_FOUND,
286             CallOpenItem(symlink_to_folder_, OPEN_FILE));
287   EXPECT_EQ(OPEN_FAILED_PATH_NOT_FOUND,
288             CallOpenItem(symlink_to_nowhere_, OPEN_FILE));
289 }
290
291 TEST_F(PlatformUtilPosixTest, OpenFolderWithPosixSymlinksChromeOS) {
292   EXPECT_EQ(OPEN_FAILED_PATH_NOT_FOUND,
293             CallOpenItem(symlink_to_folder_, OPEN_FOLDER));
294   EXPECT_EQ(OPEN_FAILED_PATH_NOT_FOUND,
295             CallOpenItem(symlink_to_file_, OPEN_FOLDER));
296   EXPECT_EQ(OPEN_FAILED_PATH_NOT_FOUND,
297             CallOpenItem(symlink_to_nowhere_, OPEN_FOLDER));
298 }
299
300 TEST_F(PlatformUtilTest, OpenFileWithUnhandledFileType) {
301   base::FilePath unhandled_file =
302       directory_.GetPath().AppendASCII("myfile.filetype");
303   ASSERT_TRUE(base::WriteFile(unhandled_file, "cat"));
304   EXPECT_EQ(OPEN_FAILED_NO_HANLDER_FOR_FILE_TYPE,
305             CallOpenItem(unhandled_file, OPEN_FILE));
306 }
307 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
308
309 #if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_CHROMEOS_ASH)
310 // On all other Posix platforms, the symbolic link tests should work as
311 // expected.
312
313 TEST_F(PlatformUtilPosixTest, OpenFileWithPosixSymlinks) {
314   EXPECT_EQ(OPEN_SUCCEEDED, CallOpenItem(symlink_to_file_, OPEN_FILE));
315   EXPECT_EQ(OPEN_FAILED_INVALID_TYPE,
316             CallOpenItem(symlink_to_folder_, OPEN_FILE));
317   EXPECT_EQ(OPEN_FAILED_PATH_NOT_FOUND,
318             CallOpenItem(symlink_to_nowhere_, OPEN_FILE));
319 }
320
321 TEST_F(PlatformUtilPosixTest, OpenFolderWithPosixSymlinks) {
322   EXPECT_EQ(OPEN_SUCCEEDED, CallOpenItem(symlink_to_folder_, OPEN_FOLDER));
323   EXPECT_EQ(OPEN_FAILED_INVALID_TYPE,
324             CallOpenItem(symlink_to_file_, OPEN_FOLDER));
325   EXPECT_EQ(OPEN_FAILED_PATH_NOT_FOUND,
326             CallOpenItem(symlink_to_nowhere_, OPEN_FOLDER));
327 }
328 #endif  // BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_CHROMEOS_ASH)
329
330 }  // namespace platform_util