// 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/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 "mojo/public/cpp/test_support/fake_message_dispatch_context.h"
#include "mojo/public/cpp/test_support/test_utils.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),
        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));
}

// Verifies that a bad index id passed in a mojo call will cause an error to be
// reported.
TEST_F(DatabaseOperationTest, GetWithInvalidId) {
  ASSERT_EQ(0u, db_->metadata().object_stores.size());

  mojo::FakeMessageDispatchContext fake_dispatch_context;
  mojo::test::BadMessageObserver bad_message_observer;

  base::RunLoop run_loop;
  auto get_callback = base::BindLambdaForTesting(
      [&](blink::mojom::IDBDatabaseGetResultPtr result) {
        EXPECT_TRUE(result->is_error_result());
        run_loop.Quit();
      });

  request_.connection()->Get(
      transaction_->id(), kTestObjectStoreId,
      /*index_id=*/blink::IndexedDBIndexMetadata::kInvalidId, {},
      /*key_only=*/true, std::move(get_callback));
  // The operation will cause the database to be torn down, so avoid a dangling
  // pointer.
  db_ = nullptr;
  run_loop.Run();

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

  EXPECT_TRUE(bad_message_observer.got_bad_message());
}

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
