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

#include "content/browser/media/cdm_storage_database.h"

#include <stdint.h>

#include <string>
#include <vector>

#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
#include "base/functional/callback_helpers.h"
#include "base/test/metrics/histogram_tester.h"
#include "content/public/browser/browsing_data_filter_builder.h"
#include "media/cdm/cdm_type.h"
#include "sql/database.h"
#include "sql/meta_table.h"
#include "sql/statement.h"
#include "sql/test/test_helpers.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/storage_key/storage_key.h"

namespace content {

namespace {

const media::CdmType kCdmType{1234, 5678};

const char kFileName[] = "file.txt";
const char kFileNameTwo[] = "file2.txt";

const std::vector<uint8_t> kPopulatedFileValue = {1, 2, 3};
const std::vector<uint8_t> kPopulatedFileValueTwo = {1, 2, 3, 4};
const std::vector<uint8_t> kPopulatedFileValueThree = {1, 2, 3, 4, 5};
}  // namespace

class CdmStorageDatabaseTest : public testing::Test {
 public:
  CdmStorageDatabaseTest() = default;
  ~CdmStorageDatabaseTest() override = default;

  void SetUp() override { ASSERT_TRUE(profile_path_.CreateUniqueTempDir()); }

 protected:
  const blink::StorageKey kTestStorageKey =
      blink::StorageKey::CreateFromStringForTesting("https://example.com/");
  const blink::StorageKey kTestStorageKeyTwo =
      blink::StorageKey::CreateFromStringForTesting("https://exampletwo.com/");

  std::unique_ptr<CdmStorageDatabase> cdm_storage_database_;

  void SetUpDatabase(base::FilePath file_path) {
    cdm_storage_database_ = std::make_unique<CdmStorageDatabase>(file_path);
  }

  base::ScopedTempDir profile_path_;

  base::HistogramTester histogram_tester_;
};

// This class is to test for when db_.Open() fails.
class CdmStorageDatabaseInvalidOpenTest : public CdmStorageDatabaseTest {
 public:
  void SetUp() override {
    ASSERT_TRUE(profile_path_.CreateUniqueTempDir());
    SetUpDatabase(profile_path_.GetPath());
  }

  void TearDown() override { ASSERT_TRUE(profile_path_.Delete()); }
};

// This class tests the CdmStorageDatabase when the path is empty.
class CdmStorageDatabaseInMemoryTest : public CdmStorageDatabaseTest {
 public:
  void SetUp() override { SetUpDatabase(base::FilePath()); }
};

// This class tests the CdmStorageDatabase with the CdmStorage path.
class CdmStorageDatabaseValidPathTest : public CdmStorageDatabaseTest {
 public:
  void SetUp() override {
    ASSERT_TRUE(profile_path_.CreateUniqueTempDir());
    const base::FilePath cdm_storage_path =
        profile_path_.GetPath().Append(kCdmStorageDatabaseFileName);
    SetUpDatabase(cdm_storage_path);
  }

  void TearDown() override {
    cdm_storage_database_->ClearDatabase();
    ASSERT_TRUE(profile_path_.Delete());
  }
};

class MockCdmStorageDatabaseV1 {
 public:
  // The database will be in-memory if `path` is empty.
  explicit MockCdmStorageDatabaseV1()
      : db_(sql::DatabaseOptions().set_page_size(32768).set_cache_size(8),
            sql::test::kTestTag) {}
  ~MockCdmStorageDatabaseV1() = default;

  void OpenDatabase(const base::FilePath& path) {
    ASSERT_TRUE(db_.Open(path));

    sql::MetaTable meta_table;
    ASSERT_TRUE(meta_table.Init(&db_, 1, 1));

    // Set up the table.
    static constexpr char kCreateTableSql[] =
        // clang-format off
      "CREATE TABLE IF NOT EXISTS cdm_storage("
          "storage_key TEXT NOT NULL,"
          "cdm_type BLOB NOT NULL,"
          "file_name TEXT NOT NULL,"
          "data BLOB NOT NULL,"
          "PRIMARY KEY(storage_key,cdm_type,file_name))";
    // clang-format on

    ASSERT_TRUE(db_.Execute(kCreateTableSql));
  }

  void WriteFile(const blink::StorageKey& storage_key,
                 const media::CdmType& cdm_type,
                 const std::string& file_name,
                 const std::vector<uint8_t>& data) {
    // clang-format off
    static constexpr char kInsertSql[] =
      "INSERT OR REPLACE INTO "
         "cdm_storage(storage_key,cdm_type,file_name,data) "
         "VALUES(?,?,?,?) ";
    // clang-format on

    sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, kInsertSql));
    statement.BindString(0, storage_key.Serialize());
    statement.BindBlob(1, cdm_type.AsBytes());
    statement.BindString(2, file_name);
    statement.BindBlob(3, data);
    ASSERT_TRUE(statement.Run());
  }

  void CloseDatabase() { db_.Close(); }

 private:
  // Empty if the database is in-memory.
  sql::Database db_;
};

// This class is to test for the migration from v1 to v2 of the
// CdmStorageDatabase.
class CdmStorageDatabaseV1Test : public CdmStorageDatabaseTest {
 public:
  void SetUp() override {
    ASSERT_TRUE(profile_path_.CreateUniqueTempDir());
    const base::FilePath cdm_storage_path =
        profile_path_.GetPath().Append(kCdmStorageDatabaseFileName);
    SetUpDatabase(cdm_storage_path);
    cdm_storage_database_v1_ = std::make_unique<MockCdmStorageDatabaseV1>();
    SetUpV1Database(cdm_storage_path);
  }

  void SetUpV1Database(const base::FilePath& path) {
    cdm_storage_database_v1_->OpenDatabase(path);
    cdm_storage_database_v1_->WriteFile(kTestStorageKey, kCdmType, kFileName,
                                        kPopulatedFileValue);
    cdm_storage_database_v1_->WriteFile(kTestStorageKeyTwo, kCdmType,
                                        kFileNameTwo, kPopulatedFileValueTwo);
    cdm_storage_database_v1_->CloseDatabase();
  }

  void TearDown() override {
    ASSERT_TRUE(cdm_storage_database_->ClearDatabase());
    ASSERT_TRUE(profile_path_.Delete());
  }

 private:
  std::unique_ptr<MockCdmStorageDatabaseV1> cdm_storage_database_v1_;
};

// Update this test and follow CdmStorageDatabaseV1Test when V3 comes out.
class CdmStorageDatabaseV2Test : public CdmStorageDatabaseTest {
 public:
  void SetUp() override {
    ASSERT_TRUE(profile_path_.CreateUniqueTempDir());
    const base::FilePath cdm_storage_path =
        profile_path_.GetPath().Append(kCdmStorageDatabaseFileName);
    SetUpDatabase(cdm_storage_path);
    SetUpV2Database();
  }

  void SetUpV2Database() {
    cdm_storage_database_->WriteFile(kTestStorageKey, kCdmType, kFileName,
                                     kPopulatedFileValue);
    cdm_storage_database_->WriteFile(kTestStorageKeyTwo, kCdmType, kFileNameTwo,
                                     kPopulatedFileValueTwo);
  }

  void TearDown() override {
    ASSERT_TRUE(cdm_storage_database_->ClearDatabase());
    ASSERT_TRUE(profile_path_.Delete());
  }
};

TEST_F(CdmStorageDatabaseV1Test, V1Works) {
  EXPECT_EQ(
      cdm_storage_database_->ReadFile(kTestStorageKey, kCdmType, kFileName),
      kPopulatedFileValue);
  EXPECT_EQ(cdm_storage_database_->ReadFile(kTestStorageKeyTwo, kCdmType,
                                            kFileNameTwo),
            kPopulatedFileValueTwo);
}

TEST_F(CdmStorageDatabaseV1Test, V1UpgradeWorks) {
  // Although it should be 6, when upgrading from v1->v2, we ALTER to add the
  // file_size column, and set the default as one. When the CDM rewrites to the
  // same file, the file_size will be updated to the proper value.
  EXPECT_EQ(cdm_storage_database_->GetSizeForTimeFrame(base::Time::Min(),
                                                       base::Time::Max()),
            2u);

  EXPECT_TRUE(cdm_storage_database_->WriteFile(kTestStorageKey, kCdmType,
                                               kFileName, kPopulatedFileValue));
  // Now that we have written the same value to one of the files, we see that
  // the size is now equivalent to 3 (the size of kPopulatedFileValue) + 1,
  // which is 4.
  EXPECT_EQ(cdm_storage_database_->GetSizeForTimeFrame(base::Time::Min(),
                                                       base::Time::Max()),
            4u);

  EXPECT_EQ(cdm_storage_database_->GetSizeForStorageKey(
                kTestStorageKeyTwo, base::Time::Min(), base::Time::Max()),
            1u);
  EXPECT_EQ(cdm_storage_database_->GetSizeForFile(kTestStorageKeyTwo, kCdmType,
                                                  kFileNameTwo),
            1u);

  cdm_storage_database_->CloseDatabaseForTesting();

  EXPECT_TRUE(cdm_storage_database_->WriteFile(kTestStorageKey, kCdmType,
                                               kFileName, kPopulatedFileValue));

  EXPECT_EQ(cdm_storage_database_->GetSizeForFile(kTestStorageKey, kCdmType,
                                                  kFileName),
            kPopulatedFileValue.size());
}

TEST_F(CdmStorageDatabaseV2Test, V2Works) {
  EXPECT_EQ(
      cdm_storage_database_->ReadFile(kTestStorageKey, kCdmType, kFileName),
      kPopulatedFileValue);
  EXPECT_EQ(cdm_storage_database_->ReadFile(kTestStorageKeyTwo, kCdmType,
                                            kFileNameTwo),
            kPopulatedFileValueTwo);
  EXPECT_EQ(cdm_storage_database_->GetSizeForTimeFrame(base::Time::Min(),
                                                       base::Time::Max()),
            kPopulatedFileValue.size() + kPopulatedFileValueTwo.size());

  EXPECT_EQ(cdm_storage_database_->GetSizeForStorageKey(
                kTestStorageKeyTwo, base::Time::Min(), base::Time::Max()),
            kPopulatedFileValueTwo.size());
  EXPECT_EQ(cdm_storage_database_->GetSizeForFile(kTestStorageKeyTwo, kCdmType,
                                                  kFileNameTwo),
            kPopulatedFileValueTwo.size());
}

TEST_F(CdmStorageDatabaseInvalidOpenTest, EnsureOpenFails) {
  auto error = cdm_storage_database_->EnsureOpen();

  // The database cannot be opened in a temporary directory, as it requires to
  // be opened at a file, thus we get an SQL open error. We return this as a
  // `kDatabaseOpenError`.
  EXPECT_EQ(error, CdmStorageOpenError::kDatabaseOpenError);
}

TEST_F(CdmStorageDatabaseInMemoryTest, EnsureOpenWithoutErrors) {
  auto error = cdm_storage_database_->EnsureOpen();

  EXPECT_EQ(error, CdmStorageOpenError::kOk);
}

TEST_F(CdmStorageDatabaseInMemoryTest, FileManipulation) {
  EXPECT_TRUE(cdm_storage_database_->WriteFile(kTestStorageKey, kCdmType,
                                               kFileName, kPopulatedFileValue));

  EXPECT_EQ(
      cdm_storage_database_->ReadFile(kTestStorageKey, kCdmType, kFileName),
      kPopulatedFileValue);

  EXPECT_TRUE(
      cdm_storage_database_->DeleteFile(kTestStorageKey, kCdmType, kFileName));

  EXPECT_TRUE(
      cdm_storage_database_->ReadFile(kTestStorageKey, kCdmType, kFileName)
          ->empty());
}

TEST_F(CdmStorageDatabaseInMemoryTest, DeleteDatabase) {
  EXPECT_TRUE(cdm_storage_database_->WriteFile(kTestStorageKey, kCdmType,
                                               kFileName, kPopulatedFileValue));

  EXPECT_TRUE(cdm_storage_database_->ClearDatabase());

  auto error = cdm_storage_database_->EnsureOpen();

  EXPECT_EQ(error, CdmStorageOpenError::kOk);

  EXPECT_TRUE(
      cdm_storage_database_->ReadFile(kTestStorageKey, kCdmType, kFileName)
          ->empty());
}

TEST_F(CdmStorageDatabaseInMemoryTest, DeleteForStorageKey) {
  auto time_now = base::Time::Now();

  EXPECT_TRUE(cdm_storage_database_->WriteFile(kTestStorageKey, kCdmType,
                                               kFileName, kPopulatedFileValue));
  EXPECT_TRUE(cdm_storage_database_->WriteFile(
      kTestStorageKey, kCdmType, kFileNameTwo, kPopulatedFileValue));

  EXPECT_TRUE(cdm_storage_database_->WriteFile(kTestStorageKeyTwo, kCdmType,
                                               kFileName, kPopulatedFileValue));
  EXPECT_TRUE(cdm_storage_database_->WriteFile(
      kTestStorageKeyTwo, kCdmType, kFileNameTwo, kPopulatedFileValueTwo));

  EXPECT_EQ(
      cdm_storage_database_->ReadFile(kTestStorageKey, kCdmType, kFileName),
      kPopulatedFileValue);
  EXPECT_EQ(
      cdm_storage_database_->ReadFile(kTestStorageKey, kCdmType, kFileNameTwo),
      kPopulatedFileValue);

  EXPECT_EQ(
      cdm_storage_database_->ReadFile(kTestStorageKeyTwo, kCdmType, kFileName),
      kPopulatedFileValue);
  EXPECT_EQ(cdm_storage_database_->ReadFile(kTestStorageKeyTwo, kCdmType,
                                            kFileNameTwo),
            kPopulatedFileValueTwo);

  EXPECT_TRUE(cdm_storage_database_->DeleteData(
      base::NullCallback(), kTestStorageKey, time_now, base::Time::Max()));

  // Expect that for the storage key, all of the file content returned is empty.
  EXPECT_TRUE(
      cdm_storage_database_->ReadFile(kTestStorageKey, kCdmType, kFileName)
          ->empty());
  EXPECT_TRUE(
      cdm_storage_database_->ReadFile(kTestStorageKey, kCdmType, kFileNameTwo)
          ->empty());

  // Expect that its not deleted for other storage keys.
  EXPECT_EQ(
      cdm_storage_database_->ReadFile(kTestStorageKeyTwo, kCdmType, kFileName),
      kPopulatedFileValue);
  EXPECT_EQ(cdm_storage_database_->ReadFile(kTestStorageKeyTwo, kCdmType,
                                            kFileNameTwo),
            kPopulatedFileValueTwo);
}

TEST_F(CdmStorageDatabaseInMemoryTest, DeleteForStorageKeyWithNoData) {
  auto time_now = base::Time::Now();

  // Even if there is no data for the storage key, the SQL statement should
  // still run properly.
  EXPECT_TRUE(cdm_storage_database_->DeleteData(
      base::NullCallback(), kTestStorageKey, time_now, base::Time::Max()));

  EXPECT_TRUE(
      cdm_storage_database_->ReadFile(kTestStorageKey, kCdmType, kFileName)
          ->empty());
}

TEST_F(CdmStorageDatabaseInMemoryTest,
       DeleteForTimeFrameMultipleFilesAndStorageKeysTimeFrame) {
  auto time_now = base::Time::Now();

  EXPECT_TRUE(cdm_storage_database_->WriteFile(kTestStorageKey, kCdmType,
                                               kFileName, kPopulatedFileValue));
  EXPECT_TRUE(cdm_storage_database_->WriteFile(
      kTestStorageKey, kCdmType, kFileNameTwo, kPopulatedFileValueTwo));

  EXPECT_TRUE(cdm_storage_database_->WriteFile(
      kTestStorageKeyTwo, kCdmType, kFileNameTwo, kPopulatedFileValueThree));

  EXPECT_EQ(
      cdm_storage_database_->GetSizeForTimeFrame(time_now, base::Time::Max()),
      kPopulatedFileValue.size() + kPopulatedFileValueTwo.size() +
          kPopulatedFileValueThree.size());

  EXPECT_TRUE(cdm_storage_database_->DeleteData(
      base::NullCallback(), blink::StorageKey(), time_now, base::Time::Max()));

  EXPECT_TRUE(
      cdm_storage_database_->ReadFile(kTestStorageKey, kCdmType, kFileName)
          ->empty());

  EXPECT_TRUE(
      cdm_storage_database_->ReadFile(kTestStorageKey, kCdmType, kFileNameTwo)
          ->empty());

  EXPECT_TRUE(cdm_storage_database_
                  ->ReadFile(kTestStorageKeyTwo, kCdmType, kFileNameTwo)
                  ->empty());

  EXPECT_EQ(
      cdm_storage_database_->GetSizeForTimeFrame(time_now, base::Time::Max()),
      0u);

  EXPECT_EQ(cdm_storage_database_->GetSizeForTimeFrame(base::Time::Min(),
                                                       base::Time::Max()),
            0u);
}

TEST_F(CdmStorageDatabaseInMemoryTest, DeleteForTimeFrameWithNoData) {
  EXPECT_EQ(cdm_storage_database_->GetSizeForTimeFrame(base::Time::Min(),
                                                       base::Time::Max()),
            0u);

  // Even if there is no data for the storage key, the SQL statement should
  // still run properly.
  EXPECT_TRUE(cdm_storage_database_->DeleteData(
      base::NullCallback(), blink::StorageKey(), base::Time::Min(),
      base::Time::Max()));
}

TEST_F(CdmStorageDatabaseInMemoryTest, WriteFileForBigData) {
  std::vector<uint8_t> big_data;
  big_data.resize(1000000);

  EXPECT_TRUE(cdm_storage_database_->WriteFile(kTestStorageKey, kCdmType,
                                               kFileName, big_data));

  histogram_tester_.ExpectTotalCount(
      "Media.EME.CdmStorageDatabase.WriteFileForBigData", 1);

  EXPECT_EQ(
      cdm_storage_database_->ReadFile(kTestStorageKey, kCdmType, kFileName),
      big_data);
}

TEST_F(CdmStorageDatabaseInMemoryTest, GetUsageForFile) {
  EXPECT_TRUE(cdm_storage_database_->WriteFile(kTestStorageKey, kCdmType,
                                               kFileName, kPopulatedFileValue));

  EXPECT_EQ(cdm_storage_database_->GetSizeForFile(kTestStorageKey, kCdmType,
                                                  kFileName),
            kPopulatedFileValue.size());
}

TEST_F(CdmStorageDatabaseInMemoryTest, GetUsageForNonExistentFile) {
  EXPECT_TRUE(cdm_storage_database_->WriteFile(kTestStorageKey, kCdmType,
                                               kFileName, kPopulatedFileValue));

  EXPECT_EQ(cdm_storage_database_->GetSizeForFile(kTestStorageKeyTwo, kCdmType,
                                                  kFileName),
            0u);
}

TEST_F(CdmStorageDatabaseInMemoryTest, GetUsageForStorageKey) {
  auto time_now = base::Time::Now();

  EXPECT_TRUE(cdm_storage_database_->WriteFile(kTestStorageKey, kCdmType,
                                               kFileName, kPopulatedFileValue));

  EXPECT_EQ(
      cdm_storage_database_->ReadFile(kTestStorageKey, kCdmType, kFileName),
      kPopulatedFileValue);

  EXPECT_EQ(cdm_storage_database_->GetSizeForStorageKey(
                kTestStorageKey, base::Time::Min(), time_now),
            0u);
  EXPECT_EQ(cdm_storage_database_->GetSizeForStorageKey(
                kTestStorageKey, time_now, base::Time::Max()),
            kPopulatedFileValue.size());
  EXPECT_EQ(cdm_storage_database_->GetSizeForStorageKey(
                kTestStorageKey, base::Time::Min(), base::Time::Max()),
            kPopulatedFileValue.size());
}

TEST_F(CdmStorageDatabaseInMemoryTest, GetUsageForNonExistentStorageKey) {
  EXPECT_TRUE(cdm_storage_database_->WriteFile(kTestStorageKey, kCdmType,
                                               kFileName, kPopulatedFileValue));

  EXPECT_EQ(
      cdm_storage_database_->ReadFile(kTestStorageKey, kCdmType, kFileName),
      kPopulatedFileValue);

  EXPECT_EQ(cdm_storage_database_->GetSizeForStorageKey(
                kTestStorageKeyTwo, base::Time::Min(), base::Time::Max()),
            0u);
}

TEST_F(CdmStorageDatabaseInMemoryTest, GetUsageForMultipleFilesInStorageKey) {
  auto time_now = base::Time::Now();

  EXPECT_TRUE(cdm_storage_database_->WriteFile(kTestStorageKey, kCdmType,
                                               kFileName, kPopulatedFileValue));

  EXPECT_TRUE(cdm_storage_database_->WriteFile(
      kTestStorageKey, kCdmType, kFileNameTwo, kPopulatedFileValueTwo));

  EXPECT_EQ(cdm_storage_database_->GetSizeForStorageKey(
                kTestStorageKey, time_now, base::Time::Max()),
            kPopulatedFileValue.size() + kPopulatedFileValueTwo.size());
  EXPECT_EQ(cdm_storage_database_->GetSizeForStorageKey(
                kTestStorageKey, base::Time::Min(), base::Time::Max()),
            kPopulatedFileValue.size() + kPopulatedFileValueTwo.size());
}

TEST_F(CdmStorageDatabaseInMemoryTest, GetUsageForTimeFrame) {
  auto time_now = base::Time::Now();

  EXPECT_TRUE(cdm_storage_database_->WriteFile(kTestStorageKey, kCdmType,
                                               kFileName, kPopulatedFileValue));

  EXPECT_EQ(
      cdm_storage_database_->GetSizeForTimeFrame(time_now, base::Time::Max()),
      kPopulatedFileValue.size());
  EXPECT_EQ(cdm_storage_database_->GetSizeForTimeFrame(base::Time::Min(),
                                                       base::Time::Max()),
            kPopulatedFileValue.size());
}

TEST_F(CdmStorageDatabaseInMemoryTest, GetUsageForNonExistentTimeFrame) {
  EXPECT_TRUE(cdm_storage_database_->WriteFile(kTestStorageKey, kCdmType,
                                               kFileName, kPopulatedFileValue));

  EXPECT_EQ(cdm_storage_database_->GetSizeForTimeFrame(base::Time::Now(),
                                                       base::Time::Max()),
            0u);
  EXPECT_EQ(cdm_storage_database_->GetSizeForTimeFrame(base::Time::Min(),
                                                       base::Time::Max()),
            kPopulatedFileValue.size());
}

TEST_F(CdmStorageDatabaseInMemoryTest,
       GetUsageForMultipleFilesAndStorageKeysTimeFrame) {
  auto time_now = base::Time::Now();

  EXPECT_TRUE(cdm_storage_database_->WriteFile(kTestStorageKey, kCdmType,
                                               kFileName, kPopulatedFileValue));
  EXPECT_TRUE(cdm_storage_database_->WriteFile(
      kTestStorageKey, kCdmType, kFileNameTwo, kPopulatedFileValueTwo));

  EXPECT_TRUE(cdm_storage_database_->WriteFile(
      kTestStorageKeyTwo, kCdmType, kFileNameTwo, kPopulatedFileValueThree));

  EXPECT_EQ(
      cdm_storage_database_->GetSizeForTimeFrame(base::Time::Min(), time_now),
      0u);

  EXPECT_EQ(
      cdm_storage_database_->GetSizeForTimeFrame(time_now, base::Time::Max()),
      kPopulatedFileValue.size() + kPopulatedFileValueTwo.size() +
          kPopulatedFileValueThree.size());

  EXPECT_EQ(cdm_storage_database_->GetSizeForTimeFrame(base::Time::Min(),
                                                       base::Time::Max()),
            kPopulatedFileValue.size() + kPopulatedFileValueTwo.size() +
                kPopulatedFileValueThree.size());
}

TEST_F(CdmStorageDatabaseInMemoryTest, GetUsagePerAllStorageKeys) {
  EXPECT_TRUE(cdm_storage_database_->WriteFile(kTestStorageKey, kCdmType,
                                               kFileName, kPopulatedFileValue));
  EXPECT_TRUE(cdm_storage_database_->WriteFile(
      kTestStorageKeyTwo, kCdmType, kFileNameTwo, kPopulatedFileValueTwo));

  EXPECT_TRUE(cdm_storage_database_->WriteFile(
      kTestStorageKeyTwo, kCdmType, kFileName, kPopulatedFileValueThree));

  auto storage_keys = cdm_storage_database_->GetUsagePerAllStorageKeys();

  const CdmStorageKeyUsageSize& expected_storage_keys = {
      {kTestStorageKey, kPopulatedFileValue.size()},
      {kTestStorageKeyTwo,
       kPopulatedFileValueTwo.size() + kPopulatedFileValueThree.size()}};

  EXPECT_EQ(storage_keys, expected_storage_keys);
}

TEST_F(CdmStorageDatabaseInMemoryTest, GetUsagePerAllStorageKeysTimeBound) {
  auto now = base::Time::Now();

  EXPECT_TRUE(cdm_storage_database_->WriteFile(kTestStorageKey, kCdmType,
                                               kFileName, kPopulatedFileValue));
  EXPECT_TRUE(cdm_storage_database_->WriteFile(
      kTestStorageKeyTwo, kCdmType, kFileNameTwo, kPopulatedFileValueTwo));

  EXPECT_TRUE(cdm_storage_database_->WriteFile(
      kTestStorageKeyTwo, kCdmType, kFileName, kPopulatedFileValueThree));

  auto storage_keys_not_populated =
      cdm_storage_database_->GetUsagePerAllStorageKeys(base::Time::Min(), now);

  auto storage_keys_in_time_frame =
      cdm_storage_database_->GetUsagePerAllStorageKeys(now, base::Time::Now());

  auto all_storage_keys = cdm_storage_database_->GetUsagePerAllStorageKeys();

  const CdmStorageKeyUsageSize& expected_storage_keys = {
      {kTestStorageKey, kPopulatedFileValue.size()},
      {kTestStorageKeyTwo,
       kPopulatedFileValueTwo.size() + kPopulatedFileValueThree.size()}};

  EXPECT_TRUE(storage_keys_not_populated.size() == 0);

  EXPECT_EQ(storage_keys_in_time_frame, expected_storage_keys);

  EXPECT_EQ(all_storage_keys, expected_storage_keys);
}

TEST_F(CdmStorageDatabaseInMemoryTest, DeleteDataForFilter) {
  auto now = base::Time::Now();

  EXPECT_TRUE(cdm_storage_database_->WriteFile(kTestStorageKey, kCdmType,
                                               kFileName, kPopulatedFileValue));

  // Try to remove the data using a deletelist that doesn't include
  // the current URL. Data should not be deleted.
  std::unique_ptr<BrowsingDataFilterBuilder> filter_builder_not_included =
      BrowsingDataFilterBuilder::Create(
          BrowsingDataFilterBuilder::Mode::kDelete);
  filter_builder_not_included->AddOrigin(kTestStorageKeyTwo.origin());

  cdm_storage_database_->DeleteData(
      filter_builder_not_included->BuildStorageKeyFilter(), blink::StorageKey(),
      now, base::Time::Max());

  EXPECT_EQ(
      cdm_storage_database_->ReadFile(kTestStorageKey, kCdmType, kFileName),
      kPopulatedFileValue);

  // When on kDelete mode, the storage key should  be deleted.
  std::unique_ptr<BrowsingDataFilterBuilder> filter_builder_delete =
      BrowsingDataFilterBuilder::Create(
          BrowsingDataFilterBuilder::Mode::kDelete);

  filter_builder_delete->AddOrigin(kTestStorageKey.origin());

  // Should not apply as time ranges do not match.
  cdm_storage_database_->DeleteData(
      filter_builder_delete->BuildStorageKeyFilter(), blink::StorageKey(),
      base::Time::Min(), now);

  EXPECT_EQ(
      cdm_storage_database_->ReadFile(kTestStorageKey, kCdmType, kFileName),
      kPopulatedFileValue);

  // Should delete in the time range.
  cdm_storage_database_->DeleteData(
      filter_builder_delete->BuildStorageKeyFilter(), blink::StorageKey(), now,
      base::Time::Max());

  EXPECT_EQ(cdm_storage_database_->GetSizeForStorageKey(kTestStorageKey, now,
                                                        base::Time::Max()),
            0u);
}

TEST_F(CdmStorageDatabaseInMemoryTest, PreserveDataForFilter) {
  auto now = base::Time::Now();

  EXPECT_TRUE(cdm_storage_database_->WriteFile(kTestStorageKey, kCdmType,
                                               kFileName, kPopulatedFileValue));

  EXPECT_TRUE(cdm_storage_database_->WriteFile(
      kTestStorageKeyTwo, kCdmType, kFileNameTwo, kPopulatedFileValueTwo));

  // When on kPreserve mode, the storage keys should not be deleted.
  std::unique_ptr<BrowsingDataFilterBuilder> filter_builder_preserve_all =
      BrowsingDataFilterBuilder::Create(
          BrowsingDataFilterBuilder::Mode::kPreserve);

  filter_builder_preserve_all->AddOrigin(kTestStorageKey.origin());
  filter_builder_preserve_all->AddOrigin(kTestStorageKeyTwo.origin());

  cdm_storage_database_->DeleteData(
      filter_builder_preserve_all->BuildStorageKeyFilter(), blink::StorageKey(),
      now, base::Time::Max());

  EXPECT_EQ(
      cdm_storage_database_->ReadFile(kTestStorageKey, kCdmType, kFileName),
      kPopulatedFileValue);
  EXPECT_EQ(cdm_storage_database_->ReadFile(kTestStorageKeyTwo, kCdmType,
                                            kFileNameTwo),
            kPopulatedFileValueTwo);

  std::unique_ptr<BrowsingDataFilterBuilder> filter_builder_preserve_one =
      BrowsingDataFilterBuilder::Create(
          BrowsingDataFilterBuilder::Mode::kPreserve);

  filter_builder_preserve_one->AddOrigin(kTestStorageKey.origin());

  // Even with the filter builder only preserving `kTestStorageKey`, the time
  // frame specified should make the cdm storage database not delete anything at
  // all.
  cdm_storage_database_->DeleteData(
      filter_builder_preserve_one->BuildStorageKeyFilter(), blink::StorageKey(),
      base::Time::Min(), now);

  EXPECT_EQ(
      cdm_storage_database_->ReadFile(kTestStorageKey, kCdmType, kFileName),
      kPopulatedFileValue);
  EXPECT_EQ(cdm_storage_database_->ReadFile(kTestStorageKeyTwo, kCdmType,
                                            kFileNameTwo),
            kPopulatedFileValueTwo);

  cdm_storage_database_->DeleteData(
      filter_builder_preserve_one->BuildStorageKeyFilter(), blink::StorageKey(),
      now, base::Time::Max());

  EXPECT_EQ(
      cdm_storage_database_->ReadFile(kTestStorageKey, kCdmType, kFileName),
      kPopulatedFileValue);
  EXPECT_EQ(cdm_storage_database_->GetSizeForFile(kTestStorageKeyTwo, kCdmType,
                                                  kFileNameTwo),
            0);
}

TEST_F(CdmStorageDatabaseValidPathTest, EnsureOpenWithoutErrors) {
  auto error = cdm_storage_database_->EnsureOpen();

  EXPECT_EQ(error, CdmStorageOpenError::kOk);
}

TEST_F(CdmStorageDatabaseValidPathTest, FileManipulation) {
  EXPECT_TRUE(cdm_storage_database_->WriteFile(kTestStorageKey, kCdmType,
                                               kFileName, kPopulatedFileValue));

  EXPECT_EQ(
      cdm_storage_database_->ReadFile(kTestStorageKey, kCdmType, kFileName),
      kPopulatedFileValue);

  EXPECT_TRUE(
      cdm_storage_database_->DeleteFile(kTestStorageKey, kCdmType, kFileName));

  EXPECT_TRUE(
      cdm_storage_database_->ReadFile(kTestStorageKey, kCdmType, kFileName)
          ->empty());
}

TEST_F(CdmStorageDatabaseValidPathTest, DeleteDatabase) {
  EXPECT_TRUE(cdm_storage_database_->WriteFile(kTestStorageKey, kCdmType,
                                               kFileName, kPopulatedFileValue));

  EXPECT_TRUE(cdm_storage_database_->ClearDatabase());

  auto error = cdm_storage_database_->EnsureOpen();

  EXPECT_EQ(error, CdmStorageOpenError::kOk);

  EXPECT_TRUE(
      cdm_storage_database_->ReadFile(kTestStorageKey, kCdmType, kFileName)
          ->empty());
}

TEST_F(CdmStorageDatabaseValidPathTest, DeleteForStorageKey) {
  auto time_now = base::Time::Now();

  EXPECT_TRUE(cdm_storage_database_->WriteFile(kTestStorageKey, kCdmType,
                                               kFileName, kPopulatedFileValue));
  EXPECT_TRUE(cdm_storage_database_->WriteFile(
      kTestStorageKey, kCdmType, kFileNameTwo, kPopulatedFileValue));

  EXPECT_TRUE(cdm_storage_database_->WriteFile(kTestStorageKeyTwo, kCdmType,
                                               kFileName, kPopulatedFileValue));
  EXPECT_TRUE(cdm_storage_database_->WriteFile(
      kTestStorageKeyTwo, kCdmType, kFileNameTwo, kPopulatedFileValue));

  EXPECT_EQ(
      cdm_storage_database_->ReadFile(kTestStorageKey, kCdmType, kFileName),
      kPopulatedFileValue);
  EXPECT_EQ(
      cdm_storage_database_->ReadFile(kTestStorageKey, kCdmType, kFileNameTwo),
      kPopulatedFileValue);

  EXPECT_EQ(
      cdm_storage_database_->ReadFile(kTestStorageKeyTwo, kCdmType, kFileName),
      kPopulatedFileValue);
  EXPECT_EQ(cdm_storage_database_->ReadFile(kTestStorageKeyTwo, kCdmType,
                                            kFileNameTwo),
            kPopulatedFileValue);

  EXPECT_TRUE(cdm_storage_database_->DeleteData(
      base::NullCallback(), kTestStorageKey, time_now, base::Time::Max()));

  // Expect that for the storage key, all of the file content returned is empty.
  EXPECT_TRUE(
      cdm_storage_database_->ReadFile(kTestStorageKey, kCdmType, kFileName)
          ->empty());
  EXPECT_TRUE(
      cdm_storage_database_->ReadFile(kTestStorageKey, kCdmType, kFileNameTwo)
          ->empty());

  // Expect that its not deleted for other storage keys.
  EXPECT_EQ(
      cdm_storage_database_->ReadFile(kTestStorageKeyTwo, kCdmType, kFileName),
      kPopulatedFileValue);
  EXPECT_EQ(cdm_storage_database_->ReadFile(kTestStorageKeyTwo, kCdmType,
                                            kFileNameTwo),
            kPopulatedFileValue);
}

TEST_F(CdmStorageDatabaseValidPathTest, DeleteForStorageKeyWithNoData) {
  auto time_now = base::Time::Now();

  // Even if there is no data for the storage key, the SQL statement should
  // still run properly.
  EXPECT_TRUE(cdm_storage_database_->DeleteData(
      base::NullCallback(), kTestStorageKey, time_now, base::Time::Max()));

  EXPECT_TRUE(
      cdm_storage_database_->ReadFile(kTestStorageKey, kCdmType, kFileName)
          ->empty());
}

TEST_F(CdmStorageDatabaseValidPathTest,
       DeleteForTimeFrameMultipleFilesAndStorageKeysTimeFrame) {
  auto time_now = base::Time::Now();

  EXPECT_TRUE(cdm_storage_database_->WriteFile(kTestStorageKey, kCdmType,
                                               kFileName, kPopulatedFileValue));
  EXPECT_TRUE(cdm_storage_database_->WriteFile(
      kTestStorageKey, kCdmType, kFileNameTwo, kPopulatedFileValueTwo));

  EXPECT_TRUE(cdm_storage_database_->WriteFile(
      kTestStorageKeyTwo, kCdmType, kFileNameTwo, kPopulatedFileValueThree));

  EXPECT_EQ(
      cdm_storage_database_->GetSizeForTimeFrame(time_now, base::Time::Max()),
      kPopulatedFileValue.size() + kPopulatedFileValueTwo.size() +
          kPopulatedFileValueThree.size());

  EXPECT_TRUE(cdm_storage_database_->DeleteData(
      base::NullCallback(), blink::StorageKey(), time_now, base::Time::Max()));

  EXPECT_TRUE(
      cdm_storage_database_->ReadFile(kTestStorageKey, kCdmType, kFileName)
          ->empty());

  EXPECT_TRUE(
      cdm_storage_database_->ReadFile(kTestStorageKey, kCdmType, kFileNameTwo)
          ->empty());

  EXPECT_TRUE(cdm_storage_database_
                  ->ReadFile(kTestStorageKeyTwo, kCdmType, kFileNameTwo)
                  ->empty());

  EXPECT_EQ(
      cdm_storage_database_->GetSizeForTimeFrame(time_now, base::Time::Max()),
      0u);

  EXPECT_EQ(cdm_storage_database_->GetSizeForTimeFrame(base::Time::Min(),
                                                       base::Time::Max()),
            0u);
}

TEST_F(CdmStorageDatabaseValidPathTest, DeleteForTimeFrameWithNoData) {
  EXPECT_EQ(cdm_storage_database_->GetSizeForTimeFrame(base::Time::Min(),
                                                       base::Time::Max()),
            0u);

  // Even if there is no data for the storage key, the SQL statement should
  // still run properly.
  EXPECT_TRUE(cdm_storage_database_->DeleteData(
      base::NullCallback(), blink::StorageKey(), base::Time::Min(),
      base::Time::Max()));
}

TEST_F(CdmStorageDatabaseValidPathTest, WriteFileForBigData) {
  std::vector<uint8_t> big_data;
  big_data.resize(1000000);

  EXPECT_TRUE(cdm_storage_database_->WriteFile(kTestStorageKey, kCdmType,
                                               kFileName, big_data));

  const char uma_name[] = "Media.EME.CdmStorageDatabase.WriteFileForBigData";
  histogram_tester_.ExpectTotalCount(uma_name, 1);
  histogram_tester_.ExpectBucketCount(uma_name, true, 1);

  EXPECT_EQ(
      cdm_storage_database_->ReadFile(kTestStorageKey, kCdmType, kFileName),
      big_data);
}

TEST_F(CdmStorageDatabaseValidPathTest, GetUsageForFile) {
  EXPECT_TRUE(cdm_storage_database_->WriteFile(kTestStorageKey, kCdmType,
                                               kFileName, kPopulatedFileValue));

  EXPECT_EQ(cdm_storage_database_->GetSizeForFile(kTestStorageKey, kCdmType,
                                                  kFileName),
            kPopulatedFileValue.size());
}

TEST_F(CdmStorageDatabaseValidPathTest, GetUsageForNonExistentFile) {
  EXPECT_TRUE(cdm_storage_database_->WriteFile(kTestStorageKey, kCdmType,
                                               kFileName, kPopulatedFileValue));

  EXPECT_EQ(cdm_storage_database_->GetSizeForFile(kTestStorageKeyTwo, kCdmType,
                                                  kFileName),
            0u);
}

TEST_F(CdmStorageDatabaseValidPathTest, GetUsageForStorageKey) {
  auto time_now = base::Time::Now();

  EXPECT_TRUE(cdm_storage_database_->WriteFile(kTestStorageKey, kCdmType,
                                               kFileName, kPopulatedFileValue));

  EXPECT_EQ(
      cdm_storage_database_->ReadFile(kTestStorageKey, kCdmType, kFileName),
      kPopulatedFileValue);

  EXPECT_EQ(cdm_storage_database_->GetSizeForStorageKey(
                kTestStorageKey, base::Time::Min(), time_now),
            0u);
  EXPECT_EQ(cdm_storage_database_->GetSizeForStorageKey(
                kTestStorageKey, time_now, base::Time::Max()),
            kPopulatedFileValue.size());
  EXPECT_EQ(cdm_storage_database_->GetSizeForStorageKey(
                kTestStorageKey, base::Time::Min(), base::Time::Max()),
            kPopulatedFileValue.size());
}

TEST_F(CdmStorageDatabaseValidPathTest, GetUsageForNonExistentStorageKey) {
  EXPECT_TRUE(cdm_storage_database_->WriteFile(kTestStorageKey, kCdmType,
                                               kFileName, kPopulatedFileValue));

  EXPECT_EQ(
      cdm_storage_database_->ReadFile(kTestStorageKey, kCdmType, kFileName),
      kPopulatedFileValue);

  EXPECT_EQ(cdm_storage_database_->GetSizeForStorageKey(
                kTestStorageKeyTwo, base::Time::Min(), base::Time::Max()),
            0u);
}

TEST_F(CdmStorageDatabaseValidPathTest, GetUsageForMultipleFilesInStorageKey) {
  auto time_now = base::Time::Now();

  EXPECT_TRUE(cdm_storage_database_->WriteFile(kTestStorageKey, kCdmType,
                                               kFileName, kPopulatedFileValue));

  EXPECT_TRUE(cdm_storage_database_->WriteFile(
      kTestStorageKey, kCdmType, kFileNameTwo, kPopulatedFileValueTwo));

  EXPECT_EQ(cdm_storage_database_->GetSizeForStorageKey(
                kTestStorageKey, time_now, base::Time::Max()),
            kPopulatedFileValue.size() + kPopulatedFileValueTwo.size());
  EXPECT_EQ(cdm_storage_database_->GetSizeForStorageKey(
                kTestStorageKey, base::Time::Min(), base::Time::Max()),
            kPopulatedFileValue.size() + kPopulatedFileValueTwo.size());
}

TEST_F(CdmStorageDatabaseValidPathTest, GetUsageForTimeFrame) {
  auto time_now = base::Time::Now();

  EXPECT_TRUE(cdm_storage_database_->WriteFile(kTestStorageKey, kCdmType,
                                               kFileName, kPopulatedFileValue));

  EXPECT_EQ(
      cdm_storage_database_->GetSizeForTimeFrame(time_now, base::Time::Max()),
      kPopulatedFileValue.size());
  EXPECT_EQ(cdm_storage_database_->GetSizeForTimeFrame(base::Time::Min(),
                                                       base::Time::Max()),
            kPopulatedFileValue.size());
}

TEST_F(CdmStorageDatabaseValidPathTest, GetUsageForNonExistentTimeFrame) {
  EXPECT_TRUE(cdm_storage_database_->WriteFile(kTestStorageKey, kCdmType,
                                               kFileName, kPopulatedFileValue));

  EXPECT_EQ(cdm_storage_database_->GetSizeForTimeFrame(base::Time::Now(),
                                                       base::Time::Max()),
            0u);
  EXPECT_EQ(cdm_storage_database_->GetSizeForTimeFrame(base::Time::Min(),
                                                       base::Time::Max()),
            kPopulatedFileValue.size());
}

TEST_F(CdmStorageDatabaseValidPathTest,
       GetUsageForMultipleFilesAndStorageKeysTimeFrame) {
  auto time_now = base::Time::Now();

  EXPECT_TRUE(cdm_storage_database_->WriteFile(kTestStorageKey, kCdmType,
                                               kFileName, kPopulatedFileValue));
  EXPECT_TRUE(cdm_storage_database_->WriteFile(
      kTestStorageKey, kCdmType, kFileNameTwo, kPopulatedFileValueTwo));

  EXPECT_TRUE(cdm_storage_database_->WriteFile(
      kTestStorageKeyTwo, kCdmType, kFileNameTwo, kPopulatedFileValueThree));

  EXPECT_EQ(
      cdm_storage_database_->GetSizeForTimeFrame(base::Time::Min(), time_now),
      0u);

  EXPECT_EQ(
      cdm_storage_database_->GetSizeForTimeFrame(time_now, base::Time::Max()),
      kPopulatedFileValue.size() + kPopulatedFileValueTwo.size() +
          kPopulatedFileValueThree.size());

  EXPECT_EQ(cdm_storage_database_->GetSizeForTimeFrame(base::Time::Min(),
                                                       base::Time::Max()),
            kPopulatedFileValue.size() + kPopulatedFileValueTwo.size() +
                kPopulatedFileValueThree.size());
}

TEST_F(CdmStorageDatabaseValidPathTest, GetUsagePerAllStorageKeys) {
  EXPECT_TRUE(cdm_storage_database_->WriteFile(kTestStorageKey, kCdmType,
                                               kFileName, kPopulatedFileValue));
  EXPECT_TRUE(cdm_storage_database_->WriteFile(
      kTestStorageKeyTwo, kCdmType, kFileNameTwo, kPopulatedFileValueTwo));

  EXPECT_TRUE(cdm_storage_database_->WriteFile(
      kTestStorageKeyTwo, kCdmType, kFileName, kPopulatedFileValueThree));

  auto storage_keys = cdm_storage_database_->GetUsagePerAllStorageKeys();

  const CdmStorageKeyUsageSize& expected_storage_keys = {
      {kTestStorageKey, kPopulatedFileValue.size()},
      {kTestStorageKeyTwo,
       kPopulatedFileValueTwo.size() + kPopulatedFileValueThree.size()}};

  EXPECT_EQ(storage_keys, expected_storage_keys);
}

TEST_F(CdmStorageDatabaseValidPathTest, GetUsagePerAllStorageKeysTimeBound) {
  auto now = base::Time::Now();

  EXPECT_TRUE(cdm_storage_database_->WriteFile(kTestStorageKey, kCdmType,
                                               kFileName, kPopulatedFileValue));
  EXPECT_TRUE(cdm_storage_database_->WriteFile(
      kTestStorageKeyTwo, kCdmType, kFileNameTwo, kPopulatedFileValueTwo));

  EXPECT_TRUE(cdm_storage_database_->WriteFile(
      kTestStorageKeyTwo, kCdmType, kFileName, kPopulatedFileValueThree));

  auto storage_keys_not_populated =
      cdm_storage_database_->GetUsagePerAllStorageKeys(base::Time::Min(), now);

  auto storage_keys_in_time_frame =
      cdm_storage_database_->GetUsagePerAllStorageKeys(now, base::Time::Now());

  auto all_storage_keys = cdm_storage_database_->GetUsagePerAllStorageKeys();

  const CdmStorageKeyUsageSize& expected_storage_keys = {
      {kTestStorageKey, kPopulatedFileValue.size()},
      {kTestStorageKeyTwo,
       kPopulatedFileValueTwo.size() + kPopulatedFileValueThree.size()}};

  EXPECT_TRUE(storage_keys_not_populated.size() == 0);

  EXPECT_EQ(storage_keys_in_time_frame, expected_storage_keys);

  EXPECT_EQ(all_storage_keys, expected_storage_keys);
}

TEST_F(CdmStorageDatabaseValidPathTest, DeleteDataForFilter) {
  auto now = base::Time::Now();

  EXPECT_TRUE(cdm_storage_database_->WriteFile(kTestStorageKey, kCdmType,
                                               kFileName, kPopulatedFileValue));

  // Try to remove the data using a deletelist that doesn't include
  // the current URL. Data should not be deleted.
  std::unique_ptr<BrowsingDataFilterBuilder> filter_builder_not_included =
      BrowsingDataFilterBuilder::Create(
          BrowsingDataFilterBuilder::Mode::kDelete);
  filter_builder_not_included->AddOrigin(kTestStorageKeyTwo.origin());

  cdm_storage_database_->DeleteData(
      filter_builder_not_included->BuildStorageKeyFilter(), blink::StorageKey(),
      now, base::Time::Max());

  EXPECT_EQ(
      cdm_storage_database_->ReadFile(kTestStorageKey, kCdmType, kFileName),
      kPopulatedFileValue);

  // When on kDelete mode, the storage key should  be deleted.
  std::unique_ptr<BrowsingDataFilterBuilder> filter_builder_delete =
      BrowsingDataFilterBuilder::Create(
          BrowsingDataFilterBuilder::Mode::kDelete);

  filter_builder_delete->AddOrigin(kTestStorageKey.origin());

  // Should not apply as time ranges do not match.
  cdm_storage_database_->DeleteData(
      filter_builder_delete->BuildStorageKeyFilter(), blink::StorageKey(),
      base::Time::Min(), now);

  EXPECT_EQ(
      cdm_storage_database_->ReadFile(kTestStorageKey, kCdmType, kFileName),
      kPopulatedFileValue);

  // Should delete in the time range.
  cdm_storage_database_->DeleteData(
      filter_builder_delete->BuildStorageKeyFilter(), blink::StorageKey(), now,
      base::Time::Max());

  EXPECT_EQ(cdm_storage_database_->GetSizeForStorageKey(kTestStorageKey, now,
                                                        base::Time::Max()),
            0u);
}

TEST_F(CdmStorageDatabaseValidPathTest, PreserveDataForFilter) {
  auto now = base::Time::Now();

  EXPECT_TRUE(cdm_storage_database_->WriteFile(kTestStorageKey, kCdmType,
                                               kFileName, kPopulatedFileValue));

  EXPECT_TRUE(cdm_storage_database_->WriteFile(
      kTestStorageKeyTwo, kCdmType, kFileNameTwo, kPopulatedFileValueTwo));

  // When on kPreserve mode, the storage keys should not be deleted.
  std::unique_ptr<BrowsingDataFilterBuilder> filter_builder_preserve_all =
      BrowsingDataFilterBuilder::Create(
          BrowsingDataFilterBuilder::Mode::kPreserve);

  filter_builder_preserve_all->AddOrigin(kTestStorageKey.origin());
  filter_builder_preserve_all->AddOrigin(kTestStorageKeyTwo.origin());

  cdm_storage_database_->DeleteData(
      filter_builder_preserve_all->BuildStorageKeyFilter(), blink::StorageKey(),
      now, base::Time::Max());

  EXPECT_EQ(
      cdm_storage_database_->ReadFile(kTestStorageKey, kCdmType, kFileName),
      kPopulatedFileValue);
  EXPECT_EQ(cdm_storage_database_->ReadFile(kTestStorageKeyTwo, kCdmType,
                                            kFileNameTwo),
            kPopulatedFileValueTwo);

  std::unique_ptr<BrowsingDataFilterBuilder> filter_builder_preserve_one =
      BrowsingDataFilterBuilder::Create(
          BrowsingDataFilterBuilder::Mode::kPreserve);

  filter_builder_preserve_one->AddOrigin(kTestStorageKey.origin());

  // Even with the filter builder only preserving `kTestStorageKey`, the time
  // frame specified should make the cdm storage database not delete anything at
  // all.
  cdm_storage_database_->DeleteData(
      filter_builder_preserve_one->BuildStorageKeyFilter(), blink::StorageKey(),
      base::Time::Min(), now);

  EXPECT_EQ(
      cdm_storage_database_->ReadFile(kTestStorageKey, kCdmType, kFileName),
      kPopulatedFileValue);
  EXPECT_EQ(cdm_storage_database_->ReadFile(kTestStorageKeyTwo, kCdmType,
                                            kFileNameTwo),
            kPopulatedFileValueTwo);

  cdm_storage_database_->DeleteData(
      filter_builder_preserve_one->BuildStorageKeyFilter(), blink::StorageKey(),
      now, base::Time::Max());

  EXPECT_EQ(
      cdm_storage_database_->ReadFile(kTestStorageKey, kCdmType, kFileName),
      kPopulatedFileValue);
  EXPECT_EQ(cdm_storage_database_->GetSizeForFile(kTestStorageKeyTwo, kCdmType,
                                                  kFileNameTwo),
            0);
}

}  // namespace content
