// Copyright 2013 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/indexed_db/instance/database.h"

#include <stdint.h>

#include <array>
#include <optional>
#include <set>
#include <string>
#include <utility>

#include "base/auto_reset.h"
#include "base/containers/span.h"
#include "base/files/scoped_temp_dir.h"
#include "base/functional/bind.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/run_loop.h"
#include "base/sequence_checker.h"
#include "base/strings/stringprintf.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/task/updateable_sequenced_task_runner.h"
#include "base/test/bind.h"
#include "base/test/gmock_callback_support.h"
#include "base/test/mock_callback.h"
#include "base/test/task_environment.h"
#include "components/services/storage/indexed_db/locks/partitioned_lock_manager.h"
#include "components/services/storage/privileged/mojom/indexed_db_client_state_checker.mojom.h"
#include "components/services/storage/public/cpp/buckets/bucket_locator.h"
#include "content/browser/indexed_db/indexed_db_leveldb_coding.h"
#include "content/browser/indexed_db/indexed_db_value.h"
#include "content/browser/indexed_db/instance/backing_store.h"
#include "content/browser/indexed_db/instance/bucket_context.h"
#include "content/browser/indexed_db/instance/connection.h"
#include "content/browser/indexed_db/instance/cursor.h"
#include "content/browser/indexed_db/instance/database_callbacks.h"
#include "content/browser/indexed_db/instance/factory_client.h"
#include "content/browser/indexed_db/instance/fake_transaction.h"
#include "content/browser/indexed_db/instance/mock_factory_client.h"
#include "content/browser/indexed_db/instance/mock_file_system_access_context.h"
#include "content/browser/indexed_db/instance/transaction.h"
#include "content/browser/indexed_db/mock_mojo_indexed_db_database_callbacks.h"
#include "mojo/public/cpp/bindings/associated_remote.h"
#include "storage/browser/test/mock_quota_manager.h"
#include "storage/browser/test/mock_quota_manager_proxy.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/storage_key/storage_key.h"

using blink::IndexedDBDatabaseMetadata;
using blink::IndexedDBIndexKeys;
using blink::IndexedDBKey;
using blink::IndexedDBKeyPath;

namespace content::indexed_db {

namespace {
constexpr int64_t kTestObjectStoreId = 1001;
constexpr int64_t kTestIndexId = 2002;
constexpr char kTestForceCloseMessage[] =
    "The database's connection is force-closed.";

// Contains a record's keys and value that tests use to populate the database.
struct TestIDBRecord {
  TestIDBRecord(IndexedDBKey primary_key,
                const IndexedDBValue& value,
                std::optional<IndexedDBKey> index_key)
      : primary_key(std::move(primary_key)),
        value(value.Clone()),
        index_key(std::move(index_key)) {}

  TestIDBRecord(const TestIDBRecord& other) {
    primary_key = other.primary_key.Clone();
    value = other.value.Clone();
    if (other.index_key) {
      index_key = other.index_key->Clone();
    }
  }

  IndexedDBKey primary_key;
  IndexedDBValue value;
  // Optional. Tests may skip index creation.
  std::optional<IndexedDBKey> index_key;
};

// Contains the options used to create an object store.  Initializes members
// to reasonable defaults that tests may override.
struct TestObjectStoreParameters {
  int64_t object_store_id = 0;
  std::u16string name{u"store"};
  IndexedDBKeyPath key_path;
  bool auto_increment = false;
};

// Contains the options used to create an index.  Optional.  Test setup skips
// index creation when `index_id` is `kInvalidId`. Initializes members to
// reasonable defaults that tests may override.
struct TestIndexParameters {
  int64_t index_id = blink::IndexedDBIndexMetadata::kInvalidId;
  std::u16string name{u"index"};
  bool unique = false;
  bool multi_entry = false;
  IndexedDBKeyPath key_path;
  bool auto_increment = false;
};

// Describes how test setup should create and populate an object store and
// optionally an index.
struct TestDatabaseParameters {
  TestObjectStoreParameters object_store_parameters;
  TestIndexParameters index_parameters;
  std::vector<TestIDBRecord> records;
};

// Contains the arguments needed to call `Database::GetAllOperation`.
// Initializes members to reasonable defaults that tests may override.
struct TestGetAllParameters {
  blink::mojom::IDBGetAllResultType result_type =
      blink::mojom::IDBGetAllResultType::Keys;

  blink::IndexedDBKeyRange key_range;

  int64_t max_count = std::numeric_limits<int64_t>::max();

  blink::mojom::IDBCursorDirection direction =
      blink::mojom::IDBCursorDirection::Next;
};

// `Database::GetAllOperation` streams record results to a sink.  This fake
// implementation enables test to wait for all the results and inspect them.
class FakeGetAllResultSink final
    : public blink::mojom::IDBDatabaseGetAllResultSink {
 public:
  FakeGetAllResultSink() = default;

  ~FakeGetAllResultSink() final {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  }

  FakeGetAllResultSink(const FakeGetAllResultSink&) = delete;
  FakeGetAllResultSink& operator=(const FakeGetAllResultSink&) = delete;

  blink::mojom::IDBError* GetError() const {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
    CHECK(is_done_);
    return error_.get();
  }

  const std::vector<blink::mojom::IDBRecordPtr>& GetResults() const {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
    CHECK(is_done_);
    return records_;
  }

  void BindReceiver(
      mojo::PendingAssociatedReceiver<blink::mojom::IDBDatabaseGetAllResultSink>
          receiver) {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
    CHECK(!is_done_);
    receiver_.Bind(std::move(receiver));
  }

  void WaitForResults() {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
    run_loop_.Run();
    CHECK(is_done_);
  }

 private:
  void ReceiveResults(std::vector<blink::mojom::IDBRecordPtr> records,
                      bool done) final {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
    CHECK(!is_done_);

    if (records_.empty()) {
      records_ = std::move(records);
    } else {
      records_.reserve(records_.size() + records.size());
      for (auto& record : records) {
        records_.emplace_back(std::move(record));
      }
    }

    if (done) {
      is_done_ = true;
      run_loop_.Quit();
    }
  }

  void OnError(blink::mojom::IDBErrorPtr error) final {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
    CHECK(!is_done_);

    error_ = std::move(error);
    is_done_ = true;
    run_loop_.Quit();
  }

  SEQUENCE_CHECKER(sequence_checker_);

  mojo::AssociatedReceiver<blink::mojom::IDBDatabaseGetAllResultSink> receiver_{
      this};

  // Used to wait until all results have been received.
  base::RunLoop run_loop_;
  bool is_done_ = false;

  // Store results and error for later inspection.  Must not be accessed until
  // `is_done_` is true.
  std::vector<blink::mojom::IDBRecordPtr> records_;
  blink::mojom::IDBErrorPtr error_;
};

void ExpectEqualsIndexedDBKey(const IndexedDBKey& expected_primary_key,
                              const IndexedDBKey& actual_primary_key) {
  ASSERT_EQ(actual_primary_key.IsValid(), expected_primary_key.IsValid());

  if (expected_primary_key.IsValid()) {
    EXPECT_TRUE(actual_primary_key.Equals(expected_primary_key))
        << "Expected " << expected_primary_key.DebugString() << " but got "
        << actual_primary_key.DebugString();
  }
}

void ExpectEqualsOptionalIndexedDBKey(
    const std::optional<IndexedDBKey>& expected_primary_key,
    const std::optional<IndexedDBKey>& actual_primary_key) {
  ASSERT_EQ(actual_primary_key.has_value(), expected_primary_key.has_value());

  if (expected_primary_key.has_value()) {
    ASSERT_NO_FATAL_FAILURE(
        ExpectEqualsIndexedDBKey(*expected_primary_key, *actual_primary_key));
  }
}

void ExpectEqualsIDBReturnValuePtr(
    const blink::mojom::IDBReturnValuePtr& expected_return_value,
    const blink::mojom::IDBReturnValuePtr& actual_return_value) {
  ASSERT_EQ(actual_return_value.is_null(), expected_return_value.is_null());

  if (!expected_return_value.is_null()) {
    // Verify the value bits.
    ASSERT_EQ(actual_return_value->value.is_null(),
              expected_return_value->value.is_null());

    if (!expected_return_value->value.is_null()) {
      EXPECT_EQ(actual_return_value->value->bits,
                expected_return_value->value->bits);

      // Verify the external objects.
      EXPECT_EQ(actual_return_value->value->external_objects.size(),
                expected_return_value->value->external_objects.size());
    }

    // Verify the return value primary key and key path.
    ASSERT_NO_FATAL_FAILURE(ExpectEqualsIndexedDBKey(
        actual_return_value->primary_key, expected_return_value->primary_key));

    EXPECT_EQ(expected_return_value->key_path, actual_return_value->key_path);
  }
}

// Creates a `IDBReturnValuePtr` with the given bits. `primary_key`,
// `key_path` are optional, required only for object stores that generate keys.
// `external_objects` is not set and remains empty.
blink::mojom::IDBReturnValuePtr CreateIDBReturnValuePtr(
    const std::string& bits,
    const IndexedDBKey* primary_key = nullptr,
    IndexedDBKeyPath key_path = {}) {
  blink::mojom::IDBReturnValuePtr result = blink::mojom::IDBReturnValue::New();
  result->value = blink::mojom::IDBValue::New();
  result->value->bits.assign(bits.begin(), bits.end());
  if (primary_key) {
    result->primary_key = primary_key->Clone();
  }
  result->key_path = std::move(key_path);
  return result;
}

}  // namespace

class DatabaseTest : public ::testing::Test {
 public:
  DatabaseTest() = default;

  void SetUp() override {
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    quota_manager_ = base::MakeRefCounted<storage::MockQuotaManager>(
        /*is_incognito=*/false, temp_dir_.GetPath(),
        base::SingleThreadTaskRunner::GetCurrentDefault(),
        /*special_storage_policy=*/nullptr);

    quota_manager_proxy_ = base::MakeRefCounted<storage::MockQuotaManagerProxy>(
        quota_manager_.get(),
        base::SingleThreadTaskRunner::GetCurrentDefault().get());

    BucketContext::Delegate delegate;
    delegate.on_ready_for_destruction =
        base::BindOnce(&DatabaseTest::OnBucketContextReadyForDestruction,
                       weak_factory_.GetWeakPtr());

    mojo::PendingRemote<storage::mojom::FileSystemAccessContext> fsa_context;
    file_system_access_context_ =
        std::make_unique<test::MockFileSystemAccessContext>();
    file_system_access_context_->Clone(
        fsa_context.InitWithNewPipeAndPassReceiver());

    bucket_context_ = std::make_unique<BucketContext>(
        storage::BucketInfo(), temp_dir_.GetPath(), std::move(delegate),
        scoped_refptr<base::UpdateableSequencedTaskRunner>(),
        quota_manager_proxy_,
        /*blob_storage_context=*/mojo::NullRemote(),
        /*file_system_access_context=*/std::move(fsa_context));

    bucket_context_->InitBackingStoreIfNeeded(true);
    db_ = bucket_context_->CreateAndAddDatabase(u"db");
  }

  void TearDown() override { db_ = nullptr; }

  void OnBucketContextReadyForDestruction() { bucket_context_.reset(); }

  void RunPostedTasks() {
    base::RunLoop run_loop;
    base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
        FROM_HERE, run_loop.QuitClosure());
    run_loop.Run();
  }

 protected:
  base::test::TaskEnvironment task_environment_;

  base::ScopedTempDir temp_dir_;
  std::unique_ptr<BucketContext> bucket_context_;
  std::unique_ptr<test::MockFileSystemAccessContext>
      file_system_access_context_;
  scoped_refptr<storage::MockQuotaManager> quota_manager_;
  scoped_refptr<storage::MockQuotaManagerProxy> quota_manager_proxy_;

  // As this is owned by `bucket_context_`, tests that cause the database to
  // be destroyed must manually reset this to null to avoid triggering dangling
  // pointer warnings.
  raw_ptr<Database> db_ = nullptr;

  base::WeakPtrFactory<DatabaseTest> weak_factory_{this};
};

TEST_F(DatabaseTest, ConnectionLifecycle) {
  MockMojoDatabaseCallbacks database_callbacks;
  MockFactoryClient request1;
  const int64_t transaction_id1 = 1;
  auto connection1 = std::make_unique<PendingConnection>(
      std::make_unique<ThunkFactoryClient>(request1),
      std::make_unique<DatabaseCallbacks>(
          database_callbacks.BindNewEndpointAndPassDedicatedRemote()),
      transaction_id1, IndexedDBDatabaseMetadata::DEFAULT_VERSION,
      mojo::NullAssociatedReceiver());
  db_->ScheduleOpenConnection(std::move(connection1));
  RunPostedTasks();

  MockMojoDatabaseCallbacks database_callbacks2;
  MockFactoryClient request2;
  const int64_t transaction_id2 = 2;
  auto connection2 = std::make_unique<PendingConnection>(
      std::make_unique<ThunkFactoryClient>(request2),
      std::make_unique<DatabaseCallbacks>(
          database_callbacks2.BindNewEndpointAndPassDedicatedRemote()),
      transaction_id2, IndexedDBDatabaseMetadata::DEFAULT_VERSION,
      mojo::NullAssociatedReceiver());
  db_->ScheduleOpenConnection(std::move(connection2));
  RunPostedTasks();
  db_ = nullptr;

  EXPECT_TRUE(request1.connection());
  request1.connection()->CloseAndReportForceClose(kTestForceCloseMessage);
  EXPECT_FALSE(request1.connection()->IsConnected());

  EXPECT_TRUE(request2.connection());
  request2.connection()->CloseAndReportForceClose(kTestForceCloseMessage);
  EXPECT_FALSE(request2.connection()->IsConnected());

  RunPostedTasks();

  EXPECT_TRUE(bucket_context_->GetDatabasesForTesting().empty());
}

TEST_F(DatabaseTest, ForcedClose) {
  MockMojoDatabaseCallbacks database_callbacks;
  MockFactoryClient request;
  const int64_t upgrade_transaction_id = 3;
  auto connection = std::make_unique<PendingConnection>(
      std::make_unique<ThunkFactoryClient>(request),
      std::make_unique<DatabaseCallbacks>(
          database_callbacks.BindNewEndpointAndPassDedicatedRemote()),
      upgrade_transaction_id, IndexedDBDatabaseMetadata::DEFAULT_VERSION,
      mojo::NullAssociatedReceiver());
  db_->ScheduleOpenConnection(std::move(connection));
  RunPostedTasks();

  EXPECT_EQ(db_, request.connection()->database().get());

  request.connection()->CreateTransaction(
      mojo::NullAssociatedReceiver(), /*transaction_id=*/123,
      /*object_store_ids=*/{}, blink::mojom::IDBTransactionMode::ReadOnly,
      blink::mojom::IDBTransactionDurability::Relaxed);
  db_ = nullptr;

  base::RunLoop run_loop;
  EXPECT_CALL(database_callbacks, ForcedClose)
      .WillOnce(base::test::RunClosure(run_loop.QuitClosure()));
  request.connection()->CloseAndReportForceClose(kTestForceCloseMessage);
  run_loop.Run();
}

namespace {

class FakeFactoryClient : public FactoryClient {
 public:
  FakeFactoryClient() : FactoryClient(mojo::NullAssociatedRemote()) {}
  ~FakeFactoryClient() override = default;

  FakeFactoryClient(const FakeFactoryClient&) = delete;
  FakeFactoryClient& operator=(const FakeFactoryClient&) = delete;

  void OnBlocked(int64_t existing_version) override { blocked_called_ = true; }
  void OnDeleteSuccess(int64_t old_version) override { success_called_ = true; }
  void OnError(const DatabaseError& error) override { error_called_ = true; }

  bool blocked_called() const { return blocked_called_; }
  bool success_called() const { return success_called_; }
  bool error_called() const { return error_called_; }

 private:
  bool blocked_called_ = false;
  bool success_called_ = false;
  bool error_called_ = false;
};

}  // namespace

TEST_F(DatabaseTest, PendingDelete) {
  MockFactoryClient request1;
  const int64_t transaction_id1 = 1;
  MockMojoDatabaseCallbacks database_callbacks1;
  auto connection = std::make_unique<PendingConnection>(
      std::make_unique<ThunkFactoryClient>(request1),
      std::make_unique<DatabaseCallbacks>(
          database_callbacks1.BindNewEndpointAndPassDedicatedRemote()),
      transaction_id1, IndexedDBDatabaseMetadata::DEFAULT_VERSION,
      mojo::NullAssociatedReceiver());
  db_->ScheduleOpenConnection(std::move(connection));
  RunPostedTasks();

  EXPECT_EQ(db_->ConnectionCount(), 1UL);
  EXPECT_EQ(db_->ActiveOpenDeleteCount(), 0UL);
  EXPECT_EQ(db_->PendingOpenDeleteCount(), 0UL);

  base::RunLoop run_loop;
  FakeFactoryClient request2;
  db_->ScheduleDeleteDatabase(std::make_unique<ThunkFactoryClient>(request2),
                              run_loop.QuitClosure());
  RunPostedTasks();
  EXPECT_EQ(db_->ConnectionCount(), 1UL);
  EXPECT_EQ(db_->ActiveOpenDeleteCount(), 1UL);
  EXPECT_EQ(db_->PendingOpenDeleteCount(), 0UL);

  EXPECT_FALSE(request2.blocked_called());
  request1.connection()->VersionChangeIgnored();
  EXPECT_TRUE(request2.blocked_called());
  EXPECT_EQ(db_->ConnectionCount(), 1UL);
  EXPECT_EQ(db_->ActiveOpenDeleteCount(), 1UL);
  EXPECT_EQ(db_->PendingOpenDeleteCount(), 0UL);

  db_->ForceCloseAndRunTasks(kTestForceCloseMessage);
  db_ = nullptr;

  run_loop.Run();
  EXPECT_FALSE(db_);

  EXPECT_TRUE(request2.success_called());
}

TEST_F(DatabaseTest, OpenDeleteClear) {
  const int64_t kDatabaseVersion = 1;

  MockFactoryClient request1(
      /*expect_connection=*/true);
  MockMojoDatabaseCallbacks database_callbacks1;
  const int64_t transaction_id1 = 1;
  auto connection1 = std::make_unique<PendingConnection>(
      std::make_unique<ThunkFactoryClient>(request1),
      std::make_unique<DatabaseCallbacks>(
          database_callbacks1.BindNewEndpointAndPassDedicatedRemote()),
      transaction_id1, kDatabaseVersion, mojo::NullAssociatedReceiver());
  db_->ScheduleOpenConnection(std::move(connection1));
  RunPostedTasks();

  EXPECT_EQ(db_->ConnectionCount(), 1UL);
  EXPECT_EQ(db_->ActiveOpenDeleteCount(), 1UL);
  EXPECT_EQ(db_->PendingOpenDeleteCount(), 0UL);

  MockFactoryClient request2(
      /*expect_connection=*/false);
  MockMojoDatabaseCallbacks database_callbacks2;
  const int64_t transaction_id2 = 2;
  auto connection2 = std::make_unique<PendingConnection>(
      std::make_unique<ThunkFactoryClient>(request2),
      std::make_unique<DatabaseCallbacks>(
          database_callbacks2.BindNewEndpointAndPassDedicatedRemote()),
      transaction_id2, kDatabaseVersion, mojo::NullAssociatedReceiver());
  db_->ScheduleOpenConnection(std::move(connection2));
  RunPostedTasks();

  EXPECT_EQ(db_->ConnectionCount(), 1UL);
  EXPECT_EQ(db_->ActiveOpenDeleteCount(), 1UL);
  EXPECT_EQ(db_->PendingOpenDeleteCount(), 1UL);

  MockFactoryClient request3(
      /*expect_connection=*/false);
  MockMojoDatabaseCallbacks database_callbacks3;
  const int64_t transaction_id3 = 3;
  auto connection3 = std::make_unique<PendingConnection>(
      std::make_unique<ThunkFactoryClient>(request3),
      std::make_unique<DatabaseCallbacks>(
          database_callbacks3.BindNewEndpointAndPassDedicatedRemote()),
      transaction_id3, kDatabaseVersion, mojo::NullAssociatedReceiver());
  db_->ScheduleOpenConnection(std::move(connection3));
  RunPostedTasks();

  EXPECT_TRUE(request1.upgrade_called());

  EXPECT_EQ(db_->ConnectionCount(), 1UL);
  EXPECT_EQ(db_->ActiveOpenDeleteCount(), 1UL);
  EXPECT_EQ(db_->PendingOpenDeleteCount(), 2UL);

  EXPECT_CALL(database_callbacks1, ForcedClose);
  EXPECT_CALL(database_callbacks2, ForcedClose);
  EXPECT_CALL(database_callbacks3, ForcedClose);

  db_->ForceCloseAndRunTasks(kTestForceCloseMessage);
  db_ = nullptr;
  database_callbacks1.FlushForTesting();

  EXPECT_TRUE(request1.error_called());
  EXPECT_TRUE(request2.error_called());
  EXPECT_TRUE(request3.error_called());
}

TEST_F(DatabaseTest, ForceDelete) {
  MockFactoryClient request1;
  MockMojoDatabaseCallbacks database_callbacks;
  const int64_t transaction_id1 = 1;
  auto connection = std::make_unique<PendingConnection>(
      std::make_unique<ThunkFactoryClient>(request1),
      std::make_unique<DatabaseCallbacks>(
          database_callbacks.BindNewEndpointAndPassDedicatedRemote()),
      transaction_id1, IndexedDBDatabaseMetadata::DEFAULT_VERSION,
      mojo::NullAssociatedReceiver());
  db_->ScheduleOpenConnection(std::move(connection));
  RunPostedTasks();

  EXPECT_EQ(db_->ConnectionCount(), 1UL);
  EXPECT_EQ(db_->ActiveOpenDeleteCount(), 0UL);
  EXPECT_EQ(db_->PendingOpenDeleteCount(), 0UL);

  base::RunLoop run_loop;
  FakeFactoryClient request2;
  db_->ScheduleDeleteDatabase(std::make_unique<ThunkFactoryClient>(request2),
                              run_loop.QuitClosure());
  RunPostedTasks();
  EXPECT_FALSE(run_loop.AnyQuitCalled());
  db_->ForceCloseAndRunTasks(kTestForceCloseMessage);
  db_ = nullptr;
  run_loop.Run();
  EXPECT_FALSE(db_);
  EXPECT_FALSE(request2.blocked_called());
  EXPECT_TRUE(request2.success_called());
}

TEST_F(DatabaseTest, ForceCloseWhileOpenPending) {
  // Verify that pending connection requests are handled correctly during a
  // ForceClose.
  MockFactoryClient request1;
  MockMojoDatabaseCallbacks database_callbacks1;
  const int64_t transaction_id1 = 1;
  auto connection1 = std::make_unique<PendingConnection>(
      std::make_unique<ThunkFactoryClient>(request1),
      std::make_unique<DatabaseCallbacks>(
          database_callbacks1.BindNewEndpointAndPassDedicatedRemote()),
      transaction_id1, IndexedDBDatabaseMetadata::DEFAULT_VERSION,
      mojo::NullAssociatedReceiver());
  db_->ScheduleOpenConnection(std::move(connection1));
  RunPostedTasks();

  EXPECT_EQ(db_->ConnectionCount(), 1UL);
  EXPECT_EQ(db_->ActiveOpenDeleteCount(), 0UL);
  EXPECT_EQ(db_->PendingOpenDeleteCount(), 0UL);

  MockFactoryClient request2(/*expect_connection=*/false);
  MockMojoDatabaseCallbacks database_callbacks2;

  const int64_t transaction_id2 = 2;
  auto connection2 = std::make_unique<PendingConnection>(
      std::make_unique<ThunkFactoryClient>(request2),
      std::make_unique<DatabaseCallbacks>(
          database_callbacks2.BindNewEndpointAndPassDedicatedRemote()),
      transaction_id2, 3, mojo::NullAssociatedReceiver());
  db_->ScheduleOpenConnection(std::move(connection2));
  RunPostedTasks();

  EXPECT_EQ(db_->ConnectionCount(), 1UL);
  EXPECT_EQ(db_->ActiveOpenDeleteCount(), 1UL);
  EXPECT_EQ(db_->PendingOpenDeleteCount(), 0UL);

  db_->ForceCloseAndRunTasks(kTestForceCloseMessage);
  db_ = nullptr;
  RunPostedTasks();
  EXPECT_FALSE(db_);
}

TEST_F(DatabaseTest, ForceCloseWhileOpenAndDeletePending) {
  // Verify that pending connection requests are handled correctly during a
  // ForceClose.
  MockFactoryClient request1;
  MockMojoDatabaseCallbacks database_callbacks1;
  const int64_t transaction_id1 = 1;
  auto connection1 = std::make_unique<PendingConnection>(
      std::make_unique<ThunkFactoryClient>(request1),
      std::make_unique<DatabaseCallbacks>(
          database_callbacks1.BindNewEndpointAndPassDedicatedRemote()),
      transaction_id1, IndexedDBDatabaseMetadata::DEFAULT_VERSION,
      mojo::NullAssociatedReceiver());
  db_->ScheduleOpenConnection(std::move(connection1));
  RunPostedTasks();

  EXPECT_EQ(db_->ConnectionCount(), 1UL);
  EXPECT_EQ(db_->ActiveOpenDeleteCount(), 0UL);
  EXPECT_EQ(db_->PendingOpenDeleteCount(), 0UL);

  MockFactoryClient request2(false);
  MockMojoDatabaseCallbacks database_callbacks2;
  const int64_t transaction_id2 = 2;
  auto connection2 = std::make_unique<PendingConnection>(
      std::make_unique<ThunkFactoryClient>(request2),
      std::make_unique<DatabaseCallbacks>(
          database_callbacks2.BindNewEndpointAndPassDedicatedRemote()),
      transaction_id2, 3, mojo::NullAssociatedReceiver());
  db_->ScheduleOpenConnection(std::move(connection2));
  RunPostedTasks();

  base::RunLoop run_loop;
  auto request3 = std::make_unique<FakeFactoryClient>();
  db_->ScheduleDeleteDatabase(std::move(request3), run_loop.QuitClosure());
  RunPostedTasks();
  EXPECT_FALSE(run_loop.AnyQuitCalled());

  EXPECT_EQ(db_->ConnectionCount(), 1UL);
  EXPECT_EQ(db_->ActiveOpenDeleteCount(), 1UL);
  EXPECT_EQ(db_->PendingOpenDeleteCount(), 1UL);

  db_->ForceCloseAndRunTasks(kTestForceCloseMessage);
  db_ = nullptr;
  run_loop.Run();
}

Status DummyOperation(Transaction* transaction) {
  return Status::OK();
}

class DatabaseOperationTest : public DatabaseTest {
 public:
  DatabaseOperationTest() = default;
  DatabaseOperationTest(const DatabaseOperationTest&) = delete;
  DatabaseOperationTest& operator=(const DatabaseOperationTest&) = delete;

  void SetUp() override {
    DatabaseTest::SetUp();

    const int64_t transaction_id = 1;
    auto connection = std::make_unique<PendingConnection>(
        std::make_unique<ThunkFactoryClient>(request_),
        std::make_unique<DatabaseCallbacks>(mojo::NullAssociatedRemote()),
        transaction_id, IndexedDBDatabaseMetadata::DEFAULT_VERSION,
        mojo::NullAssociatedReceiver());
    db_->ScheduleOpenConnection(std::move(connection));
    RunPostedTasks();
    EXPECT_EQ(IndexedDBDatabaseMetadata::NO_VERSION, db_->metadata().version);

    EXPECT_TRUE(request_.connection());
    transaction_ = request_.connection()->CreateVersionChangeTransaction(
        transaction_id, /*scope=*/std::set<int64_t>(),
        std::make_unique<FakeTransaction>(
            commit_success_,
            db_->backing_store_db()->CreateTransaction(
                blink::mojom::IDBTransactionDurability::Relaxed,
                blink::mojom::IDBTransactionMode::VersionChange)));

    std::vector<PartitionedLockManager::PartitionedLockRequest> lock_requests =
        db_->BuildLockRequestsForTransaction(
            blink::mojom::IDBTransactionMode::VersionChange, /*scope=*/{});
    db_->lock_manager().AcquireLocks(
        std::move(lock_requests), *transaction_->mutable_locks_receiver(),
        base::BindOnce(&Transaction::Start, transaction_->AsWeakPtr()));

    // Add a dummy task which takes the place of the VersionChangeOperation
    // which kicks off the upgrade. This ensures that the transaction has
    // processed at least one task before the CreateObjectStore call.
    transaction_->ScheduleTask(base::BindOnce(&DummyOperation));
    // Run posted tasks to execute the dummy operation and ensure that it is
    // stored in the connection.
    RunPostedTasks();
  }

  // Populates an object store and optionally an index with `database_records`.
  // After setup, calls `Database::GetAllOperation` with `get_all_parameters`.
  // Verifies that the results match `expected_results`.
  void TestGetAll(
      TestDatabaseParameters database_parameters,
      TestGetAllParameters get_all_parameters,
      base::span<const blink::mojom::IDBRecordPtr> expected_results) {
    // Create the object store.
    ASSERT_EQ(0u, db_->metadata().object_stores.size());
    const auto& object_store_parameters =
        database_parameters.object_store_parameters;
    const int64_t store_id = object_store_parameters.object_store_id;
    Status status = transaction_->BackingStoreTransaction()->CreateObjectStore(
        store_id, object_store_parameters.name,
        object_store_parameters.key_path,
        object_store_parameters.auto_increment);
    EXPECT_TRUE(status.ok()) << status.ToString();
    EXPECT_EQ(1u, db_->metadata().object_stores.size());

    // Optionally, create an index when the test provides a valid index id.
    const blink::IndexedDBIndexMetadata index(
        database_parameters.index_parameters.name,
        database_parameters.index_parameters.index_id,
        database_parameters.index_parameters.key_path,
        database_parameters.index_parameters.unique,
        database_parameters.index_parameters.multi_entry);
    const int64_t index_id = index.id;
    const bool has_index =
        index_id != blink::IndexedDBIndexMetadata::kInvalidId;
    if (has_index) {
      status =
          transaction_->BackingStoreTransaction()->CreateIndex(store_id, index);
    }
    EXPECT_TRUE(status.ok()) << status.ToString();

    // Populate the object store and optionally the index with the provided
    // records.
    for (TestIDBRecord& record : database_parameters.records) {
      std::vector<IndexedDBIndexKeys> index_keys;
      ASSERT_EQ(record.index_key.has_value(), has_index);
      if (has_index) {
        IndexedDBIndexKeys index_key{index_id, {}};
        index_key.keys.emplace_back(std::move(*record.index_key));
        index_keys.emplace_back(std::move(index_key));
      }

      testing::NiceMock<
          base::MockCallback<blink::mojom::IDBTransaction::PutCallback>>
          callback;

      // Set in-flight memory to a reasonably large number to prevent underflow
      // in `PutOperation`
      transaction_->in_flight_memory_ += 1000;

      status = transaction_->DoPut(
          store_id, record.value.Clone(), std::move(record.primary_key),
          blink::mojom::IDBPutMode::AddOnly, std::move(index_keys),
          callback.Get(), transaction_);
      EXPECT_TRUE(status.ok()) << status.ToString();
    }

    // Call `Database::GetAllOperation` with the provided parameters.
    FakeGetAllResultSink result_sink;
    blink::mojom::IDBDatabase::GetAllCallback get_all_callback = base::BindOnce(
        &FakeGetAllResultSink::BindReceiver, base::Unretained(&result_sink));

    std::unique_ptr<Database::GetAllResultSinkWrapper> result_sink_wrapper =
        std::make_unique<Database::GetAllResultSinkWrapper>(
            transaction_->AsWeakPtr(), std::move(get_all_callback));
    result_sink_wrapper->UseDedicatedReceiverForTesting();

    status = db_->GetAllOperation(
        store_id, index_id, std::move(get_all_parameters.key_range),
        get_all_parameters.result_type, get_all_parameters.max_count,
        get_all_parameters.direction, std::move(result_sink_wrapper),
        transaction_);
    EXPECT_TRUE(status.ok()) << status.ToString();

    result_sink.WaitForResults();
    EXPECT_EQ(result_sink.GetError(), nullptr);

    // Verify that the actual results match the expected results.
    const std::vector<blink::mojom::IDBRecordPtr>& actual_results =
        result_sink.GetResults();
    ASSERT_EQ(actual_results.size(), expected_results.size());

    for (size_t i = 0u; i < expected_results.size(); ++i) {
      ASSERT_FALSE(actual_results[i].is_null());

      // Verify the primary key.
      ASSERT_NO_FATAL_FAILURE(ExpectEqualsOptionalIndexedDBKey(
          expected_results[i]->primary_key, actual_results[i]->primary_key));

      // Verify the record value.
      ASSERT_NO_FATAL_FAILURE(ExpectEqualsIDBReturnValuePtr(
          expected_results[i]->return_value, actual_results[i]->return_value));

      // Verify the index key.
      ASSERT_NO_FATAL_FAILURE(ExpectEqualsOptionalIndexedDBKey(
          expected_results[i]->index_key, actual_results[i]->index_key));
    }

    // Perform cleanup.
    transaction_->SetCommitFlag();
    transaction_ = nullptr;
    RunPostedTasks();

    // A transaction error would have resulted in a deleted db.
    EXPECT_FALSE(bucket_context_->GetDatabasesForTesting().empty());
  }

 protected:
  MockFactoryClient request_;

  // As this is owned by `Connection`, tests that cause the transaction
  // to be committed must manually reset this to null to avoid triggering
  // dangling pointer warnings.
  raw_ptr<Transaction> transaction_ = nullptr;
  Status commit_success_;
};

TEST_F(DatabaseOperationTest, CreateObjectStore) {
  EXPECT_EQ(0ULL, db_->metadata().object_stores.size());
  const int64_t store_id = 1001;
  Status s = transaction_->BackingStoreTransaction()->CreateObjectStore(
      store_id, u"store", IndexedDBKeyPath(),
      /*auto_increment=*/false);
  EXPECT_TRUE(s.ok());
  transaction_->SetCommitFlag();
  transaction_ = nullptr;
  RunPostedTasks();
  EXPECT_TRUE(bucket_context_);
  EXPECT_EQ(1ULL, db_->metadata().object_stores.size());
}

TEST_F(DatabaseOperationTest, CreateIndex) {
  EXPECT_EQ(0ULL, db_->metadata().object_stores.size());
  const int64_t store_id = 1001;
  Status s = transaction_->BackingStoreTransaction()->CreateObjectStore(
      store_id, u"store", IndexedDBKeyPath(),
      /*auto_increment=*/false);
  EXPECT_TRUE(s.ok());
  EXPECT_EQ(1ULL, db_->metadata().object_stores.size());
  const int64_t index_id = 2002;
  s = transaction_->BackingStoreTransaction()->CreateIndex(
      store_id, blink::IndexedDBIndexMetadata(
                    u"index", index_id, IndexedDBKeyPath(), /*unique=*/false,
                    /*multi_entry=*/false));
  EXPECT_TRUE(s.ok());
  EXPECT_EQ(
      1ULL,
      db_->metadata().object_stores.find(store_id)->second.indexes.size());
  transaction_->SetCommitFlag();
  transaction_ = nullptr;
  RunPostedTasks();
  EXPECT_TRUE(bucket_context_);
  EXPECT_EQ(1ULL, db_->metadata().object_stores.size());
  EXPECT_EQ(
      1ULL,
      db_->metadata().object_stores.find(store_id)->second.indexes.size());
}

class DatabaseOperationAbortTest : public DatabaseOperationTest {
 public:
  DatabaseOperationAbortTest() {
    commit_success_ = Status::NotFound("Bummer.");
  }

  DatabaseOperationAbortTest(const DatabaseOperationAbortTest&) = delete;
  DatabaseOperationAbortTest& operator=(const DatabaseOperationAbortTest&) =
      delete;
};

TEST_F(DatabaseOperationAbortTest, CreateObjectStore) {
  EXPECT_EQ(0ULL, db_->metadata().object_stores.size());
  const int64_t store_id = 1001;
  Status s = transaction_->BackingStoreTransaction()->CreateObjectStore(
      store_id, u"store", IndexedDBKeyPath(),
      /*auto_increment=*/false);
  EXPECT_TRUE(s.ok());
  EXPECT_EQ(1ULL, db_->metadata().object_stores.size());
  db_ = nullptr;
  transaction_->SetCommitFlag();
  RunPostedTasks();
  // A transaction error results in a deleted db.
  EXPECT_TRUE(bucket_context_->GetDatabasesForTesting().empty());
}

TEST_F(DatabaseOperationAbortTest, CreateIndex) {
  EXPECT_EQ(0ULL, db_->metadata().object_stores.size());
  const int64_t store_id = 1001;
  Status s = transaction_->BackingStoreTransaction()->CreateObjectStore(
      store_id, u"store", IndexedDBKeyPath(),
      /*auto_increment=*/false);
  EXPECT_TRUE(s.ok());
  EXPECT_EQ(1ULL, db_->metadata().object_stores.size());
  const int64_t index_id = 2002;
  s = transaction_->BackingStoreTransaction()->CreateIndex(
      store_id, blink::IndexedDBIndexMetadata(
                    u"index", index_id, IndexedDBKeyPath(), /*unique=*/false,
                    /*multi_entry=*/false));
  EXPECT_TRUE(s.ok());
  EXPECT_EQ(
      1ULL,
      db_->metadata().object_stores.find(store_id)->second.indexes.size());
  db_ = nullptr;
  transaction_->SetCommitFlag();
  RunPostedTasks();
  // A transaction error results in a deleted db.
  EXPECT_TRUE(bucket_context_->GetDatabasesForTesting().empty());
}

TEST_F(DatabaseOperationTest, CreatePutDelete) {
  EXPECT_EQ(0ULL, db_->metadata().object_stores.size());
  const int64_t store_id = 1001;

  Status s = transaction_->BackingStoreTransaction()->CreateObjectStore(
      store_id, u"store", IndexedDBKeyPath(),
      /*auto_increment=*/false);
  EXPECT_TRUE(s.ok());
  EXPECT_EQ(1ULL, db_->metadata().object_stores.size());

  base::MockCallback<blink::mojom::IDBTransaction::PutCallback> callback;

  // Set in-flight memory to a reasonably large number to prevent underflow in
  // `PutOperation`
  transaction_->in_flight_memory_ += 1000;

  s = transaction_->DoPut(
      store_id, IndexedDBValue("value1", {}), IndexedDBKey("key"),
      blink::mojom::IDBPutMode::AddOnly, std::vector<IndexedDBIndexKeys>(),
      callback.Get(), transaction_);
  EXPECT_TRUE(s.ok());

  s = transaction_->BackingStoreTransaction()->DeleteObjectStore(store_id);
  EXPECT_TRUE(s.ok());

  EXPECT_EQ(0ULL, db_->metadata().object_stores.size());

  transaction_->SetCommitFlag();
  transaction_ = nullptr;
  RunPostedTasks();
  // A transaction error would have resulted in a deleted db.
  EXPECT_FALSE(bucket_context_->GetDatabasesForTesting().empty());
  EXPECT_TRUE(s.ok());
}

TEST_F(DatabaseOperationTest, ObjectStoreGetAllKeysWhenEmpty) {
  ASSERT_NO_FATAL_FAILURE(TestGetAll(
      /*database_parameters=*/
      {
          /*object_store_parameters=*/
          {
              .object_store_id = kTestObjectStoreId,
          },
          /*index_parameters=*/{},
          /*database_records=*/{},
      },
      /*get_all_parameters=*/
      {
          .result_type = blink::mojom::IDBGetAllResultType::Keys,
      },
      /*expected_results=*/{}));
}

TEST_F(DatabaseOperationTest, IndexGetAllValuesWhenEmpty) {
  ASSERT_NO_FATAL_FAILURE(TestGetAll(
      /*database_parameters=*/
      {
          /*object_store_parameters=*/
          {
              .object_store_id = kTestObjectStoreId,
          },
          /*index_parameters=*/
          {
              .index_id = kTestIndexId,
          },
          /*database_records=*/{},
      },
      /*get_all_parameters=*/
      {
          .result_type = blink::mojom::IDBGetAllResultType::Values,
      },
      /*expected_results=*/{}));
}

TEST_F(DatabaseOperationTest, ObjectStoreGetAllKeys) {
  const blink::mojom::IDBRecordPtr expected_results[] = {
      blink::mojom::IDBRecord::New(IndexedDBKey{"key1"},
                                   /*value=*/nullptr,
                                   /*index_key=*/std::nullopt),
      blink::mojom::IDBRecord::New(IndexedDBKey{"key2"},
                                   /*value=*/nullptr,
                                   /*index_key=*/std::nullopt),
      blink::mojom::IDBRecord::New(IndexedDBKey{"key3"},
                                   /*value=*/nullptr,
                                   /*index_key=*/std::nullopt),
  };

  ASSERT_NO_FATAL_FAILURE(TestGetAll(
      /*database_parameters=*/
      {
          /*object_store_parameters=*/
          {
              .object_store_id = kTestObjectStoreId,
          },
          /*index_parameters=*/{},
          /*database_records=*/
          {
              {
                  IndexedDBKey{"key1"},
                  {"value1", /*external_objects=*/{}},
                  /*index_key=*/std::nullopt,
              },
              {
                  IndexedDBKey{"key2"},
                  {"value2", /*external_objects=*/{}},
                  /*index_key=*/std::nullopt,
              },
              {
                  IndexedDBKey{"key3"},
                  {"value3", /*external_objects=*/{}},
                  /*index_key=*/std::nullopt,
              },
          },
      },
      /*get_all_parameters=*/
      {
          .result_type = blink::mojom::IDBGetAllResultType::Keys,
      },
      expected_results));
}

TEST_F(DatabaseOperationTest, ObjectStoreGetAllValues) {
  const blink::mojom::IDBRecordPtr expected_results[] = {
      blink::mojom::IDBRecord::New(
          /*primary_key=*/std::nullopt,
          /*value=*/CreateIDBReturnValuePtr("value1"),
          /*index_key=*/std::nullopt),
      blink::mojom::IDBRecord::New(
          /*primary_key=*/std::nullopt,
          /*value=*/CreateIDBReturnValuePtr("value2"),
          /*index_key=*/std::nullopt),
      blink::mojom::IDBRecord::New(
          /*primary_key=*/std::nullopt,
          /*value=*/CreateIDBReturnValuePtr("value3"),
          /*index_key=*/std::nullopt),
  };

  ASSERT_NO_FATAL_FAILURE(TestGetAll(
      /*database_parameters=*/
      {
          /*object_store_parameters=*/
          {
              .object_store_id = kTestObjectStoreId,
          },
          /*index_parameters=*/{},
          /*database_records=*/
          {
              {
                  IndexedDBKey{"key1"},
                  {"value1", /*external_objects=*/{}},
                  /*index_key=*/std::nullopt,
              },
              {
                  IndexedDBKey{"key2"},
                  {"value2", /*external_objects=*/{}},
                  /*index_key=*/std::nullopt,
              },
              {
                  IndexedDBKey{"key3"},
                  {"value3", /*external_objects=*/{}},
                  /*index_key=*/std::nullopt,
              },
          },
      },
      /*get_all_parameters=*/
      {
          .result_type = blink::mojom::IDBGetAllResultType::Values,
      },
      expected_results));
}

TEST_F(DatabaseOperationTest, ObjectStoreGetAllRecords) {
  const blink::mojom::IDBRecordPtr expected_results[] = {
      blink::mojom::IDBRecord::New(IndexedDBKey{"key1"},
                                   /*value=*/CreateIDBReturnValuePtr("value1"),
                                   /*index_key=*/std::nullopt),
      blink::mojom::IDBRecord::New(IndexedDBKey{"key2"},
                                   /*value=*/CreateIDBReturnValuePtr("value2"),
                                   /*index_key=*/std::nullopt),
      blink::mojom::IDBRecord::New(IndexedDBKey{"key3"},
                                   /*value=*/CreateIDBReturnValuePtr("value3"),
                                   /*index_key=*/std::nullopt),
  };

  ASSERT_NO_FATAL_FAILURE(TestGetAll(
      /*database_parameters=*/
      {
          /*object_store_parameters=*/
          {
              .object_store_id = kTestObjectStoreId,
          },
          /*index_parameters=*/{},
          /*database_records=*/
          {
              {
                  IndexedDBKey{"key1"},
                  {"value1", /*external_objects=*/{}},
                  /*index_key=*/std::nullopt,
              },
              {
                  IndexedDBKey{"key2"},
                  {"value2", /*external_objects=*/{}},
                  /*index_key=*/std::nullopt,
              },
              {
                  IndexedDBKey{"key3"},
                  {"value3", /*external_objects=*/{}},
                  /*index_key=*/std::nullopt,
              },
          },
      },
      /*get_all_parameters=*/
      {
          .result_type = blink::mojom::IDBGetAllResultType::Records,
      },
      expected_results));
}

TEST_F(DatabaseOperationTest, IndexGetAllKeys) {
  const blink::mojom::IDBRecordPtr expected_results[] = {
      blink::mojom::IDBRecord::New(IndexedDBKey{"key3"},
                                   /*value=*/nullptr,
                                   /*index_key=*/std::nullopt),
      blink::mojom::IDBRecord::New(IndexedDBKey{"key2"},
                                   /*value=*/nullptr,
                                   /*index_key=*/std::nullopt),
      blink::mojom::IDBRecord::New(IndexedDBKey{"key1"},
                                   /*value=*/nullptr,
                                   /*index_key=*/std::nullopt),
  };

  ASSERT_NO_FATAL_FAILURE(TestGetAll(
      /*database_parameters=*/
      {
          /*object_store_parameters=*/
          {
              .object_store_id = kTestObjectStoreId,
          },
          /*index_parameters=*/
          {
              .index_id = kTestIndexId,
          },
          /*database_records=*/
          {
              {
                  IndexedDBKey{"key1"},
                  {"value1", /*external_objects=*/{}},
                  IndexedDBKey("index_key3"),
              },
              {
                  IndexedDBKey{"key2"},
                  {"value2", /*external_objects=*/{}},
                  IndexedDBKey("index_key2"),
              },
              {
                  IndexedDBKey{"key3"},
                  {"value3", /*external_objects=*/{}},
                  IndexedDBKey("index_key1"),
              },
          },
      },
      /*get_all_parameters=*/
      {
          .result_type = blink::mojom::IDBGetAllResultType::Keys,
      },
      expected_results));
}

TEST_F(DatabaseOperationTest, IndexGetAllValues) {
  const blink::mojom::IDBRecordPtr expected_results[] = {
      blink::mojom::IDBRecord::New(
          /*primary_key=*/std::nullopt,
          /*value=*/CreateIDBReturnValuePtr("value3"),
          /*index_key=*/std::nullopt),
      blink::mojom::IDBRecord::New(
          /*primary_key=*/std::nullopt,
          /*value=*/CreateIDBReturnValuePtr("value2"),
          /*index_key=*/std::nullopt),
      blink::mojom::IDBRecord::New(
          /*primary_key=*/std::nullopt,
          /*value=*/CreateIDBReturnValuePtr("value1"),
          /*index_key=*/std::nullopt),
  };

  ASSERT_NO_FATAL_FAILURE(TestGetAll(
      /*database_parameters=*/
      {
          /*object_store_parameters=*/
          {
              .object_store_id = kTestObjectStoreId,
          },
          /*index_parameters=*/
          {
              .index_id = kTestIndexId,
          },
          /*database_records=*/
          {
              {
                  IndexedDBKey{"key1"},
                  {"value1", /*external_objects=*/{}},
                  IndexedDBKey("index_key3"),
              },
              {
                  IndexedDBKey{"key2"},
                  {"value2", /*external_objects=*/{}},
                  IndexedDBKey("index_key2"),
              },
              {
                  IndexedDBKey{"key3"},
                  {"value3", /*external_objects=*/{}},
                  IndexedDBKey("index_key1"),
              },
          },
      },
      /*get_all_parameters=*/
      {
          .result_type = blink::mojom::IDBGetAllResultType::Values,
      },
      expected_results));
}

TEST_F(DatabaseOperationTest, IndexGetAllRecords) {
  const blink::mojom::IDBRecordPtr expected_results[] = {
      blink::mojom::IDBRecord::New(IndexedDBKey{"key3"},
                                   /*value=*/CreateIDBReturnValuePtr("value3"),
                                   IndexedDBKey{"index_key1"}),
      blink::mojom::IDBRecord::New(IndexedDBKey{"key2"},
                                   /*value=*/CreateIDBReturnValuePtr("value2"),
                                   IndexedDBKey{"index_key2"}),
      blink::mojom::IDBRecord::New(IndexedDBKey{"key1"},
                                   /*value=*/CreateIDBReturnValuePtr("value1"),
                                   IndexedDBKey{"index_key3"}),
  };

  ASSERT_NO_FATAL_FAILURE(TestGetAll(
      /*database_parameters=*/
      {
          /*object_store_parameters=*/
          {
              .object_store_id = kTestObjectStoreId,
          },
          /*index_parameters=*/
          {
              .index_id = kTestIndexId,
          },
          /*database_records=*/
          {
              {
                  IndexedDBKey{"key1"},
                  {"value1", /*external_objects=*/{}},
                  IndexedDBKey("index_key3"),
              },
              {
                  IndexedDBKey{"key2"},
                  {"value2", /*external_objects=*/{}},
                  IndexedDBKey("index_key2"),
              },
              {
                  IndexedDBKey{"key3"},
                  {"value3", /*external_objects=*/{}},
                  IndexedDBKey("index_key1"),
              },
          },
      },
      /*get_all_parameters=*/
      {
          .result_type = blink::mojom::IDBGetAllResultType::Records,
      },
      expected_results));
}

TEST_F(DatabaseOperationTest, ObjectStoreGetAllKeysWithRange) {
  const blink::mojom::IDBRecordPtr expected_results[] = {
      blink::mojom::IDBRecord::New(IndexedDBKey{"key2"},
                                   /*value=*/nullptr,
                                   /*index_key=*/std::nullopt),
      blink::mojom::IDBRecord::New(IndexedDBKey{"key3"},
                                   /*value=*/nullptr,
                                   /*index_key=*/std::nullopt),
  };

  ASSERT_NO_FATAL_FAILURE(TestGetAll(
      /*database_parameters=*/
      {
          /*object_store_parameters=*/
          {
              .object_store_id = kTestObjectStoreId,
          },
          /*index_parameters=*/{},
          /*database_records=*/
          {
              {
                  IndexedDBKey{"key1"},
                  {"value1", /*external_objects=*/{}},
                  /*index_key=*/std::nullopt,
              },
              {
                  IndexedDBKey{"key2"},
                  {"value2", /*external_objects=*/{}},
                  /*index_key=*/std::nullopt,
              },
              {
                  IndexedDBKey{"key3"},
                  {"value3", /*external_objects=*/{}},
                  /*index_key=*/std::nullopt,
              },
          },
      },
      /*get_all_parameters=*/
      {
          .result_type = blink::mojom::IDBGetAllResultType::Keys,
          .key_range =
              {
                  IndexedDBKey("key2"),
                  IndexedDBKey("key9"),
                  /*lower_open=*/false,
                  /*upper_open=*/false,
              },
      },
      expected_results));
}

TEST_F(DatabaseOperationTest, ObjectStoreGetAllKeysWithRangeThatDoesNotExist) {
  ASSERT_NO_FATAL_FAILURE(TestGetAll(
      /*database_parameters=*/
      {
          /*object_store_parameters=*/
          {
              .object_store_id = kTestObjectStoreId,
          },
          /*index_parameters=*/{},
          /*database_records=*/
          {
              {
                  IndexedDBKey{"key1"},
                  {"value1", /*external_objects=*/{}},
                  /*index_key=*/std::nullopt,
              },
              {
                  IndexedDBKey{"key2"},
                  {"value2", /*external_objects=*/{}},
                  /*index_key=*/std::nullopt,
              },
              {
                  IndexedDBKey{"key3"},
                  {"value3", /*external_objects=*/{}},
                  /*index_key=*/std::nullopt,
              },
          },
      },
      /*get_all_parameters=*/
      {
          .result_type = blink::mojom::IDBGetAllResultType::Keys,
          .key_range =
              {
                  IndexedDBKey("key7"),
                  IndexedDBKey("key9"),
                  /*lower_open=*/false,
                  /*upper_open=*/false,
              },
      },
      /*expected_results=*/{}));
}

TEST_F(DatabaseOperationTest, ObjectStoreGetAllKeysWithInvalidRange) {
  ASSERT_NO_FATAL_FAILURE(TestGetAll(
      /*database_parameters=*/
      {
          /*object_store_parameters=*/
          {
              .object_store_id = kTestObjectStoreId,
          },
          /*index_parameters=*/{},
          /*database_records=*/
          {
              {
                  IndexedDBKey{"key1"},
                  {"value1", /*external_objects=*/{}},
                  /*index_key=*/std::nullopt,
              },
              {
                  IndexedDBKey{"key2"},
                  {"value2", /*external_objects=*/{}},
                  /*index_key=*/std::nullopt,
              },
              {
                  IndexedDBKey{"key3"},
                  {"value3", /*external_objects=*/{}},
                  /*index_key=*/std::nullopt,
              },
          },
      },
      /*get_all_parameters=*/
      {
          .result_type = blink::mojom::IDBGetAllResultType::Keys,
          .key_range =
              {
                  IndexedDBKey("key9"),
                  IndexedDBKey("key7"),
                  /*lower_open=*/false,
                  /*upper_open=*/false,
              },
      },
      /*expected_results=*/{}));
}

TEST_F(DatabaseOperationTest, ObjectStoreGetAllKeysWithMaxCount) {
  const blink::mojom::IDBRecordPtr expected_results[] = {
      blink::mojom::IDBRecord::New(IndexedDBKey{"key1"},
                                   /*value=*/nullptr,
                                   /*index_key=*/std::nullopt),
      blink::mojom::IDBRecord::New(IndexedDBKey{"key2"},
                                   /*value=*/nullptr,
                                   /*index_key=*/std::nullopt),
  };

  ASSERT_NO_FATAL_FAILURE(TestGetAll(
      /*database_parameters=*/
      {
          /*object_store_parameters=*/
          {
              .object_store_id = kTestObjectStoreId,
          },
          /*index_parameters=*/{},
          /*database_records=*/
          {
              {
                  IndexedDBKey{"key1"},
                  {"value1", /*external_objects=*/{}},
                  /*index_key=*/std::nullopt,
              },
              {
                  IndexedDBKey{"key2"},
                  {"value2", /*external_objects=*/{}},
                  /*index_key=*/std::nullopt,
              },
              {
                  IndexedDBKey{"key3"},
                  {"value3", /*external_objects=*/{}},
                  /*index_key=*/std::nullopt,
              },
          },
      },
      /*get_all_parameters=*/
      {
          .result_type = blink::mojom::IDBGetAllResultType::Keys,
          .max_count = 2,
      },
      expected_results));
}

TEST_F(DatabaseOperationTest, ObjectStoreGetAllRecordsWithPrevDirection) {
  const blink::mojom::IDBRecordPtr expected_results[] = {
      blink::mojom::IDBRecord::New(IndexedDBKey{"key3"},
                                   /*value=*/CreateIDBReturnValuePtr("value3"),
                                   /*index_key=*/std::nullopt),
      blink::mojom::IDBRecord::New(IndexedDBKey{"key2"},
                                   /*value=*/CreateIDBReturnValuePtr("value2"),
                                   /*index_key=*/std::nullopt),
      blink::mojom::IDBRecord::New(IndexedDBKey{"key1"},
                                   /*value=*/CreateIDBReturnValuePtr("value1"),
                                   /*index_key=*/std::nullopt),
  };

  ASSERT_NO_FATAL_FAILURE(TestGetAll(
      /*database_parameters=*/
      {
          /*object_store_parameters=*/
          {
              .object_store_id = kTestObjectStoreId,
          },
          /*index_parameters=*/{},
          /*database_records=*/
          {
              {
                  IndexedDBKey{"key1"},
                  {"value1", /*external_objects=*/{}},
                  /*index_key=*/std::nullopt,
              },
              {
                  IndexedDBKey{"key2"},
                  {"value2", /*external_objects=*/{}},
                  /*index_key=*/std::nullopt,
              },
              {
                  IndexedDBKey{"key3"},
                  {"value3", /*external_objects=*/{}},
                  /*index_key=*/std::nullopt,
              },
          },
      },
      /*get_all_parameters=*/
      {
          .result_type = blink::mojom::IDBGetAllResultType::Records,
          .direction = blink::mojom::IDBCursorDirection::Prev,
      },
      expected_results));
}

TEST_F(DatabaseOperationTest, IndexGetAllRecordsWithNextNoDuplicateDirection) {
  const blink::mojom::IDBRecordPtr expected_results[] = {
      blink::mojom::IDBRecord::New(IndexedDBKey{"key1"},
                                   /*value=*/CreateIDBReturnValuePtr("value1"),
                                   IndexedDBKey{"index_key1"}),
      blink::mojom::IDBRecord::New(IndexedDBKey{"key2"},
                                   /*value=*/CreateIDBReturnValuePtr("value2"),
                                   IndexedDBKey{"index_key2"}),
      blink::mojom::IDBRecord::New(IndexedDBKey{"key4"},
                                   /*value=*/CreateIDBReturnValuePtr("value4"),
                                   IndexedDBKey{"index_key3"}),
  };

  ASSERT_NO_FATAL_FAILURE(TestGetAll(
      /*database_parameters=*/
      {
          /*object_store_parameters=*/
          {
              .object_store_id = kTestObjectStoreId,
          },
          /*index_parameters=*/
          {
              .index_id = kTestIndexId,
          },
          /*database_records=*/
          {
              {
                  IndexedDBKey{"key1"},
                  {"value1", /*external_objects=*/{}},
                  IndexedDBKey("index_key1"),
              },
              {
                  IndexedDBKey{"key2"},
                  {"value2", /*external_objects=*/{}},
                  IndexedDBKey("index_key2"),
              },
              {
                  IndexedDBKey{"key3"},
                  {"value3", /*external_objects=*/{}},
                  IndexedDBKey("index_key2"),
              },
              {
                  IndexedDBKey{"key4"},
                  {"value4", /*external_objects=*/{}},
                  IndexedDBKey("index_key3"),
              },
              {
                  IndexedDBKey{"key5"},
                  {"value5", /*external_objects=*/{}},
                  IndexedDBKey("index_key3"),
              },
              {
                  IndexedDBKey{"key6"},
                  {"value6", /*external_objects=*/{}},
                  IndexedDBKey("index_key3"),
              },
          },
      },
      /*get_all_parameters=*/
      {
          .result_type = blink::mojom::IDBGetAllResultType::Records,
          .direction = blink::mojom::IDBCursorDirection::NextNoDuplicate,
      },
      expected_results));
}

TEST_F(DatabaseOperationTest, IndexGetAllRecordsWithPrevNoDuplicateDirection) {
  const blink::mojom::IDBRecordPtr expected_results[] = {
      blink::mojom::IDBRecord::New(IndexedDBKey{"key4"},
                                   /*value=*/CreateIDBReturnValuePtr("value4"),
                                   IndexedDBKey{"index_key3"}),
      blink::mojom::IDBRecord::New(IndexedDBKey{"key2"},
                                   /*value=*/CreateIDBReturnValuePtr("value2"),
                                   IndexedDBKey{"index_key2"}),
      blink::mojom::IDBRecord::New(IndexedDBKey{"key1"},
                                   /*value=*/CreateIDBReturnValuePtr("value1"),
                                   IndexedDBKey{"index_key1"}),
  };

  ASSERT_NO_FATAL_FAILURE(TestGetAll(
      /*database_parameters=*/
      {
          /*object_store_parameters=*/
          {
              .object_store_id = kTestObjectStoreId,
          },
          /*index_parameters=*/
          {
              .index_id = kTestIndexId,
          },
          /*database_records=*/
          {
              {
                  IndexedDBKey{"key1"},
                  {"value1", /*external_objects=*/{}},
                  IndexedDBKey("index_key1"),
              },
              {
                  IndexedDBKey{"key2"},
                  {"value2", /*external_objects=*/{}},
                  IndexedDBKey("index_key2"),
              },
              {
                  IndexedDBKey{"key3"},
                  {"value3", /*external_objects=*/{}},
                  IndexedDBKey("index_key2"),
              },
              {
                  IndexedDBKey{"key4"},
                  {"value4", /*external_objects=*/{}},
                  IndexedDBKey("index_key3"),
              },
              {
                  IndexedDBKey{"key5"},
                  {"value5", /*external_objects=*/{}},
                  IndexedDBKey("index_key3"),
              },
              {
                  IndexedDBKey{"key6"},
                  {"value6", /*external_objects=*/{}},
                  IndexedDBKey("index_key3"),
              },
          },
      },
      /*get_all_parameters=*/
      {
          .result_type = blink::mojom::IDBGetAllResultType::Records,
          .direction = blink::mojom::IDBCursorDirection::PrevNoDuplicate,
      },
      expected_results));
}

TEST_F(DatabaseOperationTest, ObjectStoreGetAllKeysWithInvalidObjectStoreId) {
  ASSERT_EQ(0u, db_->metadata().object_stores.size());

  // Call `Database::GetAllOperation` with an invalid object store id, which
  // must fail with an invalid argument status.
  FakeGetAllResultSink result_sink;
  blink::mojom::IDBDatabase::GetAllCallback get_all_callback = base::BindOnce(
      &FakeGetAllResultSink::BindReceiver, base::Unretained(&result_sink));

  std::unique_ptr<Database::GetAllResultSinkWrapper> result_sink_wrapper =
      std::make_unique<Database::GetAllResultSinkWrapper>(
          transaction_->AsWeakPtr(), std::move(get_all_callback));
  result_sink_wrapper->UseDedicatedReceiverForTesting();

  TestGetAllParameters get_all_parameters;

  Status status = db_->GetAllOperation(
      kTestObjectStoreId,
      /*index_id=*/blink::IndexedDBIndexMetadata::kInvalidId,
      std::move(get_all_parameters.key_range), get_all_parameters.result_type,
      get_all_parameters.max_count, get_all_parameters.direction,
      std::move(result_sink_wrapper), transaction_);
  ASSERT_TRUE(status.IsInvalidArgument()) << status.ToString();

  // Verify that the result sink received an error.
  result_sink.WaitForResults();
  ASSERT_NE(result_sink.GetError(), nullptr);
  EXPECT_EQ(result_sink.GetError()->error_code,
            blink::mojom::IDBException::kUnknownError);

  // Perform cleanup.
  transaction_->SetCommitFlag();
  transaction_ = nullptr;
  RunPostedTasks();
}

TEST_F(DatabaseOperationTest, IndexGetAllKeysWithInvalidIndexId) {
  // Create an object store.
  ASSERT_EQ(0u, db_->metadata().object_stores.size());
  Status status = transaction_->BackingStoreTransaction()->CreateObjectStore(
      kTestObjectStoreId, u"store", IndexedDBKeyPath(),
      /*auto_increment=*/false);
  ASSERT_TRUE(status.ok()) << status.ToString();
  ASSERT_EQ(1u, db_->metadata().object_stores.size());

  // Call `Database::GetAllOperation` with an invalid index id, which must fail
  // with an invalid argument status.
  FakeGetAllResultSink result_sink;
  blink::mojom::IDBDatabase::GetAllCallback get_all_callback = base::BindOnce(
      &FakeGetAllResultSink::BindReceiver, base::Unretained(&result_sink));

  std::unique_ptr<Database::GetAllResultSinkWrapper> result_sink_wrapper =
      std::make_unique<Database::GetAllResultSinkWrapper>(
          transaction_->AsWeakPtr(), std::move(get_all_callback));
  result_sink_wrapper->UseDedicatedReceiverForTesting();

  TestGetAllParameters get_all_parameters;

  status = db_->GetAllOperation(
      kTestObjectStoreId, kTestIndexId, std::move(get_all_parameters.key_range),
      get_all_parameters.result_type, get_all_parameters.max_count,
      get_all_parameters.direction, std::move(result_sink_wrapper),
      transaction_);
  ASSERT_TRUE(status.IsInvalidArgument()) << status.ToString();

  // Verify that the result sink received an error.
  result_sink.WaitForResults();
  ASSERT_NE(result_sink.GetError(), nullptr);
  EXPECT_EQ(result_sink.GetError()->error_code,
            blink::mojom::IDBException::kUnknownError);

  // Perform cleanup.
  transaction_->SetCommitFlag();
  transaction_ = nullptr;
  RunPostedTasks();
}

TEST_F(DatabaseOperationTest,
       ObjectStoreGetAllRecordsWithMultipleResultChunks) {
  // Generate 2.5 chunks of results.
  const size_t record_count = (blink::mojom::kIDBGetAllChunkSize * 2) +
                              (blink::mojom::kIDBGetAllChunkSize / 2);

  std::vector<TestIDBRecord> database_records;
  std::vector<blink::mojom::IDBRecordPtr> expected_results;

  for (size_t i = 0u; i < record_count; ++i) {
    const std::string primary_key = base::StringPrintf("key%zu", i);
    const std::string value = base::StringPrintf("value%zu", i);

    database_records.emplace_back(IndexedDBKey{primary_key},
                                  IndexedDBValue{value, {}},
                                  /*index_key=*/std::nullopt);

    expected_results.emplace_back(
        blink::mojom::IDBRecord::New(IndexedDBKey{primary_key},
                                     /*value=*/CreateIDBReturnValuePtr(value),
                                     /*index_key=*/std::nullopt));
  }

  // Sort the expected results by primary key.
  std::sort(expected_results.begin(), expected_results.end(),
            [](const blink::mojom::IDBRecordPtr& left,
               const blink::mojom::IDBRecordPtr& right) {
              return left->primary_key->IsLessThan(*right->primary_key);
            });

  ASSERT_NO_FATAL_FAILURE(TestGetAll(
      /*database_parameters=*/
      {
          /*object_store_parameters=*/
          {
              .object_store_id = kTestObjectStoreId,
          },
          /*index_parameters=*/{},
          std::move(database_records),
      },
      /*get_all_parameters=*/
      {
          .result_type = blink::mojom::IDBGetAllResultType::Records,
      },
      expected_results));
}

TEST_F(DatabaseOperationTest, IndexGetAllRecordsWithAutoIncrementingKeys) {
  const IndexedDBKeyPath object_store_key_path{u"id"};

  const auto expected_generated_keys = std::to_array<IndexedDBKey>({
      IndexedDBKey(1.0, blink::mojom::IDBKeyType::Number),
      IndexedDBKey(2.0, blink::mojom::IDBKeyType::Number),
      IndexedDBKey(3.0, blink::mojom::IDBKeyType::Number),
  });

  const blink::mojom::IDBRecordPtr expected_results[] = {
      blink::mojom::IDBRecord::New(
          /*primary_key=*/expected_generated_keys[2].Clone(),
          /*value=*/
          CreateIDBReturnValuePtr("value3", &expected_generated_keys[2],
                                  object_store_key_path),
          /*index_key=*/IndexedDBKey{"index_key1"}),
      blink::mojom::IDBRecord::New(
          /*primary_key=*/expected_generated_keys[1].Clone(),
          /*value=*/
          CreateIDBReturnValuePtr("value2", &expected_generated_keys[1],
                                  object_store_key_path),
          /*index_key=*/IndexedDBKey{"index_key2"}),
      blink::mojom::IDBRecord::New(
          /*primary_key=*/expected_generated_keys[0].Clone(),
          /*value=*/
          CreateIDBReturnValuePtr("value1", &expected_generated_keys[0],
                                  object_store_key_path),
          /*index_key=*/IndexedDBKey{"index_key3"}),
  };

  ASSERT_NO_FATAL_FAILURE(TestGetAll(
      /*database_parameters=*/
      {
          /*object_store_parameters=*/
          {
              .object_store_id = kTestObjectStoreId,
              .key_path = object_store_key_path,
              .auto_increment = true,
          },
          /*index_parameters=*/
          {
              .index_id = kTestIndexId,
          },
          /*database_records=*/
          {
              {
                  /*primary_key (generated)=*/IndexedDBKey(),
                  {"value1", /*external_objects=*/{}},
                  IndexedDBKey("index_key3"),
              },
              {
                  /*primary_key (generated)=*/IndexedDBKey(),
                  {"value2", /*external_objects=*/{}},
                  IndexedDBKey("index_key2"),
              },
              {
                  /*primary_key (generated)=*/IndexedDBKey(),
                  {"value3", /*external_objects=*/{}},
                  IndexedDBKey("index_key1"),
              },
          },
      },
      /*get_all_parameters=*/
      {
          .result_type = blink::mojom::IDBGetAllResultType::Records,
      },
      expected_results));
}

}  // namespace content::indexed_db
