blob: 7594dbe09589fb61bf10ac87cb5a9d5021f8dd93 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/web_applications/components/web_app_shortcut_linux.h"
#include <stddef.h>
#include <algorithm>
#include <cstdlib>
#include <map>
#include <vector>
#include "base/base_paths.h"
#include "base/command_line.h"
#include "base/environment.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/macros.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_path_override.h"
#include "chrome/browser/web_applications/components/web_app_helpers.h"
#include "chrome/browser/web_applications/components/web_app_shortcut.h"
#include "chrome/common/chrome_constants.h"
#include "content/public/test/browser_task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
namespace web_app {
namespace {
// Provides mock environment variables values based on a stored map.
class MockEnvironment : public base::Environment {
public:
MockEnvironment() {}
void Set(base::StringPiece name, const std::string& value) {
variables_[name.as_string()] = value;
}
bool GetVar(base::StringPiece variable_name, std::string* result) override {
if (base::Contains(variables_, variable_name.as_string())) {
*result = variables_[variable_name.as_string()];
return true;
}
return false;
}
bool SetVar(base::StringPiece variable_name,
const std::string& new_value) override {
ADD_FAILURE();
return false;
}
bool UnSetVar(base::StringPiece variable_name) override {
ADD_FAILURE();
return false;
}
private:
std::map<std::string, std::string> variables_;
DISALLOW_COPY_AND_ASSIGN(MockEnvironment);
};
bool WriteEmptyFile(const base::FilePath& path) {
return base::WriteFile(path, "", 0) == 0;
}
bool WriteString(const base::FilePath& path, const base::StringPiece& str) {
int bytes_written = base::WriteFile(path, str.data(), str.size());
if (bytes_written < 0)
return false;
return static_cast<size_t>(bytes_written) == str.size();
}
} // namespace
TEST(ShellIntegrationTest, GetExistingShortcutLocations) {
base::FilePath kProfilePath("Profile 1");
const char kExtensionId[] = "test_extension";
const char kTemplateFilename[] = "chrome-test_extension-Profile_1.desktop";
base::FilePath kTemplateFilepath(kTemplateFilename);
const char kNoDisplayDesktopFile[] = "[Desktop Entry]\nNoDisplay=true";
content::BrowserTaskEnvironment task_environment;
// No existing shortcuts.
{
MockEnvironment env;
web_app::ShortcutLocations result =
GetExistingShortcutLocations(&env, kProfilePath, kExtensionId);
EXPECT_FALSE(result.on_desktop);
EXPECT_EQ(web_app::APP_MENU_LOCATION_NONE,
result.applications_menu_location);
EXPECT_FALSE(result.in_quick_launch_bar);
}
// Shortcut on desktop.
{
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
base::FilePath desktop_path = temp_dir.GetPath();
MockEnvironment env;
ASSERT_TRUE(base::CreateDirectory(desktop_path));
ASSERT_TRUE(WriteEmptyFile(desktop_path.Append(kTemplateFilename)));
web_app::ShortcutLocations result = GetExistingShortcutLocations(
&env, kProfilePath, kExtensionId, desktop_path);
EXPECT_TRUE(result.on_desktop);
EXPECT_EQ(web_app::APP_MENU_LOCATION_NONE,
result.applications_menu_location);
EXPECT_FALSE(result.in_quick_launch_bar);
}
// Shortcut in applications directory.
{
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
base::FilePath apps_path = temp_dir.GetPath().Append("applications");
MockEnvironment env;
env.Set("XDG_DATA_HOME", temp_dir.GetPath().value());
ASSERT_TRUE(base::CreateDirectory(apps_path));
ASSERT_TRUE(WriteEmptyFile(apps_path.Append(kTemplateFilename)));
web_app::ShortcutLocations result =
GetExistingShortcutLocations(&env, kProfilePath, kExtensionId);
EXPECT_FALSE(result.on_desktop);
EXPECT_EQ(web_app::APP_MENU_LOCATION_SUBDIR_CHROMEAPPS,
result.applications_menu_location);
EXPECT_FALSE(result.in_quick_launch_bar);
}
// Shortcut in applications directory with NoDisplay=true.
{
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
base::FilePath apps_path = temp_dir.GetPath().Append("applications");
MockEnvironment env;
env.Set("XDG_DATA_HOME", temp_dir.GetPath().value());
ASSERT_TRUE(base::CreateDirectory(apps_path));
ASSERT_TRUE(WriteString(apps_path.Append(kTemplateFilename),
kNoDisplayDesktopFile));
web_app::ShortcutLocations result =
GetExistingShortcutLocations(&env, kProfilePath, kExtensionId);
// Doesn't count as being in applications menu.
EXPECT_FALSE(result.on_desktop);
EXPECT_EQ(web_app::APP_MENU_LOCATION_HIDDEN,
result.applications_menu_location);
EXPECT_FALSE(result.in_quick_launch_bar);
}
// Shortcut on desktop and in applications directory.
{
base::ScopedTempDir temp_dir1;
ASSERT_TRUE(temp_dir1.CreateUniqueTempDir());
base::FilePath desktop_path = temp_dir1.GetPath();
base::ScopedTempDir temp_dir2;
ASSERT_TRUE(temp_dir2.CreateUniqueTempDir());
base::FilePath apps_path = temp_dir2.GetPath().Append("applications");
MockEnvironment env;
ASSERT_TRUE(base::CreateDirectory(desktop_path));
ASSERT_TRUE(WriteEmptyFile(desktop_path.Append(kTemplateFilename)));
env.Set("XDG_DATA_HOME", temp_dir2.GetPath().value());
ASSERT_TRUE(base::CreateDirectory(apps_path));
ASSERT_TRUE(WriteEmptyFile(apps_path.Append(kTemplateFilename)));
web_app::ShortcutLocations result = GetExistingShortcutLocations(
&env, kProfilePath, kExtensionId, desktop_path);
EXPECT_TRUE(result.on_desktop);
EXPECT_EQ(web_app::APP_MENU_LOCATION_SUBDIR_CHROMEAPPS,
result.applications_menu_location);
EXPECT_FALSE(result.in_quick_launch_bar);
}
}
TEST(ShellIntegrationTest, GetExtensionShortcutFilename) {
base::FilePath kProfilePath("a/b/c/Profile Name?");
const char kExtensionId[] = "extensionid";
EXPECT_EQ(base::FilePath("chrome-extensionid-Profile_Name_.desktop"),
GetAppShortcutFilename(kProfilePath, kExtensionId));
}
} // namespace web_app