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

#include "third_party/blink/renderer/core/fetch/bytes_consumer_tee.h"

#include "base/memory/scoped_refptr.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/core/fetch/bytes_consumer_test_util.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
#include "third_party/blink/renderer/platform/blob/blob_data.h"
#include "third_party/blink/renderer/platform/loader/testing/bytes_consumer_test_reader.h"
#include "third_party/blink/renderer/platform/loader/testing/replaying_bytes_consumer.h"
#include "third_party/blink/renderer/platform/network/encoded_form_data.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"

namespace blink {

namespace {

using Result = BytesConsumer::Result;

class BytesConsumerTestClient final
    : public GarbageCollected<BytesConsumerTestClient>,
      public BytesConsumer::Client {
 public:
  void OnStateChange() override { ++num_on_state_change_called_; }
  String DebugName() const override { return "BytesConsumerTestClient"; }
  int NumOnStateChangeCalled() const { return num_on_state_change_called_; }

 private:
  int num_on_state_change_called_ = 0;
};

class BytesConsumerTeeTest : public PageTestBase {
 public:
  using Command = ReplayingBytesConsumer::Command;
  void SetUp() override { PageTestBase::SetUp(IntSize()); }
};

class FakeBlobBytesConsumer : public BytesConsumer {
 public:
  explicit FakeBlobBytesConsumer(scoped_refptr<BlobDataHandle> handle)
      : blob_handle_(std::move(handle)) {}
  ~FakeBlobBytesConsumer() override {}

  Result BeginRead(const char** buffer, size_t* available) override {
    if (state_ == PublicState::kClosed)
      return Result::kDone;
    blob_handle_ = nullptr;
    state_ = PublicState::kErrored;
    return Result::kError;
  }
  Result EndRead(size_t read_size) override {
    if (state_ == PublicState::kClosed)
      return Result::kError;
    blob_handle_ = nullptr;
    state_ = PublicState::kErrored;
    return Result::kError;
  }
  scoped_refptr<BlobDataHandle> DrainAsBlobDataHandle(
      BlobSizePolicy policy) override {
    if (state_ != PublicState::kReadableOrWaiting)
      return nullptr;
    DCHECK(blob_handle_);
    if (policy == BlobSizePolicy::kDisallowBlobWithInvalidSize &&
        blob_handle_->size() == UINT64_MAX)
      return nullptr;
    state_ = PublicState::kClosed;
    return std::move(blob_handle_);
  }

  void SetClient(Client*) override {}
  void ClearClient() override {}
  void Cancel() override {}
  PublicState GetPublicState() const override { return state_; }
  Error GetError() const override { return Error(); }
  String DebugName() const override { return "FakeBlobBytesConsumer"; }

 private:
  PublicState state_ = PublicState::kReadableOrWaiting;
  scoped_refptr<BlobDataHandle> blob_handle_;
};

class FakeFormDataBytesConsumer : public BytesConsumer {
 public:
  explicit FakeFormDataBytesConsumer(scoped_refptr<EncodedFormData> form_data)
      : form_data_(std::move(form_data)) {}
  ~FakeFormDataBytesConsumer() override {}

  Result BeginRead(const char** buffer, size_t* available) override {
    if (state_ == PublicState::kClosed)
      return Result::kDone;
    form_data_ = nullptr;
    state_ = PublicState::kErrored;
    return Result::kError;
  }
  Result EndRead(size_t read_size) override {
    if (state_ == PublicState::kClosed)
      return Result::kError;
    form_data_ = nullptr;
    state_ = PublicState::kErrored;
    return Result::kError;
  }
  scoped_refptr<EncodedFormData> DrainAsFormData() override {
    if (state_ != PublicState::kReadableOrWaiting)
      return nullptr;
    DCHECK(form_data_);
    return std::move(form_data_);
  }

  void SetClient(Client*) override {}
  void ClearClient() override {}
  void Cancel() override {}
  PublicState GetPublicState() const override { return state_; }
  Error GetError() const override { return Error(); }
  String DebugName() const override { return "FakeFormDataBytesConsumer"; }

 private:
  PublicState state_ = PublicState::kReadableOrWaiting;
  scoped_refptr<EncodedFormData> form_data_;
};

TEST_F(BytesConsumerTeeTest, CreateDone) {
  ReplayingBytesConsumer* src = MakeGarbageCollected<ReplayingBytesConsumer>(
      GetDocument().GetTaskRunner(TaskType::kNetworking));
  src->Add(Command(Command::kDone));
  EXPECT_FALSE(src->IsCancelled());

  BytesConsumer* dest1 = nullptr;
  BytesConsumer* dest2 = nullptr;
  BytesConsumerTee(GetFrame().DomWindow(), src, &dest1, &dest2);

  auto result1 = (MakeGarbageCollected<BytesConsumerTestReader>(dest1))->Run();
  auto result2 = (MakeGarbageCollected<BytesConsumerTestReader>(dest2))->Run();

  EXPECT_EQ(Result::kDone, result1.first);
  EXPECT_TRUE(result1.second.IsEmpty());
  EXPECT_EQ(BytesConsumer::PublicState::kClosed, dest1->GetPublicState());
  EXPECT_EQ(Result::kDone, result2.first);
  EXPECT_TRUE(result2.second.IsEmpty());
  EXPECT_EQ(BytesConsumer::PublicState::kClosed, dest2->GetPublicState());
  EXPECT_FALSE(src->IsCancelled());

  // Cancelling does nothing when closed.
  dest1->Cancel();
  dest2->Cancel();
  EXPECT_EQ(BytesConsumer::PublicState::kClosed, dest1->GetPublicState());
  EXPECT_EQ(BytesConsumer::PublicState::kClosed, dest2->GetPublicState());
  EXPECT_FALSE(src->IsCancelled());
}

TEST_F(BytesConsumerTeeTest, TwoPhaseRead) {
  ReplayingBytesConsumer* src = MakeGarbageCollected<ReplayingBytesConsumer>(
      GetDocument().GetTaskRunner(TaskType::kNetworking));

  src->Add(Command(Command::kWait));
  src->Add(Command(Command::kData, "hello, "));
  src->Add(Command(Command::kWait));
  src->Add(Command(Command::kData, "world"));
  src->Add(Command(Command::kWait));
  src->Add(Command(Command::kWait));
  src->Add(Command(Command::kDone));

  BytesConsumer* dest1 = nullptr;
  BytesConsumer* dest2 = nullptr;
  BytesConsumerTee(GetFrame().DomWindow(), src, &dest1, &dest2);

  EXPECT_EQ(BytesConsumer::PublicState::kReadableOrWaiting,
            dest1->GetPublicState());
  EXPECT_EQ(BytesConsumer::PublicState::kReadableOrWaiting,
            dest2->GetPublicState());

  auto result1 = (MakeGarbageCollected<BytesConsumerTestReader>(dest1))->Run();
  auto result2 = (MakeGarbageCollected<BytesConsumerTestReader>(dest2))->Run();

  EXPECT_EQ(Result::kDone, result1.first);
  EXPECT_EQ("hello, world",
            BytesConsumerTestUtil::CharVectorToString(result1.second));
  EXPECT_EQ(BytesConsumer::PublicState::kClosed, dest1->GetPublicState());
  EXPECT_EQ(Result::kDone, result2.first);
  EXPECT_EQ("hello, world",
            BytesConsumerTestUtil::CharVectorToString(result2.second));
  EXPECT_EQ(BytesConsumer::PublicState::kClosed, dest2->GetPublicState());
  EXPECT_FALSE(src->IsCancelled());
}

TEST_F(BytesConsumerTeeTest, TwoPhaseReadWithDataAndDone) {
  ReplayingBytesConsumer* src = MakeGarbageCollected<ReplayingBytesConsumer>(
      GetDocument().GetTaskRunner(TaskType::kNetworking));

  src->Add(Command(Command::kWait));
  src->Add(Command(Command::kData, "hello, "));
  src->Add(Command(Command::kWait));
  src->Add(Command(Command::kDataAndDone, "world"));

  BytesConsumer* dest1 = nullptr;
  BytesConsumer* dest2 = nullptr;
  BytesConsumerTee(GetFrame().DomWindow(), src, &dest1, &dest2);

  EXPECT_EQ(BytesConsumer::PublicState::kReadableOrWaiting,
            dest1->GetPublicState());
  EXPECT_EQ(BytesConsumer::PublicState::kReadableOrWaiting,
            dest2->GetPublicState());

  auto result1 = (MakeGarbageCollected<BytesConsumerTestReader>(dest1))->Run();
  auto result2 = (MakeGarbageCollected<BytesConsumerTestReader>(dest2))->Run();

  EXPECT_EQ(Result::kDone, result1.first);
  EXPECT_EQ("hello, world",
            BytesConsumerTestUtil::CharVectorToString(result1.second));
  EXPECT_EQ(BytesConsumer::PublicState::kClosed, dest1->GetPublicState());
  EXPECT_EQ(Result::kDone, result2.first);
  EXPECT_EQ("hello, world",
            BytesConsumerTestUtil::CharVectorToString(result2.second));
  EXPECT_EQ(BytesConsumer::PublicState::kClosed, dest2->GetPublicState());
  EXPECT_FALSE(src->IsCancelled());
}

TEST_F(BytesConsumerTeeTest, Error) {
  ReplayingBytesConsumer* src = MakeGarbageCollected<ReplayingBytesConsumer>(
      GetDocument().GetTaskRunner(TaskType::kNetworking));

  src->Add(Command(Command::kData, "hello, "));
  src->Add(Command(Command::kData, "world"));
  src->Add(Command(Command::kError));

  BytesConsumer* dest1 = nullptr;
  BytesConsumer* dest2 = nullptr;
  BytesConsumerTee(GetFrame().DomWindow(), src, &dest1, &dest2);

  EXPECT_EQ(BytesConsumer::PublicState::kErrored, dest1->GetPublicState());
  EXPECT_EQ(BytesConsumer::PublicState::kErrored, dest2->GetPublicState());

  auto result1 = (MakeGarbageCollected<BytesConsumerTestReader>(dest1))->Run();
  auto result2 = (MakeGarbageCollected<BytesConsumerTestReader>(dest2))->Run();

  EXPECT_EQ(Result::kError, result1.first);
  EXPECT_TRUE(result1.second.IsEmpty());
  EXPECT_EQ(BytesConsumer::PublicState::kErrored, dest1->GetPublicState());
  EXPECT_EQ(Result::kError, result2.first);
  EXPECT_TRUE(result2.second.IsEmpty());
  EXPECT_EQ(BytesConsumer::PublicState::kErrored, dest2->GetPublicState());
  EXPECT_FALSE(src->IsCancelled());

  // Cancelling does nothing when errored.
  dest1->Cancel();
  dest2->Cancel();
  EXPECT_EQ(BytesConsumer::PublicState::kErrored, dest1->GetPublicState());
  EXPECT_EQ(BytesConsumer::PublicState::kErrored, dest2->GetPublicState());
  EXPECT_FALSE(src->IsCancelled());
}

TEST_F(BytesConsumerTeeTest, Cancel) {
  ReplayingBytesConsumer* src = MakeGarbageCollected<ReplayingBytesConsumer>(
      GetDocument().GetTaskRunner(TaskType::kNetworking));

  src->Add(Command(Command::kData, "hello, "));
  src->Add(Command(Command::kWait));

  BytesConsumer* dest1 = nullptr;
  BytesConsumer* dest2 = nullptr;
  BytesConsumerTee(GetFrame().DomWindow(), src, &dest1, &dest2);

  EXPECT_EQ(BytesConsumer::PublicState::kReadableOrWaiting,
            dest1->GetPublicState());
  EXPECT_EQ(BytesConsumer::PublicState::kReadableOrWaiting,
            dest2->GetPublicState());

  EXPECT_FALSE(src->IsCancelled());
  dest1->Cancel();
  EXPECT_EQ(BytesConsumer::PublicState::kClosed, dest1->GetPublicState());
  EXPECT_EQ(BytesConsumer::PublicState::kReadableOrWaiting,
            dest2->GetPublicState());
  EXPECT_FALSE(src->IsCancelled());
  dest2->Cancel();
  EXPECT_EQ(BytesConsumer::PublicState::kClosed, dest1->GetPublicState());
  EXPECT_EQ(BytesConsumer::PublicState::kClosed, dest2->GetPublicState());
  EXPECT_TRUE(src->IsCancelled());
}

TEST_F(BytesConsumerTeeTest, CancelShouldNotAffectTheOtherDestination) {
  ReplayingBytesConsumer* src = MakeGarbageCollected<ReplayingBytesConsumer>(
      GetDocument().GetTaskRunner(TaskType::kNetworking));

  src->Add(Command(Command::kData, "hello, "));
  src->Add(Command(Command::kWait));
  src->Add(Command(Command::kData, "world"));
  src->Add(Command(Command::kDone));

  BytesConsumer* dest1 = nullptr;
  BytesConsumer* dest2 = nullptr;
  BytesConsumerTee(GetFrame().DomWindow(), src, &dest1, &dest2);

  EXPECT_EQ(BytesConsumer::PublicState::kReadableOrWaiting,
            dest1->GetPublicState());
  EXPECT_EQ(BytesConsumer::PublicState::kReadableOrWaiting,
            dest2->GetPublicState());

  EXPECT_FALSE(src->IsCancelled());
  dest1->Cancel();
  EXPECT_EQ(BytesConsumer::PublicState::kClosed, dest1->GetPublicState());
  EXPECT_EQ(BytesConsumer::PublicState::kReadableOrWaiting,
            dest2->GetPublicState());
  EXPECT_FALSE(src->IsCancelled());

  auto result2 = (MakeGarbageCollected<BytesConsumerTestReader>(dest2))->Run();

  EXPECT_EQ(BytesConsumer::PublicState::kClosed, dest1->GetPublicState());
  EXPECT_EQ(BytesConsumer::PublicState::kClosed, dest2->GetPublicState());
  EXPECT_EQ(Result::kDone, result2.first);
  EXPECT_EQ("hello, world",
            BytesConsumerTestUtil::CharVectorToString(result2.second));
  EXPECT_FALSE(src->IsCancelled());
}

TEST_F(BytesConsumerTeeTest, CancelShouldNotAffectTheOtherDestination2) {
  ReplayingBytesConsumer* src = MakeGarbageCollected<ReplayingBytesConsumer>(
      GetDocument().GetTaskRunner(TaskType::kNetworking));

  src->Add(Command(Command::kData, "hello, "));
  src->Add(Command(Command::kWait));
  src->Add(Command(Command::kData, "world"));
  src->Add(Command(Command::kError));

  BytesConsumer* dest1 = nullptr;
  BytesConsumer* dest2 = nullptr;
  BytesConsumerTee(GetFrame().DomWindow(), src, &dest1, &dest2);

  EXPECT_EQ(BytesConsumer::PublicState::kReadableOrWaiting,
            dest1->GetPublicState());
  EXPECT_EQ(BytesConsumer::PublicState::kReadableOrWaiting,
            dest2->GetPublicState());

  EXPECT_FALSE(src->IsCancelled());
  dest1->Cancel();
  EXPECT_EQ(BytesConsumer::PublicState::kClosed, dest1->GetPublicState());
  EXPECT_EQ(BytesConsumer::PublicState::kReadableOrWaiting,
            dest2->GetPublicState());
  EXPECT_FALSE(src->IsCancelled());

  auto result2 = (MakeGarbageCollected<BytesConsumerTestReader>(dest2))->Run();

  EXPECT_EQ(BytesConsumer::PublicState::kClosed, dest1->GetPublicState());
  EXPECT_EQ(BytesConsumer::PublicState::kErrored, dest2->GetPublicState());
  EXPECT_EQ(Result::kError, result2.first);
  EXPECT_FALSE(src->IsCancelled());
}

TEST_F(BytesConsumerTeeTest, BlobHandle) {
  scoped_refptr<BlobDataHandle> blob_data_handle =
      BlobDataHandle::Create(std::make_unique<BlobData>(), 12345);
  BytesConsumer* src =
      MakeGarbageCollected<FakeBlobBytesConsumer>(blob_data_handle);

  BytesConsumer* dest1 = nullptr;
  BytesConsumer* dest2 = nullptr;
  BytesConsumerTee(GetFrame().DomWindow(), src, &dest1, &dest2);

  scoped_refptr<BlobDataHandle> dest_blob_data_handle1 =
      dest1->DrainAsBlobDataHandle(
          BytesConsumer::BlobSizePolicy::kAllowBlobWithInvalidSize);
  scoped_refptr<BlobDataHandle> dest_blob_data_handle2 =
      dest2->DrainAsBlobDataHandle(
          BytesConsumer::BlobSizePolicy::kDisallowBlobWithInvalidSize);
  ASSERT_TRUE(dest_blob_data_handle1);
  ASSERT_TRUE(dest_blob_data_handle2);
  EXPECT_EQ(12345u, dest_blob_data_handle1->size());
  EXPECT_EQ(12345u, dest_blob_data_handle2->size());
}

TEST_F(BytesConsumerTeeTest, BlobHandleWithInvalidSize) {
  scoped_refptr<BlobDataHandle> blob_data_handle = BlobDataHandle::Create(
      std::make_unique<BlobData>(), std::numeric_limits<uint64_t>::max());
  BytesConsumer* src =
      MakeGarbageCollected<FakeBlobBytesConsumer>(blob_data_handle);

  BytesConsumer* dest1 = nullptr;
  BytesConsumer* dest2 = nullptr;
  BytesConsumerTee(GetFrame().DomWindow(), src, &dest1, &dest2);

  scoped_refptr<BlobDataHandle> dest_blob_data_handle1 =
      dest1->DrainAsBlobDataHandle(
          BytesConsumer::BlobSizePolicy::kAllowBlobWithInvalidSize);
  scoped_refptr<BlobDataHandle> dest_blob_data_handle2 =
      dest2->DrainAsBlobDataHandle(
          BytesConsumer::BlobSizePolicy::kDisallowBlobWithInvalidSize);
  ASSERT_TRUE(dest_blob_data_handle1);
  ASSERT_FALSE(dest_blob_data_handle2);
  EXPECT_EQ(UINT64_MAX, dest_blob_data_handle1->size());
}

TEST_F(BytesConsumerTeeTest, FormData) {
  auto form_data = EncodedFormData::Create();

  auto* src = MakeGarbageCollected<FakeFormDataBytesConsumer>(form_data);

  BytesConsumer* dest1 = nullptr;
  BytesConsumer* dest2 = nullptr;
  BytesConsumerTee(GetFrame().DomWindow(), src, &dest1, &dest2);

  scoped_refptr<EncodedFormData> dest_form_data1 = dest1->DrainAsFormData();
  scoped_refptr<EncodedFormData> dest_form_data2 = dest2->DrainAsFormData();
  EXPECT_EQ(form_data, dest_form_data1);
  EXPECT_EQ(form_data, dest_form_data2);
}

TEST_F(BytesConsumerTeeTest, ConsumerCanBeErroredInTwoPhaseRead) {
  ReplayingBytesConsumer* src = MakeGarbageCollected<ReplayingBytesConsumer>(
      GetDocument().GetTaskRunner(TaskType::kNetworking));
  src->Add(Command(Command::kData, "a"));
  src->Add(Command(Command::kWait));
  src->Add(Command(Command::kError));

  BytesConsumer* dest1 = nullptr;
  BytesConsumer* dest2 = nullptr;
  BytesConsumerTee(GetFrame().DomWindow(), src, &dest1, &dest2);
  BytesConsumerTestClient* client =
      MakeGarbageCollected<BytesConsumerTestClient>();
  dest1->SetClient(client);

  const char* buffer = nullptr;
  size_t available = 0;
  ASSERT_EQ(Result::kOk, dest1->BeginRead(&buffer, &available));
  ASSERT_EQ(1u, available);

  EXPECT_EQ(BytesConsumer::PublicState::kReadableOrWaiting,
            dest1->GetPublicState());
  int num_on_state_change_called = client->NumOnStateChangeCalled();
  EXPECT_EQ(
      Result::kError,
      (MakeGarbageCollected<BytesConsumerTestReader>(dest2))->Run().first);
  EXPECT_EQ(BytesConsumer::PublicState::kErrored, dest1->GetPublicState());
  EXPECT_EQ(num_on_state_change_called + 1, client->NumOnStateChangeCalled());
  EXPECT_EQ('a', buffer[0]);
  EXPECT_EQ(Result::kOk, dest1->EndRead(available));
}

TEST_F(BytesConsumerTeeTest,
       AsyncNotificationShouldBeDispatchedWhenAllDataIsConsumed) {
  ReplayingBytesConsumer* src = MakeGarbageCollected<ReplayingBytesConsumer>(
      GetDocument().GetTaskRunner(TaskType::kNetworking));
  src->Add(Command(Command::kData, "a"));
  src->Add(Command(Command::kWait));
  src->Add(Command(Command::kDone));
  BytesConsumerTestClient* client =
      MakeGarbageCollected<BytesConsumerTestClient>();

  BytesConsumer* dest1 = nullptr;
  BytesConsumer* dest2 = nullptr;
  BytesConsumerTee(GetFrame().DomWindow(), src, &dest1, &dest2);

  dest1->SetClient(client);

  const char* buffer = nullptr;
  size_t available = 0;
  ASSERT_EQ(Result::kOk, dest1->BeginRead(&buffer, &available));
  ASSERT_EQ(1u, available);
  EXPECT_EQ('a', buffer[0]);

  EXPECT_EQ(BytesConsumer::PublicState::kReadableOrWaiting,
            src->GetPublicState());
  test::RunPendingTasks();
  EXPECT_EQ(BytesConsumer::PublicState::kClosed, src->GetPublicState());
  // Just for checking UAF.
  EXPECT_EQ('a', buffer[0]);
  ASSERT_EQ(Result::kOk, dest1->EndRead(1));

  EXPECT_EQ(0, client->NumOnStateChangeCalled());
  EXPECT_EQ(BytesConsumer::PublicState::kReadableOrWaiting,
            dest1->GetPublicState());
  test::RunPendingTasks();
  EXPECT_EQ(1, client->NumOnStateChangeCalled());
  EXPECT_EQ(BytesConsumer::PublicState::kClosed, dest1->GetPublicState());
}

TEST_F(BytesConsumerTeeTest,
       AsyncCloseNotificationShouldBeCancelledBySubsequentReadCall) {
  ReplayingBytesConsumer* src = MakeGarbageCollected<ReplayingBytesConsumer>(
      GetDocument().GetTaskRunner(TaskType::kNetworking));
  src->Add(Command(Command::kData, "a"));
  src->Add(Command(Command::kDone));
  BytesConsumerTestClient* client =
      MakeGarbageCollected<BytesConsumerTestClient>();

  BytesConsumer* dest1 = nullptr;
  BytesConsumer* dest2 = nullptr;
  BytesConsumerTee(GetFrame().DomWindow(), src, &dest1, &dest2);

  dest1->SetClient(client);

  const char* buffer = nullptr;
  size_t available = 0;
  ASSERT_EQ(Result::kOk, dest1->BeginRead(&buffer, &available));
  ASSERT_EQ(1u, available);
  EXPECT_EQ('a', buffer[0]);

  test::RunPendingTasks();
  // Just for checking UAF.
  EXPECT_EQ('a', buffer[0]);
  ASSERT_EQ(Result::kOk, dest1->EndRead(1));
  EXPECT_EQ(BytesConsumer::PublicState::kReadableOrWaiting,
            dest1->GetPublicState());

  EXPECT_EQ(Result::kDone, dest1->BeginRead(&buffer, &available));
  EXPECT_EQ(0, client->NumOnStateChangeCalled());
  EXPECT_EQ(BytesConsumer::PublicState::kClosed, dest1->GetPublicState());
  test::RunPendingTasks();
  EXPECT_EQ(0, client->NumOnStateChangeCalled());
  EXPECT_EQ(BytesConsumer::PublicState::kClosed, dest1->GetPublicState());
}

TEST(BytesConusmerTest, ClosedBytesConsumer) {
  BytesConsumer* consumer = BytesConsumer::CreateClosed();

  const char* buffer = nullptr;
  size_t available = 0;
  EXPECT_EQ(Result::kDone, consumer->BeginRead(&buffer, &available));
  EXPECT_EQ(BytesConsumer::PublicState::kClosed, consumer->GetPublicState());
}

TEST(BytesConusmerTest, ErroredBytesConsumer) {
  BytesConsumer::Error error("hello");
  BytesConsumer* consumer = BytesConsumer::CreateErrored(error);

  const char* buffer = nullptr;
  size_t available = 0;
  EXPECT_EQ(Result::kError, consumer->BeginRead(&buffer, &available));
  EXPECT_EQ(BytesConsumer::PublicState::kErrored, consumer->GetPublicState());
  EXPECT_EQ(error.Message(), consumer->GetError().Message());

  consumer->Cancel();
  EXPECT_EQ(BytesConsumer::PublicState::kErrored, consumer->GetPublicState());
}

}  // namespace

}  // namespace blink
