| Index: chrome/browser/android/webapps/add_to_homescreen_data_fetcher_unittest.cc
|
| diff --git a/chrome/browser/android/webapps/add_to_homescreen_data_fetcher_unittest.cc b/chrome/browser/android/webapps/add_to_homescreen_data_fetcher_unittest.cc
|
| index 8725d7ff0162e89ecb6ed5bb2fccaef94acc377a..ebe6b852474512e45d248f019add558b189a8fd1 100644
|
| --- a/chrome/browser/android/webapps/add_to_homescreen_data_fetcher_unittest.cc
|
| +++ b/chrome/browser/android/webapps/add_to_homescreen_data_fetcher_unittest.cc
|
| @@ -17,6 +17,7 @@
|
| #include "base/strings/string_util.h"
|
| #include "base/strings/utf_string_conversions.h"
|
| #include "base/time/time.h"
|
| +#include "chrome/browser/installable/installable_manager.h"
|
| #include "chrome/common/web_application_info.h"
|
| #include "chrome/test/base/chrome_render_view_host_test_harness.h"
|
| #include "chrome/test/base/testing_profile.h"
|
| @@ -33,11 +34,9 @@
|
| #include "ui/gfx/image/image_unittest_util.h"
|
| #include "url/gurl.h"
|
|
|
| -// TODO(zpeng): Effectively test scenarios where both timeout callback and
|
| -// success callback are invoked. See crbug.com/697228.
|
| -
|
| namespace {
|
|
|
| +const char* kWebApplicationInfoTitle = "Meta Title";
|
| const char* kDefaultManifestUrl = "https://www.example.com/manifest.json";
|
| const char* kDefaultManifestName = "Default Name";
|
| const char* kDefaultManifestShortName = "Default Short Name";
|
| @@ -49,20 +48,16 @@ const blink::WebDisplayMode kDefaultManifestDisplayMode =
|
| class MockWebContents : public content::TestWebContents {
|
| public:
|
| explicit MockWebContents(content::BrowserContext* browser_context)
|
| - : content::TestWebContents(browser_context) {}
|
| + : content::TestWebContents(browser_context),
|
| + should_image_time_out_(false),
|
| + should_manifest_time_out_(false) {}
|
|
|
| - ~MockWebContents() override {
|
| - }
|
| + ~MockWebContents() override {}
|
|
|
| - // Sets the manifest to be returned by GetManifest().
|
| - // |fetch_delay_ms| is the time in milliseconds that the simulated fetch of
|
| - // the web manifest should take.
|
| void SetManifest(const GURL& manifest_url,
|
| - const content::Manifest& manifest,
|
| - int fetch_delay_ms) {
|
| + const content::Manifest& manifest) {
|
| manifest_url_ = manifest_url;
|
| manifest_ = manifest;
|
| - manifest_fetch_delay_ms_ = fetch_delay_ms;
|
| }
|
|
|
| int DownloadImage(const GURL& url,
|
| @@ -70,28 +65,40 @@ class MockWebContents : public content::TestWebContents {
|
| uint32_t max_bitmap_size,
|
| bool bypass_cache,
|
| const ImageDownloadCallback& callback) override {
|
| + if (should_image_time_out_)
|
| + return 0;
|
| +
|
| const int kIconSizePx = 144;
|
| SkBitmap icon = gfx::test::CreateBitmap(kIconSizePx, kIconSizePx);
|
| std::vector<SkBitmap> icons(1u, icon);
|
| std::vector<gfx::Size> pixel_sizes(1u, gfx::Size(kIconSizePx, kIconSizePx));
|
| - content::BrowserThread::PostTask(
|
| - content::BrowserThread::UI,
|
| - FROM_HERE,
|
| - base::Bind(callback, 0, net::HTTP_OK, url, icons, pixel_sizes));
|
| + content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::UI)
|
| + ->PostTask(FROM_HERE, base::Bind(callback, 0, net::HTTP_OK, url, icons,
|
| + pixel_sizes));
|
| return 0;
|
| }
|
|
|
| void GetManifest(const GetManifestCallback& callback) override {
|
| - content::BrowserThread::PostDelayedTask(
|
| - content::BrowserThread::UI, FROM_HERE,
|
| - base::Bind(callback, manifest_url_, manifest_),
|
| - base::TimeDelta::FromMilliseconds(manifest_fetch_delay_ms_));
|
| + if (should_manifest_time_out_)
|
| + return;
|
| +
|
| + content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::UI)
|
| + ->PostTask(FROM_HERE, base::Bind(callback, manifest_url_, manifest_));
|
| + }
|
| +
|
| + void SetShouldImageTimeOut(bool should_time_out) {
|
| + should_image_time_out_ = should_time_out;
|
| + }
|
| +
|
| + void SetShouldManifestTimeOut(bool should_time_out) {
|
| + should_manifest_time_out_ = should_time_out;
|
| }
|
|
|
| private:
|
| GURL manifest_url_;
|
| content::Manifest manifest_;
|
| - int manifest_fetch_delay_ms_;
|
| + bool should_image_time_out_;
|
| + bool should_manifest_time_out_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(MockWebContents);
|
| };
|
| @@ -118,12 +125,15 @@ class ObserverWaiter : public AddToHomescreenDataFetcher::Observer {
|
| }
|
|
|
| void OnDidDetermineWebApkCompatibility(bool is_webapk_compatible) override {
|
| + EXPECT_FALSE(title_available_);
|
| determined_webapk_compatibility_ = true;
|
| is_webapk_compatible_ = is_webapk_compatible;
|
| }
|
|
|
| void OnUserTitleAvailable(const base::string16& title) override {
|
| + EXPECT_FALSE(data_available_);
|
| title_available_ = true;
|
| + title_ = title;
|
| }
|
|
|
| SkBitmap FinalizeLauncherIconInBackground(const SkBitmap& icon,
|
| @@ -136,11 +146,13 @@ class ObserverWaiter : public AddToHomescreenDataFetcher::Observer {
|
| void OnDataAvailable(const ShortcutInfo& info,
|
| const SkBitmap& primary_icon,
|
| const SkBitmap& badge_icon) override {
|
| + EXPECT_TRUE(title_available_);
|
| data_available_ = true;
|
| if (!quit_closure_.is_null())
|
| quit_closure_.Run();
|
| }
|
|
|
| + base::string16 title() const { return title_; }
|
| bool is_webapk_compatible() const { return is_webapk_compatible_; }
|
| bool determined_webapk_compatibility() const {
|
| return determined_webapk_compatibility_;
|
| @@ -148,6 +160,7 @@ class ObserverWaiter : public AddToHomescreenDataFetcher::Observer {
|
| bool title_available() const { return title_available_; }
|
|
|
| private:
|
| + base::string16 title_;
|
| bool is_webapk_compatible_;
|
| bool determined_webapk_compatibility_;
|
| bool title_available_;
|
| @@ -162,6 +175,10 @@ base::NullableString16 NullableStringFromUTF8(const std::string& value) {
|
| return base::NullableString16(base::UTF8ToUTF16(value), false);
|
| }
|
|
|
| +content::Manifest BuildEmptyManifest() {
|
| + return content::Manifest();
|
| +}
|
| +
|
| // Builds WebAPK compatible content::Manifest.
|
| content::Manifest BuildDefaultManifest() {
|
| content::Manifest manifest;
|
| @@ -169,6 +186,14 @@ content::Manifest BuildDefaultManifest() {
|
| manifest.short_name = NullableStringFromUTF8(kDefaultManifestShortName);
|
| manifest.start_url = GURL(kDefaultStartUrl);
|
| manifest.display = kDefaultManifestDisplayMode;
|
| +
|
| + content::Manifest::Icon primary_icon;
|
| + primary_icon.type = base::ASCIIToUTF16("image/png");
|
| + primary_icon.sizes.push_back(gfx::Size(144, 144));
|
| + primary_icon.purpose.push_back(content::Manifest::Icon::IconPurpose::ANY);
|
| + primary_icon.src = GURL("https://www.google.com/image.png");
|
| + manifest.icons.push_back(primary_icon);
|
| +
|
| return manifest;
|
| }
|
|
|
| @@ -196,7 +221,9 @@ class AddToHomescreenDataFetcherTest : public ChromeRenderViewHostTestHarness {
|
| MockWebContents* mock_web_contents = new MockWebContents(browser_context());
|
| mock_web_contents->Init(content::WebContents::CreateParams(
|
| browser_context(), std::move(site_instance)));
|
| + InstallableManager::CreateForWebContents(mock_web_contents);
|
| SetContents(mock_web_contents);
|
| + NavigateAndCommit(GURL(kDefaultStartUrl));
|
| }
|
|
|
| void TearDown() override {
|
| @@ -207,17 +234,28 @@ class AddToHomescreenDataFetcherTest : public ChromeRenderViewHostTestHarness {
|
| scoped_refptr<AddToHomescreenDataFetcher> BuildFetcher(
|
| bool check_webapk_compatible,
|
| AddToHomescreenDataFetcher::Observer* observer) {
|
| - return new AddToHomescreenDataFetcher(web_contents(), 1, 1, 1, 1, 1,
|
| + return new AddToHomescreenDataFetcher(web_contents(), 1, 1, 1, 1, 1, 500,
|
| check_webapk_compatible, observer);
|
| }
|
|
|
| // Set the manifest to be returned as a result of WebContents::GetManifest().
|
| void SetManifest(const GURL& manifest_url,
|
| - const content::Manifest& manifest,
|
| - int fetch_delay_ms) {
|
| + const content::Manifest& manifest) {
|
| MockWebContents* mock_web_contents =
|
| static_cast<MockWebContents*>(web_contents());
|
| - mock_web_contents->SetManifest(manifest_url, manifest, fetch_delay_ms);
|
| + mock_web_contents->SetManifest(manifest_url, manifest);
|
| + }
|
| +
|
| + void SetShouldImageTimeOut(bool should_time_out) {
|
| + MockWebContents* mock_web_contents =
|
| + static_cast<MockWebContents*>(web_contents());
|
| + mock_web_contents->SetShouldImageTimeOut(should_time_out);
|
| + }
|
| +
|
| + void SetShouldManifestTimeOut(bool should_time_out) {
|
| + MockWebContents* mock_web_contents =
|
| + static_cast<MockWebContents*>(web_contents());
|
| + mock_web_contents->SetShouldManifestTimeOut(should_time_out);
|
| }
|
|
|
| // Registers service worker at |url|. Blocks till the service worker is
|
| @@ -248,25 +286,6 @@ class AddToHomescreenDataFetcherTest : public ChromeRenderViewHostTestHarness {
|
| DISALLOW_COPY_AND_ASSIGN(AddToHomescreenDataFetcherTest);
|
| };
|
|
|
| -// Checks that AddToHomescreenDataFetcher::Observer::OnUserTitleAvailable() is
|
| -// called when the web manifest fetch times out. The add-to-homescreen dialog
|
| -// makes the dialog's text field editable once OnUserTitleAvailable() is called.
|
| -TEST_F(AddToHomescreenDataFetcherTest,
|
| - DISABLED_ManifestFetchTimesOutNoServiceWorker) {
|
| - SetManifest(GURL(kDefaultManifestUrl), BuildDefaultManifest(), 10000);
|
| -
|
| - ObserverWaiter waiter;
|
| - scoped_refptr<AddToHomescreenDataFetcher> fetcher(
|
| - BuildFetcher(false, &waiter));
|
| - fetcher->OnDidGetWebApplicationInfo(WebApplicationInfo());
|
| - waiter.WaitForDataAvailable();
|
| -
|
| - EXPECT_FALSE(waiter.determined_webapk_compatibility());
|
| - EXPECT_TRUE(waiter.title_available());
|
| -
|
| - fetcher->set_weak_observer(nullptr);
|
| -}
|
| -
|
| // Class for tests which should be run with AddToHomescreenDataFetcher built
|
| // with both true and false values of |check_webapk_compatible|.
|
| class AddToHomescreenDataFetcherTestCommon
|
| @@ -290,25 +309,49 @@ class AddToHomescreenDataFetcherTestCommon
|
| DISALLOW_COPY_AND_ASSIGN(AddToHomescreenDataFetcherTestCommon);
|
| };
|
|
|
| +// Checks that AddToHomescreenDataFetcher::Observer::OnUserTitleAvailable() is
|
| +// called when the web manifest returned is empty. The add-to-homescreen dialog
|
| +// makes the dialog's text field editable once OnUserTitleAvailable() is called.
|
| +TEST_P(AddToHomescreenDataFetcherTestCommon, EmptyManifest) {
|
| + WebApplicationInfo web_application_info;
|
| + web_application_info.title = base::UTF8ToUTF16(kWebApplicationInfoTitle);
|
| +
|
| + SetManifest(GURL(kDefaultManifestUrl), BuildEmptyManifest());
|
| +
|
| + ObserverWaiter waiter;
|
| + scoped_refptr<AddToHomescreenDataFetcher> fetcher(BuildFetcher(&waiter));
|
| + fetcher->OnDidGetWebApplicationInfo(web_application_info);
|
| + waiter.WaitForDataAvailable();
|
| +
|
| + EXPECT_EQ(check_webapk_compatibility(),
|
| + waiter.determined_webapk_compatibility());
|
| + EXPECT_FALSE(waiter.is_webapk_compatible());
|
| + EXPECT_TRUE(waiter.title_available());
|
| + EXPECT_TRUE(base::EqualsASCII(waiter.title(), kWebApplicationInfoTitle));
|
| +
|
| + fetcher->set_weak_observer(nullptr);
|
| +}
|
| +
|
| // Test that when the manifest provides Manifest::short_name but not
|
| // Manifest::name that Manifest::short_name is used as the name instead of
|
| // WebApplicationInfo::title.
|
| TEST_P(AddToHomescreenDataFetcherTestCommon,
|
| ManifestShortNameClobbersWebApplicationName) {
|
| WebApplicationInfo web_application_info;
|
| - web_application_info.title = base::UTF8ToUTF16("Meta Title");
|
| + web_application_info.title = base::UTF8ToUTF16(kWebApplicationInfoTitle);
|
|
|
| content::Manifest manifest(BuildDefaultManifest());
|
| manifest.name = base::NullableString16();
|
|
|
| RegisterServiceWorker(GURL(kDefaultStartUrl));
|
| - SetManifest(GURL(kDefaultManifestUrl), manifest, 0);
|
| + SetManifest(GURL(kDefaultManifestUrl), manifest);
|
|
|
| ObserverWaiter waiter;
|
| scoped_refptr<AddToHomescreenDataFetcher> fetcher(BuildFetcher(&waiter));
|
| fetcher->OnDidGetWebApplicationInfo(web_application_info);
|
| waiter.WaitForDataAvailable();
|
|
|
| + EXPECT_TRUE(base::EqualsASCII(waiter.title(), kDefaultManifestShortName));
|
| EXPECT_TRUE(base::EqualsASCII(fetcher->shortcut_info().name,
|
| kDefaultManifestShortName));
|
|
|
| @@ -320,50 +363,107 @@ TEST_P(AddToHomescreenDataFetcherTestCommon,
|
| // - The page is not WebAPK compatible.
|
| // - WebApplicationInfo::title is used as the "name".
|
| TEST_P(AddToHomescreenDataFetcherTestCommon, ManifestNoNameNoShortName) {
|
| - const char* kWebApplicationInfoTitle = "Meta Title";
|
| - WebApplicationInfo web_application_info;
|
| - web_application_info.title = base::UTF8ToUTF16(kWebApplicationInfoTitle);
|
| + WebApplicationInfo web_application_info;
|
| + web_application_info.title = base::UTF8ToUTF16(kWebApplicationInfoTitle);
|
|
|
| - content::Manifest manifest(BuildDefaultManifest());
|
| - manifest.name = base::NullableString16();
|
| - manifest.short_name = base::NullableString16();
|
| + content::Manifest manifest(BuildDefaultManifest());
|
| + manifest.name = base::NullableString16();
|
| + manifest.short_name = base::NullableString16();
|
|
|
| - RegisterServiceWorker(GURL(kDefaultStartUrl));
|
| - SetManifest(GURL(kDefaultManifestUrl), manifest, 0);
|
| + RegisterServiceWorker(GURL(kDefaultStartUrl));
|
| + SetManifest(GURL(kDefaultManifestUrl), manifest);
|
|
|
| - ObserverWaiter waiter;
|
| - scoped_refptr<AddToHomescreenDataFetcher> fetcher(BuildFetcher(&waiter));
|
| - fetcher->OnDidGetWebApplicationInfo(web_application_info);
|
| - waiter.WaitForDataAvailable();
|
| + ObserverWaiter waiter;
|
| + scoped_refptr<AddToHomescreenDataFetcher> fetcher(BuildFetcher(&waiter));
|
| + fetcher->OnDidGetWebApplicationInfo(web_application_info);
|
| + waiter.WaitForDataAvailable();
|
|
|
| - EXPECT_FALSE(waiter.is_webapk_compatible());
|
| - EXPECT_TRUE(base::EqualsASCII(fetcher->shortcut_info().name,
|
| - kWebApplicationInfoTitle));
|
| + EXPECT_EQ(check_webapk_compatibility(),
|
| + waiter.determined_webapk_compatibility());
|
| + EXPECT_FALSE(waiter.is_webapk_compatible());
|
| + EXPECT_TRUE(base::EqualsASCII(waiter.title(), kWebApplicationInfoTitle));
|
| + EXPECT_TRUE(base::EqualsASCII(fetcher->shortcut_info().name,
|
| + kWebApplicationInfoTitle));
|
|
|
| - fetcher->set_weak_observer(nullptr);
|
| + fetcher->set_weak_observer(nullptr);
|
| }
|
|
|
| // Checks that the AddToHomescreenDataFetcher::Observer callbacks are called
|
| -// when a service worker is registered and the manifest fetch times out.
|
| -TEST_P(AddToHomescreenDataFetcherTestCommon, DISABLED_ManifestFetchTimesOut) {
|
| - RegisterServiceWorker(GURL(kDefaultStartUrl));
|
| - SetManifest(GURL(kDefaultManifestUrl), BuildDefaultManifest(), 10000);
|
| -
|
| - ObserverWaiter waiter;
|
| - scoped_refptr<AddToHomescreenDataFetcher> fetcher(BuildFetcher(&waiter));
|
| - fetcher->OnDidGetWebApplicationInfo(WebApplicationInfo());
|
| - waiter.WaitForDataAvailable();
|
| -
|
| - if (check_webapk_compatibility()) {
|
| - EXPECT_TRUE(waiter.determined_webapk_compatibility());
|
| - EXPECT_FALSE(waiter.is_webapk_compatible());
|
| - } else {
|
| - EXPECT_FALSE(waiter.determined_webapk_compatibility());
|
| - }
|
| - // This callback enables the text field in the add-to-homescreen dialog.
|
| - EXPECT_TRUE(waiter.title_available());
|
| -
|
| - fetcher->set_weak_observer(nullptr);
|
| +// when the manifest fetch times out.
|
| +TEST_P(AddToHomescreenDataFetcherTestCommon, ManifestFetchTimesOut) {
|
| + WebApplicationInfo web_application_info;
|
| + web_application_info.title = base::UTF8ToUTF16(kWebApplicationInfoTitle);
|
| +
|
| + RegisterServiceWorker(GURL(kDefaultStartUrl));
|
| + SetManifest(GURL(kDefaultManifestUrl), BuildDefaultManifest());
|
| + SetShouldManifestTimeOut(true);
|
| + SetShouldImageTimeOut(false);
|
| +
|
| + ObserverWaiter waiter;
|
| + scoped_refptr<AddToHomescreenDataFetcher> fetcher(BuildFetcher(&waiter));
|
| + fetcher->OnDidGetWebApplicationInfo(web_application_info);
|
| + waiter.WaitForDataAvailable();
|
| +
|
| + EXPECT_EQ(check_webapk_compatibility(),
|
| + waiter.determined_webapk_compatibility());
|
| + EXPECT_FALSE(waiter.is_webapk_compatible());
|
| + EXPECT_TRUE(base::EqualsASCII(waiter.title(), kWebApplicationInfoTitle));
|
| + EXPECT_TRUE(waiter.title_available());
|
| +
|
| + fetcher->set_weak_observer(nullptr);
|
| +}
|
| +
|
| +// Checks that the AddToHomescreenDataFetcher::Observer callbacks are called
|
| +// when the image fetch times out.
|
| +TEST_P(AddToHomescreenDataFetcherTestCommon, ImageFetchTimesOut) {
|
| + WebApplicationInfo web_application_info;
|
| + web_application_info.title = base::UTF8ToUTF16(kWebApplicationInfoTitle);
|
| +
|
| + RegisterServiceWorker(GURL(kDefaultStartUrl));
|
| + SetManifest(GURL(kDefaultManifestUrl), BuildDefaultManifest());
|
| + SetShouldManifestTimeOut(false);
|
| + SetShouldImageTimeOut(true);
|
| +
|
| + ObserverWaiter waiter;
|
| + scoped_refptr<AddToHomescreenDataFetcher> fetcher(BuildFetcher(&waiter));
|
| + fetcher->OnDidGetWebApplicationInfo(web_application_info);
|
| + waiter.WaitForDataAvailable();
|
| +
|
| + EXPECT_EQ(check_webapk_compatibility(),
|
| + waiter.determined_webapk_compatibility());
|
| + EXPECT_FALSE(waiter.is_webapk_compatible());
|
| + EXPECT_TRUE(waiter.title_available());
|
| + EXPECT_TRUE(base::EqualsASCII(waiter.title(), kWebApplicationInfoTitle));
|
| +
|
| + fetcher->set_weak_observer(nullptr);
|
| +}
|
| +
|
| +// Checks that the AddToHomescreenDataFetcher::Observer callbacks are called
|
| +// when the service worker check times out.
|
| +TEST_P(AddToHomescreenDataFetcherTestCommon, ServiceWorkerCheckTimesOut) {
|
| + WebApplicationInfo web_application_info;
|
| + web_application_info.title = base::UTF8ToUTF16(kWebApplicationInfoTitle);
|
| +
|
| + // Not registering a service worker means we'll wait and time out for the
|
| + // worker.
|
| + SetManifest(GURL(kDefaultManifestUrl), BuildDefaultManifest());
|
| + SetShouldManifestTimeOut(false);
|
| + SetShouldImageTimeOut(false);
|
| +
|
| + ObserverWaiter waiter;
|
| + scoped_refptr<AddToHomescreenDataFetcher> fetcher(BuildFetcher(&waiter));
|
| + fetcher->OnDidGetWebApplicationInfo(web_application_info);
|
| + waiter.WaitForDataAvailable();
|
| +
|
| + EXPECT_EQ(check_webapk_compatibility(),
|
| + waiter.determined_webapk_compatibility());
|
| + EXPECT_FALSE(waiter.is_webapk_compatible());
|
| + EXPECT_TRUE(waiter.title_available());
|
| + EXPECT_TRUE(base::EqualsASCII(waiter.title(), kDefaultManifestShortName));
|
| + EXPECT_TRUE(base::EqualsASCII(fetcher->shortcut_info().user_title,
|
| + kDefaultManifestShortName));
|
| +
|
| + fetcher->set_weak_observer(nullptr);
|
| }
|
|
|
| INSTANTIATE_TEST_CASE_P(CheckWebApkCompatibility,
|
|
|