// Copyright 2014 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/extensions/bookmark_app_helper.h"

#include "base/macros.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/banners/app_banner_settings_helper.h"
#include "chrome/browser/extensions/convert_web_app.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_service_test_base.h"
#include "chrome/browser/extensions/launch_util.h"
#include "chrome/browser/installable/installable_data.h"
#include "chrome/browser/web_applications/components/web_app_icon_downloader.h"
#include "chrome/browser/web_applications/components/web_app_install_utils.h"
#include "chrome/browser/web_applications/extensions/bookmark_app_util.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
#include "chrome/common/extensions/manifest_handlers/app_theme_color_info.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/test_utils.h"
#include "content/public/test/web_contents_tester.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/constants.h"
#include "extensions/common/extension_icon_set.h"
#include "extensions/common/manifest_handlers/icons_handler.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/manifest/manifest.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/skia_util.h"

namespace extensions {

namespace {

using ForInstallableSite = web_app::ForInstallableSite;

const char kManifestUrl[] = "http://www.chromium.org/manifest.json";
const char kAppUrl[] = "http://www.chromium.org/index.html";
const char kAppScope[] = "http://www.chromium.org/scope/";
const char kAppAlternativeScope[] = "http://www.chromium.org/new/";
const char kAppDefaultScope[] = "http://www.chromium.org/";
const char kAppTitle[] = "Test title";
const char kAlternativeAppTitle[] = "Different test title";
const char kAppDescription[] = "Test description";
const char kAppIconURL1[] = "http://foo.com/1.png";
const char kAppIconURL2[] = "http://foo.com/2.png";

const int kIconSizeTiny = extension_misc::EXTENSION_ICON_BITTY;
const int kIconSizeSmall = extension_misc::EXTENSION_ICON_SMALL;
const int kIconSizeMedium = extension_misc::EXTENSION_ICON_MEDIUM;
const int kIconSizeLarge = extension_misc::EXTENSION_ICON_LARGE;

class BookmarkAppHelperTest : public testing::Test {
 public:
  BookmarkAppHelperTest() {}
  ~BookmarkAppHelperTest() override {}

 private:
  DISALLOW_COPY_AND_ASSIGN(BookmarkAppHelperTest);
};

class BookmarkAppHelperExtensionServiceTest
    : public extensions::ExtensionServiceTestBase {
 public:
  BookmarkAppHelperExtensionServiceTest() {}
  ~BookmarkAppHelperExtensionServiceTest() override {}

  void SetUp() override {
    extensions::ExtensionServiceTestBase::SetUp();
    InitializeEmptyExtensionService();
    service_->Init();
    EXPECT_EQ(0u, registry()->enabled_extensions().size());
    web_contents_ =
        content::WebContentsTester::CreateTestWebContents(profile(), nullptr);
  }

  void TearDown() override {
    ExtensionServiceTestBase::TearDown();
    for (content::RenderProcessHost::iterator i(
             content::RenderProcessHost::AllHostsIterator());
         !i.IsAtEnd();
         i.Advance()) {
      content::RenderProcessHost* host = i.GetCurrentValue();
      if (Profile::FromBrowserContext(host->GetBrowserContext()) ==
          profile_.get())
        host->Cleanup();
    }
  }

  content::WebContents* web_contents() { return web_contents_.get(); }

 private:
  std::unique_ptr<content::WebContents> web_contents_;

  DISALLOW_COPY_AND_ASSIGN(BookmarkAppHelperExtensionServiceTest);
};

SkBitmap CreateSquareBitmapWithColor(int size, SkColor color) {
  SkBitmap bitmap;
  bitmap.allocN32Pixels(size, size);
  bitmap.eraseColor(color);
  return bitmap;
}

WebApplicationInfo::IconInfo CreateIconInfoWithBitmap(int size, SkColor color) {
  WebApplicationInfo::IconInfo icon_info;
  icon_info.width = size;
  icon_info.height = size;
  icon_info.data = CreateSquareBitmapWithColor(size, color);
  return icon_info;
}

class TestBookmarkAppHelper : public BookmarkAppHelper {
 public:
  TestBookmarkAppHelper(ExtensionService* service,
                        WebApplicationInfo web_app_info,
                        content::WebContents* contents)
      : BookmarkAppHelper(service->profile(),
                          web_app_info,
                          contents,
                          WebappInstallSource::MENU_BROWSER_TAB),
        bitmap_(CreateSquareBitmapWithColor(32, SK_ColorRED)) {}

  ~TestBookmarkAppHelper() override {}

  void CreationComplete(const extensions::Extension* extension,
                        const WebApplicationInfo& web_app_info) {
    extension_ = extension;
  }

  void CompleteInstallableCheck(const char* manifest_url,
                                const blink::Manifest& manifest,
                                ForInstallableSite for_installable_site) {
    bool installable = for_installable_site == ForInstallableSite::kYes;
    InstallableData data = {
        installable ? NO_ERROR_DETECTED : MANIFEST_DISPLAY_NOT_SUPPORTED,
        GURL(manifest_url),
        &manifest,
        GURL(kAppIconURL1),
        &bitmap_,
        false,
        GURL(),
        nullptr,
        installable,
        installable,
    };
    BookmarkAppHelper::OnDidPerformInstallableCheck(data);
  }

  void CompleteIconDownload(
      bool success,
      const std::map<GURL, std::vector<SkBitmap> >& bitmaps) {
    BookmarkAppHelper::OnIconsDownloaded(success, bitmaps);
  }

  void FinishCreationForNonInstallableSite() {
    CompleteInstallableCheck("", blink::Manifest(), ForInstallableSite::kNo);

    std::map<GURL, std::vector<SkBitmap>> icon_map;
    icon_map[GURL(kAppUrl)].push_back(
        CreateSquareBitmapWithColor(kIconSizeSmall, SK_ColorRED));
    CompleteIconDownload(true, icon_map);

    content::RunAllTasksUntilIdle();
  }

  const Extension* extension() { return extension_; }

  const web_app::WebAppIconDownloader* web_app_icon_downloader() {
    return web_app_icon_downloader_.get();
  }

 private:
  const Extension* extension_;
  SkBitmap bitmap_;

  DISALLOW_COPY_AND_ASSIGN(TestBookmarkAppHelper);
};

}  // namespace

TEST_F(BookmarkAppHelperExtensionServiceTest, CreateBookmarkApp) {
  WebApplicationInfo web_app_info;
  web_app_info.app_url = GURL(kAppUrl);
  web_app_info.title = base::UTF8ToUTF16(kAppTitle);
  web_app_info.description = base::UTF8ToUTF16(kAppDescription);

  TestBookmarkAppHelper helper(service_, web_app_info, web_contents());
  helper.Create(base::Bind(&TestBookmarkAppHelper::CreationComplete,
                           base::Unretained(&helper)));
  helper.FinishCreationForNonInstallableSite();

  EXPECT_TRUE(helper.extension());
  const Extension* extension =
      service_->GetInstalledExtension(helper.extension()->id());
  EXPECT_TRUE(extension);
  EXPECT_EQ(1u, registry()->enabled_extensions().size());
  EXPECT_TRUE(extension->from_bookmark());
  EXPECT_FALSE(extension->was_installed_by_default());
  EXPECT_FALSE(Manifest::IsPolicyLocation(helper.extension()->location()));

  EXPECT_EQ(kAppTitle, extension->name());
  EXPECT_EQ(kAppDescription, extension->description());
  EXPECT_EQ(GURL(kAppUrl), AppLaunchInfo::GetLaunchWebURL(extension));
  EXPECT_FALSE(
      IconsInfo::GetIconResource(
          extension, kIconSizeSmall, ExtensionIconSet::MATCH_EXACTLY).empty());
  EXPECT_FALSE(
      AppBannerSettingsHelper::GetSingleBannerEvent(
          web_contents(), web_app_info.app_url, web_app_info.app_url.spec(),
          AppBannerSettingsHelper::APP_BANNER_EVENT_DID_ADD_TO_HOMESCREEN)
          .is_null());
}

TEST_F(BookmarkAppHelperExtensionServiceTest, CreateBookmarkAppDefaultApp) {
  WebApplicationInfo web_app_info;
  web_app_info.app_url = GURL(kAppUrl);
  web_app_info.title = base::UTF8ToUTF16(kAppTitle);
  web_app_info.description = base::UTF8ToUTF16(kAppDescription);

  TestBookmarkAppHelper helper(service_, web_app_info, web_contents());
  helper.set_is_default_app();
  helper.Create(base::Bind(&TestBookmarkAppHelper::CreationComplete,
                           base::Unretained(&helper)));
  helper.FinishCreationForNonInstallableSite();

  ASSERT_TRUE(helper.extension());
  EXPECT_TRUE(helper.extension()->from_bookmark());
  EXPECT_TRUE(helper.extension()->was_installed_by_default());
  EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, helper.extension()->location());
  EXPECT_FALSE(Manifest::IsPolicyLocation(helper.extension()->location()));
}

TEST_F(BookmarkAppHelperExtensionServiceTest,
       CreateBookmarkAppPolicyInstalled) {
  WebApplicationInfo web_app_info;
  web_app_info.app_url = GURL(kAppUrl);
  web_app_info.title = base::UTF8ToUTF16(kAppTitle);
  web_app_info.description = base::UTF8ToUTF16(kAppDescription);

  TestBookmarkAppHelper helper(service_, web_app_info, web_contents());
  helper.set_is_policy_installed_app();
  helper.Create(base::Bind(&TestBookmarkAppHelper::CreationComplete,
                           base::Unretained(&helper)));
  helper.FinishCreationForNonInstallableSite();

  ASSERT_TRUE(helper.extension());
  EXPECT_TRUE(helper.extension()->from_bookmark());
  EXPECT_FALSE(helper.extension()->was_installed_by_default());
  EXPECT_TRUE(Manifest::IsPolicyLocation(helper.extension()->location()));
}

class BookmarkAppHelperExtensionServiceInstallableSiteTest
    : public BookmarkAppHelperExtensionServiceTest,
      public ::testing::WithParamInterface<ForInstallableSite> {
 public:
  BookmarkAppHelperExtensionServiceInstallableSiteTest() {}
  ~BookmarkAppHelperExtensionServiceInstallableSiteTest() override {}

 private:
  DISALLOW_COPY_AND_ASSIGN(
      BookmarkAppHelperExtensionServiceInstallableSiteTest);
};

TEST_P(BookmarkAppHelperExtensionServiceInstallableSiteTest,
       CreateBookmarkAppWithManifest) {
  WebApplicationInfo web_app_info;

  TestBookmarkAppHelper helper(service_, web_app_info, web_contents());
  helper.Create(base::Bind(&TestBookmarkAppHelper::CreationComplete,
                           base::Unretained(&helper)));

  blink::Manifest manifest;
  manifest.start_url = GURL(kAppUrl);
  manifest.name = base::NullableString16(base::UTF8ToUTF16(kAppTitle), false);
  manifest.scope = GURL(kAppScope);
  manifest.theme_color = SK_ColorBLUE;
  helper.CompleteInstallableCheck(kManifestUrl, manifest, GetParam());

  std::map<GURL, std::vector<SkBitmap> > icon_map;
  helper.CompleteIconDownload(true, icon_map);

  content::RunAllTasksUntilIdle();
  EXPECT_TRUE(helper.extension());
  const Extension* extension =
      service_->GetInstalledExtension(helper.extension()->id());
  EXPECT_TRUE(extension);
  EXPECT_EQ(1u, registry()->enabled_extensions().size());
  EXPECT_TRUE(extension->from_bookmark());
  EXPECT_EQ(kAppTitle, extension->name());
  EXPECT_EQ(GURL(kAppUrl), AppLaunchInfo::GetLaunchWebURL(extension));
  EXPECT_EQ(SK_ColorBLUE, AppThemeColorInfo::GetThemeColor(extension).value());
  EXPECT_FALSE(
      AppBannerSettingsHelper::GetSingleBannerEvent(
          web_contents(), manifest.start_url, manifest.start_url.spec(),
          AppBannerSettingsHelper::APP_BANNER_EVENT_DID_ADD_TO_HOMESCREEN)
          .is_null());

  if (GetParam() == ForInstallableSite::kYes) {
    EXPECT_EQ(GURL(kAppScope), GetScopeURLFromBookmarkApp(extension));
  } else {
    EXPECT_EQ(GURL(), GetScopeURLFromBookmarkApp(extension));
  }
}

TEST_P(BookmarkAppHelperExtensionServiceInstallableSiteTest,
       CreateBookmarkAppWithManifestIcons) {
  WebApplicationInfo web_app_info;
  TestBookmarkAppHelper helper(service_, web_app_info, web_contents());
  helper.Create(base::Bind(&TestBookmarkAppHelper::CreationComplete,
                           base::Unretained(&helper)));

  blink::Manifest manifest;
  manifest.start_url = GURL(kAppUrl);
  manifest.name = base::NullableString16(base::UTF8ToUTF16(kAppTitle), false);
  manifest.scope = GURL(kAppScope);
  blink::Manifest::ImageResource icon;
  icon.src = GURL(kAppIconURL1);
  icon.purpose = {blink::Manifest::ImageResource::Purpose::ANY};
  manifest.icons.push_back(icon);
  icon.src = GURL(kAppIconURL2);
  manifest.icons.push_back(icon);
  helper.CompleteInstallableCheck(kManifestUrl, manifest, GetParam());

  // Favicon URLs are ignored because the site has a manifest with icons.
  EXPECT_FALSE(helper.web_app_icon_downloader()->need_favicon_urls_);

  // Only 1 icon should be downloading since the other was provided by the
  // InstallableManager.
  EXPECT_EQ(1u, helper.web_app_icon_downloader()->in_progress_requests_.size());

  std::map<GURL, std::vector<SkBitmap>> icon_map;
  icon_map[GURL(kAppIconURL2)].push_back(
      CreateSquareBitmapWithColor(kIconSizeSmall, SK_ColorRED));
  helper.CompleteIconDownload(true, icon_map);

  content::RunAllTasksUntilIdle();
  EXPECT_TRUE(helper.extension());
  const Extension* extension =
      service_->GetInstalledExtension(helper.extension()->id());
  EXPECT_TRUE(extension);
  EXPECT_EQ(1u, registry()->enabled_extensions().size());
  EXPECT_TRUE(extension->from_bookmark());
  EXPECT_EQ(kAppTitle, extension->name());
  EXPECT_EQ(GURL(kAppUrl), AppLaunchInfo::GetLaunchWebURL(extension));

  if (GetParam() == ForInstallableSite::kYes) {
    EXPECT_EQ(GURL(kAppScope), GetScopeURLFromBookmarkApp(extension));
  } else {
    EXPECT_EQ(GURL(), GetScopeURLFromBookmarkApp(extension));
  }
}

TEST_P(BookmarkAppHelperExtensionServiceInstallableSiteTest,
       CreateBookmarkAppWithManifestNoScope) {
  WebApplicationInfo web_app_info;

  TestBookmarkAppHelper helper(service_, web_app_info, web_contents());
  helper.Create(base::Bind(&TestBookmarkAppHelper::CreationComplete,
                           base::Unretained(&helper)));

  blink::Manifest manifest;
  manifest.start_url = GURL(kAppUrl);
  manifest.name = base::NullableString16(base::UTF8ToUTF16(kAppTitle), false);
  helper.CompleteInstallableCheck(kManifestUrl, manifest, GetParam());

  std::map<GURL, std::vector<SkBitmap>> icon_map;
  helper.CompleteIconDownload(true, icon_map);
  content::RunAllTasksUntilIdle();
  EXPECT_TRUE(helper.extension());

  const Extension* extension =
      service_->GetInstalledExtension(helper.extension()->id());
  if (GetParam() == ForInstallableSite::kYes) {
    EXPECT_EQ(GURL(kAppDefaultScope), GetScopeURLFromBookmarkApp(extension));
  } else {
    EXPECT_EQ(GURL(), GetScopeURLFromBookmarkApp(extension));
  }
}

INSTANTIATE_TEST_CASE_P(/* no prefix */,
                        BookmarkAppHelperExtensionServiceInstallableSiteTest,
                        ::testing::Values(ForInstallableSite::kNo,
                                          ForInstallableSite::kYes));

TEST_F(BookmarkAppHelperExtensionServiceTest,
       CreateBookmarkAppDefaultLauncherContainers) {
  auto scoped_feature_list = std::make_unique<base::test::ScopedFeatureList>();
  scoped_feature_list->InitAndEnableFeature(features::kDesktopPWAWindowing);

  std::map<GURL, std::vector<SkBitmap>> icon_map;

  blink::Manifest manifest;
  manifest.start_url = GURL(kAppUrl);
  manifest.name = base::NullableString16(base::UTF8ToUTF16(kAppTitle), false);
  manifest.scope = GURL(kAppScope);
  {
    WebApplicationInfo web_app_info;
    web_app_info.open_as_window = true;
    TestBookmarkAppHelper helper(service_, web_app_info, web_contents());
    helper.Create(base::Bind(&TestBookmarkAppHelper::CreationComplete,
                             base::Unretained(&helper)));

    helper.CompleteInstallableCheck(kManifestUrl, manifest,
                                    ForInstallableSite::kYes);
    helper.CompleteIconDownload(true, icon_map);

    content::RunAllTasksUntilIdle();
    EXPECT_TRUE(helper.extension());
    const Extension* extension =
        service_->GetInstalledExtension(helper.extension()->id());
    EXPECT_TRUE(extension);
    EXPECT_EQ(LAUNCH_CONTAINER_WINDOW,
              GetLaunchContainer(ExtensionPrefs::Get(profile()), extension));

    // Mark the app as not locally installed and check that it now opens in a
    // tab.
    SetBookmarkAppIsLocallyInstalled(profile(), extension, false);
    EXPECT_EQ(LAUNCH_CONTAINER_TAB,
              GetLaunchContainer(ExtensionPrefs::Get(profile()), extension));

    // Mark the app as locally installed and check that it now opens in a
    // window.
    SetBookmarkAppIsLocallyInstalled(profile(), extension, true);
    EXPECT_EQ(LAUNCH_CONTAINER_WINDOW,
              GetLaunchContainer(ExtensionPrefs::Get(profile()), extension));
  }
  {
    WebApplicationInfo web_app_info;
    web_app_info.open_as_window = false;
    TestBookmarkAppHelper helper(service_, web_app_info, web_contents());
    helper.Create(base::Bind(&TestBookmarkAppHelper::CreationComplete,
                             base::Unretained(&helper)));

    helper.CompleteInstallableCheck(kManifestUrl, manifest,
                                    ForInstallableSite::kNo);
    helper.CompleteIconDownload(true, icon_map);

    content::RunAllTasksUntilIdle();
    EXPECT_TRUE(helper.extension());
    const Extension* extension =
        service_->GetInstalledExtension(helper.extension()->id());
    EXPECT_TRUE(extension);
    EXPECT_EQ(LAUNCH_CONTAINER_TAB,
              GetLaunchContainer(ExtensionPrefs::Get(profile()), extension));
  }
}

TEST_F(BookmarkAppHelperExtensionServiceTest,
       CreateBookmarkAppForcedLauncherContainers) {
  auto scoped_feature_list = std::make_unique<base::test::ScopedFeatureList>();
  scoped_feature_list->InitAndEnableFeature(features::kDesktopPWAWindowing);

  WebApplicationInfo web_app_info;
  std::map<GURL, std::vector<SkBitmap>> icon_map;

  blink::Manifest manifest;
  manifest.start_url = GURL(kAppUrl);
  manifest.name = base::NullableString16(base::UTF8ToUTF16(kAppTitle), false);
  manifest.scope = GURL(kAppScope);
  {
    TestBookmarkAppHelper helper(service_, web_app_info, web_contents());
    helper.set_forced_launch_type(LAUNCH_TYPE_REGULAR);
    helper.Create(base::Bind(&TestBookmarkAppHelper::CreationComplete,
                             base::Unretained(&helper)));

    helper.CompleteInstallableCheck(kManifestUrl, manifest,
                                    ForInstallableSite::kYes);
    helper.CompleteIconDownload(true, icon_map);

    content::RunAllTasksUntilIdle();
    ASSERT_TRUE(helper.extension());
    EXPECT_EQ(
        LAUNCH_CONTAINER_TAB,
        GetLaunchContainer(ExtensionPrefs::Get(profile()), helper.extension()));
  }
  {
    TestBookmarkAppHelper helper(service_, web_app_info, web_contents());
    helper.set_forced_launch_type(LAUNCH_TYPE_WINDOW);
    helper.Create(base::Bind(&TestBookmarkAppHelper::CreationComplete,
                             base::Unretained(&helper)));

    helper.CompleteInstallableCheck(kManifestUrl, manifest,
                                    ForInstallableSite::kNo);
    helper.CompleteIconDownload(true, icon_map);

    content::RunAllTasksUntilIdle();
    ASSERT_TRUE(helper.extension());
    EXPECT_EQ(
        LAUNCH_CONTAINER_WINDOW,
        GetLaunchContainer(ExtensionPrefs::Get(profile()), helper.extension()));
  }
}

TEST_F(BookmarkAppHelperExtensionServiceTest,
       CreateBookmarkAppWithoutManifest) {
  WebApplicationInfo web_app_info;
  web_app_info.title = base::UTF8ToUTF16(kAppTitle);
  web_app_info.description = base::UTF8ToUTF16(kAppDescription);
  web_app_info.app_url = GURL(kAppUrl);

  TestBookmarkAppHelper helper(service_, web_app_info, web_contents());
  helper.Create(base::Bind(&TestBookmarkAppHelper::CreationComplete,
                           base::Unretained(&helper)));

  helper.CompleteInstallableCheck(kManifestUrl, blink::Manifest(),
                                  ForInstallableSite::kNo);
  std::map<GURL, std::vector<SkBitmap>> icon_map;
  helper.CompleteIconDownload(true, icon_map);
  content::RunAllTasksUntilIdle();
  EXPECT_TRUE(helper.extension());

  const Extension* extension =
      service_->GetInstalledExtension(helper.extension()->id());
  EXPECT_TRUE(extension);
  EXPECT_EQ(kAppTitle, extension->name());
  EXPECT_EQ(kAppDescription, extension->description());
  EXPECT_EQ(GURL(kAppUrl), AppLaunchInfo::GetLaunchWebURL(extension));
  EXPECT_EQ(GURL(), GetScopeURLFromBookmarkApp(extension));
  EXPECT_FALSE(AppThemeColorInfo::GetThemeColor(extension));
}

TEST_F(BookmarkAppHelperExtensionServiceTest, CreateBookmarkAppNoContents) {
  WebApplicationInfo web_app_info;
  web_app_info.app_url = GURL(kAppUrl);
  web_app_info.title = base::UTF8ToUTF16(kAppTitle);
  web_app_info.description = base::UTF8ToUTF16(kAppDescription);
  web_app_info.scope = GURL(kAppScope);
  web_app_info.icons.push_back(
      CreateIconInfoWithBitmap(kIconSizeTiny, SK_ColorRED));

  TestBookmarkAppHelper helper(service_, web_app_info, NULL);
  helper.Create(base::Bind(&TestBookmarkAppHelper::CreationComplete,
                           base::Unretained(&helper)));

  content::RunAllTasksUntilIdle();
  EXPECT_TRUE(helper.extension());
  const Extension* extension =
      service_->GetInstalledExtension(helper.extension()->id());
  EXPECT_TRUE(extension);
  EXPECT_EQ(1u, registry()->enabled_extensions().size());
  EXPECT_TRUE(extension->from_bookmark());
  EXPECT_EQ(kAppTitle, extension->name());
  EXPECT_EQ(kAppDescription, extension->description());
  EXPECT_EQ(GURL(kAppUrl), AppLaunchInfo::GetLaunchWebURL(extension));
  EXPECT_EQ(GURL(kAppScope), GetScopeURLFromBookmarkApp(extension));
  EXPECT_FALSE(
      IconsInfo::GetIconResource(extension, kIconSizeTiny,
                                 ExtensionIconSet::MATCH_EXACTLY).empty());
  EXPECT_FALSE(
      IconsInfo::GetIconResource(
          extension, kIconSizeSmall, ExtensionIconSet::MATCH_EXACTLY).empty());
  EXPECT_FALSE(
      IconsInfo::GetIconResource(extension,
                                 kIconSizeSmall * 2,
                                 ExtensionIconSet::MATCH_EXACTLY).empty());
  EXPECT_FALSE(
      IconsInfo::GetIconResource(
          extension, kIconSizeMedium, ExtensionIconSet::MATCH_EXACTLY).empty());
  EXPECT_FALSE(
      IconsInfo::GetIconResource(extension,
                                 kIconSizeMedium * 2,
                                 ExtensionIconSet::MATCH_EXACTLY).empty());
}

TEST_F(BookmarkAppHelperExtensionServiceTest, CreateAndUpdateBookmarkApp) {
  EXPECT_EQ(0u, registry()->enabled_extensions().size());
  WebApplicationInfo web_app_info;
  web_app_info.app_url = GURL(kAppUrl);
  web_app_info.title = base::UTF8ToUTF16(kAppTitle);
  web_app_info.description = base::UTF8ToUTF16(kAppDescription);
  web_app_info.scope = GURL(kAppScope);
  web_app_info.icons.push_back(
      CreateIconInfoWithBitmap(kIconSizeSmall, SK_ColorRED));

  extensions::CreateOrUpdateBookmarkApp(service_, &web_app_info,
                                        false /* is_locally_installed */);
  content::RunAllTasksUntilIdle();

  {
    EXPECT_EQ(1u, registry()->enabled_extensions().size());
    const Extension* extension =
        registry()->enabled_extensions().begin()->get();
    EXPECT_TRUE(extension->from_bookmark());
    EXPECT_EQ(kAppTitle, extension->name());
    EXPECT_EQ(kAppDescription, extension->description());
    EXPECT_EQ(GURL(kAppUrl), AppLaunchInfo::GetLaunchWebURL(extension));
    EXPECT_EQ(GURL(kAppScope), GetScopeURLFromBookmarkApp(extension));
    EXPECT_FALSE(extensions::IconsInfo::GetIconResource(
                     extension, kIconSizeSmall, ExtensionIconSet::MATCH_EXACTLY)
                     .empty());
    EXPECT_FALSE(BookmarkAppIsLocallyInstalled(profile(), extension));
  }

  web_app_info.title = base::UTF8ToUTF16(kAlternativeAppTitle);
  web_app_info.icons[0] = CreateIconInfoWithBitmap(kIconSizeLarge, SK_ColorRED);
  web_app_info.scope = GURL(kAppAlternativeScope);

  extensions::CreateOrUpdateBookmarkApp(service_, &web_app_info,
                                        true /* is_locally_installed */);
  content::RunAllTasksUntilIdle();

  {
    EXPECT_EQ(1u, registry()->enabled_extensions().size());
    const Extension* extension =
        registry()->enabled_extensions().begin()->get();
    EXPECT_TRUE(extension->from_bookmark());
    EXPECT_EQ(kAlternativeAppTitle, extension->name());
    EXPECT_EQ(kAppDescription, extension->description());
    EXPECT_EQ(GURL(kAppUrl), AppLaunchInfo::GetLaunchWebURL(extension));
    EXPECT_EQ(GURL(kAppAlternativeScope),
              GetScopeURLFromBookmarkApp(extension));
    EXPECT_FALSE(extensions::IconsInfo::GetIconResource(
                     extension, kIconSizeSmall, ExtensionIconSet::MATCH_EXACTLY)
                     .empty());
    EXPECT_FALSE(extensions::IconsInfo::GetIconResource(
                     extension, kIconSizeLarge, ExtensionIconSet::MATCH_EXACTLY)
                     .empty());
    EXPECT_TRUE(BookmarkAppIsLocallyInstalled(profile(), extension));
  }
}

TEST_F(BookmarkAppHelperTest, IsValidBookmarkAppUrl) {
  EXPECT_TRUE(IsValidBookmarkAppUrl(GURL("https://chromium.org")));
  EXPECT_TRUE(IsValidBookmarkAppUrl(GURL("https://www.chromium.org")));
  EXPECT_TRUE(IsValidBookmarkAppUrl(
      GURL("https://www.chromium.org/path/to/page.html")));
  EXPECT_TRUE(IsValidBookmarkAppUrl(GURL("http://chromium.org")));
  EXPECT_TRUE(IsValidBookmarkAppUrl(GURL("http://www.chromium.org")));
  EXPECT_TRUE(
      IsValidBookmarkAppUrl(GURL("http://www.chromium.org/path/to/page.html")));
  EXPECT_TRUE(IsValidBookmarkAppUrl(
      GURL("chrome-extension://oafaagfgbdpldilgjjfjocjglfbolmac")));

  EXPECT_FALSE(IsValidBookmarkAppUrl(GURL("ftp://www.chromium.org")));
  EXPECT_FALSE(IsValidBookmarkAppUrl(GURL("chrome://flags")));
  EXPECT_FALSE(IsValidBookmarkAppUrl(GURL("about:blank")));
  EXPECT_FALSE(IsValidBookmarkAppUrl(
      GURL("file://mhjfbmdgcfjbbpaeojofohoefgiehjai")));
  EXPECT_FALSE(IsValidBookmarkAppUrl(GURL("chrome://extensions")));
}

}  // namespace extensions
