// Copyright 2017 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 "content/browser/background_fetch/background_fetch_data_manager.h"

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/barrier_closure.h"
#include "base/bind_helpers.h"
#include "base/callback_helpers.h"
#include "base/command_line.h"
#include "base/guid.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/test/metrics/histogram_tester.h"
#include "content/browser/background_fetch/background_fetch.pb.h"
#include "content/browser/background_fetch/background_fetch_data_manager_observer.h"
#include "content/browser/background_fetch/background_fetch_request_info.h"
#include "content/browser/background_fetch/background_fetch_request_match_params.h"
#include "content/browser/background_fetch/background_fetch_test_base.h"
#include "content/browser/background_fetch/background_fetch_test_data_manager.h"
#include "content/browser/background_fetch/storage/database_helpers.h"
#include "content/browser/background_fetch/storage/image_helpers.h"
#include "content/browser/cache_storage/cache_storage_manager.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/public/browser/background_fetch_response.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/storage_partition.h"
#include "services/network/public/mojom/fetch_api.mojom.h"
#include "storage/browser/blob/blob_data_handle.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkColor.h"

namespace content {
namespace {

using background_fetch::BackgroundFetchInitializationData;
using ::testing::_;
using ::testing::UnorderedElementsAre;
using ::testing::IsEmpty;

const char kUserDataPrefix[] = "bgfetch_";

const char kExampleDeveloperId[] = "my-example-id";
const char kAlternativeDeveloperId[] = "my-other-id";
const char kExampleUniqueId[] = "7e57ab1e-c0de-a150-ca75-1e75f005ba11";
const char kAlternativeUniqueId[] = "bb48a9fb-c21f-4c2d-a9ae-58bd48a9fb53";

const char kInitialTitle[] = "Initial Title";
const char kUpdatedTitle[] = "Updated Title";

constexpr size_t kResponseFileSize = 42u;

void DidGetInitializationData(
    base::Closure quit_closure,
    std::vector<BackgroundFetchInitializationData>* out_result,
    blink::mojom::BackgroundFetchError error,
    std::vector<BackgroundFetchInitializationData> result) {
  DCHECK_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  *out_result = std::move(result);
  std::move(quit_closure).Run();
}

void DidCreateRegistration(base::OnceClosure quit_closure,
                           blink::mojom::BackgroundFetchError* out_error,
                           blink::mojom::BackgroundFetchError error,
                           const BackgroundFetchRegistration& registration) {
  *out_error = error;
  std::move(quit_closure).Run();
}

void DidGetError(base::OnceClosure quit_closure,
                 blink::mojom::BackgroundFetchError* out_error,
                 blink::mojom::BackgroundFetchError error) {
  *out_error = error;
  std::move(quit_closure).Run();
}

void DidGetRegistrationUserDataByKeyPrefix(
    base::OnceClosure quit_closure,
    std::vector<std::string>* out_data,
    const std::vector<std::string>& data,
    blink::ServiceWorkerStatusCode status) {
  DCHECK(out_data);
  DCHECK_EQ(blink::ServiceWorkerStatusCode::kOk, status);
  *out_data = data;
  std::move(quit_closure).Run();
}

void AnnotateRequestInfoWithFakeDownloadManagerData(
    BackgroundFetchRequestInfo* request_info,
    bool success = false) {
  DCHECK(request_info);

  std::string headers =
      success ? "HTTP/1.1 200 OK\n" : "HTTP/1.1 404 Not found\n";
  request_info->PopulateWithResponse(std::make_unique<BackgroundFetchResponse>(
      std::vector<GURL>(1u, request_info->fetch_request().url),
      base::MakeRefCounted<net::HttpResponseHeaders>(headers)));

  if (!success) {
    // Fill |request_info| with a failed result.
    request_info->SetResult(std::make_unique<BackgroundFetchResult>(
        base::Time::Now(), BackgroundFetchResult::FailureReason::UNKNOWN));
    return;
  }

  // This is treated as an empty response, but the size is set to
  // |kResponseFileSize| for tests that use filesize.
  request_info->SetResult(std::make_unique<BackgroundFetchResult>(
      base::Time::Now(), base::FilePath(), base::nullopt /* blob_handle */,
      kResponseFileSize));
}

void GetNumUserData(base::Closure quit_closure,
                    int* out_size,
                    const std::vector<std::string>& data,
                    blink::ServiceWorkerStatusCode status) {
  DCHECK(out_size);
  DCHECK_EQ(blink::ServiceWorkerStatusCode::kOk, status);
  *out_size = data.size();
  std::move(quit_closure).Run();
}

struct ResponseStateStats {
  int pending_requests = 0;
  int active_requests = 0;
  int completed_requests = 0;
};

bool operator==(const ResponseStateStats& s1, const ResponseStateStats& s2) {
  return s1.pending_requests == s2.pending_requests &&
         s1.active_requests == s2.active_requests &&
         s1.completed_requests == s2.completed_requests;
}

std::vector<ServiceWorkerFetchRequest> CreateValidRequests(
    const url::Origin& origin,
    size_t num_requests = 1u) {
  std::vector<ServiceWorkerFetchRequest> requests(num_requests);
  for (size_t i = 0; i < requests.size(); i++) {
    // Creates a URL of the form: `http://example.com/x`
    requests[i].url = GURL(origin.GetURL().spec() + base::NumberToString(i));
  }
  return requests;
}

SkBitmap CreateTestIcon(int size = 42, SkColor color = SK_ColorGREEN) {
  SkBitmap icon;
  icon.allocN32Pixels(size, size);
  icon.eraseColor(SK_ColorGREEN);
  return icon;
}

void ExpectIconProperties(const SkBitmap& icon, int size, SkColor color) {
  EXPECT_FALSE(icon.isNull());
  EXPECT_EQ(icon.width(), size);
  EXPECT_EQ(icon.height(), size);
  for (int i = 0; i < icon.width(); i++) {
    for (int j = 0; j < icon.height(); j++)
      EXPECT_EQ(icon.getColor(i, j), color);
  }
}

}  // namespace

class BackgroundFetchDataManagerTest
    : public BackgroundFetchTestBase,
      public BackgroundFetchDataManagerObserver {
 public:
  BackgroundFetchDataManagerTest() {
    RestartDataManagerFromPersistentStorage();
  }

  ~BackgroundFetchDataManagerTest() override {
    background_fetch_data_manager_->RemoveObserver(this);
  }

  // Re-creates the data manager. Useful for testing that data was persisted.
  void RestartDataManagerFromPersistentStorage() {
    background_fetch_data_manager_ =
        std::make_unique<BackgroundFetchTestDataManager>(
            browser_context(), storage_partition(),
            embedded_worker_test_helper()->context_wrapper(),
            true /* mock_fill_response */);

    background_fetch_data_manager_->AddObserver(this);
    background_fetch_data_manager_->InitializeOnIOThread();
  }

  // Synchronous version of BackgroundFetchDataManager::GetInitializationData().
  std::vector<BackgroundFetchInitializationData> GetInitializationData() {
    // Simulate browser restart. This re-initializes |data_manager_|, since
    // this DatabaseTask should only be called on browser startup.
    RestartDataManagerFromPersistentStorage();

    std::vector<BackgroundFetchInitializationData> result;

    base::RunLoop run_loop;
    background_fetch_data_manager_->GetInitializationData(base::BindOnce(
        &DidGetInitializationData, run_loop.QuitClosure(), &result));
    run_loop.Run();

    return result;
  }

  // Synchronous version of BackgroundFetchDataManager::CreateRegistration().
  void CreateRegistration(
      const BackgroundFetchRegistrationId& registration_id,
      const std::vector<ServiceWorkerFetchRequest>& requests,
      const BackgroundFetchOptions& options,
      const SkBitmap& icon,
      blink::mojom::BackgroundFetchError* out_error) {
    DCHECK(out_error);

    base::RunLoop run_loop;
    background_fetch_data_manager_->CreateRegistration(
        registration_id, requests, options, icon,
        base::BindOnce(&DidCreateRegistration, run_loop.QuitClosure(),
                       out_error));
    run_loop.Run();
  }

  BackgroundFetchRegistration GetRegistration(
      int64_t service_worker_registration_id,
      const url::Origin& origin,
      const std::string developer_id,
      blink::mojom::BackgroundFetchError* out_error) {
    DCHECK(out_error);

    BackgroundFetchRegistration registration;
    base::RunLoop run_loop;
    background_fetch_data_manager_->GetRegistration(
        service_worker_registration_id, origin, developer_id,
        base::BindOnce(&BackgroundFetchDataManagerTest::DidGetRegistration,
                       base::Unretained(this), run_loop.QuitClosure(),
                       out_error, &registration));
    run_loop.Run();

    return registration;
  }

  std::unique_ptr<proto::BackgroundFetchMetadata> GetMetadata(
      int64_t service_worker_registration_id,
      const std::string& unique_id) {
    std::unique_ptr<proto::BackgroundFetchMetadata> metadata;

    base::RunLoop run_loop;
    embedded_worker_test_helper()->context_wrapper()->GetRegistrationUserData(
        service_worker_registration_id,
        {background_fetch::RegistrationKey(unique_id)},
        base::BindOnce(&BackgroundFetchDataManagerTest::DidGetMetadata,
                       base::Unretained(this), run_loop.QuitClosure(),
                       &metadata));
    run_loop.Run();

    return metadata;
  }

  void UpdateRegistrationUI(
      const BackgroundFetchRegistrationId& registration_id,
      const base::Optional<std::string>& updated_title,
      const base::Optional<SkBitmap>& updated_icon,
      blink::mojom::BackgroundFetchError* out_error) {
    DCHECK(out_error);

    base::RunLoop run_loop;
    background_fetch_data_manager_->UpdateRegistrationUI(
        registration_id, updated_title, updated_icon,
        base::BindOnce(&BackgroundFetchDataManagerTest::DidUpdateRegistrationUI,
                       base::Unretained(this), run_loop.QuitClosure(),
                       out_error));
    run_loop.Run();
  }

  std::vector<std::string> GetDeveloperIds(
      int64_t service_worker_registration_id,
      const url::Origin& origin,
      blink::mojom::BackgroundFetchError* out_error) {
    DCHECK(out_error);

    std::vector<std::string> ids;
    base::RunLoop run_loop;
    background_fetch_data_manager_->GetDeveloperIdsForServiceWorker(
        service_worker_registration_id, origin,
        base::BindOnce(&BackgroundFetchDataManagerTest::DidGetDeveloperIds,
                       base::Unretained(this), run_loop.QuitClosure(),
                       out_error, &ids));
    run_loop.Run();

    return ids;
  }

  // Synchronous version of
  // BackgroundFetchDataManager::PopNextRequest().
  void PopNextRequest(
      const BackgroundFetchRegistrationId& registration_id,
      scoped_refptr<BackgroundFetchRequestInfo>* out_request_info) {
    DCHECK(out_request_info);

    base::RunLoop run_loop;
    background_fetch_data_manager_->PopNextRequest(
        registration_id,
        base::BindOnce(&BackgroundFetchDataManagerTest::DidPopNextRequest,
                       base::Unretained(this), run_loop.QuitClosure(),
                       out_request_info));
    run_loop.Run();
  }

  // Synchronous version of
  // BackgroundFetchDataManager::MarkRegistrationForDeletion().
  void MarkRegistrationForDeletion(
      const BackgroundFetchRegistrationId& registration_id,
      blink::mojom::BackgroundFetchError* out_error) {
    DCHECK(out_error);

    base::RunLoop run_loop;
    background_fetch_data_manager_->MarkRegistrationForDeletion(
        registration_id,
        base::BindOnce(&DidGetError, run_loop.QuitClosure(), out_error));
    run_loop.Run();
  }

  // Synchronous version of BackgroundFetchDataManager::DeleteRegistration().
  void DeleteRegistration(const BackgroundFetchRegistrationId& registration_id,
                          blink::mojom::BackgroundFetchError* out_error) {
    DCHECK(out_error);

    base::RunLoop run_loop;
    background_fetch_data_manager_->DeleteRegistration(
        registration_id,
        base::BindOnce(&DidGetError, run_loop.QuitClosure(), out_error));
    run_loop.Run();
  }

  // Synchronous version of BackgroundFetchDataManager::MarkRequestAsComplete().
  void MarkRequestAsComplete(
      const BackgroundFetchRegistrationId& registration_id,
      BackgroundFetchRequestInfo* request_info) {
    base::RunLoop run_loop;
    background_fetch_data_manager_->MarkRequestAsComplete(
        registration_id, request_info,
        base::BindOnce(
            &BackgroundFetchDataManagerTest::DidMarkRequestAsComplete,
            base::Unretained(this), run_loop.QuitClosure()));
    run_loop.Run();
  }

  // Synchronous version of
  // BackgroundFetchDataManager::GetSettledFetchesForRegistration().
  void GetSettledFetchesForRegistration(
      const BackgroundFetchRegistrationId& registration_id,
      base::Optional<ServiceWorkerFetchRequest> request_to_match,
      blink::mojom::BackgroundFetchError* out_error,
      bool* out_succeeded,
      std::vector<BackgroundFetchSettledFetch>* out_settled_fetches) {
    DCHECK(out_error);
    DCHECK(out_succeeded);
    DCHECK(out_settled_fetches);

    base::RunLoop run_loop;
    auto match_params = std::make_unique<BackgroundFetchRequestMatchParams>(
        request_to_match, nullptr /* cache_query_params */);
    background_fetch_data_manager_->GetSettledFetchesForRegistration(
        registration_id, std::move(match_params),
        base::BindOnce(&BackgroundFetchDataManagerTest::
                           DidGetSettledFetchesForRegistration,
                       base::Unretained(this), run_loop.QuitClosure(),
                       out_error, out_succeeded, out_settled_fetches));
    run_loop.Run();
  }

  // Synchronous version of
  // ServiceWorkerContextWrapper::GetRegistrationUserDataByKeyPrefix.
  std::vector<std::string> GetRegistrationUserDataByKeyPrefix(
      int64_t service_worker_registration_id,
      const std::string& key_prefix) {
    std::vector<std::string> data;

    base::RunLoop run_loop;
    embedded_worker_test_helper()
        ->context_wrapper()
        ->GetRegistrationUserDataByKeyPrefix(
            service_worker_registration_id, key_prefix,
            base::BindOnce(&DidGetRegistrationUserDataByKeyPrefix,
                           run_loop.QuitClosure(), &data));
    run_loop.Run();

    return data;
  }

  // Synchronous version of CacheStorageManager::HasCache().
  bool HasCache(const std::string& cache_name) {
    bool result = false;

    base::RunLoop run_loop;
    background_fetch_data_manager_->cache_manager()->HasCache(
        origin(), CacheStorageOwner::kBackgroundFetch, cache_name,
        base::BindOnce(&BackgroundFetchDataManagerTest::DidFindCache,
                       base::Unretained(this), run_loop.QuitClosure(),
                       &result));
    run_loop.Run();

    return result;
  }

  // Synchronous version of CacheStorageManager::MatchCache().
  bool MatchCache(const ServiceWorkerFetchRequest& request) {
    bool result = false;
    auto request_ptr = std::make_unique<ServiceWorkerFetchRequest>(request);

    base::RunLoop run_loop;
    background_fetch_data_manager_->cache_manager()->MatchCache(
        origin(), CacheStorageOwner::kBackgroundFetch, kExampleUniqueId,
        std::move(request_ptr), nullptr /* match_params */,
        base::BindOnce(&BackgroundFetchDataManagerTest::DidMatchCache,
                       base::Unretained(this), run_loop.QuitClosure(),
                       &result));
    run_loop.Run();

    return result;
  }

  // Returns the title and the icon.
  std::pair<std::string, SkBitmap> GetUIOptions(
      int64_t service_worker_registration_id) {
    auto results = GetRegistrationUserDataByKeyPrefix(
        service_worker_registration_id, background_fetch::kUIOptionsKeyPrefix);
    DCHECK_LT(results.size(), 2u)
        << "Using GetUIOptions with multiple registrations is unimplemented";

    proto::BackgroundFetchUIOptions ui_options;
    if (results.empty())
      return {"", SkBitmap()};

    bool did_parse = ui_options.ParseFromString(results[0]);
    DCHECK(did_parse);

    std::pair<std::string, SkBitmap> result{ui_options.title(), SkBitmap()};

    if (ui_options.icon().empty())
      return result;

    // Deserialize icon.
    {
      base::RunLoop run_loop;
      background_fetch::DeserializeIcon(
          std::unique_ptr<std::string>(ui_options.release_icon()),
          base::BindOnce(
              [](base::OnceClosure quit_closure, SkBitmap* out_icon,
                 SkBitmap icon) {
                DCHECK(out_icon);
                *out_icon = std::move(icon);
                std::move(quit_closure).Run();
              },
              run_loop.QuitClosure(), &result.second));
      run_loop.Run();
    }

    return result;
  }

  // Gets information about the number of background fetch requests by state.
  ResponseStateStats GetRequestStats(int64_t service_worker_registration_id) {
    ResponseStateStats stats;
    {
      base::RunLoop run_loop;
      embedded_worker_test_helper()
          ->context_wrapper()
          ->GetRegistrationUserDataByKeyPrefix(
              service_worker_registration_id,
              background_fetch::kPendingRequestKeyPrefix,
              base::BindOnce(&GetNumUserData, run_loop.QuitClosure(),
                             &stats.pending_requests));
      run_loop.Run();
    }
    {
      base::RunLoop run_loop;
      embedded_worker_test_helper()
          ->context_wrapper()
          ->GetRegistrationUserDataByKeyPrefix(
              service_worker_registration_id,
              background_fetch::kActiveRequestKeyPrefix,
              base::BindOnce(&GetNumUserData, run_loop.QuitClosure(),
                             &stats.active_requests));
      run_loop.Run();
    }
    {
      base::RunLoop run_loop;
      embedded_worker_test_helper()
          ->context_wrapper()
          ->GetRegistrationUserDataByKeyPrefix(
              service_worker_registration_id,
              background_fetch::kCompletedRequestKeyPrefix,
              base::BindOnce(&GetNumUserData, run_loop.QuitClosure(),
                             &stats.completed_requests));
      run_loop.Run();
    }
    return stats;
  }

  // BackgroundFetchDataManagerObserver mocks:
  MOCK_METHOD5(OnRegistrationCreated,
               void(const BackgroundFetchRegistrationId& registration_id,
                    const BackgroundFetchRegistration& registration,
                    const BackgroundFetchOptions& options,
                    const SkBitmap& icon,
                    int num_requests));
  MOCK_METHOD3(OnUpdatedUI,
               void(const BackgroundFetchRegistrationId& registration,
                    const base::Optional<std::string>& title,
                    const base::Optional<SkBitmap>& icon));
  MOCK_METHOD1(OnServiceWorkerDatabaseCorrupted,
               void(int64_t service_worker_registration_id));

 protected:
  void DidGetRegistration(base::OnceClosure quit_closure,
                          blink::mojom::BackgroundFetchError* out_error,
                          BackgroundFetchRegistration* out_registration,
                          blink::mojom::BackgroundFetchError error,
                          const BackgroundFetchRegistration& registration) {
    *out_error = error;
    *out_registration = registration;

    std::move(quit_closure).Run();
  }

  void DidGetMetadata(
      base::OnceClosure quit_closure,
      std::unique_ptr<proto::BackgroundFetchMetadata>* out_metadata,
      const std::vector<std::string>& data,
      blink::ServiceWorkerStatusCode status) {
    if (status == blink::ServiceWorkerStatusCode::kOk) {
      DCHECK_EQ(data.size(), 1u);

      auto metadata = std::make_unique<proto::BackgroundFetchMetadata>();
      if (metadata->ParseFromString(data[0]))
        *out_metadata = std::move(metadata);
    }

    std::move(quit_closure).Run();
  }

  void DidUpdateRegistrationUI(base::OnceClosure quit_closure,
                               blink::mojom::BackgroundFetchError* out_error,
                               blink::mojom::BackgroundFetchError error) {
    *out_error = error;
    std::move(quit_closure).Run();
  }

  void DidGetDeveloperIds(base::Closure quit_closure,
                          blink::mojom::BackgroundFetchError* out_error,
                          std::vector<std::string>* out_ids,
                          blink::mojom::BackgroundFetchError error,
                          const std::vector<std::string>& ids) {
    *out_error = error;
    *out_ids = ids;

    std::move(quit_closure).Run();
  }

  void DidPopNextRequest(
      base::OnceClosure quit_closure,
      scoped_refptr<BackgroundFetchRequestInfo>* out_request_info,
      scoped_refptr<BackgroundFetchRequestInfo> request_info) {
    *out_request_info = request_info;
    std::move(quit_closure).Run();
  }

  void DidMarkRequestAsComplete(base::OnceClosure quit_closure) {
    std::move(quit_closure).Run();
  }

  void DidGetSettledFetchesForRegistration(
      base::OnceClosure quit_closure,
      blink::mojom::BackgroundFetchError* out_error,
      bool* out_succeeded,
      std::vector<BackgroundFetchSettledFetch>* out_settled_fetches,
      blink::mojom::BackgroundFetchError error,
      bool succeeded,
      std::vector<BackgroundFetchSettledFetch> settled_fetches,
      std::vector<std::unique_ptr<storage::BlobDataHandle>>) {
    *out_error = error;
    *out_succeeded = succeeded;
    *out_settled_fetches = std::move(settled_fetches);

    std::move(quit_closure).Run();
  }

  void DidFindCache(base::OnceClosure quit_closure,
                    bool* out_result,
                    bool has_cache,
                    blink::mojom::CacheStorageError error) {
    DCHECK_EQ(error, blink::mojom::CacheStorageError::kSuccess);
    *out_result = has_cache;
    std::move(quit_closure).Run();
  }

  void DidMatchCache(base::OnceClosure quit_closure,
                     bool* out_result,
                     blink::mojom::CacheStorageError error,
                     blink::mojom::FetchAPIResponsePtr response) {
    if (error == blink::mojom::CacheStorageError::kSuccess) {
      DCHECK(response);
      *out_result = true;
    } else {
      *out_result = false;
    }
    std::move(quit_closure).Run();
  }

  std::unique_ptr<BackgroundFetchTestDataManager>
      background_fetch_data_manager_;
};

TEST_F(BackgroundFetchDataManagerTest, NoDuplicateRegistrations) {
  // Tests that the BackgroundFetchDataManager correctly rejects creating a
  // registration with a |developer_id| for which there is already an active
  // registration.

  int64_t service_worker_registration_id = RegisterServiceWorker();
  ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId,
            service_worker_registration_id);

  BackgroundFetchRegistrationId registration_id1(service_worker_registration_id,
                                                 origin(), kExampleDeveloperId,
                                                 kExampleUniqueId);

  std::vector<ServiceWorkerFetchRequest> requests;
  BackgroundFetchOptions options;

  blink::mojom::BackgroundFetchError error;

  // Deactivating the not-yet-created registration should fail.
  MarkRegistrationForDeletion(registration_id1, &error);
  EXPECT_EQ(error, blink::mojom::BackgroundFetchError::INVALID_ID);

  // Creating the initial registration should succeed.
  {
    EXPECT_CALL(*this, OnRegistrationCreated(registration_id1, _, _, _, _));

    CreateRegistration(registration_id1, requests, options, SkBitmap(), &error);
    ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  }

  // Different |unique_id|, since this is a new Background Fetch registration,
  // even though it shares the same |developer_id|.
  BackgroundFetchRegistrationId registration_id2(service_worker_registration_id,
                                                 origin(), kExampleDeveloperId,
                                                 kAlternativeUniqueId);

  // Attempting to create a second registration with the same |developer_id| and
  // |service_worker_registration_id| should yield an error.
  CreateRegistration(registration_id2, requests, options, SkBitmap(), &error);
  EXPECT_EQ(error, blink::mojom::BackgroundFetchError::DUPLICATED_DEVELOPER_ID);

  // Deactivating the second registration that failed to be created should fail.
  MarkRegistrationForDeletion(registration_id2, &error);
  EXPECT_EQ(error, blink::mojom::BackgroundFetchError::INVALID_ID);

  // Deactivating the initial registration should succeed.
  MarkRegistrationForDeletion(registration_id1, &error);
  EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);

  // And now registering the second registration should work fine, since there
  // is no longer an *active* registration with the same |developer_id|, even
  // though the initial registration has not yet been deleted.
  {
    EXPECT_CALL(*this, OnRegistrationCreated(registration_id2, _, _, _, _));

    CreateRegistration(registration_id2, requests, options, SkBitmap(), &error);
    ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  }
}

TEST_F(BackgroundFetchDataManagerTest, GetDeveloperIds) {
  int64_t sw_id = RegisterServiceWorker();
  ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);

  std::vector<ServiceWorkerFetchRequest> requests(2u);
  BackgroundFetchOptions options;
  blink::mojom::BackgroundFetchError error;

  // Verify that no developer IDs can be found.
  auto developer_ids = GetDeveloperIds(sw_id, origin(), &error);
  EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  EXPECT_THAT(developer_ids, IsEmpty());

  // Create a single registration.
  BackgroundFetchRegistrationId registration_id1(
      sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);
  {
    EXPECT_CALL(*this, OnRegistrationCreated(registration_id1, _, _, _, _));

    CreateRegistration(registration_id1, requests, options, SkBitmap(), &error);
    ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  }

  // Verify that the developer ID can be found.
  developer_ids = GetDeveloperIds(sw_id, origin(), &error);
  EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  EXPECT_THAT(developer_ids, UnorderedElementsAre(kExampleDeveloperId));

  RestartDataManagerFromPersistentStorage();

  // After a restart, GetDeveloperIds should still find the IDs.
  developer_ids = GetDeveloperIds(sw_id, origin(), &error);
  EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  EXPECT_THAT(developer_ids, UnorderedElementsAre(kExampleDeveloperId));

  // Create another registration.
  BackgroundFetchRegistrationId registration_id2(
      sw_id, origin(), kAlternativeDeveloperId, kAlternativeUniqueId);
  {
    EXPECT_CALL(*this, OnRegistrationCreated(registration_id2, _, _, _, _));

    CreateRegistration(registration_id2, requests, options, SkBitmap(), &error);
    ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  }
  // Verify that both developer IDs can be found.
  developer_ids = GetDeveloperIds(sw_id, origin(), &error);
  EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  EXPECT_THAT(developer_ids, UnorderedElementsAre(kExampleDeveloperId,
                                                  kAlternativeDeveloperId));
  RestartDataManagerFromPersistentStorage();

  // After a restart, GetDeveloperIds should still find the IDs.
  developer_ids = GetDeveloperIds(sw_id, origin(), &error);
  EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  EXPECT_THAT(developer_ids, UnorderedElementsAre(kExampleDeveloperId,
                                                  kAlternativeDeveloperId));
}

TEST_F(BackgroundFetchDataManagerTest, GetRegistration) {
  int64_t sw_id = RegisterServiceWorker();
  ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);

  BackgroundFetchRegistrationId registration_id(
      sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);

  std::vector<ServiceWorkerFetchRequest> requests(2u);
  BackgroundFetchOptions options;
  blink::mojom::BackgroundFetchError error;

  // Create a single registration.
  {
    EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _));

    CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
    ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  }

  // Verify that the registration can be retrieved.
  auto registration =
      GetRegistration(sw_id, origin(), kExampleDeveloperId, &error);
  ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);

  EXPECT_EQ(kExampleUniqueId, registration.unique_id);
  EXPECT_EQ(kExampleDeveloperId, registration.developer_id);

  // Verify that retrieving using the wrong developer id doesn't work.
  registration =
      GetRegistration(sw_id, origin(), kAlternativeDeveloperId, &error);
  ASSERT_EQ(error, blink::mojom::BackgroundFetchError::INVALID_ID);

  RestartDataManagerFromPersistentStorage();

  // After a restart, GetRegistration should still find the registration.
  registration = GetRegistration(sw_id, origin(), kExampleDeveloperId, &error);
  ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);

  EXPECT_EQ(kExampleUniqueId, registration.unique_id);
  EXPECT_EQ(kExampleDeveloperId, registration.developer_id);
}

TEST_F(BackgroundFetchDataManagerTest, GetMetadata) {
  int64_t sw_id = RegisterServiceWorker();
  ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);

  BackgroundFetchRegistrationId registration_id(
      sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);

  std::vector<ServiceWorkerFetchRequest> requests(2u);
  BackgroundFetchOptions options;
  blink::mojom::BackgroundFetchError error;

  // Create a single registration.
  {
    EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _));

    CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
    ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  }
  // Verify that the metadata can be retrieved.
  auto metadata = GetMetadata(sw_id, kExampleUniqueId);
  ASSERT_TRUE(metadata);
  EXPECT_EQ(metadata->origin(), origin().Serialize());
  EXPECT_NE(metadata->creation_microseconds_since_unix_epoch(), 0);
  EXPECT_EQ(metadata->num_fetches(), static_cast<int>(requests.size()));

  RestartDataManagerFromPersistentStorage();

  // After a restart, GetMetadata should still find the registration.
  metadata = GetMetadata(sw_id, kExampleUniqueId);
  ASSERT_TRUE(metadata);
  EXPECT_EQ(metadata->origin(), origin().Serialize());
  EXPECT_NE(metadata->creation_microseconds_since_unix_epoch(), 0);
  EXPECT_EQ(metadata->num_fetches(), static_cast<int>(requests.size()));
}

TEST_F(BackgroundFetchDataManagerTest, LargeIconNotPersisted) {
  int64_t sw_id = RegisterServiceWorker();
  ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);

  BackgroundFetchRegistrationId registration_id(
      sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);

  std::vector<ServiceWorkerFetchRequest> requests(2u);
  BackgroundFetchOptions options;
  blink::mojom::BackgroundFetchError error;

  SkBitmap icon = CreateTestIcon(512 /* size */);
  ASSERT_FALSE(background_fetch::ShouldPersistIcon(icon));

  // Create a single registration.
  {
    EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _));

    CreateRegistration(registration_id, requests, options, icon, &error);
    ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  }

  // Verify that the metadata can be retrieved.
  auto metadata = GetMetadata(sw_id, kExampleUniqueId);
  ASSERT_TRUE(metadata);
  EXPECT_EQ(metadata->origin(), origin().Serialize());
  EXPECT_NE(metadata->creation_microseconds_since_unix_epoch(), 0);
  EXPECT_EQ(metadata->num_fetches(), static_cast<int>(requests.size()));
  EXPECT_TRUE(GetUIOptions(sw_id).second.isNull());
}

TEST_F(BackgroundFetchDataManagerTest, UpdateRegistrationUI) {
  int64_t sw_id = RegisterServiceWorker();
  ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);

  BackgroundFetchRegistrationId registration_id(
      sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);

  std::vector<ServiceWorkerFetchRequest> requests(2u);
  BackgroundFetchOptions options;
  options.title = kInitialTitle;
  blink::mojom::BackgroundFetchError error;

  // There should be no title before the registration.
  EXPECT_TRUE(GetUIOptions(sw_id).first.empty());

  // Create a single registration.
  {
    EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _));

    CreateRegistration(registration_id, requests, options, CreateTestIcon(),
                       &error);
    ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  }

  // Verify that the UI Options can be retrieved.
  {
    auto ui_options = GetUIOptions(sw_id);
    EXPECT_EQ(ui_options.first, kInitialTitle);
    EXPECT_NO_FATAL_FAILURE(
        ExpectIconProperties(ui_options.second, 42, SK_ColorGREEN));
  }

  // Update only the title.
  {
    EXPECT_CALL(*this,
                OnUpdatedUI(registration_id,
                            base::Optional<std::string>(kUpdatedTitle), _));

    UpdateRegistrationUI(registration_id, kUpdatedTitle, base::nullopt, &error);
    ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);

    auto ui_options = GetUIOptions(sw_id);
    // Expect new title.
    EXPECT_EQ(ui_options.first, kUpdatedTitle);
    // Expect same icon as before.
    EXPECT_NO_FATAL_FAILURE(
        ExpectIconProperties(ui_options.second, 42, SK_ColorGREEN));
  }

  // Update only the icon.
  {
    EXPECT_CALL(*this, OnUpdatedUI(registration_id, _, _));

    UpdateRegistrationUI(registration_id, base::nullopt,
                         CreateTestIcon(24 /* size */), &error);
    ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);

    auto ui_options = GetUIOptions(sw_id);
    // Expect the same title as before.
    EXPECT_EQ(ui_options.first, kUpdatedTitle);
    // Expect the new icon with the different size.
    EXPECT_NO_FATAL_FAILURE(
        ExpectIconProperties(ui_options.second, 24, SK_ColorGREEN));
  }

  // Update both the title and icon.
  {
    EXPECT_CALL(*this,
                OnUpdatedUI(registration_id,
                            base::Optional<std::string>(kInitialTitle), _));

    UpdateRegistrationUI(registration_id, kInitialTitle,
                         CreateTestIcon(66 /* size */), &error);
    ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);

    auto ui_options = GetUIOptions(sw_id);
    // Expect the initial title again.
    EXPECT_EQ(ui_options.first, kInitialTitle);
    // Expect the new icon with the different size.
    EXPECT_NO_FATAL_FAILURE(
        ExpectIconProperties(ui_options.second, 66, SK_ColorGREEN));
  }

  // New title and an icon that's too large.
  {
    EXPECT_CALL(*this,
                OnUpdatedUI(registration_id,
                            base::Optional<std::string>(kUpdatedTitle), _));

    UpdateRegistrationUI(registration_id, kUpdatedTitle,
                         CreateTestIcon(512 /* size */), &error);
    ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);

    auto ui_options = GetUIOptions(sw_id);
    // Expect the new title.
    EXPECT_EQ(ui_options.first, kUpdatedTitle);
    // Expect same icon as before.
    EXPECT_NO_FATAL_FAILURE(
        ExpectIconProperties(ui_options.second, 66, SK_ColorGREEN));
  }
}

TEST_F(BackgroundFetchDataManagerTest, CreateAndDeleteRegistration) {
  int64_t sw_id = RegisterServiceWorker();
  ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);

  BackgroundFetchRegistrationId registration_id1(
      sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);

  std::vector<ServiceWorkerFetchRequest> requests(2u);
  BackgroundFetchOptions options;
  blink::mojom::BackgroundFetchError error;

  {
    EXPECT_CALL(*this, OnRegistrationCreated(registration_id1, _, _, _, _));

    CreateRegistration(registration_id1, requests, options, SkBitmap(), &error);
    ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  }

  RestartDataManagerFromPersistentStorage();

  // Different |unique_id|, since this is a new Background Fetch registration,
  // even though it shares the same |developer_id|.
  BackgroundFetchRegistrationId registration_id2(
      sw_id, origin(), kExampleDeveloperId, kAlternativeUniqueId);

  // Attempting to create a second registration with the same |developer_id| and
  // |service_worker_registration_id| should yield an error, even after
  // restarting.
  CreateRegistration(registration_id2, requests, options, SkBitmap(), &error);
  ASSERT_EQ(error, blink::mojom::BackgroundFetchError::DUPLICATED_DEVELOPER_ID);

  // Verify that the registration can be retrieved before deletion.
  auto registration =
      GetRegistration(sw_id, origin(), kExampleDeveloperId, &error);
  ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);

  EXPECT_EQ(kExampleUniqueId, registration.unique_id);
  EXPECT_EQ(kExampleDeveloperId, registration.developer_id);

  // Deactivating the registration should succeed.
  MarkRegistrationForDeletion(registration_id1, &error);
  EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);

  // Verify that the registration cannot be retrieved after deletion
  registration = GetRegistration(sw_id, origin(), kExampleDeveloperId, &error);
  ASSERT_EQ(error, blink::mojom::BackgroundFetchError::INVALID_ID);

  RestartDataManagerFromPersistentStorage();

  // Verify again that the registration cannot be retrieved after deletion and
  // a restart.
  registration = GetRegistration(sw_id, origin(), kExampleDeveloperId, &error);
  ASSERT_EQ(error, blink::mojom::BackgroundFetchError::INVALID_ID);

  // And now registering the second registration should work fine, even after
  // restarting, since there is no longer an *active* registration with the same
  // |developer_id|, even though the initial registration has not yet been
  // deleted.
  {
    EXPECT_CALL(*this, OnRegistrationCreated(registration_id2, _, _, _, _));

    CreateRegistration(registration_id2, requests, options, SkBitmap(), &error);
    ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  }

  RestartDataManagerFromPersistentStorage();

  // Deleting the inactive first registration should succeed.
  DeleteRegistration(registration_id1, &error);
  EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
}

TEST_F(BackgroundFetchDataManagerTest, PopNextRequestAndMarkAsComplete) {
  int64_t sw_id = RegisterServiceWorker();
  ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);

  scoped_refptr<BackgroundFetchRequestInfo> request_info;

  BackgroundFetchRegistrationId registration_id(
      sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);

  // There registration hasn't been created yet, so there are no pending
  // requests.
  PopNextRequest(registration_id, &request_info);
  EXPECT_FALSE(request_info);
  EXPECT_EQ(
      GetRequestStats(sw_id),
      (ResponseStateStats{0 /* pending_requests */, 0 /* active_requests */,
                          0 /* completed_requests */}));

  std::vector<ServiceWorkerFetchRequest> requests(2u);
  BackgroundFetchOptions options;
  blink::mojom::BackgroundFetchError error;

  {
    EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _));

    CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
    ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  }

  EXPECT_EQ(
      GetRequestStats(sw_id),
      (ResponseStateStats{2 /* pending_requests */, 0 /* active_requests */,
                          0 /* completed_requests */}));

  // Popping should work now.
  PopNextRequest(registration_id, &request_info);
  EXPECT_TRUE(request_info);
  EXPECT_EQ(request_info->request_index(), 0);
  EXPECT_FALSE(request_info->download_guid().empty());
  EXPECT_EQ(
      GetRequestStats(sw_id),
      (ResponseStateStats{1 /* pending_requests */, 1 /* active_requests */,
                          0 /* completed_requests */}));

  // Mark as complete.
  AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get());
  MarkRequestAsComplete(registration_id, request_info.get());
  ASSERT_EQ(
      GetRequestStats(sw_id),
      (ResponseStateStats{1 /* pending_requests */, 0 /* active_requests */,
                          1 /* completed_requests */}));

  RestartDataManagerFromPersistentStorage();

  PopNextRequest(registration_id, &request_info);
  EXPECT_TRUE(request_info);
  EXPECT_EQ(request_info->request_index(), 1);
  EXPECT_FALSE(request_info->download_guid().empty());
  EXPECT_EQ(
      GetRequestStats(sw_id),
      (ResponseStateStats{0 /* pending_requests */, 1 /* active_requests */,
                          1 /* completed_requests */}));

  // Mark as complete.
  AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get());
  MarkRequestAsComplete(registration_id, request_info.get());
  ASSERT_EQ(
      GetRequestStats(sw_id),
      (ResponseStateStats{0 /* pending_requests */, 0 /* active_requests */,
                          2 /* completed_requests */}));

  // We are out of pending requests.
  PopNextRequest(registration_id, &request_info);
  EXPECT_FALSE(request_info);
  EXPECT_EQ(
      GetRequestStats(sw_id),
      (ResponseStateStats{0 /* pending_requests */, 0 /* active_requests */,
                          2 /* completed_requests */}));
}

TEST_F(BackgroundFetchDataManagerTest, DownloadTotalUpdated) {
  int64_t sw_id = RegisterServiceWorker();
  ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);

  BackgroundFetchRegistrationId registration_id(
      sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);
  auto requests = CreateValidRequests(origin(), 3u /* num_requests */);

  BackgroundFetchOptions options;
  blink::mojom::BackgroundFetchError error;
  {
    EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _));

    CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
    ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  }

  auto registration =
      GetRegistration(sw_id, origin(), kExampleDeveloperId, &error);
  ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  EXPECT_EQ(registration.download_total, 0u);

  scoped_refptr<BackgroundFetchRequestInfo> request_info;
  PopNextRequest(registration_id, &request_info);
  AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get(),
                                                 true /* succeeded */);
  MarkRequestAsComplete(registration_id, request_info.get());

  registration = GetRegistration(sw_id, origin(), kExampleDeveloperId, &error);
  ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  EXPECT_EQ(registration.download_total, kResponseFileSize);

  PopNextRequest(registration_id, &request_info);
  AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get(),
                                                 true /* succeeded */);
  MarkRequestAsComplete(registration_id, request_info.get());

  registration = GetRegistration(sw_id, origin(), kExampleDeveloperId, &error);
  ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  EXPECT_EQ(registration.download_total, 2 * kResponseFileSize);

  PopNextRequest(registration_id, &request_info);
  AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get(),
                                                 false /* succeeded */);
  MarkRequestAsComplete(registration_id, request_info.get());

  registration = GetRegistration(sw_id, origin(), kExampleDeveloperId, &error);
  ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  // |download_total| is unchanged.
  EXPECT_EQ(registration.download_total, 2 * kResponseFileSize);
}

TEST_F(BackgroundFetchDataManagerTest, WriteToCache) {
  int64_t sw_id = RegisterServiceWorker();
  ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);

  BackgroundFetchRegistrationId registration_id(
      sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);
  auto requests = CreateValidRequests(origin(), 2u /* num_requests */);

  BackgroundFetchOptions options;
  blink::mojom::BackgroundFetchError error;
  {
    EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _));

    CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
    ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  }

  scoped_refptr<BackgroundFetchRequestInfo> request_info;
  PopNextRequest(registration_id, &request_info);
  ASSERT_TRUE(request_info);

  AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get(),
                                                 true /* success */);
  MarkRequestAsComplete(registration_id, request_info.get());

  EXPECT_TRUE(HasCache(kExampleUniqueId));
  EXPECT_FALSE(HasCache("foo"));

  EXPECT_TRUE(MatchCache(requests[0]));
  EXPECT_FALSE(MatchCache(requests[1]));

  PopNextRequest(registration_id, &request_info);
  ASSERT_TRUE(request_info);

  AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get(),
                                                 true /* success */);
  MarkRequestAsComplete(registration_id, request_info.get());
  EXPECT_TRUE(MatchCache(requests[0]));
  EXPECT_TRUE(MatchCache(requests[1]));

  RestartDataManagerFromPersistentStorage();
  EXPECT_TRUE(MatchCache(requests[0]));
  EXPECT_TRUE(MatchCache(requests[1]));
}

TEST_F(BackgroundFetchDataManagerTest, CacheDeleted) {
  int64_t sw_id = RegisterServiceWorker();
  ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);

  BackgroundFetchRegistrationId registration_id(
      sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);

  ServiceWorkerFetchRequest request;
  request.url = GURL(origin().GetURL().spec());

  BackgroundFetchOptions options;
  blink::mojom::BackgroundFetchError error;
  {
    EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _));

    CreateRegistration(registration_id, {request}, options, SkBitmap(), &error);
    ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  }

  scoped_refptr<BackgroundFetchRequestInfo> request_info;
  PopNextRequest(registration_id, &request_info);
  ASSERT_TRUE(request_info);

  AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get(),
                                                 true /* success */);
  MarkRequestAsComplete(registration_id, request_info.get());

  EXPECT_TRUE(HasCache(kExampleUniqueId));
  EXPECT_TRUE(MatchCache(request));

  MarkRegistrationForDeletion(registration_id, &error);
  ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  DeleteRegistration(registration_id, &error);
  EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);

  EXPECT_FALSE(HasCache(kExampleUniqueId));
}

TEST_F(BackgroundFetchDataManagerTest, GetSettledFetchesForRegistration) {
  int64_t sw_id = RegisterServiceWorker();
  ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);

  std::vector<ServiceWorkerFetchRequest> requests(2u);
  BackgroundFetchOptions options;
  blink::mojom::BackgroundFetchError error;
  BackgroundFetchRegistrationId registration_id(
      sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);

  {
    EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _));

    CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
    ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  }

  EXPECT_EQ(
      GetRequestStats(sw_id),
      (ResponseStateStats{2 /* pending_requests */, 0 /* active_requests */,
                          0 /* completed_requests */}));

  // Nothing is downloaded yet.
  bool succeeded = false;
  std::vector<BackgroundFetchSettledFetch> settled_fetches;
  GetSettledFetchesForRegistration(registration_id,
                                   base::nullopt /* request_to_match */, &error,
                                   &succeeded, &settled_fetches);
  EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  EXPECT_TRUE(succeeded);
  EXPECT_EQ(settled_fetches.size(), 0u);

  for (size_t i = 0; i < requests.size(); i++) {
    scoped_refptr<BackgroundFetchRequestInfo> request_info;
    PopNextRequest(registration_id, &request_info);
    ASSERT_TRUE(request_info);
    AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get());
    MarkRequestAsComplete(registration_id, request_info.get());
  }

  RestartDataManagerFromPersistentStorage();

  EXPECT_EQ(
      GetRequestStats(sw_id),
      (ResponseStateStats{0 /* pending_requests */, 0 /* active_requests */,
                          requests.size() /* completed_requests */}));

  GetSettledFetchesForRegistration(registration_id,
                                   base::nullopt /* request_to_match */, &error,
                                   &succeeded, &settled_fetches);

  EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  // We are marking the responses as failed in Download Manager.
  EXPECT_FALSE(succeeded);
  EXPECT_EQ(settled_fetches.size(), requests.size());
}

TEST_F(BackgroundFetchDataManagerTest, GetSettledFetchesFromCache) {
  int64_t sw_id = RegisterServiceWorker();
  ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);

  BackgroundFetchRegistrationId registration_id(
      sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);
  auto requests = CreateValidRequests(origin(), 2u /* num_requests */);

  BackgroundFetchOptions options;
  blink::mojom::BackgroundFetchError error;
  {
    EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _));

    CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
    ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  }

  bool succeeded = false;
  std::vector<BackgroundFetchSettledFetch> settled_fetches;
  // Nothing is downloaded yet.
  GetSettledFetchesForRegistration(registration_id,
                                   base::nullopt /* request_to_match */, &error,
                                   &succeeded, &settled_fetches);
  EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  EXPECT_TRUE(succeeded);
  EXPECT_EQ(settled_fetches.size(), 0u);

  scoped_refptr<BackgroundFetchRequestInfo> request_info;
  PopNextRequest(registration_id, &request_info);
  ASSERT_TRUE(request_info);
  AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get(),
                                                 true /* success */);
  MarkRequestAsComplete(registration_id, request_info.get());

  GetSettledFetchesForRegistration(registration_id,
                                   base::nullopt /* request_to_match */, &error,
                                   &succeeded, &settled_fetches);
  EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  EXPECT_TRUE(succeeded);
  EXPECT_EQ(settled_fetches.size(), 1u);

  PopNextRequest(registration_id, &request_info);
  ASSERT_TRUE(request_info);
  AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get(),
                                                 true /* success */);
  MarkRequestAsComplete(registration_id, request_info.get());

  GetSettledFetchesForRegistration(registration_id,
                                   base::nullopt /* request_to_match */, &error,
                                   &succeeded, &settled_fetches);
  EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  EXPECT_TRUE(succeeded);
  ASSERT_EQ(settled_fetches.size(), 2u);

  // Sanity check that the responses are written to / read from the cache.
  EXPECT_TRUE(MatchCache(requests[0]));
  EXPECT_TRUE(MatchCache(requests[1]));
  EXPECT_EQ(settled_fetches[0].response->cache_storage_cache_name,
            kExampleUniqueId);
  EXPECT_EQ(settled_fetches[1].response->cache_storage_cache_name,
            kExampleUniqueId);

  RestartDataManagerFromPersistentStorage();

  GetSettledFetchesForRegistration(registration_id,
                                   base::nullopt /* request_to_match */, &error,
                                   &succeeded, &settled_fetches);
  EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  EXPECT_TRUE(succeeded);
  EXPECT_EQ(settled_fetches.size(), 2u);
}

TEST_F(BackgroundFetchDataManagerTest, GetSettledFetchesForASpecificRequest) {
  int64_t sw_id = RegisterServiceWorker();
  ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);

  auto requests = CreateValidRequests(origin(), 2u /* num_requests */);
  BackgroundFetchOptions options;
  blink::mojom::BackgroundFetchError error;
  BackgroundFetchRegistrationId registration_id(
      sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);

  {
    EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _));

    CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
    ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  }

  for (size_t i = 0; i < requests.size(); i++) {
    SCOPED_TRACE(i);
    scoped_refptr<BackgroundFetchRequestInfo> request_info;
    PopNextRequest(registration_id, &request_info);
    ASSERT_TRUE(request_info);
    AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get());
    MarkRequestAsComplete(registration_id, request_info.get());
  }

  EXPECT_EQ(
      GetRequestStats(sw_id),
      (ResponseStateStats{0 /* pending_requests */, 0 /* active_requests */,
                          requests.size() /* completed_requests */}));

  bool succeeded = false;
  std::vector<BackgroundFetchSettledFetch> settled_fetches;
  GetSettledFetchesForRegistration(registration_id,
                                   requests[0] /* request_to_match */, &error,
                                   &succeeded, &settled_fetches);

  ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  // We are marking the responses as failed in Download Manager.
  EXPECT_FALSE(succeeded);
  EXPECT_EQ(settled_fetches.size(), 1u);
}

TEST_F(BackgroundFetchDataManagerTest,
       GetSettledFetchesForANonMatchingRequest) {
  int64_t sw_id = RegisterServiceWorker();
  ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);

  auto requests = CreateValidRequests(origin(), 3u /* num_requests */);
  BackgroundFetchOptions options;
  blink::mojom::BackgroundFetchError error;
  BackgroundFetchRegistrationId registration_id(
      sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);

  {
    EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _));

    CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
    ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  }

  for (size_t i = 0; i < requests.size() - 1; i++) {
    SCOPED_TRACE(i);
    scoped_refptr<BackgroundFetchRequestInfo> request_info;
    PopNextRequest(registration_id, &request_info);
    ASSERT_TRUE(request_info);
    AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get());
    MarkRequestAsComplete(registration_id, request_info.get());
  }

  EXPECT_EQ(
      GetRequestStats(sw_id),
      (ResponseStateStats{1 /* pending_requests */, 0 /* active_requests */,
                          requests.size() - 1 /* completed_requests */}));

  bool succeeded = false;
  std::vector<BackgroundFetchSettledFetch> settled_fetches;
  GetSettledFetchesForRegistration(registration_id,
                                   requests[2] /* request_to_match */, &error,
                                   &succeeded, &settled_fetches);
  ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  EXPECT_EQ(settled_fetches.size(), 1u);
  EXPECT_EQ(settled_fetches[0].response->response_type,
            network::mojom::FetchResponseType::kError);
}

TEST_F(BackgroundFetchDataManagerTest, Cleanup) {
  // Tests that the BackgroundFetchDataManager cleans up registrations
  // marked for deletion.
  int64_t sw_id = RegisterServiceWorker();
  ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);

  BackgroundFetchRegistrationId registration_id(
      sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);

  // The requests are default-initialized, but valid.
  std::vector<ServiceWorkerFetchRequest> requests(2u);
  BackgroundFetchOptions options;
  blink::mojom::BackgroundFetchError error;

  EXPECT_EQ(0u,
            GetRegistrationUserDataByKeyPrefix(sw_id, kUserDataPrefix).size());
  // Create a registration.
  {
    EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _));

    CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
    ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  }

  // We expect as many pending entries as there are requests.
  EXPECT_EQ(requests.size(),
            GetRegistrationUserDataByKeyPrefix(
                sw_id, background_fetch::kPendingRequestKeyPrefix)
                .size());

  // And deactivate it.
  MarkRegistrationForDeletion(registration_id, &error);
  ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);

  RestartDataManagerFromPersistentStorage();

  // Pending Requests should be deleted after marking a registration for
  // deletion.
  EXPECT_EQ(0u, GetRegistrationUserDataByKeyPrefix(
                    sw_id, background_fetch::kPendingRequestKeyPrefix)
                    .size());
  EXPECT_EQ(2u,  // Metadata proto + title.
            GetRegistrationUserDataByKeyPrefix(sw_id, kUserDataPrefix).size());

  // Cleanup should delete the registration.
  background_fetch_data_manager_->Cleanup();
  thread_bundle_.RunUntilIdle();
  EXPECT_EQ(0u,
            GetRegistrationUserDataByKeyPrefix(sw_id, kUserDataPrefix).size());

  RestartDataManagerFromPersistentStorage();

  // The deletion should have been persisted.
  EXPECT_EQ(0u,
            GetRegistrationUserDataByKeyPrefix(sw_id, kUserDataPrefix).size());
}

TEST_F(BackgroundFetchDataManagerTest, GetInitializationData) {
  {
    // No registered ServiceWorkers.
    std::vector<BackgroundFetchInitializationData> data =
        GetInitializationData();
    EXPECT_TRUE(data.empty());
  }

  int64_t sw_id = RegisterServiceWorker();
  ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
  {
    // Register ServiceWorker with no Background Fetch Registrations.
    std::vector<BackgroundFetchInitializationData> data =
        GetInitializationData();
    EXPECT_TRUE(data.empty());
  }

  std::vector<ServiceWorkerFetchRequest> requests(2u);
  BackgroundFetchOptions options;
  options.title = kInitialTitle;
  options.download_total = 42u;
  blink::mojom::BackgroundFetchError error;
  // Register a Background Fetch.
  BackgroundFetchRegistrationId registration_id(
      sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);

  {
    EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _));

    CreateRegistration(registration_id, requests, options, CreateTestIcon(),
                       &error);
    ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  }

  {
    std::vector<BackgroundFetchInitializationData> data =
        GetInitializationData();
    ASSERT_EQ(data.size(), 1u);
    const BackgroundFetchInitializationData& init = data[0];

    EXPECT_EQ(init.registration_id, registration_id);
    EXPECT_EQ(init.registration.unique_id, kExampleUniqueId);
    EXPECT_EQ(init.registration.developer_id, kExampleDeveloperId);
    EXPECT_EQ(init.options.title, kInitialTitle);
    EXPECT_EQ(init.options.download_total, 42u);
    EXPECT_EQ(init.ui_title, kInitialTitle);
    EXPECT_EQ(init.num_requests, requests.size());
    EXPECT_EQ(init.num_completed_requests, 0u);
    EXPECT_TRUE(init.active_fetch_requests.empty());

    // Check icon.
    ASSERT_FALSE(init.icon.drawsNothing());
    EXPECT_NO_FATAL_FAILURE(ExpectIconProperties(init.icon, 42, SK_ColorGREEN));
  }

  // Mark one request as complete and start another.
  scoped_refptr<BackgroundFetchRequestInfo> request_info;
  PopNextRequest(registration_id, &request_info);
  ASSERT_TRUE(request_info);
  AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get());
  MarkRequestAsComplete(registration_id, request_info.get());
  PopNextRequest(registration_id, &request_info);
  ASSERT_TRUE(request_info);
  {
    std::vector<BackgroundFetchInitializationData> data =
        GetInitializationData();
    ASSERT_EQ(data.size(), 1u);

    EXPECT_EQ(data[0].num_requests, requests.size());
    EXPECT_EQ(data[0].num_completed_requests, 1u);
    ASSERT_EQ(data[0].active_fetch_requests.size(), 1u);

    const auto& init_request_info = data[0].active_fetch_requests[0];
    ASSERT_TRUE(init_request_info);
    EXPECT_EQ(request_info->download_guid(),
              init_request_info->download_guid());
    EXPECT_EQ(request_info->request_index(),
              init_request_info->request_index());
    EXPECT_EQ(request_info->fetch_request().Serialize(),
              init_request_info->fetch_request().Serialize());
  }

  // Create another registration.
  BackgroundFetchRegistrationId registration_id2(
      sw_id, origin(), kAlternativeDeveloperId, kAlternativeUniqueId);
  {
    EXPECT_CALL(*this, OnRegistrationCreated(registration_id2, _, _, _, _));

    CreateRegistration(registration_id2, requests, options, SkBitmap(), &error);
    ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
  }

  {
    std::vector<BackgroundFetchInitializationData> data =
        GetInitializationData();
    ASSERT_EQ(data.size(), 2u);
  }
}

TEST_F(BackgroundFetchDataManagerTest, CreateInParallel) {
  // Tests that multiple parallel calls to the BackgroundFetchDataManager are
  // linearized and handled one at a time, rather than producing inconsistent
  // results due to interleaving.
  int64_t service_worker_registration_id = RegisterServiceWorker();
  ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId,
            service_worker_registration_id);

  std::vector<ServiceWorkerFetchRequest> requests;
  BackgroundFetchOptions options;

  std::vector<blink::mojom::BackgroundFetchError> errors(5);

  // We expect a single successful registration to be created.
  EXPECT_CALL(*this, OnRegistrationCreated(_, _, _, _, _));

  const int num_parallel_creates = 5;

  base::RunLoop run_loop;
  base::RepeatingClosure quit_once_all_finished_closure =
      base::BarrierClosure(num_parallel_creates, run_loop.QuitClosure());

  for (int i = 0; i < num_parallel_creates; i++) {
    // New |unique_id| per iteration, since each is a distinct registration.
    BackgroundFetchRegistrationId registration_id(
        service_worker_registration_id, origin(), kExampleDeveloperId,
        base::GenerateGUID());

    background_fetch_data_manager_->CreateRegistration(
        registration_id, requests, options, SkBitmap(),
        base::BindOnce(&DidCreateRegistration, quit_once_all_finished_closure,
                       &errors[i]));
  }
  run_loop.Run();

  int success_count = 0;
  int duplicated_developer_id_count = 0;
  for (auto error : errors) {
    switch (error) {
      case blink::mojom::BackgroundFetchError::NONE:
        success_count++;
        break;
      case blink::mojom::BackgroundFetchError::DUPLICATED_DEVELOPER_ID:
        duplicated_developer_id_count++;
        break;
      default:
        break;
    }
  }
  // Exactly one of the calls should have succeeded in creating a registration,
  // and all the others should have failed with DUPLICATED_DEVELOPER_ID.
  EXPECT_EQ(1, success_count);
  EXPECT_EQ(num_parallel_creates - 1, duplicated_developer_id_count);
}

TEST_F(BackgroundFetchDataManagerTest, StorageErrorsReported) {
  int64_t sw_id = RegisterServiceWorker();
  ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);

  auto requests = CreateValidRequests(origin(), 3u /* num_requests */);
  BackgroundFetchOptions options;
  blink::mojom::BackgroundFetchError error;
  BackgroundFetchRegistrationId registration_id(
      sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);

  {
    base::HistogramTester histogram_tester;
    CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
    ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
    histogram_tester.ExpectBucketCount(
        "BackgroundFetch.Storage.CreateMetadataTask", 0 /* kNone */, 1);
  }

  BackgroundFetchRegistrationId registration_id2(
      sw_id, url::Origin::Create(GURL("https://examplebad.com")),
      kAlternativeDeveloperId, kAlternativeUniqueId);

  {
    base::HistogramTester histogram_tester;
    // This should fail because the Service Worker doesn't exist.
    CreateRegistration(registration_id2, requests, options, SkBitmap(), &error);
    ASSERT_EQ(error, blink::mojom::BackgroundFetchError::STORAGE_ERROR);
    histogram_tester.ExpectBucketCount(
        "BackgroundFetch.Storage.CreateMetadataTask",
        1 /* kServiceWorkerStorageError */, 1);
  }
}

}  // namespace content
