chromium/components/favicon/core/favicon_handler_unittest.cc

// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/favicon/core/favicon_handler.h"

#include <stddef.h>

#include <map>
#include <memory>
#include <utility>
#include <vector>

#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/task/single_thread_task_runner.h"
#include "base/test/task_environment.h"
#include "base/test/test_simple_task_runner.h"
#include "components/favicon/core/favicon_driver.h"
#include "components/favicon/core/test/mock_favicon_service.h"
#include "skia/ext/image_operations.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/base/resource/resource_scale_factor.h"
#include "ui/gfx/codec/png_codec.h"
#include "ui/gfx/favicon_size.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_unittest_util.h"

namespace favicon {
namespace {

FaviconRawBitmapResult;
_;
AnyNumber;
Assign;
Contains;
ElementsAre;
InSequence;
Invoke;
IsEmpty;
Not;
Return;
SizeIs;

IntVector;
URLVector;
BitmapVector;
SizeVector;

constexpr favicon_base::IconType kFavicon =;
constexpr favicon_base::IconType kTouchIcon =;
constexpr favicon_base::IconType kTouchPrecomposedIcon =;
constexpr favicon_base::IconType kWebManifestIcon =;

MATCHER_P2(ImageSizeIs, width, height, "") {}

// `arg` is a gfx::Image.
MATCHER_P(ImageColorIs, expected_color, "") {}

// Fill the given data buffer with valid png data.
std::vector<unsigned char> FillBitmapWithEdgeSize(int size, SkColor color) {}

std::vector<FaviconRawBitmapResult> CreateRawBitmapResult(
    const GURL& icon_url,
    favicon_base::IconType icon_type = kFavicon,
    bool expired = false,
    int edge_size = gfx::kFaviconSize,
    SkColor color = SK_ColorRED) {}

// Fake that implements the calls to FaviconHandler::Delegate's DownloadImage(),
// delegated to this class through MockDelegate.
class FakeImageDownloader {};

// Fake that implements the calls to FaviconHandler::Delegate's
// DownloadManifest(), delegated to this class through MockDelegate.
class FakeManifestDownloader {};

class MockDelegate : public FaviconHandler::Delegate {};

// FakeFaviconService mimics a FaviconService backend that allows setting up
// test data stored via Store(). If Store() has not been called for a
// particular URL, the callback is called with empty database results.
class FakeFaviconService {};

// MockFaviconService subclass that delegates DB reads to FakeFaviconService.
class MockFaviconServiceWithFake : public MockFaviconService {};

class FaviconHandlerTest : public testing::Test {};

TEST_F(FaviconHandlerTest, GetFaviconFromHistory) {}

TEST_F(FaviconHandlerTest, GetFaviconFromHistoryInIncognito) {}

// Test that UpdateFaviconsAndFetch() is called with the appropriate parameters
// when there is no data in the database for the page URL.
TEST_F(FaviconHandlerTest, UpdateFaviconMappingsAndFetch) {}

// Verifies same document navigation to the last page does not trigger fetch.
TEST_F(FaviconHandlerTest, SameDocumentNavigationToLastUrlDoesNotFetchAgain) {}

// Test that we don't try to delete favicon mappings when a page URL is not in
// history even if the page lists no favicons.
TEST_F(FaviconHandlerTest, DoNotDeleteFaviconMappingsIfNotInHistory) {}

// Test that favicon mappings are deleted when:
// - There is data in the favicon database for the page URL.
// - The page lists no candidates.
// AND
// - FaviconService::OnFaviconDataForManifestFromFaviconService() runs before
//   FaviconHandler::OnUpdateCandidates() is called.
TEST_F(FaviconHandlerTest, DeleteFaviconMappingsIfCandidatesSlower) {}

// Test that favicon mappings are deleted when:
// - There is data in the favicon database for the page URL.
// - The page lists no candidates.
// AND
// - FaviconHandler::OnUpdateCandidates() is called before
//   FaviconService::OnFaviconDataForManifestFromFaviconService() runs.
TEST_F(FaviconHandlerTest, DeleteFaviconMappingsIfCandidatesFaster) {}

// Test that favicon mappings are deleted when a page in history lists a
// candidate that is expired and is known to return a 404.
TEST_F(FaviconHandlerTest, DeleteFaviconMappingsDespitePrior404) {}

// Test that favicon mappings are deleted for a page in history, when all icons
// listed in the page return a 404.
TEST_F(FaviconHandlerTest, DeleteFaviconMappingsDueTo404) {}

// Test that we don't try to delete favicon mappings when a page URL is not in
// history even if all icons listed in the page return a 404.
TEST_F(FaviconHandlerTest, DoNotDeleteFaviconMappingsIfNotInHistoryDespite404) {}

// Test that favicon mappings are not deleted for a page in history when all
// icons listed in the page return a 503.
TEST_F(FaviconHandlerTest, DoNotDeleteFaviconMappingsDueTo503) {}

// Test that UpdateFaviconsAndFetch() is called with the appropriate parameters
// when there is no data in the database for the page URL, for the case where
// multiple page URLs exist due to a quick in-same-document navigation (e.g.
// fragment navigation).
TEST_F(FaviconHandlerTest, UpdateFaviconMappingsAndFetchWithMultipleURLs) {}

// Test that CloneFaviconMappingsForPages() is called for the simplest case,
// i.e. a single page without redirect URLs to update mappings for (no known
// in-same-document navigation). This is important in case there are server-side
// redirects to update (that are only known within HistoryService).
TEST_F(FaviconHandlerTest, CloneFaviconMappingsForPageInHistory) {}

// Test that CloneFaviconMappingsForPages() is called when there is data in the
// database for the page URL, for the case where multiple page URLs exist due to
// a quick in-same-document navigation (e.g. fragment navigation).
// FaviconService should be told to propagate the mappings from the last page
// URL (lookup hit) to the rest of the URLs.
TEST_F(FaviconHandlerTest, CloneFaviconMappingsWithMultipleURLs) {}

// Test that CloneFaviconMappingsForPages() is not called for incognito tabs.
TEST_F(FaviconHandlerTest, NotCloneFaviconMappingsInIncognito) {}

// Test that the FaviconHandler process finishes when:
// - There is data in the database for neither the page URL nor the icon URL.
// AND
// - FaviconService::GetFaviconForPageURL() callback returns before
//   FaviconHandler::OnUpdateCandidates() is called.
TEST_F(FaviconHandlerTest, DownloadUnknownFaviconIfCandidatesSlower) {}

// Test that the FaviconHandler process finishes when:
// - There is data in the database for neither the page URL nor the icon URL.
// AND
// - FaviconService::GetFaviconForPageURL() callback returns after
//   FaviconHandler::OnUpdateCandidates() is called.
TEST_F(FaviconHandlerTest, DownloadUnknownFaviconIfCandidatesFaster) {}

// Test that the FaviconHandler process does not save anything to the database
// for incognito tabs.
TEST_F(FaviconHandlerTest, DownloadUnknownFaviconInIncognito) {}

// Test that favicon mappings are not deleted in incognito even if the page
// lists no candidates.
TEST_F(FaviconHandlerTest, DoNotDeleteFaviconMappingsInIncognito) {}

// Test that the icon is redownloaded if the icon cached for the page URL
// expired.
TEST_F(FaviconHandlerTest, RedownloadExpiredPageUrlFavicon) {}

// Test that FaviconHandler requests the new data when:
// - There is valid data in the database for the page URL.
// AND
// - The icon URL used by the page has changed.
// AND
// - There is no data in database for the new icon URL.
TEST_F(FaviconHandlerTest, UpdateAndDownloadFavicon) {}

// If there is data for the page URL in history which is invalid, test that:
// - The invalid data is not sent to the UI.
// - The icon is redownloaded.
TEST_F(FaviconHandlerTest, FaviconInHistoryInvalid) {}

// Test that no downloads are done if a user visits a page which changed its
// favicon URL to a favicon URL which is already cached in the database.
TEST_F(FaviconHandlerTest, UpdateFavicon) {}

TEST_F(FaviconHandlerTest, Download2ndFaviconURLCandidate) {}

// Test that download data for icon URLs other than the current favicon
// candidate URLs is ignored. This test tests the scenario where a download is
// in flight when FaviconHandler::OnUpdateCandidates() is called.
// TODO(mastiz): Make this test deal with FaviconURLs of type
// favicon_base::IconType::kFavicon and add new ones like
// OnlyDownloadMatchingIconType and CallSetFaviconsWithCorrectIconType.
TEST_F(FaviconHandlerTest, UpdateDuringDownloading) {}

// Test that sending an icon URL update different to the previous icon URL
// update during a database lookup ignores the first icon URL and processes the
// second.
TEST_F(FaviconHandlerTest, UpdateDuringDatabaseLookup) {}

// Test that sending an icon URL update identical to the previous icon URL
// update during image download is a no-op.
TEST_F(FaviconHandlerTest, UpdateSameIconURLsWhileDownloadingShouldBeNoop) {}

// Test that sending an icon URL update identical to the previous icon URL
// update during a database lookup is a no-op.
TEST_F(FaviconHandlerTest, UpdateSameIconURLsWhileDatabaseLookupShouldBeNoop) {}

// Test that calling OnUpdateFaviconUrl() with the same icon URLs as before is a
// no-op. This is important because OnUpdateFaviconUrl() is called when the page
// finishes loading. This can occur several times for pages with iframes.
TEST_F(FaviconHandlerTest, UpdateSameIconURLsAfterFinishedShouldBeNoop) {}

// Fixes crbug.com/544560
// Tests that Delegate::OnFaviconUpdated() is called if:
// - The best icon on the initial page is not the last icon.
// - All of the initial page's icons are downloaded.
// AND
// - JavaScript modifies the page's <link rel="icon"> tags to contain only the
//   last icon.
TEST_F(FaviconHandlerTest,
       OnFaviconAvailableNotificationSentAfterIconURLChange) {}

// Test that favicon mappings are removed if the page initially lists a favicon
// and later uses Javascript to remove it.
TEST_F(FaviconHandlerTest, RemoveFaviconViaJavascript) {}

// Tests that there is not crash and SetFavicons() is called with the
// appropriate icon URL in the following scenario:
// - The database initially has a cached but expired icon for the page.
// - Initial favicon candidates are received fast, before the history lookup
//   completes.
// - Before the history lookup completes, favicon candidates are updated via
//   javascript to include a different set of icons.
TEST_F(FaviconHandlerTest,
       UpdateIconsViaJavascriptAfterFastCandidatesAndExpiredIcon) {}

// Test the favicon which is selected when the web page provides several
// favicons and none of the favicons are cached in history.
// The goal of this test is to be more of an integration test than
// SelectFaviconFramesTest.*.
class FaviconHandlerMultipleFaviconsTest : public FaviconHandlerTest {};

// Tests that running FaviconHandler
// - On an OS which supports the 1x and 2x scale factor
// - On a page with <link rel="icon"> tags with no "sizes" information.
// Selects the largest exact match. Note that a 32x32 PNG image is not a "true
// exact match" on an OS which supports an 1x and 2x. A "true exact match" is
// a .ico file with 16x16 and 32x32 bitmaps.
TEST_F(FaviconHandlerMultipleFaviconsTest, ChooseLargestExactMatch) {}

// Test that if there are several single resolution favicons to choose
// from, the exact match is preferred even if it results in upsampling.
TEST_F(FaviconHandlerMultipleFaviconsTest, ChooseExactMatchDespiteUpsampling) {}

// Test that favicons which need to be upsampled a little or downsampled
// a little are preferred over huge favicons.
TEST_F(FaviconHandlerMultipleFaviconsTest,
       ChooseMinorDownsamplingOverHugeIcon) {}

TEST_F(FaviconHandlerMultipleFaviconsTest, ChooseMinorUpsamplingOverHugeIcon) {}

// Test a page with multiple favicon candidates with explicit sizes information.
// Only the best one should be downloaded.
TEST_F(FaviconHandlerMultipleFaviconsTest,
       StopsDownloadingWhenRemainingCandidatesWorse) {}

// Mostly for behavioral documentation purposes: test that downloads stops when
// remaining candidates are worse or equal, for the following advanced scenario:
// - The page provides multiple favicons: various with explicit sizes
//   information and one without.
// - Among the ones with explicit sizes information, downloading the best
//   returns a 404.
// - The remaining ones (with explicit sizes information) are worse than the one
//   without sizes information, and shouldn't be downloaded.
TEST_F(FaviconHandlerTest,
       StopsDownloadingWhenRemainingCandidatesWorseDespite404) {}

TEST_F(FaviconHandlerMultipleFaviconsTest,
       DownloadsAllIconsWithoutSizesAttributeIfNotWantsLargest) {}

TEST_F(FaviconHandlerMultipleFaviconsTest,
       DownloadsOnlyOneIconWithoutSizesAttributeIfWantsLargest) {}

TEST_F(FaviconHandlerTest, Report404) {}

// Test that WasUnableToDownloadFavicon() is not called if a download returns
// HTTP status 503.
TEST_F(FaviconHandlerTest, NotReport503) {}

// Test that the best favicon is selected when:
// - The page provides several favicons.
// - Downloading one of the page's icon URLs previously returned a 404.
// - None of the favicons are cached in the Favicons database.
TEST_F(FaviconHandlerTest, MultipleFavicons404) {}

// Test that the best favicon is selected when:
// - The page provides several favicons.
// - Downloading the last page icon URL previously returned a 404.
// - None of the favicons are cached in the Favicons database.
// - All of the icons are downloaded because none of the icons have the ideal
//   size.
// - The 404 icon is last.
TEST_F(FaviconHandlerTest, MultipleFaviconsLast404) {}

// Test that no favicon is selected when:
// - The page provides several favicons.
// - Downloading the page's icons has previously returned a 404.
// - None of the favicons are cached in the Favicons database.
TEST_F(FaviconHandlerTest, MultipleFaviconsAll404) {}

// Test that favicon mappings are removed if the page initially lists a favicon
// and later uses Javascript to change it to another icon that returns a 404.
TEST_F(FaviconHandlerTest, ChangeFaviconViaJavascriptTo404) {}

// Test that favicon mappings are not removed in incognito if the page initially
// lists a favicon and later uses Javascript to change it to another icon that
// returns a 404.
TEST_F(FaviconHandlerTest, ChangeFaviconViaJavascriptTo404InIncognito) {}

// Test that no favicon is selected when the page's only icon uses an invalid
// URL syntax.
TEST_F(FaviconHandlerTest, FaviconInvalidURL) {}

TEST_F(FaviconHandlerTest, TestSortFavicon) {}

TEST_F(FaviconHandlerTest, TestSortTouchIconLargest) {}

TEST_F(FaviconHandlerTest, TestDownloadLargestFavicon) {}

TEST_F(FaviconHandlerTest, TestSelectLargestFavicon) {}

TEST_F(FaviconHandlerTest, TestFaviconWasScaledAfterDownload) {}

// Test that if several icons are downloaded because the icons are smaller than
// expected that OnFaviconUpdated() is called with the largest downloaded
// bitmap.
TEST_F(FaviconHandlerTest, TestKeepDownloadedLargestFavicon) {}

// Test that the special size keyword "any" (represented as a size of 0x0 in
// FaviconURL) is handled.
TEST_F(FaviconHandlerTest, TestConsiderAnySize) {}

// Test that if a page URL is followed by another page URL which is not
// considered the same document, favicon candidates listed in the second page
// get associated to that second page only.
TEST_F(FaviconHandlerTest, SetFaviconsForLastPageUrlOnly) {}

// Test that if a page URL is followed by another page URL which is considered
// the same document (e.g. fragment navigation), favicon candidates listed in
// the second page get associated to both page URLs.
TEST_F(FaviconHandlerTest, SetFaviconsForMultipleUrlsWithinDocument) {}

// Manifests are currently enabled by default. Leaving this fixture for
// logical grouping and blame layer.
class FaviconHandlerManifestsEnabledTest : public FaviconHandlerTest {};

// Test that favicon mappings are deleted when a manifest previously cached in
// the DB is no longer referenced by the page and the page lists no regular
// icons.
TEST_F(FaviconHandlerManifestsEnabledTest,
       RemovedWebManifestAndNoRegularIcons) {}

// Test that favicon mappings are updated (but not deleted) when a manifest
// previously cached in the DB is no longer referenced by the page and the page
// lists regular icons.
TEST_F(FaviconHandlerManifestsEnabledTest, RemovedWebManifestAndRegularIcons) {}

// Test that favicon mappings are updated (but not deleted) when a manifest
// previously cached in the DB (but expired) is no longer referenced by the page
// and the page lists regular icons.
TEST_F(FaviconHandlerManifestsEnabledTest,
       ExpiredAndRemovedWebManifestAndRegularIcons) {}

// Test that a favicon corresponding to a web manifest is reported when:
// - There is data in the favicon database for the manifest URL.
// AND
// - FaviconService::OnFaviconDataForManifestFromFaviconService() runs before
//   FaviconHandler::OnUpdateCandidates() is called.
TEST_F(FaviconHandlerManifestsEnabledTest,
       GetFaviconFromManifestInHistoryIfCandidatesSlower) {}

// Test that a favicon corresponding to a web manifest is reported when:
// - There is data in the favicon database for the manifest URL.
// AND
// - FaviconHandler::OnUpdateCandidates() is called before
//   FaviconService::OnFaviconDataForManifestFromFaviconService() runs.
TEST_F(FaviconHandlerManifestsEnabledTest,
       GetFaviconFromManifestInHistoryIfCandidatesFaster) {}

// Believed to fix crbug.com/544560.
// Tests that there is not crash and SetFavicons() is called with the
// appropriate icon URL in the following scenario:
// - The database initially has a cached icon for the page (not expired).
// - Two initial favicon candidates are received fast, before the history lookup
//   completes. There is no manifest URL initially.
// - Before the history lookup completes, favicon candidates are updated via
//   javascript to include a manifest URL.
// - The manifest lists at least one icon.
TEST_F(FaviconHandlerManifestsEnabledTest,
       AddManifestWithIconsViaJavascriptAfterFastCandidates) {}

// Believed to fix crbug.com/544560.
// Tests that there is not crash and SetFavicons() is called with the
// appropriate icon URL in the following scenario:
// - The database initially has a cached but expired icon for the page.
// - Initial favicon candidates are received fast, before the history lookup
//   completes. There is no manifest URL initially.
// - Before the history lookup completes, favicon candidates are updated via
//   javascript to include a manifest URL.
// - The manifest lists at least one icon.
TEST_F(FaviconHandlerManifestsEnabledTest,
       AddManifestWithIconsViaJavascriptAfterFastCandidatesAndExpiredIcon) {}

// Believed to fix crbug.com/544560.
// Same as the test above with the difference that the manifest contains no
// icons.
TEST_F(FaviconHandlerManifestsEnabledTest,
       AddManifestWithoutIconsViaJavascriptAfterFastCandidatesAndExpiredIcon) {}

// Test that a favicon corresponding to a web manifest is reported when there is
// data in the database for neither the page URL nor the manifest URL.
TEST_F(FaviconHandlerManifestsEnabledTest, GetFaviconFromUnknownManifest) {}

// Test that icons from a web manifest use a desired size of 192x192.
TEST_F(FaviconHandlerManifestsEnabledTest, Prefer192x192IconFromManifest) {}

// Test that a 192x192 favicon corresponding to a web manifest is reported with
// the appropriate size when there is data in the database for neither the page
// URL nor the manifest URL.
TEST_F(FaviconHandlerManifestsEnabledTest,
       GetNonResized192x192FaviconFromUnknownManifest) {}

// Test that the manifest and icon are redownloaded if the icon cached for the
// page URL expired.
TEST_F(FaviconHandlerManifestsEnabledTest, GetFaviconFromExpiredManifest) {}

// Test that the manifest and icon are redownloaded if the icon cached for the
// manifest URL expired, which was observed during a visit to a different page
// URL.
TEST_F(FaviconHandlerManifestsEnabledTest,
       GetFaviconFromExpiredManifestLinkedFromOtherPage) {}

// Test that a favicon corresponding to a web manifest is reported when:
// - There is data in the database for neither the page URL nor the manifest
//   URL.
// - There is data in the database for the icon URL listed in the manifest.
TEST_F(FaviconHandlerManifestsEnabledTest,
       GetFaviconFromUnknownManifestButKnownIcon) {}

// Test a manifest that returns a 404 gets blacklisted via
// UnableToDownloadFavicon() AND that the regular favicon is selected as
// fallback.
TEST_F(FaviconHandlerManifestsEnabledTest, UnknownManifestReturning404) {}

// Test that a manifest that was previously blacklisted via
// UnableToDownloadFavicon() is ignored and that the regular favicon is selected
// as fallback.
TEST_F(FaviconHandlerManifestsEnabledTest, IgnoreManifestWithPrior404) {}

// Test that favicon mappings are deleted when a manifest previously cached in
// the DB (but expired) returns a 404, when the page lists no regular icons.
TEST_F(FaviconHandlerManifestsEnabledTest,
       ExpiredManifestReturning404AndNoRegularIcons) {}

// Test that favicon mappings are updated (but not deleted) when a manifest
// previously cached in the DB (but expired) returns a 404, when the page lists
// regular icons that haven't been cached before.
TEST_F(FaviconHandlerManifestsEnabledTest,
       ExpiredManifestReturning404AndRegularIcons) {}

// Test that favicon mappings are deleted when a manifest previously cached in
// the DB (but expired) contains no icons, when the page lists no regular icons.
TEST_F(FaviconHandlerManifestsEnabledTest,
       ExpiredManifestWithoutIconsAndNoRegularIcons) {}

// Test that favicon mappings are updated (but not deleted) when a manifest
// previously cached in the DB (but expired) contains no icons, when the page
// lists regular icons that haven't been cached before.
TEST_F(FaviconHandlerManifestsEnabledTest,
       ExpiredManifestWithoutIconsAndRegularIcons) {}

// Test that the regular favicon is selected when:
// - The page links to a Web Manifest.
// - The Web Manifest does not contain any icon URLs (it is not a 404).
// - The page has an icon URL provided via a <link rel="icon"> tag.
// - The database does not know about the page URL, manifest URL or icon URL.
TEST_F(FaviconHandlerManifestsEnabledTest, UnknownManifestWithoutIcons) {}

// Test that the regular favicon is selected when:
// - The page links to a Web Manifest.
// - The Web Manifest does not contain any icon URLs (it is not a 404).
// - The page has an icon URL provided via a <link rel="icon"> tag.
// - The database does not know about the page URL.
// - The database does not know about the manifest URL.
// - The database knows about the icon URL.
TEST_F(FaviconHandlerManifestsEnabledTest,
       UnknownManifestWithoutIconsAndKnownRegularIcons) {}

// Test that the database remains unmodified when:
// - The page links to a Web Manifest.
// - The Web Manifest does not contain any icon URLs (it is not a 404).
// - The page has an icon URL provided via a <link rel="icon"> tag.
// - The database has a mapping between the page URL to the favicon URL.
TEST_F(FaviconHandlerManifestsEnabledTest,
       UnknownManifestWithoutIconsAndRegularIconInHistory) {}

// Test that Delegate::OnFaviconUpdated() is called if a page uses Javascript to
// modify the page's <link rel="manifest"> tag to point to a different manifest.
TEST_F(FaviconHandlerManifestsEnabledTest, ManifestUpdateViaJavascript) {}

// Test that Delegate::OnFaviconUpdated() is called if a page uses Javascript to
// remove the page's <link rel="manifest"> tag (i.e. no web manifest) WHILE a
// lookup to the history database is ongoing for the manifest URL.
TEST_F(FaviconHandlerManifestsEnabledTest,
       RemoveManifestViaJavascriptWhileDatabaseLookup) {}

// Tests that favicon mappings are removed if a page initially lists no regular
// favicons but does link to a web manifest, and later uses Javascript to remove
// the manifest URL.
TEST_F(FaviconHandlerManifestsEnabledTest,
       RemoveManifestViaJavascriptDeletesMappings) {}

// Test that Delegate::OnFaviconUpdated() is called a page without manifest uses
// Javascript to add a <link rel="manifest"> tag (i.e. a new web manifest) WHILE
// a lookup to the history database is ongoing for the icon URL.
TEST_F(FaviconHandlerManifestsEnabledTest,
       AddManifestViaJavascriptWhileDatabaseLookup) {}

// Test that SetFavicons() is not called when:
// - The page doesn't initially link to a Web Manifest.
// - The page has an icon URL provided via a <link rel="icon"> tag.
// - The database does not know about the page URL or icon URL.
// - While the icon is being downloaded, the page uses Javascript to add a
//   <link rel="manifest"> tag.
// - The database has bitmap data for the manifest URL.
TEST_F(FaviconHandlerManifestsEnabledTest,
       AddKnownManifestViaJavascriptWhileImageDownload) {}

// Test that SetFavicons() is called with the icon URL when:
// - The page doesn't initially link to a Web Manifest.
// - The page has an icon URL provided via a <link rel="icon"> tag.
// - The database does not know about the page URL or icon URL.
// - During the database lookup, the page uses Javascript to add a
//   <link rel="manifest"> tag.
// - The database does not know about the manifest URL.
// - The manifest contains no icons.
TEST_F(FaviconHandlerManifestsEnabledTest,
       AddManifestWithoutIconsViaJavascriptWhileDatabaseLookup) {}

// Test that SetFavicons() is called when:
// - The page links to one Web Manifest, which contains one icon.
// - The database does not know about the page URL, icon URL or manifest URL.
// - During image download, the page updates the manifest URL to point to
//   another manifest.
// - The second manifest contains the same icons as the first.
TEST_F(FaviconHandlerManifestsEnabledTest,
       UpdateManifestWithSameIconURLsWhileDownloading) {}

}  // namespace
}  // namespace favicon