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

#include "content/browser/service_worker/service_worker_database.h"

#include <stddef.h>
#include <stdint.h>

#include <string>

#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/test/metrics/histogram_tester.h"
#include "content/browser/service_worker/service_worker_database.pb.h"
#include "content/common/service_worker/service_worker_types.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
#include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
#include "url/origin.h"

namespace content {

namespace {

using ::testing::ElementsAreArray;
using ::testing::IsEmpty;

typedef ServiceWorkerDatabase::RegistrationData RegistrationData;
typedef ServiceWorkerDatabase::ResourceRecord Resource;

struct AvailableIds {
  int64_t reg_id;
  int64_t res_id;
  int64_t ver_id;

  AvailableIds() : reg_id(-1), res_id(-1), ver_id(-1) {}
  ~AvailableIds() {}
};

GURL URL(const GURL& origin, const std::string& path) {
  EXPECT_TRUE(origin.is_valid());
  EXPECT_EQ(origin, origin.GetOrigin());
  GURL out(origin.spec() + path);
  EXPECT_TRUE(out.is_valid());
  return out;
}

Resource CreateResource(int64_t resource_id,
                        const GURL& url,
                        uint64_t size_bytes) {
  EXPECT_TRUE(url.is_valid());
  return Resource(resource_id, url, size_bytes);
}

ServiceWorkerDatabase* CreateDatabase(const base::FilePath& path) {
  return new ServiceWorkerDatabase(path);
}

ServiceWorkerDatabase* CreateDatabaseInMemory() {
  return new ServiceWorkerDatabase(base::FilePath());
}

void VerifyRegistrationData(const RegistrationData& expected,
                            const RegistrationData& actual) {
  EXPECT_EQ(expected.registration_id, actual.registration_id);
  EXPECT_EQ(expected.scope, actual.scope);
  EXPECT_EQ(expected.script, actual.script);
  EXPECT_EQ(expected.script_type, actual.script_type);
  EXPECT_EQ(expected.update_via_cache, actual.update_via_cache);
  EXPECT_EQ(expected.version_id, actual.version_id);
  EXPECT_EQ(expected.is_active, actual.is_active);
  EXPECT_EQ(expected.has_fetch_handler, actual.has_fetch_handler);
  EXPECT_EQ(expected.last_update_check, actual.last_update_check);
  EXPECT_EQ(expected.used_features, actual.used_features);
  EXPECT_EQ(expected.resources_total_size_bytes,
            actual.resources_total_size_bytes);
}

void VerifyResourceRecords(const std::vector<Resource>& expected,
                           const std::vector<Resource>& actual) {
  ASSERT_EQ(expected.size(), actual.size());
  for (size_t i = 0; i < expected.size(); ++i) {
    EXPECT_EQ(expected[i].resource_id, actual[i].resource_id);
    EXPECT_EQ(expected[i].url, actual[i].url);
    EXPECT_EQ(expected[i].size_bytes, actual[i].size_bytes);
  }
}

}  // namespace

TEST(ServiceWorkerDatabaseTest, OpenDatabase) {
  base::ScopedTempDir database_dir;
  ASSERT_TRUE(database_dir.CreateUniqueTempDir());
  std::unique_ptr<ServiceWorkerDatabase> database(
      CreateDatabase(database_dir.GetPath()));

  // Should be false because the database does not exist at the path.
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
            database->LazyOpen(false));

  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->LazyOpen(true));

  database.reset(CreateDatabase(database_dir.GetPath()));
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->LazyOpen(false));
}

TEST(ServiceWorkerDatabaseTest, OpenDatabase_InMemory) {
  std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());

  // Should be false because the database does not exist in memory.
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
            database->LazyOpen(false));

  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->LazyOpen(true));
  database.reset(CreateDatabaseInMemory());

  // Should be false because the database is not persistent.
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
            database->LazyOpen(false));
}

TEST(ServiceWorkerDatabaseTest, DatabaseVersion_ValidSchemaVersion) {
  GURL origin("https://example.com");
  std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->LazyOpen(true));

  // Opening a new database does not write anything, so its schema version
  // should be 0.
  int64_t db_version = -1;
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->ReadDatabaseVersion(&db_version));
  EXPECT_EQ(0u, db_version);

  // First writing triggers database initialization and bumps the schema
  // version.
  std::vector<ServiceWorkerDatabase::ResourceRecord> resources;
  resources.push_back(CreateResource(1, URL(origin, "/resource"), 10));
  ServiceWorkerDatabase::RegistrationData deleted_version;
  std::vector<int64_t> newly_purgeable_resources;
  ServiceWorkerDatabase::RegistrationData data;
  data.resources_total_size_bytes = 10;
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteRegistration(
                data, resources, &deleted_version, &newly_purgeable_resources));

  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->ReadDatabaseVersion(&db_version));
  EXPECT_LT(0, db_version);
}

TEST(ServiceWorkerDatabaseTest, DatabaseVersion_ObsoleteSchemaVersion) {
  base::ScopedTempDir database_dir;
  ASSERT_TRUE(database_dir.CreateUniqueTempDir());
  std::unique_ptr<ServiceWorkerDatabase> database(
      CreateDatabase(database_dir.GetPath()));
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->LazyOpen(true));

  // First writing triggers database initialization and bumps the schema
  // version.
  GURL origin("https://example.com");
  std::vector<ServiceWorkerDatabase::ResourceRecord> resources;
  resources.push_back(CreateResource(1, URL(origin, "/resource"), 10));
  ServiceWorkerDatabase::RegistrationData deleted_version;
  std::vector<int64_t> newly_purgeable_resources;
  ServiceWorkerDatabase::RegistrationData data;
  data.resources_total_size_bytes = 10;
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteRegistration(data, resources, &deleted_version,
                                        &newly_purgeable_resources));
  int64_t db_version = -1;
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->ReadDatabaseVersion(&db_version));
  ASSERT_LT(0, db_version);

  // Emulate an obsolete schema version.
  int64_t old_db_version = 1;
  leveldb::WriteBatch batch;
  batch.Put("INITDATA_DB_VERSION", base::Int64ToString(old_db_version));
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK, database->WriteBatch(&batch));
  db_version = -1;
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->ReadDatabaseVersion(&db_version));
  ASSERT_EQ(old_db_version, db_version);

  // Opening the database whose schema version is obsolete should fail.
  database.reset(CreateDatabase(database_dir.GetPath()));
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_FAILED,
            database->LazyOpen(true));
}

TEST(ServiceWorkerDatabaseTest, DatabaseVersion_CorruptedSchemaVersion) {
  base::ScopedTempDir database_dir;
  ASSERT_TRUE(database_dir.CreateUniqueTempDir());
  std::unique_ptr<ServiceWorkerDatabase> database(
      CreateDatabase(database_dir.GetPath()));
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->LazyOpen(true));

  // First writing triggers database initialization and bumps the schema
  // version.
  GURL origin("https://example.com");
  std::vector<ServiceWorkerDatabase::ResourceRecord> resources;
  resources.push_back(CreateResource(1, URL(origin, "/resource"), 10));
  ServiceWorkerDatabase::RegistrationData deleted_version;
  std::vector<int64_t> newly_purgeable_resources;
  ServiceWorkerDatabase::RegistrationData data;
  data.resources_total_size_bytes = 10;
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteRegistration(data, resources, &deleted_version,
                                        &newly_purgeable_resources));
  int64_t db_version = -1;
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->ReadDatabaseVersion(&db_version));
  ASSERT_LT(0, db_version);

  // Emulate a corrupted schema version.
  int64_t corrupted_db_version = -10;
  leveldb::WriteBatch batch;
  batch.Put("INITDATA_DB_VERSION", base::Int64ToString(corrupted_db_version));
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK, database->WriteBatch(&batch));
  db_version = -1;
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_CORRUPTED,
            database->ReadDatabaseVersion(&db_version));

  // Opening the database whose schema version is corrupted should fail.
  database.reset(CreateDatabase(database_dir.GetPath()));
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_CORRUPTED,
            database->LazyOpen(true));
}

TEST(ServiceWorkerDatabaseTest, GetNextAvailableIds) {
  base::ScopedTempDir database_dir;
  ASSERT_TRUE(database_dir.CreateUniqueTempDir());
  std::unique_ptr<ServiceWorkerDatabase> database(
      CreateDatabase(database_dir.GetPath()));

  GURL origin("https://example.com");

  // The database has never been used, so returns initial values.
  AvailableIds ids;
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->GetNextAvailableIds(
      &ids.reg_id, &ids.ver_id, &ids.res_id));
  EXPECT_EQ(0, ids.reg_id);
  EXPECT_EQ(0, ids.ver_id);
  EXPECT_EQ(0, ids.res_id);

  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK, database->LazyOpen(true));
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->GetNextAvailableIds(
      &ids.reg_id, &ids.ver_id, &ids.res_id));
  EXPECT_EQ(0, ids.reg_id);
  EXPECT_EQ(0, ids.ver_id);
  EXPECT_EQ(0, ids.res_id);

  // Writing uncommitted resources bumps the next available resource id.
  const int64_t kUncommittedIds[] = {0, 1, 3, 5, 6, 10};
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_OK,
      database->WriteUncommittedResourceIds(std::set<int64_t>(
          kUncommittedIds, kUncommittedIds + base::size(kUncommittedIds))));
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_OK,
      database->GetNextAvailableIds(&ids.reg_id, &ids.ver_id, &ids.res_id));
  EXPECT_EQ(0, ids.reg_id);
  EXPECT_EQ(0, ids.ver_id);
  EXPECT_EQ(11, ids.res_id);

  // Writing purgeable resources bumps the next available id.
  const int64_t kPurgeableIds[] = {4, 12, 16, 17, 20};
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteUncommittedResourceIds(std::set<int64_t>(
                kPurgeableIds, kPurgeableIds + base::size(kPurgeableIds))));
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_OK,
      database->GetNextAvailableIds(&ids.reg_id, &ids.ver_id, &ids.res_id));
  EXPECT_EQ(0, ids.reg_id);
  EXPECT_EQ(0, ids.ver_id);
  EXPECT_EQ(21, ids.res_id);

  // Writing a registration bumps the next available registration and version
  // ids.
  std::vector<Resource> resources1;
  RegistrationData data1;
  ServiceWorkerDatabase::RegistrationData deleted_version;
  std::vector<int64_t> newly_purgeable_resources;
  data1.registration_id = 100;
  data1.scope = URL(origin, "/foo");
  data1.script = URL(origin, "/script1.js");
  data1.version_id = 200;
  data1.resources_total_size_bytes = 300;
  resources1.push_back(CreateResource(1, data1.script, 300));
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteRegistration(data1, resources1, &deleted_version,
                                        &newly_purgeable_resources));

  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_OK,
      database->GetNextAvailableIds(&ids.reg_id, &ids.ver_id, &ids.res_id));
  EXPECT_EQ(101, ids.reg_id);
  EXPECT_EQ(201, ids.ver_id);
  EXPECT_EQ(21, ids.res_id);

  // Writing a registration whose ids are lower than the stored ones should not
  // bump the next available ids.
  RegistrationData data2;
  data2.registration_id = 10;
  data2.scope = URL(origin, "/bar");
  data2.script = URL(origin, "/script2.js");
  data2.version_id = 20;
  data2.resources_total_size_bytes = 400;
  std::vector<Resource> resources2;
  resources2.push_back(CreateResource(2, data2.script, 400));
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteRegistration(data2, resources2, &deleted_version,
                                        &newly_purgeable_resources));

  // Same with resources.
  int64_t kLowResourceId = 15;
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteUncommittedResourceIds(
                std::set<int64_t>(&kLowResourceId, &kLowResourceId + 1)));

  // Close and reopen the database to verify the stored values.
  database.reset(CreateDatabase(database_dir.GetPath()));

  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->GetNextAvailableIds(
      &ids.reg_id, &ids.ver_id, &ids.res_id));
  EXPECT_EQ(101, ids.reg_id);
  EXPECT_EQ(201, ids.ver_id);
  EXPECT_EQ(21, ids.res_id);
}

TEST(ServiceWorkerDatabaseTest, GetOriginsWithRegistrations) {
  std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());

  std::set<GURL> origins;
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->GetOriginsWithRegistrations(&origins));
  EXPECT_TRUE(origins.empty());

  ServiceWorkerDatabase::RegistrationData deleted_version;
  std::vector<int64_t> newly_purgeable_resources;

  GURL origin1("https://example.com");
  RegistrationData data1;
  data1.registration_id = 123;
  data1.scope = URL(origin1, "/foo");
  data1.script = URL(origin1, "/script1.js");
  data1.version_id = 456;
  data1.resources_total_size_bytes = 100;
  std::vector<Resource> resources1;
  resources1.push_back(CreateResource(1, data1.script, 100));
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteRegistration(data1, resources1, &deleted_version,
                                        &newly_purgeable_resources));

  GURL origin2("https://www.example.com");
  RegistrationData data2;
  data2.registration_id = 234;
  data2.scope = URL(origin2, "/bar");
  data2.script = URL(origin2, "/script2.js");
  data2.version_id = 567;
  data2.resources_total_size_bytes = 200;
  std::vector<Resource> resources2;
  resources2.push_back(CreateResource(2, data2.script, 200));
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteRegistration(data2, resources2, &deleted_version,
                                        &newly_purgeable_resources));

  GURL origin3("https://example.org");
  RegistrationData data3;
  data3.registration_id = 345;
  data3.scope = URL(origin3, "/hoge");
  data3.script = URL(origin3, "/script3.js");
  data3.version_id = 678;
  data3.resources_total_size_bytes = 300;
  std::vector<Resource> resources3;
  resources3.push_back(CreateResource(3, data3.script, 300));
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteRegistration(data3, resources3, &deleted_version,
                                        &newly_purgeable_resources));

  // |origin3| has two registrations.
  RegistrationData data4;
  data4.registration_id = 456;
  data4.scope = URL(origin3, "/fuga");
  data4.script = URL(origin3, "/script4.js");
  data4.version_id = 789;
  data4.resources_total_size_bytes = 400;
  std::vector<Resource> resources4;
  resources4.push_back(CreateResource(4, data4.script, 400));
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteRegistration(data4, resources4, &deleted_version,
                                        &newly_purgeable_resources));

  origins.clear();
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->GetOriginsWithRegistrations(&origins));
  EXPECT_EQ(3U, origins.size());
  EXPECT_TRUE(base::ContainsKey(origins, origin1));
  EXPECT_TRUE(base::ContainsKey(origins, origin2));
  EXPECT_TRUE(base::ContainsKey(origins, origin3));

  // |origin3| has another registration, so should not remove it from the
  // unique origin list.
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->DeleteRegistration(data4.registration_id,
                                         origin3,
                                         &deleted_version,
                                         &newly_purgeable_resources));
  EXPECT_EQ(data4.registration_id, deleted_version.registration_id);

  origins.clear();
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->GetOriginsWithRegistrations(&origins));
  EXPECT_EQ(3U, origins.size());
  EXPECT_TRUE(base::ContainsKey(origins, origin1));
  EXPECT_TRUE(base::ContainsKey(origins, origin2));
  EXPECT_TRUE(base::ContainsKey(origins, origin3));

  // |origin3| should be removed from the unique origin list.
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->DeleteRegistration(data3.registration_id,
                                         origin3,
                                         &deleted_version,
                                         &newly_purgeable_resources));
  EXPECT_EQ(data3.registration_id, deleted_version.registration_id);

  origins.clear();
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->GetOriginsWithRegistrations(&origins));
  EXPECT_EQ(2U, origins.size());
  EXPECT_TRUE(base::ContainsKey(origins, origin1));
  EXPECT_TRUE(base::ContainsKey(origins, origin2));
}

TEST(ServiceWorkerDatabaseTest, GetRegistrationsForOrigin) {
  std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());

  GURL origin1("https://example.com");
  GURL origin2("https://www.example.com");
  GURL origin3("https://example.org");

  std::vector<RegistrationData> registrations;
  std::vector<std::vector<Resource>> resources_list;
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->GetRegistrationsForOrigin(origin1, &registrations,
                                                &resources_list));
  EXPECT_TRUE(registrations.empty());
  EXPECT_TRUE(resources_list.empty());

  ServiceWorkerDatabase::RegistrationData deleted_version;
  std::vector<int64_t> newly_purgeable_resources;

  RegistrationData data1;
  data1.registration_id = 100;
  data1.scope = URL(origin1, "/foo");
  data1.script = URL(origin1, "/script1.js");
  data1.version_id = 1000;
  data1.resources_total_size_bytes = 100;
  std::vector<Resource> resources1;
  resources1.push_back(CreateResource(1, data1.script, 100));
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteRegistration(data1, resources1, &deleted_version,
                                        &newly_purgeable_resources));

  registrations.clear();
  resources_list.clear();
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->GetRegistrationsForOrigin(origin1, &registrations,
                                                &resources_list));
  EXPECT_EQ(1U, registrations.size());
  VerifyRegistrationData(data1, registrations[0]);
  EXPECT_EQ(1U, resources_list.size());
  VerifyResourceRecords(resources1, resources_list[0]);

  RegistrationData data2;
  data2.registration_id = 200;
  data2.scope = URL(origin2, "/bar");
  data2.script = URL(origin2, "/script2.js");
  data2.version_id = 2000;
  data2.resources_total_size_bytes = 200;
  std::vector<Resource> resources2;
  resources2.push_back(CreateResource(2, data2.script, 200));
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteRegistration(data2, resources2, &deleted_version,
                                        &newly_purgeable_resources));

  registrations.clear();
  resources_list.clear();
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->GetRegistrationsForOrigin(origin2, &registrations,
                                                &resources_list));
  EXPECT_EQ(1U, registrations.size());
  VerifyRegistrationData(data2, registrations[0]);
  EXPECT_EQ(1U, resources_list.size());
  VerifyResourceRecords(resources2, resources_list[0]);

  RegistrationData data3;
  data3.registration_id = 300;
  data3.scope = URL(origin3, "/hoge");
  data3.script = URL(origin3, "/script3.js");
  data3.version_id = 3000;
  data3.resources_total_size_bytes = 300;
  std::vector<Resource> resources3;
  resources3.push_back(CreateResource(3, data3.script, 300));
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteRegistration(data3, resources3, &deleted_version,
                                        &newly_purgeable_resources));

  // |origin3| has two registrations.
  RegistrationData data4;
  data4.registration_id = 400;
  data4.scope = URL(origin3, "/fuga");
  data4.script = URL(origin3, "/script4.js");
  data4.version_id = 4000;
  data4.resources_total_size_bytes = 400;
  std::vector<Resource> resources4;
  resources4.push_back(CreateResource(4, data4.script, 400));
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteRegistration(data4, resources4, &deleted_version,
                                        &newly_purgeable_resources));

  registrations.clear();
  resources_list.clear();
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->GetRegistrationsForOrigin(origin3, &registrations,
                                                &resources_list));
  EXPECT_EQ(2U, registrations.size());
  VerifyRegistrationData(data3, registrations[0]);
  VerifyRegistrationData(data4, registrations[1]);
  EXPECT_EQ(2U, resources_list.size());
  VerifyResourceRecords(resources3, resources_list[0]);
  VerifyResourceRecords(resources4, resources_list[1]);

  // The third parameter |opt_resources_list| to GetRegistrationsForOrigin()
  // is optional. So, nullptr should be acceptable.
  registrations.clear();
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_OK,
      database->GetRegistrationsForOrigin(origin1, &registrations, nullptr));
  EXPECT_EQ(1U, registrations.size());
  VerifyRegistrationData(data1, registrations[0]);
}

TEST(ServiceWorkerDatabaseTest, GetAllRegistrations) {
  std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());

  std::vector<RegistrationData> registrations;
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->GetAllRegistrations(&registrations));
  EXPECT_TRUE(registrations.empty());

  ServiceWorkerDatabase::RegistrationData deleted_version;
  std::vector<int64_t> newly_purgeable_resources;

  GURL origin1("https://www1.example.com");
  RegistrationData data1;
  data1.registration_id = 100;
  data1.scope = URL(origin1, "/foo");
  data1.script = URL(origin1, "/script1.js");
  data1.version_id = 1000;
  data1.resources_total_size_bytes = 100;
  std::vector<Resource> resources1;
  resources1.push_back(CreateResource(1, data1.script, 100));
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteRegistration(data1, resources1, &deleted_version,
                                        &newly_purgeable_resources));

  GURL origin2("https://www2.example.com");
  RegistrationData data2;
  data2.registration_id = 200;
  data2.scope = URL(origin2, "/bar");
  data2.script = URL(origin2, "/script2.js");
  data2.version_id = 2000;
  data2.resources_total_size_bytes = 200;
  data2.update_via_cache = blink::mojom::ServiceWorkerUpdateViaCache::kNone;
  std::vector<Resource> resources2;
  resources2.push_back(CreateResource(2, data2.script, 200));
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteRegistration(data2, resources2, &deleted_version,
                                        &newly_purgeable_resources));

  GURL origin3("https://www3.example.com");
  RegistrationData data3;
  data3.registration_id = 300;
  data3.scope = URL(origin3, "/hoge");
  data3.script = URL(origin3, "/script3.js");
  data3.version_id = 3000;
  data3.resources_total_size_bytes = 300;
  std::vector<Resource> resources3;
  resources3.push_back(CreateResource(3, data3.script, 300));
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteRegistration(data3, resources3, &deleted_version,
                                        &newly_purgeable_resources));

  // |origin3| has two registrations.
  RegistrationData data4;
  data4.registration_id = 400;
  data4.scope = URL(origin3, "/fuga");
  data4.script = URL(origin3, "/script4.js");
  data4.version_id = 4000;
  data4.resources_total_size_bytes = 400;
  std::vector<Resource> resources4;
  resources4.push_back(CreateResource(4, data4.script, 400));
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteRegistration(data4, resources4, &deleted_version,
                                        &newly_purgeable_resources));

  registrations.clear();
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->GetAllRegistrations(&registrations));
  EXPECT_EQ(4U, registrations.size());

  VerifyRegistrationData(data1, registrations[0]);
  VerifyRegistrationData(data2, registrations[1]);
  VerifyRegistrationData(data3, registrations[2]);
  VerifyRegistrationData(data4, registrations[3]);
}

TEST(ServiceWorkerDatabaseTest, Registration_Basic) {
  std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());

  GURL origin("https://example.com");
  RegistrationData data;
  data.registration_id = 100;
  data.scope = URL(origin, "/foo");
  data.script = URL(origin, "/resource1");
  data.version_id = 200;
  data.resources_total_size_bytes = 10939 + 200;
  data.used_features = {124, 901, 1019};

  std::vector<Resource> resources;
  resources.push_back(CreateResource(1, URL(origin, "/resource1"), 10939));
  resources.push_back(CreateResource(2, URL(origin, "/resource2"), 200));

  // Write a resource to the uncommitted list to make sure that writing
  // registration removes resource ids associated with the registration from
  // the uncommitted list.
  std::set<int64_t> uncommitted_ids;
  uncommitted_ids.insert(resources[0].resource_id);
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteUncommittedResourceIds(uncommitted_ids));
  std::set<int64_t> uncommitted_ids_out;
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->GetUncommittedResourceIds(&uncommitted_ids_out));
  EXPECT_EQ(uncommitted_ids, uncommitted_ids_out);

  ServiceWorkerDatabase::RegistrationData deleted_version;
  deleted_version.version_id = 222;  // Dummy initial value
  std::vector<int64_t> newly_purgeable_resources;

  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteRegistration(
                data, resources, &deleted_version, &newly_purgeable_resources));
  EXPECT_EQ(blink::mojom::kInvalidServiceWorkerVersionId,
            deleted_version.version_id);
  EXPECT_TRUE(newly_purgeable_resources.empty());

  // Make sure that the registration and resource records are stored.
  RegistrationData data_out;
  std::vector<Resource> resources_out;
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->ReadRegistration(
                data.registration_id, origin, &data_out, &resources_out));
  VerifyRegistrationData(data, data_out);
  VerifyResourceRecords(resources, resources_out);
  GURL origin_out;
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_OK,
      database->ReadRegistrationOrigin(data.registration_id, &origin_out));
  EXPECT_EQ(origin, origin_out);

  // Make sure that the resource is removed from the uncommitted list.
  uncommitted_ids_out.clear();
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->GetUncommittedResourceIds(&uncommitted_ids_out));
  EXPECT_TRUE(uncommitted_ids_out.empty());

  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->DeleteRegistration(data.registration_id,
                                         origin,
                                         &deleted_version,
                                         &newly_purgeable_resources));
  EXPECT_EQ(data.version_id, deleted_version.version_id);
  ASSERT_EQ(resources.size(), newly_purgeable_resources.size());
  for (size_t i = 0; i < resources.size(); ++i)
    EXPECT_EQ(newly_purgeable_resources[i], resources[i].resource_id);

  // Make sure that the registration and resource records are gone.
  resources_out.clear();
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
            database->ReadRegistration(
                data.registration_id, origin, &data_out, &resources_out));
  EXPECT_TRUE(resources_out.empty());
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
      database->ReadRegistrationOrigin(data.registration_id, &origin_out));

  // Resources should be purgeable because these are no longer referred.
  std::set<int64_t> purgeable_ids_out;
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->GetPurgeableResourceIds(&purgeable_ids_out));
  EXPECT_EQ(2u, purgeable_ids_out.size());
  EXPECT_TRUE(base::ContainsKey(purgeable_ids_out, resources[0].resource_id));
  EXPECT_TRUE(base::ContainsKey(purgeable_ids_out, resources[1].resource_id));
}

TEST(ServiceWorkerDatabaseTest, DeleteNonExistentRegistration) {
  std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());

  GURL origin("https://example.com");
  RegistrationData data;
  data.registration_id = 100;
  data.scope = URL(origin, "/foo");
  data.script = URL(origin, "/resource1");
  data.version_id = 200;
  data.resources_total_size_bytes = 19 + 29129;

  std::vector<Resource> resources;
  resources.push_back(CreateResource(1, URL(origin, "/resource1"), 19));
  resources.push_back(CreateResource(2, URL(origin, "/resource2"), 29129));

  const int64_t kNonExistentRegistrationId = 999;
  const int64_t kArbitraryVersionId = 222;  // Used as a dummy initial value

  ServiceWorkerDatabase::RegistrationData deleted_version;
  deleted_version.version_id = kArbitraryVersionId;
  std::vector<int64_t> newly_purgeable_resources;
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteRegistration(
                data, resources, &deleted_version, &newly_purgeable_resources));
  EXPECT_EQ(blink::mojom::kInvalidServiceWorkerVersionId,
            deleted_version.version_id);
  EXPECT_TRUE(newly_purgeable_resources.empty());

  // Delete from an origin that has a registration.
  deleted_version.version_id = kArbitraryVersionId;
  newly_purgeable_resources.clear();
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->DeleteRegistration(kNonExistentRegistrationId,
                                         origin,
                                         &deleted_version,
                                         &newly_purgeable_resources));
  EXPECT_EQ(blink::mojom::kInvalidServiceWorkerVersionId,
            deleted_version.version_id);
  EXPECT_TRUE(newly_purgeable_resources.empty());

  // Delete from an origin that has no registration.
  deleted_version.version_id = kArbitraryVersionId;
  newly_purgeable_resources.clear();
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->DeleteRegistration(
                kNonExistentRegistrationId, GURL("https://example.net"),
                &deleted_version, &newly_purgeable_resources));
  EXPECT_EQ(blink::mojom::kInvalidServiceWorkerVersionId,
            deleted_version.version_id);
  EXPECT_TRUE(newly_purgeable_resources.empty());
}

TEST(ServiceWorkerDatabaseTest, Registration_Overwrite) {
  std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());

  GURL origin("https://example.com");
  RegistrationData data;
  data.registration_id = 100;
  data.scope = URL(origin, "/foo");
  data.script = URL(origin, "/resource1");
  data.version_id = 200;
  data.resources_total_size_bytes = 10 + 11;
  data.used_features = {124, 901, 1019};

  std::vector<Resource> resources1;
  resources1.push_back(CreateResource(1, URL(origin, "/resource1"), 10));
  resources1.push_back(CreateResource(2, URL(origin, "/resource2"), 11));

  ServiceWorkerDatabase::RegistrationData deleted_version;
  deleted_version.version_id = 222;  // Dummy inital value
  std::vector<int64_t> newly_purgeable_resources;

  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_OK,
      database->WriteRegistration(
          data, resources1, &deleted_version, &newly_purgeable_resources));
  EXPECT_EQ(blink::mojom::kInvalidServiceWorkerVersionId,
            deleted_version.version_id);
  EXPECT_TRUE(newly_purgeable_resources.empty());

  // Make sure that the registration and resource records are stored.
  RegistrationData data_out;
  std::vector<Resource> resources_out;
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->ReadRegistration(
      data.registration_id, origin, &data_out, &resources_out));
  VerifyRegistrationData(data, data_out);
  VerifyResourceRecords(resources1, resources_out);

  // Update the registration.
  RegistrationData updated_data = data;
  updated_data.script = URL(origin, "/resource3");
  updated_data.version_id = data.version_id + 1;
  updated_data.resources_total_size_bytes = 12 + 13;
  updated_data.used_features = {109, 421, 9101};
  updated_data.script_type = blink::mojom::ScriptType::kModule;
  updated_data.update_via_cache =
      blink::mojom::ServiceWorkerUpdateViaCache::kAll;
  std::vector<Resource> resources2;
  resources2.push_back(CreateResource(3, URL(origin, "/resource3"), 12));
  resources2.push_back(CreateResource(4, URL(origin, "/resource4"), 13));

  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteRegistration(updated_data,
                                        resources2,
                                        &deleted_version,
                                        &newly_purgeable_resources));
  EXPECT_EQ(data.version_id, deleted_version.version_id);
  ASSERT_EQ(resources1.size(), newly_purgeable_resources.size());
  for (size_t i = 0; i < resources1.size(); ++i)
    EXPECT_EQ(newly_purgeable_resources[i], resources1[i].resource_id);

  // Make sure that |updated_data| is stored and resources referred from |data|
  // is moved to the purgeable list.
  resources_out.clear();
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->ReadRegistration(
      updated_data.registration_id, origin, &data_out, &resources_out));
  VerifyRegistrationData(updated_data, data_out);
  VerifyResourceRecords(resources2, resources_out);

  std::set<int64_t> purgeable_ids_out;
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->GetPurgeableResourceIds(&purgeable_ids_out));
  EXPECT_EQ(2u, purgeable_ids_out.size());
  EXPECT_TRUE(base::ContainsKey(purgeable_ids_out, resources1[0].resource_id));
  EXPECT_TRUE(base::ContainsKey(purgeable_ids_out, resources1[1].resource_id));
}

TEST(ServiceWorkerDatabaseTest, Registration_Multiple) {
  std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
  GURL origin("https://example.com");

  ServiceWorkerDatabase::RegistrationData deleted_version;
  std::vector<int64_t> newly_purgeable_resources;

  // Add registration1.
  RegistrationData data1;
  data1.registration_id = 100;
  data1.scope = URL(origin, "/foo");
  data1.script = URL(origin, "/resource1");
  data1.version_id = 200;
  data1.resources_total_size_bytes = 1451 + 15234;

  std::vector<Resource> resources1;
  resources1.push_back(CreateResource(1, URL(origin, "/resource1"), 1451));
  resources1.push_back(CreateResource(2, URL(origin, "/resource2"), 15234));
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_OK,
      database->WriteRegistration(
          data1, resources1, &deleted_version, &newly_purgeable_resources));

  // Add registration2.
  RegistrationData data2;
  data2.registration_id = 101;
  data2.scope = URL(origin, "/bar");
  data2.script = URL(origin, "/resource3");
  data2.version_id = 201;
  data2.resources_total_size_bytes = 5 + 6;

  std::vector<Resource> resources2;
  resources2.push_back(CreateResource(3, URL(origin, "/resource3"), 5));
  resources2.push_back(CreateResource(4, URL(origin, "/resource4"), 6));
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_OK,
      database->WriteRegistration(
          data2, resources2, &deleted_version, &newly_purgeable_resources));

  // Make sure that registration1 is stored.
  RegistrationData data_out;
  std::vector<Resource> resources_out;
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->ReadRegistration(
      data1.registration_id, origin, &data_out, &resources_out));
  VerifyRegistrationData(data1, data_out);
  VerifyResourceRecords(resources1, resources_out);
  GURL origin_out;
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_OK,
      database->ReadRegistrationOrigin(data1.registration_id, &origin_out));
  EXPECT_EQ(origin, origin_out);

  // Make sure that registration2 is also stored.
  resources_out.clear();
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->ReadRegistration(
      data2.registration_id, origin, &data_out, &resources_out));
  VerifyRegistrationData(data2, data_out);
  VerifyResourceRecords(resources2, resources_out);
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_OK,
      database->ReadRegistrationOrigin(data2.registration_id, &origin_out));
  EXPECT_EQ(origin, origin_out);

  std::set<int64_t> purgeable_ids_out;
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->GetPurgeableResourceIds(&purgeable_ids_out));
  EXPECT_TRUE(purgeable_ids_out.empty());

  // Delete registration1.
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->DeleteRegistration(data1.registration_id,
                                         origin,
                                         &deleted_version,
                                         &newly_purgeable_resources));
  EXPECT_EQ(data1.registration_id, deleted_version.registration_id);

  // Make sure that registration1 is gone.
  resources_out.clear();
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
            database->ReadRegistration(
                data1.registration_id, origin, &data_out, &resources_out));
  EXPECT_TRUE(resources_out.empty());
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
      database->ReadRegistrationOrigin(data1.registration_id, &origin_out));

  purgeable_ids_out.clear();
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->GetPurgeableResourceIds(&purgeable_ids_out));
  EXPECT_EQ(2u, purgeable_ids_out.size());
  EXPECT_TRUE(base::ContainsKey(purgeable_ids_out, resources1[0].resource_id));
  EXPECT_TRUE(base::ContainsKey(purgeable_ids_out, resources1[1].resource_id));

  // Make sure that registration2 is still alive.
  resources_out.clear();
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->ReadRegistration(
      data2.registration_id, origin, &data_out, &resources_out));
  VerifyRegistrationData(data2, data_out);
  VerifyResourceRecords(resources2, resources_out);
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_OK,
      database->ReadRegistrationOrigin(data2.registration_id, &origin_out));
  EXPECT_EQ(origin, origin_out);
}

TEST(ServiceWorkerDatabaseTest, Registration_UninitializedDatabase) {
  std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
  const GURL origin("https://example.com");

  // Should be failed because the database does not exist.
  RegistrationData data_out;
  std::vector<Resource> resources_out;
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
            database->ReadRegistration(
                100, origin, &data_out, &resources_out));
  EXPECT_EQ(blink::mojom::kInvalidServiceWorkerRegistrationId,
            data_out.registration_id);
  EXPECT_TRUE(resources_out.empty());
  GURL origin_out;
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
            database->ReadRegistrationOrigin(100, &origin_out));

  // Deleting non-existent registration should succeed.
  RegistrationData deleted_version;
  std::vector<int64_t> newly_purgeable_resources;
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->DeleteRegistration(
                100, origin, &deleted_version, &newly_purgeable_resources));
  EXPECT_EQ(blink::mojom::kInvalidServiceWorkerVersionId,
            deleted_version.version_id);
  EXPECT_TRUE(newly_purgeable_resources.empty());

  // Actually create a new database, but not initialized yet.
  database->LazyOpen(true);

  // Should be failed because the database is not initialized.
  ASSERT_EQ(ServiceWorkerDatabase::DATABASE_STATE_UNINITIALIZED,
            database->state_);
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
            database->ReadRegistration(
                100, origin, &data_out, &resources_out));
  EXPECT_EQ(blink::mojom::kInvalidServiceWorkerRegistrationId,
            data_out.registration_id);
  EXPECT_TRUE(resources_out.empty());
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
            database->ReadRegistrationOrigin(100, &origin_out));

  // Deleting non-existent registration should succeed.
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->DeleteRegistration(
                100, origin, &deleted_version, &newly_purgeable_resources));
  EXPECT_EQ(blink::mojom::kInvalidServiceWorkerVersionId,
            deleted_version.version_id);
  EXPECT_TRUE(newly_purgeable_resources.empty());
}

TEST(ServiceWorkerDatabaseTest, Registration_ScriptType) {
  std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());

  ServiceWorkerDatabase::RegistrationData deleted_version;
  std::vector<int64_t> newly_purgeable_resources;

  // Default script type.
  GURL origin1("https://www1.example.com");
  RegistrationData data1;
  data1.registration_id = 100;
  data1.scope = URL(origin1, "/foo");
  data1.script = URL(origin1, "/resource1");
  data1.version_id = 100;
  data1.resources_total_size_bytes = 10 + 10000;
  EXPECT_EQ(blink::mojom::ScriptType::kClassic, data1.script_type);
  std::vector<Resource> resources1;
  resources1.push_back(CreateResource(1, URL(origin1, "/resource1"), 10));
  resources1.push_back(CreateResource(2, URL(origin1, "/resource2"), 10000));
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteRegistration(data1, resources1, &deleted_version,
                                        &newly_purgeable_resources));

  // Classic script type.
  GURL origin2("https://www2.example.com");
  RegistrationData data2;
  data2.registration_id = 200;
  data2.scope = URL(origin2, "/bar");
  data2.script = URL(origin2, "/resource3");
  data2.version_id = 200;
  data2.resources_total_size_bytes = 20 + 20000;
  data2.script_type = blink::mojom::ScriptType::kClassic;
  std::vector<Resource> resources2;
  resources2.push_back(CreateResource(3, URL(origin2, "/resource3"), 20));
  resources2.push_back(CreateResource(4, URL(origin2, "/resource4"), 20000));
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteRegistration(data2, resources2, &deleted_version,
                                        &newly_purgeable_resources));

  // Module script type.
  GURL origin3("https://www3.example.com");
  RegistrationData data3;
  data3.registration_id = 300;
  data3.scope = URL(origin3, "/baz");
  data3.script = URL(origin3, "/resource5");
  data3.version_id = 300;
  data3.resources_total_size_bytes = 30 + 30000;
  data3.script_type = blink::mojom::ScriptType::kModule;
  std::vector<Resource> resources3;
  resources3.push_back(CreateResource(5, URL(origin3, "/resource5"), 30));
  resources3.push_back(CreateResource(6, URL(origin3, "/resource6"), 30000));
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteRegistration(data3, resources3, &deleted_version,
                                        &newly_purgeable_resources));

  RegistrationData data;
  std::vector<Resource> resources;
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->ReadRegistration(data1.registration_id, origin1, &data,
                                       &resources));
  VerifyRegistrationData(data1, data);
  VerifyResourceRecords(resources1, resources);
  EXPECT_EQ(2U, resources.size());
  resources.clear();

  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->ReadRegistration(data2.registration_id, origin2, &data,
                                       &resources));
  VerifyRegistrationData(data2, data);
  VerifyResourceRecords(resources2, resources);
  EXPECT_EQ(2U, resources.size());
  resources.clear();

  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->ReadRegistration(data3.registration_id, origin3, &data,
                                       &resources));
  VerifyRegistrationData(data3, data);
  VerifyResourceRecords(resources3, resources);
  EXPECT_EQ(2U, resources.size());
  resources.clear();
}

TEST(ServiceWorkerDatabaseTest, UserData_Basic) {
  std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
  const GURL kOrigin("https://example.com");

  // Add a registration.
  RegistrationData data;
  data.registration_id = 100;
  data.scope = URL(kOrigin, "/foo");
  data.script = URL(kOrigin, "/script.js");
  data.version_id = 200;
  data.resources_total_size_bytes = 100;
  std::vector<Resource> resources;
  resources.push_back(CreateResource(1, data.script, 100));
  ServiceWorkerDatabase::RegistrationData deleted_version;
  std::vector<int64_t> newly_purgeable_resources;
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteRegistration(
                data, resources, &deleted_version, &newly_purgeable_resources));

  // Write user data associated with the stored registration.
  std::vector<std::string> user_data_out;
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteUserData(data.registration_id, kOrigin,
                                    {{"key1", "data"}}));
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_OK,
      database->ReadUserData(data.registration_id, {"key1"}, &user_data_out));
  ASSERT_EQ(1u, user_data_out.size());
  EXPECT_EQ("data", user_data_out[0]);

  // Writing user data not associated with the stored registration should be
  // failed.
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
            database->WriteUserData(300, kOrigin, {{"key1", "data"}}));

  // Write empty user data for a different key.
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteUserData(data.registration_id, kOrigin,
                                    {{"key2", std::string()}}));
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_OK,
      database->ReadUserData(data.registration_id, {"key2"}, &user_data_out));
  ASSERT_EQ(1u, user_data_out.size());
  EXPECT_EQ(std::string(), user_data_out[0]);
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_OK,
      database->ReadUserData(data.registration_id, {"key1"}, &user_data_out));
  ASSERT_EQ(1u, user_data_out.size());
  EXPECT_EQ("data", user_data_out[0]);

  // Overwrite the existing user data.
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteUserData(data.registration_id, kOrigin,
                                    {{"key1", "overwrite"}}));
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_OK,
      database->ReadUserData(data.registration_id, {"key1"}, &user_data_out));
  ASSERT_EQ(1u, user_data_out.size());
  EXPECT_EQ("overwrite", user_data_out[0]);

  // Delete the user data.
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->DeleteUserData(data.registration_id, {"key1"}));
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
      database->ReadUserData(data.registration_id, {"key1"}, &user_data_out));
  EXPECT_TRUE(user_data_out.empty());
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_OK,
      database->ReadUserData(data.registration_id, {"key2"}, &user_data_out));
  ASSERT_EQ(1u, user_data_out.size());
  EXPECT_EQ(std::string(), user_data_out[0]);

  // Write/overwrite multiple user data keys.
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_OK,
      database->WriteUserData(
          data.registration_id, kOrigin,
          {{"key2", "overwrite2"}, {"key3", "data3"}, {"key4", "data4"}}));
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
      database->ReadUserData(data.registration_id, {"key1"}, &user_data_out));
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->ReadUserData(data.registration_id,
                                   {"key2", "key3", "key4"}, &user_data_out));
  ASSERT_EQ(3u, user_data_out.size());
  EXPECT_EQ("overwrite2", user_data_out[0]);
  EXPECT_EQ("data3", user_data_out[1]);
  EXPECT_EQ("data4", user_data_out[2]);
  // Multiple reads fail if one is not found.
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
            database->ReadUserData(data.registration_id, {"key2", "key1"},
                                   &user_data_out));
  EXPECT_TRUE(user_data_out.empty());

  // Delete multiple user data keys, even if some are not found.
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_OK,
      database->DeleteUserData(data.registration_id, {"key1", "key2", "key3"}));
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
      database->ReadUserData(data.registration_id, {"key1"}, &user_data_out));
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
      database->ReadUserData(data.registration_id, {"key2"}, &user_data_out));
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
      database->ReadUserData(data.registration_id, {"key3"}, &user_data_out));
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_OK,
      database->ReadUserData(data.registration_id, {"key4"}, &user_data_out));
  ASSERT_EQ(1u, user_data_out.size());
  EXPECT_EQ("data4", user_data_out[0]);
}

TEST(ServiceWorkerDatabaseTest,
     UserData_ReadUserDataForAllRegistrationsByKeyPrefix) {
  std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
  const GURL kOrigin("https://example.com");

  // Add registration 1.
  RegistrationData data1;
  data1.registration_id = 100;
  data1.scope = URL(kOrigin, "/foo");
  data1.script = URL(kOrigin, "/script1.js");
  data1.version_id = 200;
  data1.resources_total_size_bytes = 100;
  std::vector<Resource> resources1;
  resources1.push_back(CreateResource(1, data1.script, 100));

  // Add registration 2.
  RegistrationData data2;
  data2.registration_id = 101;
  data2.scope = URL(kOrigin, "/bar");
  data2.script = URL(kOrigin, "/script2.js");
  data2.version_id = 201;
  data2.resources_total_size_bytes = 200;
  std::vector<Resource> resources2;
  resources2.push_back(CreateResource(2, data2.script, 200));

  ServiceWorkerDatabase::RegistrationData deleted_version;
  std::vector<int64_t> newly_purgeable_resources;
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteRegistration(data1, resources1, &deleted_version,
                                        &newly_purgeable_resources));
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteRegistration(data2, resources2, &deleted_version,
                                        &newly_purgeable_resources));

  // Write user data associated with the registration1.
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteUserData(data1.registration_id, kOrigin,
                                    {{"key_prefix:key1", "value1"}}));
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteUserData(data1.registration_id, kOrigin,
                                    {{"key_prefix:key2", "value2"}}));
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteUserData(data1.registration_id, kOrigin,
                                    {{"key_prefix:key3", "value3"}}));

  // Write user data associated with the registration2.
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteUserData(data2.registration_id, kOrigin,
                                    {{"key_prefix:key1", "value1"}}));
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteUserData(data2.registration_id, kOrigin,
                                    {{"key_prefix:key2", "value2"}}));
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteUserData(data2.registration_id, kOrigin,
                                    {{"another_key_prefix:key1", "value1"}}));
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteUserData(data2.registration_id, kOrigin,
                                    {{"another_key_prefix:key2", "value2"}}));

  // Get all registrations with user data by key prefix.
  std::vector<std::pair<int64_t, std::string>> user_data_list;
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->ReadUserDataForAllRegistrationsByKeyPrefix(
                "key_prefix:", &user_data_list));
  ASSERT_EQ(5u, user_data_list.size());

  EXPECT_EQ(data1.registration_id, user_data_list[0].first);
  EXPECT_EQ("value1", user_data_list[0].second);
  EXPECT_EQ(data2.registration_id, user_data_list[1].first);
  EXPECT_EQ("value1", user_data_list[1].second);
  EXPECT_EQ(data1.registration_id, user_data_list[2].first);
  EXPECT_EQ("value2", user_data_list[2].second);
  EXPECT_EQ(data2.registration_id, user_data_list[3].first);
  EXPECT_EQ("value2", user_data_list[3].second);
  EXPECT_EQ(data1.registration_id, user_data_list[4].first);
  EXPECT_EQ("value3", user_data_list[4].second);
}

TEST(ServiceWorkerDatabaseTest, ReadUserDataByKeyPrefix) {
  std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
  const GURL kOrigin("https://example.com");

  // Add a registration.
  RegistrationData data;
  data.registration_id = 100;
  data.scope = URL(kOrigin, "/foo");
  data.script = URL(kOrigin, "/script.js");
  data.version_id = 200;
  data.resources_total_size_bytes = 100;
  std::vector<Resource> resources;
  resources.push_back(CreateResource(1, data.script, 100));
  ServiceWorkerDatabase::RegistrationData deleted_version;
  std::vector<int64_t> newly_purgeable_resources;
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteRegistration(data, resources, &deleted_version,
                                        &newly_purgeable_resources));

  // Write user data associated with the registration.
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteUserData(data.registration_id, kOrigin,
                                    {{"key_prefix:key1", "value_c1"},
                                     {"key_prefix:key2", "value_c2"},
                                     {"other_key_prefix:k1", "value_d1"},
                                     {"other_key_prefix:k2", "value_d2"}}));

  std::vector<std::string> user_data;
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->ReadUserDataByKeyPrefix(data.registration_id,
                                              "bogus_prefix:", &user_data));
  EXPECT_THAT(user_data, IsEmpty());

  user_data.clear();
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->ReadUserDataByKeyPrefix(data.registration_id,
                                              "key_prefix:", &user_data));
  EXPECT_THAT(user_data, ElementsAreArray({"value_c1", "value_c2"}));

  user_data.clear();
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->ReadUserDataByKeyPrefix(data.registration_id,
                                              "other_key_prefix:", &user_data));
  EXPECT_THAT(user_data, ElementsAreArray({"value_d1", "value_d2"}));
}

TEST(ServiceWorkerDatabaseTest, ReadUserKeysAndDataByKeyPrefix) {
  std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
  const GURL kOrigin("https://example.com");

  // Add a registration.
  RegistrationData data;
  data.registration_id = 100;
  data.scope = URL(kOrigin, "/foo");
  data.script = URL(kOrigin, "/script.js");
  data.version_id = 200;
  data.resources_total_size_bytes = 100;
  std::vector<Resource> resources;
  resources.push_back(CreateResource(1, data.script, 100));
  ServiceWorkerDatabase::RegistrationData deleted_version;
  std::vector<int64_t> newly_purgeable_resources;
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteRegistration(data, resources, &deleted_version,
                                        &newly_purgeable_resources));

  // Write user data associated with the registration.
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteUserData(data.registration_id, kOrigin,
                                    {{"key_prefix:key1", "value_c1"},
                                     {"key_prefix:key2", "value_c2"},
                                     {"other_key_prefix:k1", "value_d1"},
                                     {"other_key_prefix:k2", "value_d2"}}));

  base::flat_map<std::string, std::string> user_data_map;
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->ReadUserKeysAndDataByKeyPrefix(
                data.registration_id, "bogus_prefix:", &user_data_map));
  EXPECT_THAT(user_data_map, IsEmpty());

  user_data_map.clear();
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->ReadUserKeysAndDataByKeyPrefix(
                data.registration_id, "key_prefix:", &user_data_map));
  EXPECT_THAT(user_data_map,
              ElementsAreArray(std::vector<std::pair<std::string, std::string>>{
                  {"key1", "value_c1"}, {"key2", "value_c2"}}));

  user_data_map.clear();
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->ReadUserKeysAndDataByKeyPrefix(
                data.registration_id, "other_key_prefix:", &user_data_map));
  EXPECT_THAT(user_data_map,
              ElementsAreArray(std::vector<std::pair<std::string, std::string>>{
                  {"k1", "value_d1"}, {"k2", "value_d2"}}));
}

TEST(ServiceWorkerDatabaseTest, UserData_DeleteUserDataByKeyPrefixes) {
  std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
  const GURL kOrigin("https://example.com");

  // Add registration 1.
  RegistrationData data1;
  data1.registration_id = 100;
  data1.scope = URL(kOrigin, "/foo");
  data1.script = URL(kOrigin, "/script1.js");
  data1.version_id = 200;
  data1.resources_total_size_bytes = 100;
  std::vector<Resource> resources1;
  resources1.push_back(CreateResource(1, data1.script, 100));

  // Add registration 2.
  RegistrationData data2;
  data2.registration_id = 101;
  data2.scope = URL(kOrigin, "/bar");
  data2.script = URL(kOrigin, "/script2.js");
  data2.version_id = 201;
  data2.resources_total_size_bytes = 200;
  std::vector<Resource> resources2;
  resources2.push_back(CreateResource(2, data2.script, 200));

  ServiceWorkerDatabase::RegistrationData deleted_version;
  std::vector<int64_t> newly_purgeable_resources;
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteRegistration(data1, resources1, &deleted_version,
                                        &newly_purgeable_resources));
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteRegistration(data2, resources2, &deleted_version,
                                        &newly_purgeable_resources));

  // Write user data associated with registration 1.
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteUserData(data1.registration_id, kOrigin,
                                    {{"key_prefix:key1", "value_a1"},
                                     {"key_prefix:key2", "value_a2"},
                                     {"key_prefix:key3", "value_a3"},
                                     {"kept_key_prefix:key1", "value_b1"}}));

  // Write user data associated with registration 2.
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteUserData(data2.registration_id, kOrigin,
                                    {{"key_prefix:key1", "value_c1"},
                                     {"key_prefix:key2", "value_c2"},
                                     {"other_key_prefix:key1", "value_d1"},
                                     {"other_key_prefix:key2", "value_d2"},
                                     {"kept_key_prefix:key1", "value_e1"},
                                     {"kept_key_prefix:key2", "value_e2"}}));

  // Deleting user data by key prefixes should return STATUS_OK (rather than
  // STATUS_ERROR_NOT_FOUND) even if no keys match the prefixes and so nothing
  // is deleted.
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->DeleteUserDataByKeyPrefixes(
                data2.registration_id,
                {"not_found_key_prefix1:", "not_found_key_prefix2:"}));

  // Actually delete user data by key prefixes for registration 2.
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->DeleteUserDataByKeyPrefixes(
                data2.registration_id,
                {"key_prefix:", "other_key_prefix:", "not_found_key_prefix:"}));

  // User data with deleted "key_prefix:" should only remain for registration 1.
  std::vector<std::pair<int64_t, std::string>> user_data_list;
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->ReadUserDataForAllRegistrationsByKeyPrefix(
                "key_prefix:", &user_data_list));
  ASSERT_EQ(3u, user_data_list.size());
  EXPECT_EQ(data1.registration_id, user_data_list[0].first);
  EXPECT_EQ("value_a1", user_data_list[0].second);
  EXPECT_EQ(data1.registration_id, user_data_list[1].first);
  EXPECT_EQ("value_a2", user_data_list[1].second);
  EXPECT_EQ(data1.registration_id, user_data_list[2].first);
  EXPECT_EQ("value_a3", user_data_list[2].second);

  // User data for second deleted key prefix should also have been deleted.
  user_data_list.clear();
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->ReadUserDataForAllRegistrationsByKeyPrefix(
                "other_key_prefix:", &user_data_list));
  ASSERT_EQ(0u, user_data_list.size());

  // User data with "kept_key_prefix:" that was not deleted should remain on
  // both registrations.
  user_data_list.clear();
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->ReadUserDataForAllRegistrationsByKeyPrefix(
                "kept_key_prefix:", &user_data_list));
  ASSERT_EQ(3u, user_data_list.size());
  EXPECT_EQ(data1.registration_id, user_data_list[0].first);
  EXPECT_EQ("value_b1", user_data_list[0].second);
  EXPECT_EQ(data2.registration_id, user_data_list[1].first);
  EXPECT_EQ("value_e1", user_data_list[1].second);
  EXPECT_EQ(data2.registration_id, user_data_list[2].first);
  EXPECT_EQ("value_e2", user_data_list[2].second);
}

TEST(ServiceWorkerDatabaseTest, UserData_DataIsolation) {
  std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
  const GURL kOrigin("https://example.com");

  // Add registration 1.
  RegistrationData data1;
  data1.registration_id = 100;
  data1.scope = URL(kOrigin, "/foo");
  data1.script = URL(kOrigin, "/script1.js");
  data1.version_id = 200;
  data1.resources_total_size_bytes = 100;
  std::vector<Resource> resources1;
  resources1.push_back(CreateResource(1, data1.script, 100));

  // Add registration 2.
  RegistrationData data2;
  data2.registration_id = 101;
  data2.scope = URL(kOrigin, "/bar");
  data2.script = URL(kOrigin, "/script2.js");
  data2.version_id = 201;
  data2.resources_total_size_bytes = 200;
  data2.update_via_cache = blink::mojom::ServiceWorkerUpdateViaCache::kImports;
  std::vector<Resource> resources2;
  resources2.push_back(CreateResource(2, data2.script, 200));

  ServiceWorkerDatabase::RegistrationData deleted_version;
  std::vector<int64_t> newly_purgeable_resources;
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteRegistration(data1, resources1, &deleted_version,
                                        &newly_purgeable_resources));
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteRegistration(data2, resources2, &deleted_version,
                                        &newly_purgeable_resources));

  // Write user data associated with the registration1.
  std::vector<std::string> user_data_out;
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteUserData(data1.registration_id, kOrigin,
                                    {{"key", "data1"}}));
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_OK,
      database->ReadUserData(data1.registration_id, {"key"}, &user_data_out));
  ASSERT_EQ(1u, user_data_out.size());
  EXPECT_EQ("data1", user_data_out[0]);
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
      database->ReadUserData(data2.registration_id, {"key"}, &user_data_out));

  // Write user data associated with the registration2. This shouldn't overwrite
  // the data associated with registration1.
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteUserData(data2.registration_id, kOrigin,
                                    {{"key", "data2"}}));
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_OK,
      database->ReadUserData(data1.registration_id, {"key"}, &user_data_out));
  ASSERT_EQ(1u, user_data_out.size());
  EXPECT_EQ("data1", user_data_out[0]);
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_OK,
      database->ReadUserData(data2.registration_id, {"key"}, &user_data_out));
  ASSERT_EQ(1u, user_data_out.size());
  EXPECT_EQ("data2", user_data_out[0]);

  // Get all registrations with user data.
  std::vector<std::pair<int64_t, std::string>> user_data_list;
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->ReadUserDataForAllRegistrations("key", &user_data_list));
  EXPECT_EQ(2u, user_data_list.size());
  EXPECT_EQ(data1.registration_id, user_data_list[0].first);
  EXPECT_EQ("data1", user_data_list[0].second);
  EXPECT_EQ(data2.registration_id, user_data_list[1].first);
  EXPECT_EQ("data2", user_data_list[1].second);

  // Delete the data associated with the registration2. This shouldn't delete
  // the data associated with registration1.
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->DeleteUserData(data2.registration_id, {"key"}));
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_OK,
      database->ReadUserData(data1.registration_id, {"key"}, &user_data_out));
  ASSERT_EQ(1u, user_data_out.size());
  EXPECT_EQ("data1", user_data_out[0]);
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
      database->ReadUserData(data2.registration_id, {"key"}, &user_data_out));

  // And again get all registrations with user data.
  user_data_list.clear();
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->ReadUserDataForAllRegistrations("key", &user_data_list));
  EXPECT_EQ(1u, user_data_list.size());
  EXPECT_EQ(data1.registration_id, user_data_list[0].first);
  EXPECT_EQ("data1", user_data_list[0].second);
}

TEST(ServiceWorkerDatabaseTest, UserData_DeleteRegistration) {
  std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
  const GURL kOrigin("https://example.com");

  // Add registration 1.
  RegistrationData data1;
  data1.registration_id = 100;
  data1.scope = URL(kOrigin, "/foo");
  data1.script = URL(kOrigin, "/script1.js");
  data1.version_id = 200;
  data1.resources_total_size_bytes = 100;
  std::vector<Resource> resources1;
  resources1.push_back(CreateResource(1, data1.script, 100));

  // Add registration 2.
  RegistrationData data2;
  data2.registration_id = 101;
  data2.scope = URL(kOrigin, "/bar");
  data2.script = URL(kOrigin, "/script2.js");
  data2.version_id = 201;
  data2.resources_total_size_bytes = 200;
  std::vector<Resource> resources2;
  resources2.push_back(CreateResource(2, data2.script, 200));

  ServiceWorkerDatabase::RegistrationData deleted_version;
  std::vector<int64_t> newly_purgeable_resources;
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteRegistration(data1, resources1, &deleted_version,
                                        &newly_purgeable_resources));
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteRegistration(data2, resources2, &deleted_version,
                                        &newly_purgeable_resources));

  // Write user data associated with the registration1.
  std::vector<std::string> user_data_out;
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteUserData(data1.registration_id, kOrigin,
                                    {{"key1", "data1"}}));
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteUserData(data1.registration_id, kOrigin,
                                    {{"key2", "data2"}}));
  ASSERT_EQ(
      ServiceWorkerDatabase::STATUS_OK,
      database->ReadUserData(data1.registration_id, {"key1"}, &user_data_out));
  ASSERT_EQ(1u, user_data_out.size());
  ASSERT_EQ("data1", user_data_out[0]);
  ASSERT_EQ(
      ServiceWorkerDatabase::STATUS_OK,
      database->ReadUserData(data1.registration_id, {"key2"}, &user_data_out));
  ASSERT_EQ(1u, user_data_out.size());
  ASSERT_EQ("data2", user_data_out[0]);

  // Write user data associated with the registration2.
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteUserData(data2.registration_id, kOrigin,
                                    {{"key3", "data3"}}));
  ASSERT_EQ(
      ServiceWorkerDatabase::STATUS_OK,
      database->ReadUserData(data2.registration_id, {"key3"}, &user_data_out));
  ASSERT_EQ(1u, user_data_out.size());
  ASSERT_EQ("data3", user_data_out[0]);

  // Delete all data associated with the registration1. This shouldn't delete
  // the data associated with registration2.
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->DeleteRegistration(
                data1.registration_id, kOrigin,
                &deleted_version, &newly_purgeable_resources));
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
      database->ReadUserData(data1.registration_id, {"key1"}, &user_data_out));
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
      database->ReadUserData(data1.registration_id, {"key2"}, &user_data_out));
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_OK,
      database->ReadUserData(data2.registration_id, {"key3"}, &user_data_out));
  ASSERT_EQ(1u, user_data_out.size());
  EXPECT_EQ("data3", user_data_out[0]);
}

TEST(ServiceWorkerDatabaseTest, UserData_UninitializedDatabase) {
  std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
  const GURL kOrigin("https://example.com");

  // Should be failed because the database does not exist.
  std::vector<std::string> user_data_out;
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
            database->ReadUserData(100, {"key"}, &user_data_out));

  // Should be failed because the associated registration does not exist.
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
            database->WriteUserData(100, kOrigin, {{"key", "data"}}));

  // Deleting non-existent entry should succeed.
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->DeleteUserData(100, {"key"}));

  // Actually create a new database, but not initialized yet.
  database->LazyOpen(true);

  // Should be failed because the database is not initialized.
  ASSERT_EQ(ServiceWorkerDatabase::DATABASE_STATE_UNINITIALIZED,
            database->state_);
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
            database->ReadUserData(100, {"key"}, &user_data_out));
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
            database->WriteUserData(100, kOrigin, {{"key", "data"}}));

  // Deleting non-existent entry should succeed.
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->DeleteUserData(100, {"key"}));
}

TEST(ServiceWorkerDatabaseTest, UpdateVersionToActive) {
  std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
  GURL origin("https://example.com");

  ServiceWorkerDatabase::RegistrationData deleted_version;
  std::vector<int64_t> newly_purgeable_resources;

  // Should be false because a registration does not exist.
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
            database->UpdateVersionToActive(0, origin));

  // Add a registration.
  RegistrationData data;
  data.registration_id = 100;
  data.scope = URL(origin, "/foo");
  data.script = URL(origin, "/script.js");
  data.version_id = 200;
  data.is_active = false;
  data.resources_total_size_bytes = 100;
  std::vector<Resource> resources;
  resources.push_back(CreateResource(1, data.script, 100));
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteRegistration(data, resources, &deleted_version,
                                        &newly_purgeable_resources));

  // Make sure that the registration is stored.
  RegistrationData data_out;
  std::vector<Resource> resources_out;
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->ReadRegistration(
                data.registration_id, origin, &data_out, &resources_out));
  VerifyRegistrationData(data, data_out);
  EXPECT_EQ(1u, resources_out.size());

  // Activate the registration.
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->UpdateVersionToActive(data.registration_id, origin));

  // Make sure that the registration is activated.
  resources_out.clear();
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->ReadRegistration(
                data.registration_id, origin, &data_out, &resources_out));
  RegistrationData expected_data = data;
  expected_data.is_active = true;
  VerifyRegistrationData(expected_data, data_out);
  EXPECT_EQ(1u, resources_out.size());

  // Delete the registration.
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->DeleteRegistration(data.registration_id,
                                         origin,
                                         &deleted_version,
                                         &newly_purgeable_resources));
  EXPECT_EQ(data.registration_id, deleted_version.registration_id);

  // Should be false because the registration is gone.
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
            database->UpdateVersionToActive(data.registration_id, origin));
}

TEST(ServiceWorkerDatabaseTest, UpdateLastCheckTime) {
  std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
  GURL origin("https://example.com");
  ServiceWorkerDatabase::RegistrationData deleted_version;
  std::vector<int64_t> newly_purgeable_resources;

  // Should be false because a registration does not exist.
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
            database->UpdateLastCheckTime(0, origin, base::Time::Now()));

  // Add a registration.
  RegistrationData data;
  data.registration_id = 100;
  data.scope = URL(origin, "/foo");
  data.script = URL(origin, "/script.js");
  data.version_id = 200;
  data.last_update_check = base::Time::Now();
  data.resources_total_size_bytes = 100;
  std::vector<Resource> resources;
  resources.push_back(CreateResource(1, data.script, 100));
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteRegistration(data, resources, &deleted_version,
                                        &newly_purgeable_resources));

  // Make sure that the registration is stored.
  RegistrationData data_out;
  std::vector<Resource> resources_out;
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->ReadRegistration(
                data.registration_id, origin, &data_out, &resources_out));
  VerifyRegistrationData(data, data_out);
  EXPECT_EQ(1u, resources_out.size());

  // Update the last check time.
  base::Time updated_time = base::Time::Now();
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->UpdateLastCheckTime(
                data.registration_id, origin, updated_time));

  // Make sure that the registration is updated.
  resources_out.clear();
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->ReadRegistration(
                data.registration_id, origin, &data_out, &resources_out));
  RegistrationData expected_data = data;
  expected_data.last_update_check = updated_time;
  VerifyRegistrationData(expected_data, data_out);
  EXPECT_EQ(1u, resources_out.size());

  // Delete the registration.
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->DeleteRegistration(data.registration_id,
                                         origin,
                                         &deleted_version,
                                         &newly_purgeable_resources));
  EXPECT_EQ(data.registration_id, deleted_version.registration_id);

  // Should be false because the registration is gone.
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
            database->UpdateLastCheckTime(
                data.registration_id, origin, base::Time::Now()));
}

TEST(ServiceWorkerDatabaseTest, UncommittedAndPurgeableResourceIds) {
  std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());

  // Write {1, 2, 3} into the uncommitted list.
  std::set<int64_t> ids1;
  ids1.insert(1);
  ids1.insert(2);
  ids1.insert(3);
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteUncommittedResourceIds(ids1));

  std::set<int64_t> ids_out;
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->GetUncommittedResourceIds(&ids_out));
  EXPECT_EQ(ids1, ids_out);

  // Write {2, 4} into the uncommitted list.
  std::set<int64_t> ids2;
  ids2.insert(2);
  ids2.insert(4);
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteUncommittedResourceIds(ids2));

  ids_out.clear();
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->GetUncommittedResourceIds(&ids_out));
  std::set<int64_t> expected = base::STLSetUnion<std::set<int64_t>>(ids1, ids2);
  EXPECT_EQ(expected, ids_out);

  // Move {2, 4} from the uncommitted list to the purgeable list.
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->PurgeUncommittedResourceIds(ids2));
  ids_out.clear();
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->GetPurgeableResourceIds(&ids_out));
  EXPECT_EQ(ids2, ids_out);

  // Delete {2, 4} from the purgeable list.
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->ClearPurgeableResourceIds(ids2));
  ids_out.clear();
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->GetPurgeableResourceIds(&ids_out));
  EXPECT_TRUE(ids_out.empty());

  // {1, 3} should be still in the uncommitted list.
  ids_out.clear();
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->GetUncommittedResourceIds(&ids_out));
  expected = base::STLSetDifference<std::set<int64_t>>(ids1, ids2);
  EXPECT_EQ(expected, ids_out);
}

TEST(ServiceWorkerDatabaseTest, DeleteAllDataForOrigin) {
  std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
  ServiceWorkerDatabase::RegistrationData deleted_version;
  std::vector<int64_t> newly_purgeable_resources;

  // Data associated with |origin1| will be removed.
  GURL origin1("https://example.com");
  GURL origin2("https://example.org");

  // |origin1| has two registrations (registration1 and registration2).
  RegistrationData data1;
  data1.registration_id = 10;
  data1.scope = URL(origin1, "/foo");
  data1.script = URL(origin1, "/resource1");
  data1.version_id = 100;
  data1.resources_total_size_bytes = 2013 + 512;

  std::vector<Resource> resources1;
  resources1.push_back(CreateResource(1, URL(origin1, "/resource1"), 2013));
  resources1.push_back(CreateResource(2, URL(origin1, "/resource2"), 512));
  ASSERT_EQ(
      ServiceWorkerDatabase::STATUS_OK,
      database->WriteRegistration(
          data1, resources1, &deleted_version, &newly_purgeable_resources));
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteUserData(data1.registration_id, origin1,
                                    {{"key1", "data1"}}));
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteUserData(data1.registration_id, origin1,
                                    {{"key2", "data2"}}));

  RegistrationData data2;
  data2.registration_id = 11;
  data2.scope = URL(origin1, "/bar");
  data2.script = URL(origin1, "/resource3");
  data2.version_id = 101;
  data2.resources_total_size_bytes = 4 + 5;

  std::vector<Resource> resources2;
  resources2.push_back(CreateResource(3, URL(origin1, "/resource3"), 4));
  resources2.push_back(CreateResource(4, URL(origin1, "/resource4"), 5));
  ASSERT_EQ(
      ServiceWorkerDatabase::STATUS_OK,
      database->WriteRegistration(
          data2, resources2, &deleted_version, &newly_purgeable_resources));
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteUserData(data2.registration_id, origin1,
                                    {{"key3", "data3"}}));
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteUserData(data2.registration_id, origin1,
                                    {{"key4", "data4"}}));

  // |origin2| has one registration (registration3).
  RegistrationData data3;
  data3.registration_id = 12;
  data3.scope = URL(origin2, "/hoge");
  data3.script = URL(origin2, "/resource5");
  data3.version_id = 102;
  data3.resources_total_size_bytes = 6 + 7;

  std::vector<Resource> resources3;
  resources3.push_back(CreateResource(5, URL(origin2, "/resource5"), 6));
  resources3.push_back(CreateResource(6, URL(origin2, "/resource6"), 7));
  ASSERT_EQ(
      ServiceWorkerDatabase::STATUS_OK,
      database->WriteRegistration(
          data3, resources3, &deleted_version, &newly_purgeable_resources));
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteUserData(data3.registration_id, origin2,
                                    {{"key5", "data5"}}));
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteUserData(data3.registration_id, origin2,
                                    {{"key6", "data6"}}));

  std::set<GURL> origins_to_delete;
  origins_to_delete.insert(origin1);
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->DeleteAllDataForOrigins(origins_to_delete,
                                              &newly_purgeable_resources));

  // |origin1| should be removed from the unique origin list.
  std::set<GURL> unique_origins;
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->GetOriginsWithRegistrations(&unique_origins));
  EXPECT_EQ(1u, unique_origins.size());
  EXPECT_TRUE(base::ContainsKey(unique_origins, origin2));

  // The registrations for |origin1| should be removed.
  std::vector<RegistrationData> registrations;
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_OK,
      database->GetRegistrationsForOrigin(origin1, &registrations, nullptr));
  EXPECT_TRUE(registrations.empty());
  GURL origin_out;
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
      database->ReadRegistrationOrigin(data1.registration_id, &origin_out));

  // The registration for |origin2| should not be removed.
  RegistrationData data_out;
  std::vector<Resource> resources_out;
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->ReadRegistration(
      data3.registration_id, origin2, &data_out, &resources_out));
  VerifyRegistrationData(data3, data_out);
  VerifyResourceRecords(resources3, resources_out);
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_OK,
      database->ReadRegistrationOrigin(data3.registration_id, &origin_out));
  EXPECT_EQ(origin2, origin_out);

  // The resources associated with |origin1| should be purgeable.
  std::set<int64_t> purgeable_ids_out;
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->GetPurgeableResourceIds(&purgeable_ids_out));
  EXPECT_EQ(4u, purgeable_ids_out.size());
  EXPECT_TRUE(base::ContainsKey(purgeable_ids_out, 1));
  EXPECT_TRUE(base::ContainsKey(purgeable_ids_out, 2));
  EXPECT_TRUE(base::ContainsKey(purgeable_ids_out, 3));
  EXPECT_TRUE(base::ContainsKey(purgeable_ids_out, 4));

  // The user data associated with |origin1| should be removed.
  std::vector<std::string> user_data_out;
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
      database->ReadUserData(data1.registration_id, {"key1"}, &user_data_out));
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
      database->ReadUserData(data1.registration_id, {"key2"}, &user_data_out));
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
      database->ReadUserData(data2.registration_id, {"key3"}, &user_data_out));
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
      database->ReadUserData(data2.registration_id, {"key4"}, &user_data_out));

  // The user data associated with |origin2| should not be removed.
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_OK,
      database->ReadUserData(data3.registration_id, {"key5"}, &user_data_out));
  ASSERT_EQ(1u, user_data_out.size());
  EXPECT_EQ("data5", user_data_out[0]);
  EXPECT_EQ(
      ServiceWorkerDatabase::STATUS_OK,
      database->ReadUserData(data3.registration_id, {"key6"}, &user_data_out));
  ASSERT_EQ(1u, user_data_out.size());
  EXPECT_EQ("data6", user_data_out[0]);
}

TEST(ServiceWorkerDatabaseTest, DestroyDatabase) {
  base::ScopedTempDir database_dir;
  ASSERT_TRUE(database_dir.CreateUniqueTempDir());
  std::unique_ptr<ServiceWorkerDatabase> database(
      CreateDatabase(database_dir.GetPath()));

  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->LazyOpen(true));
  ASSERT_TRUE(base::DirectoryExists(database_dir.GetPath()));

  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->DestroyDatabase());
  ASSERT_FALSE(base::DirectoryExists(database_dir.GetPath()));
}

TEST(ServiceWorkerDatabaseTest, Corruption_NoMainResource) {
  std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
  ServiceWorkerDatabase::RegistrationData deleted_version;
  std::vector<int64_t> newly_purgeable_resources;

  GURL origin("https://example.com");

  RegistrationData data;
  data.registration_id = 10;
  data.scope = URL(origin, "/foo");
  data.script = URL(origin, "/resource1");
  data.version_id = 100;
  data.resources_total_size_bytes = 2016;

  // Simulate that "/resource1" wasn't correctly written in the database by not
  // adding it.
  std::vector<Resource> resources;
  resources.push_back(CreateResource(2, URL(origin, "/resource2"), 2016));

  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteRegistration(data, resources, &deleted_version,
                                        &newly_purgeable_resources));

  // The database should detect lack of the main resource (i.e. "/resource1").
  RegistrationData data_out;
  std::vector<Resource> resources_out;
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_CORRUPTED,
            database->ReadRegistration(data.registration_id, origin, &data_out,
                                       &resources_out));
  EXPECT_TRUE(resources_out.empty());
}

// Tests that GetRegistrationsForOrigin() detects corruption without crashing.
// It must delete the database after freeing the iterator it uses to read all
// registrations. Regression test for https://crbug.com/909024.
TEST(ServiceWorkerDatabaseTest, Corruption_GetRegistrationsForOrigin) {
  std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
  ServiceWorkerDatabase::RegistrationData deleted_version;
  std::vector<int64_t> newly_purgeable_resources;
  std::vector<Resource> resources;
  GURL origin("https://example.com");

  // Write a normal registration.
  RegistrationData data1;
  data1.registration_id = 1;
  data1.scope = URL(origin, "/foo");
  data1.script = URL(origin, "/resource1");
  data1.version_id = 1;
  data1.resources_total_size_bytes = 2016;
  resources = {CreateResource(1, URL(origin, "/resource1"), 2016)};
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteRegistration(data1, resources, &deleted_version,
                                        &newly_purgeable_resources));

  // Write a corrupt registration.
  RegistrationData data2;
  data2.registration_id = 2;
  data2.scope = URL(origin, "/foo");
  data2.script = URL(origin, "/resource2");
  data2.version_id = 2;
  data2.resources_total_size_bytes = 2016;
  // Simulate that "/resource2" wasn't correctly written in the database by
  // not adding it.
  resources = {CreateResource(3, URL(origin, "/resource3"), 2016)};
  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
            database->WriteRegistration(data2, resources, &deleted_version,
                                        &newly_purgeable_resources));

  // Call GetRegistrationsForOrigin(). It should detect corruption, and not
  // crash.
  base::HistogramTester histogram_tester;
  std::vector<RegistrationData> registrations;
  std::vector<std::vector<ServiceWorkerDatabase::ResourceRecord>>
      resources_list;
  EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_CORRUPTED,
            database->GetRegistrationsForOrigin(origin, &registrations,
                                                &resources_list));
  EXPECT_TRUE(registrations.empty());
  EXPECT_TRUE(resources_list.empty());

  // There should be three "read" operations logged:
  // 1. Reading all registration data.
  // 2. Reading the resources of the first registration.
  // 3. Reading the resources of the second registration. This one fails.
  histogram_tester.ExpectTotalCount("ServiceWorker.Database.ReadResult", 3);
  histogram_tester.ExpectBucketCount("ServiceWorker.Database.ReadResult",
                                     ServiceWorkerDatabase::STATUS_OK, 2);
  histogram_tester.ExpectBucketCount(
      "ServiceWorker.Database.ReadResult",
      ServiceWorkerDatabase::STATUS_ERROR_CORRUPTED, 1);
}

}  // namespace content
