// Copyright 2023 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 "quiche/quic/moqt/moqt_session.h"

#include <algorithm>
#include <cstdint>
#include <cstring>
#include <memory>
#include <optional>
#include <queue>
#include <string>
#include <utility>
#include <variant>
#include <vector>

#include "absl/base/casts.h"
#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "quiche/quic/core/quic_data_reader.h"
#include "quiche/quic/core/quic_time.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/moqt/moqt_bidi_stream.h"
#include "quiche/quic/moqt/moqt_error.h"
#include "quiche/quic/moqt/moqt_fetch_task.h"
#include "quiche/quic/moqt/moqt_framer.h"
#include "quiche/quic/moqt/moqt_key_value_pair.h"
#include "quiche/quic/moqt/moqt_known_track_publisher.h"
#include "quiche/quic/moqt/moqt_messages.h"
#include "quiche/quic/moqt/moqt_names.h"
#include "quiche/quic/moqt/moqt_object.h"
#include "quiche/quic/moqt/moqt_object_subscriber.h"
#include "quiche/quic/moqt/moqt_priority.h"
#include "quiche/quic/moqt/moqt_publisher.h"
#include "quiche/quic/moqt/moqt_session_callbacks.h"
#include "quiche/quic/moqt/moqt_session_interface.h"
#include "quiche/quic/moqt/moqt_types.h"
#include "quiche/quic/moqt/test_tools/moqt_framer_utils.h"
#include "quiche/quic/moqt/test_tools/moqt_mock_visitor.h"
#include "quiche/quic/moqt/test_tools/moqt_session_peer.h"
#include "quiche/quic/platform/api/quic_test.h"
#include "quiche/quic/test_tools/quic_test_utils.h"
#include "quiche/common/quiche_buffer_allocator.h"
#include "quiche/common/quiche_data_reader.h"
#include "quiche/common/quiche_mem_slice.h"
#include "quiche/common/quiche_weak_ptr.h"
#include "quiche/web_transport/test_tools/in_memory_stream.h"
#include "quiche/web_transport/test_tools/mock_web_transport.h"
#include "quiche/web_transport/web_transport.h"

namespace moqt {

namespace test {

namespace {

using ::testing::_;
using ::testing::Optional;
using ::testing::Return;
using ::testing::StrictMock;

constexpr webtransport::StreamId kIncomingUniStreamId = 15;
constexpr webtransport::StreamId kOutgoingUniStreamId = 14;
constexpr uint64_t kDefaultLocalRequestId = 0;
constexpr uint64_t kDefaultPeerRequestId = 1;
const MoqtDataStreamType kDefaultSubgroupStreamType =
    MoqtDataStreamType::Subgroup(2, 4, false, false, true);
constexpr MoqtPriority kDefaultPublisherPriority = 0x80;
const TrackExtensions kNoExtensions;

std::vector<quiche::QuicheMemSlice> PayloadFromString(absl::string_view s) {
  std::vector<quiche::QuicheMemSlice> payload;
  payload.push_back(quiche::QuicheMemSlice::Copy(s));
  return payload;
}

FullTrackName kDefaultTrackName() { return FullTrackName("foo", "bar"); }

MoqtSubscribe DefaultSubscribe(uint64_t request_id) {
  MoqtSubscribe subscribe = {
      request_id,
      kDefaultTrackName(),
      MessageParameters(),
  };
  return subscribe;
}

MessageParameters SubscribeForTest() {
  MessageParameters parameters;
  parameters.delivery_timeout = quic::QuicTimeDelta::FromMilliseconds(10000);
  parameters.authorization_tokens.emplace_back(AuthTokenType::kOutOfBand,
                                               "bar");
  parameters.set_forward(true);
  parameters.subscriber_priority = 0x20;
  parameters.subscription_filter.emplace(Location(4, 1));
  parameters.group_order = MoqtDeliveryOrder::kDescending;
  return parameters;
}

// The usual test case is that a SUBSCRIBE is coming in.
MoqtSubscribe DefaultSubscribe() {
  return DefaultSubscribe(kDefaultPeerRequestId);
}

// Used when a test sets up a remote track.
MoqtSubscribe DefaultLocalSubscribe() {
  return DefaultSubscribe(kDefaultLocalRequestId);
}

MoqtFetch DefaultFetch() {
  MoqtFetch fetch = {
      kDefaultPeerRequestId,
      StandaloneFetch(kDefaultTrackName(), Location(0, 0),
                      Location(1, kMaxObjectId)),
      MessageParameters(),
  };
  return fetch;
}

std::optional<MoqtMessageType> PeekControlMessageType(absl::string_view data) {
  quiche::QuicheDataReader reader(data);
  uint64_t varint;
  if (!reader.ReadMoqVarInt(&varint)) {
    return std::nullopt;
  }
  return static_cast<MoqtMessageType>(varint);
}

}  // namespace

class MoqtSessionTest : public quic::test::QuicTest {
 public:
  MoqtSessionTest()
      : session_(&mock_session_,
                 MoqtSessionParameters(quic::Perspective::IS_CLIENT, "", ""),
                 std::make_unique<quic::test::TestAlarmFactory>(),
                 session_callbacks_.AsSessionCallbacks()) {
    session_.set_publisher(&publisher_);
    MoqtSessionPeer::set_peer_max_request_id(&session_,
                                             kDefaultInitialMaxRequestId);
    ON_CALL(mock_session_, GetStreamById)
        .WillByDefault(Return(&mock_bidi_stream_));
    EXPECT_EQ(MoqtSessionPeer::GetImplementationString(&session_),
              kImplementationName);
  }
  ~MoqtSessionTest() {
    EXPECT_CALL(session_callbacks_.session_deleted_callback, Call());
  }

  MockTrackPublisher* CreateTrackPublisher() {
    auto publisher = std::make_shared<MockTrackPublisher>(kDefaultTrackName());
    publisher_.Add(publisher);
    ON_CALL(*publisher, largest_location()).WillByDefault(Return(std::nullopt));
    ON_CALL(*publisher, expiration()).WillByDefault(Return(std::nullopt));
    ON_CALL(*publisher, extensions())
        .WillByDefault(testing::ReturnRef(kNoExtensions));
    return publisher.get();
  }

  void SetLargestId(MockTrackPublisher* publisher, Location largest_id) {
    ON_CALL(*publisher, largest_location()).WillByDefault(Return(largest_id));
  }

  // Opens an incoming request stream, determines the type based on first_byte
  // and returns MoqtBidiStreamBase that can be downcast to the correct type.
  // |wt_stream| is the underlying mock WebTransport stream; if nullptr, use
  // mock_bidi_stream_.
  static constexpr absl::string_view kSubscribeByte = "\x03";
  static constexpr absl::string_view kSubscribeNamespaceByte = "\x50";
  static constexpr absl::string_view kPublishByte = "\x1d";
  static constexpr absl::string_view kTrackStatusByte = "\x0d";
  std::unique_ptr<MoqtBidiStreamBase> ResponseStream(
      absl::string_view first_byte,
      webtransport::test::MockStream* wt_stream = nullptr) {
    webtransport::test::MockStream* stream =
        wt_stream != nullptr ? wt_stream : &mock_bidi_stream_;
    EXPECT_CALL(mock_session_, AcceptIncomingBidirectionalStream())
        .WillOnce(Return(stream))
        .WillOnce(Return(nullptr));
    std::unique_ptr<webtransport::StreamVisitor> unknown_bidi_stream;
    std::unique_ptr<MoqtBidiStreamBase> final_stream;
    EXPECT_CALL(*stream, SetVisitor)
        .WillOnce([&](std::unique_ptr<webtransport::StreamVisitor> visitor) {
          unknown_bidi_stream = std::move(visitor);
        })
        .WillOnce([&](std::unique_ptr<webtransport::StreamVisitor> visitor) {
          final_stream = std::unique_ptr<MoqtBidiStreamBase>(
              absl::down_cast<MoqtBidiStreamBase*>(visitor.release()));
        });
    EXPECT_CALL(*stream, visitor())
        .WillOnce([&]() { return unknown_bidi_stream.get(); })
        .WillRepeatedly([&]() { return final_stream.get(); });
    EXPECT_CALL(*stream, PeekNextReadableRegion)
        .WillOnce(
            Return(webtransport::Stream::PeekResult(first_byte, false, false)))
        .WillRepeatedly(
            Return(webtransport::Stream::PeekResult("", false, false)));
    EXPECT_CALL(*stream, ReadableBytes())
        .WillOnce(Return(first_byte.length()))
        .WillRepeatedly(Return(0));
    EXPECT_CALL(*stream, Read(::testing::An<absl::Span<char>>()))
        .WillOnce([&](absl::Span<char> bytes_to_read) {
          memcpy(bytes_to_read.data(), first_byte.data(), first_byte.length());
          return webtransport::Stream::ReadResult(first_byte.length(), false);
        });
    session_.OnIncomingBidirectionalStreamAvailable();
    EXPECT_NE(final_stream, nullptr);
    EXPECT_CALL(*stream, CanWrite).WillRepeatedly(Return(true));
    return final_stream;
  }

  void PrepareRequestStream(
      std::unique_ptr<MoqtBidiStreamTestWrapper>& stream_wrapper,
      webtransport::test::MockStream* wt_stream = nullptr) {
    webtransport::test::MockStream* stream =
        wt_stream != nullptr ? wt_stream : &mock_bidi_stream_;
    EXPECT_CALL(mock_session_, CanOpenNextOutgoingBidirectionalStream())
        .WillOnce(Return(true));
    EXPECT_CALL(mock_session_, OpenOutgoingBidirectionalStream())
        .WillOnce(Return(stream));
    EXPECT_CALL(*stream, SetVisitor)
        .WillOnce([&](std::unique_ptr<webtransport::StreamVisitor> visitor) {
          stream_wrapper = std::make_unique<MoqtBidiStreamTestWrapper>(
              std::unique_ptr<MoqtBidiStreamBase>(
                  absl::down_cast<MoqtBidiStreamBase*>(visitor.release())));
        });
    EXPECT_CALL(*stream, CanWrite).WillRepeatedly(Return(true));
  }

  // The publisher receives SUBSCRIBE and synchronously publishes namespaces it
  // supports.
  MoqtObjectListener* ReceiveSubscribeSynchronousOk(
      MockTrackPublisher* publisher, MoqtSubscribe& subscribe,
      MoqtBidiStreamTestWrapper* control_parser, uint64_t track_alias = 0,
      TrackExtensions extensions = TrackExtensions()) {
    MoqtObjectListener* listener_ptr = nullptr;
    EXPECT_CALL(*publisher, AddObjectListener)
        .WillOnce([&](MoqtObjectListener* listener) {
          listener_ptr = listener;
          listener->OnSubscribeAccepted();
        });
    MessageParameters parameters;
    parameters.expires = publisher->expiration();
    parameters.largest_object = publisher->largest_location();
    MoqtSubscribeOk expected_ok = {
        subscribe.request_id,
        track_alias,
        parameters,
        extensions,
    };
    EXPECT_CALL(mock_bidi_stream_,
                Writev(SerializedControlMessage(expected_ok), _));
    control_parser->ReceiveMessage(subscribe);
    return listener_ptr;
  }

  // If visitor == nullptr, it's the first object in the stream, and will be
  // assigned to the visitor the session creates.
  // TODO(martinduke): Support delivering object payload.
  void DeliverObject(MoqtObject& object, bool fin,
                     webtransport::test::MockSession& session,
                     webtransport::test::MockStream* stream,
                     std::unique_ptr<webtransport::StreamVisitor>& visitor,
                     MockLiveSubscriberVisitor* track_visitor) {
    MoqtFramer framer(true, quic::Perspective::IS_SERVER);
    std::optional<PublishedObjectMetadata> previous_object;
    if (visitor != nullptr) {
      previous_object = PublishedObjectMetadata();
      previous_object->location.object = object.object_id - 1;
    }
    quiche::QuicheBuffer buffer = framer.SerializeObjectHeader(
        object,
        MoqtDataStreamType::Subgroup(
            *object.subgroup_id, object.object_id, false, false,
            object.first_object_in_subgroup.value_or(true)),
        previous_object);
    size_t data_read = 0;
    if (visitor == nullptr) {  // It's the first object in the stream
      EXPECT_CALL(session, AcceptIncomingUnidirectionalStream())
          .WillOnce(Return(stream))
          .WillOnce(Return(nullptr));
      EXPECT_CALL(*stream, SetVisitor(_))
          .WillOnce(
              [&](std::unique_ptr<webtransport::StreamVisitor> new_visitor) {
                visitor = std::move(new_visitor);
              });
      EXPECT_CALL(*stream, visitor()).WillRepeatedly([&]() {
        return visitor.get();
      });
    }
    EXPECT_CALL(*stream, PeekNextReadableRegion()).WillRepeatedly([&]() {
      return webtransport::Stream::PeekResult(
          absl::string_view(buffer.data() + data_read,
                            buffer.size() - data_read),
          fin && data_read == buffer.size(), fin);
    });
    EXPECT_CALL(*stream, ReadableBytes()).WillRepeatedly([&]() {
      return buffer.size() - data_read;
    });
    EXPECT_CALL(*stream, Read(testing::An<absl::Span<char>>()))
        .WillRepeatedly([&](absl::Span<char> bytes_to_read) {
          size_t read_size =
              std::min(bytes_to_read.size(), buffer.size() - data_read);
          memcpy(bytes_to_read.data(), buffer.data() + data_read, read_size);
          data_read += read_size;
          return webtransport::Stream::ReadResult(
              read_size, fin && data_read == buffer.size());
        });
    EXPECT_CALL(*stream, SkipBytes(_)).WillRepeatedly([&](size_t bytes) {
      data_read += bytes;
      return fin && data_read == buffer.size();
    });
    EXPECT_CALL(*track_visitor, OnObjectFragment).Times(1);
    if (visitor == nullptr) {
      session_.OnIncomingUnidirectionalStreamAvailable();
    } else {
      visitor->OnCanRead();
    }
  }

  MockLiveSubscriberVisitor remote_track_visitor_;
  MoqtKnownTrackPublisher publisher_;
  webtransport::test::MockSession mock_session_;
  MockSessionCallbacks session_callbacks_;
  std::unique_ptr<MoqtBidiStreamTestWrapper> bidi_wrapper_;
  MoqtSession session_;
  webtransport::test::MockStream mock_bidi_stream_, mock_uni_stream_;
  //  std::shared_ptr<IncomingSubscribeInfo> last_incoming_subscribe_;
};

TEST_F(MoqtSessionTest, Queries) {
  EXPECT_EQ(session_.perspective(), quic::Perspective::IS_CLIENT);
}

// Verify the session sends CLIENT_SETUP on the control stream.
TEST_F(MoqtSessionTest, OnSessionReady) {
  EXPECT_CALL(mock_session_, GetNegotiatedSubprotocol)
      .WillOnce(Return(std::optional<std::string>(kDefaultMoqtVersion)));
  EXPECT_CALL(mock_session_, CanOpenNextOutgoingBidirectionalStream())
      .WillOnce(Return(true));
  EXPECT_CALL(mock_session_, OpenOutgoingBidirectionalStream())
      .WillOnce(Return(&mock_bidi_stream_));
  EXPECT_CALL(mock_bidi_stream_, CanWrite).WillRepeatedly(Return(true));
  std::unique_ptr<webtransport::StreamVisitor> visitor;
  // Save a reference to MoqtSession::Stream
  EXPECT_CALL(mock_bidi_stream_, SetVisitor(_))
      .WillOnce([&](std::unique_ptr<webtransport::StreamVisitor> new_visitor) {
        visitor = std::move(new_visitor);
      });
  EXPECT_CALL(mock_bidi_stream_, GetStreamId())
      .WillRepeatedly(Return(webtransport::StreamId(4)));
  EXPECT_CALL(mock_bidi_stream_,
              Writev(ControlMessageOfType(MoqtMessageType::kSetup), _));
  session_.OnSessionReady();

  // Receive SERVER_SETUP
  bidi_wrapper_ =
      MoqtSessionPeer::FetchParserVisitorFromWebtransportStreamVisitor(
          std::move(visitor));
  // Handle the server setup
  MoqtSetup setup;  // No fields are set.
  EXPECT_CALL(session_callbacks_.session_established_callback, Call()).Times(1);
  bidi_wrapper_->ReceiveMessage(setup);
}

TEST_F(MoqtSessionTest, OnSessionReadyNoControlStream) {
  EXPECT_CALL(mock_session_, GetNegotiatedSubprotocol)
      .WillOnce(Return(std::optional<std::string>(kDefaultMoqtVersion)));
  EXPECT_CALL(mock_session_, CanOpenNextOutgoingBidirectionalStream)
      .WillOnce(Return(false));
  EXPECT_CALL(session_callbacks_.session_terminated_callback, Call);
  session_.OnSessionReady();
}

TEST_F(MoqtSessionTest, PeerOpensBidiStream) {
  MoqtSession server_session(
      &mock_session_, MoqtSessionParameters(quic::Perspective::IS_SERVER),
      std::make_unique<quic::test::TestAlarmFactory>(),
      session_callbacks_.AsSessionCallbacks());
  EXPECT_CALL(mock_session_, AcceptIncomingBidirectionalStream())
      .WillOnce(Return(&mock_bidi_stream_))
      .WillOnce(Return(nullptr));
  std::unique_ptr<webtransport::StreamVisitor> visitor;
  webtransport::test::MockStreamVisitor mock_stream_visitor;
  EXPECT_CALL(mock_bidi_stream_, SetVisitor)
      .WillOnce([&](std::unique_ptr<webtransport::StreamVisitor> new_visitor) {
        visitor = std::move(new_visitor);
        EXPECT_CALL(mock_bidi_stream_, visitor).WillOnce(Return(visitor.get()));
      });
  EXPECT_CALL(mock_bidi_stream_, PeekNextReadableRegion())
      .WillRepeatedly(Return(
          webtransport::Stream::PeekResult(absl::string_view(), false, false)));
  server_session.OnIncomingBidirectionalStreamAvailable();
}

TEST_F(MoqtSessionTest, OnClientSetup) {
  MoqtSessionParameters session_parameters(quic::Perspective::IS_SERVER);
  MoqtSession server_session(&mock_session_, session_parameters,
                             std::make_unique<quic::test::TestAlarmFactory>(),
                             session_callbacks_.AsSessionCallbacks());
  // Load a CLIENT_SETUP message into an in-memory stream.
  webtransport::test::InMemoryStreamWithWriteBuffer in_memory_stream(0);
  MoqtFramer framer(session_parameters.using_webtrans,
                    quic::Perspective::IS_CLIENT);
  MoqtSetup setup;
  session_parameters.ToSetupParameters(setup.parameters);
  quiche::QuicheBuffer buffer = framer.SerializeSetup(setup);
  in_memory_stream.Receive(absl::string_view(buffer.data(), buffer.size()),
                           /*fin=*/false);

  EXPECT_CALL(mock_session_, AcceptIncomingBidirectionalStream())
      .WillOnce(Return(&in_memory_stream))
      .WillOnce(Return(nullptr));
  EXPECT_CALL(session_callbacks_.session_established_callback, Call());
  server_session.OnIncomingBidirectionalStreamAvailable();
  EXPECT_EQ(PeekControlMessageType(in_memory_stream.write_buffer()),
            MoqtMessageType::kSetup);
  EXPECT_NE(MoqtSessionPeer::GetControlStream(&server_session), nullptr);
}

TEST_F(MoqtSessionTest, OnSessionClosed) {
  bool reported_error = false;
  EXPECT_CALL(session_callbacks_.session_terminated_callback, Call(_))
      .WillOnce([&](absl::string_view error_message) {
        reported_error = true;
        EXPECT_EQ(error_message, "foo");
      });
  session_.OnSessionClosed(webtransport::SessionErrorCode(1), "foo");
  EXPECT_TRUE(reported_error);
}

TEST_F(MoqtSessionTest, OnIncomingBidirectionalStream) {
  ::testing::InSequence seq;
  StrictMock<webtransport::test::MockStreamVisitor> mock_stream_visitor;
  EXPECT_CALL(mock_session_, AcceptIncomingBidirectionalStream())
      .WillOnce(Return(&mock_bidi_stream_));
  EXPECT_CALL(mock_bidi_stream_, SetVisitor).Times(1);
  EXPECT_CALL(mock_bidi_stream_, visitor())
      .WillOnce(Return(&mock_stream_visitor));
  EXPECT_CALL(mock_stream_visitor, OnCanRead()).Times(1);
  EXPECT_CALL(mock_session_, AcceptIncomingBidirectionalStream())
      .WillOnce(Return(nullptr));
  session_.OnIncomingBidirectionalStreamAvailable();
}

TEST_F(MoqtSessionTest, OnIncomingUnidirectionalStream) {
  ::testing::InSequence seq;
  StrictMock<webtransport::test::MockStreamVisitor> mock_stream_visitor;
  EXPECT_CALL(mock_session_, AcceptIncomingUnidirectionalStream())
      .WillOnce(Return(&mock_uni_stream_));
  EXPECT_CALL(mock_uni_stream_, SetVisitor(_)).Times(1);
  EXPECT_CALL(mock_uni_stream_, visitor())
      .WillOnce(Return(&mock_stream_visitor));
  EXPECT_CALL(mock_stream_visitor, OnCanRead()).Times(1);
  EXPECT_CALL(mock_session_, AcceptIncomingUnidirectionalStream())
      .WillOnce(Return(nullptr));
  session_.OnIncomingUnidirectionalStreamAvailable();
}

TEST_F(MoqtSessionTest, Error) {
  bool reported_error = false;
  EXPECT_CALL(
      mock_session_,
      CloseSession(static_cast<uint64_t>(MoqtError::kProtocolViolation), "foo"))
      .Times(1);
  EXPECT_CALL(session_callbacks_.session_terminated_callback, Call(_))
      .WillOnce([&](absl::string_view error_message) {
        reported_error = (error_message == "foo");
      });
  session_.Error(MoqtError::kProtocolViolation, "foo");
  EXPECT_TRUE(reported_error);
}

TEST_F(MoqtSessionTest, AddLocalTrack) {
  MoqtSubscribe request = DefaultSubscribe();
  bidi_wrapper_ = std::make_unique<MoqtBidiStreamTestWrapper>(
      ResponseStream(kSubscribeByte));
  // Request for track returns REQUEST_ERROR.
  EXPECT_CALL(mock_bidi_stream_,
              Writev(ControlMessageOfType(MoqtMessageType::kRequestError), _));
  bidi_wrapper_->ReceiveMessage(request);

  // Add the track. Now Subscribe should succeed.
  MockTrackPublisher* track = CreateTrackPublisher();
  request.request_id += 2;
  bidi_wrapper_ = std::make_unique<MoqtBidiStreamTestWrapper>(
      ResponseStream(kSubscribeByte));
  ReceiveSubscribeSynchronousOk(track, request, bidi_wrapper_.get(),
                                MoqtSessionPeer::GetLastTrackAlias(&session_));
}

TEST_F(MoqtSessionTest, IncomingPublishRejected) {
  MoqtPublish publish = {
      .request_id = 1,
      .full_track_name = FullTrackName("foo", "bar"),
      .track_alias = 2,
      .parameters = MessageParameters(),
  };
  publish.parameters.largest_object = Location(4, 5);
  bidi_wrapper_ =
      std::make_unique<MoqtBidiStreamTestWrapper>(ResponseStream(kPublishByte));
  // With the default incoming_publish_callbackm, will return REQUEST_ERROR.
  EXPECT_CALL(mock_bidi_stream_,
              Writev(ControlMessageOfType(MoqtMessageType::kRequestError), _));
  bidi_wrapper_->ReceiveMessage(publish);
}

TEST_F(MoqtSessionTest, PublishNamespaceWithOkAndCancel) {
  testing::MockFunction<void(
      std::variant<MessageParameters, MoqtRequestErrorInfo> error_message)>
      publish_namespace_response_callback;
  std::unique_ptr<MoqtBidiStreamTestWrapper> bidi_wrapper_ =
      MoqtSessionPeer::CreateControlStream(&session_, &mock_bidi_stream_);
  EXPECT_CALL(
      mock_bidi_stream_,
      Writev(ControlMessageOfType(MoqtMessageType::kPublishNamespace), _));
  MoqtRequestErrorInfo cancel_error_info;
  session_.PublishNamespace(
      TrackNamespace({"foo"}), MessageParameters(),
      publish_namespace_response_callback.AsStdFunction(),
      [&](MoqtRequestErrorInfo info) { cancel_error_info = info; });

  MoqtRequestOk ok = {/*request_id=*/0, MessageParameters()};
  EXPECT_CALL(publish_namespace_response_callback, Call)
      .WillOnce(
          [&](std::variant<MessageParameters, MoqtRequestErrorInfo> response) {
            EXPECT_TRUE(std::holds_alternative<MessageParameters>(response));
          });
  bidi_wrapper_->ReceiveMessage(ok);

  MoqtPublishNamespaceCancel cancel = {
      /*request_id=*/0,
      RequestErrorCode::kInternalError,
      /*error_reason=*/"Test error",
  };
  bidi_wrapper_->ReceiveMessage(cancel);
  EXPECT_EQ(cancel_error_info.error_code, RequestErrorCode::kInternalError);
  EXPECT_EQ(cancel_error_info.reason_phrase, "Test error");
  // State is gone.
  EXPECT_FALSE(session_.PublishNamespaceDone(TrackNamespace({"foo"})));
}

TEST_F(MoqtSessionTest, PublishNamespaceWithOkAndPublishNamespaceDone) {
  testing::MockFunction<void(
      std::variant<MessageParameters, MoqtRequestErrorInfo>)>
      publish_namespace_resolved_callback;
  std::unique_ptr<MoqtBidiStreamTestWrapper> bidi_wrapper_ =
      MoqtSessionPeer::CreateControlStream(&session_, &mock_bidi_stream_);
  EXPECT_CALL(
      mock_bidi_stream_,
      Writev(ControlMessageOfType(MoqtMessageType::kPublishNamespace), _));
  session_.PublishNamespace(TrackNamespace{"foo"}, MessageParameters(),
                            publish_namespace_resolved_callback.AsStdFunction(),
                            [](MoqtRequestErrorInfo) {});

  MoqtRequestOk ok = {/*request_id=*/0, MessageParameters()};
  EXPECT_CALL(publish_namespace_resolved_callback, Call)
      .WillOnce(
          [&](std::variant<MessageParameters, MoqtRequestErrorInfo> response) {
            EXPECT_TRUE(std::holds_alternative<MessageParameters>(response));
          });
  bidi_wrapper_->ReceiveMessage(ok);

  EXPECT_CALL(
      mock_bidi_stream_,
      Writev(ControlMessageOfType(MoqtMessageType::kPublishNamespaceDone), _));
  session_.PublishNamespaceDone(TrackNamespace{"foo"});
  // State is gone.
  EXPECT_FALSE(session_.PublishNamespaceDone(TrackNamespace{"foo"}));
}

TEST_F(MoqtSessionTest, PublishNamespaceWithError) {
  testing::MockFunction<void(
      std::variant<MessageParameters, MoqtRequestErrorInfo>)>
      publish_namespace_resolved_callback;
  std::unique_ptr<MoqtBidiStreamTestWrapper> bidi_wrapper_ =
      MoqtSessionPeer::CreateControlStream(&session_, &mock_bidi_stream_);
  EXPECT_CALL(
      mock_bidi_stream_,
      Writev(ControlMessageOfType(MoqtMessageType::kPublishNamespace), _));
  session_.PublishNamespace(TrackNamespace{"foo"}, MessageParameters(),
                            publish_namespace_resolved_callback.AsStdFunction(),
                            [](MoqtRequestErrorInfo) {});

  MoqtRequestError error{/*request_id=*/0, RequestErrorCode::kInternalError,
                         std::nullopt, "Test error"};
  EXPECT_CALL(publish_namespace_resolved_callback, Call)
      .WillOnce(
          [&](std::variant<MessageParameters, MoqtRequestErrorInfo> response) {
            ASSERT_TRUE(std::holds_alternative<MoqtRequestErrorInfo>(response));
            const MoqtRequestErrorInfo& error =
                std::get<MoqtRequestErrorInfo>(response);
            EXPECT_EQ(error.error_code, RequestErrorCode::kInternalError);
            EXPECT_EQ(error.reason_phrase, "Test error");
          });
  bidi_wrapper_->ReceiveMessage(error);
  // State is gone.
  EXPECT_FALSE(session_.PublishNamespaceDone(TrackNamespace{"foo"}));
}

TEST_F(MoqtSessionTest, AsynchronousSubscribeReturnsOk) {
  bidi_wrapper_ = std::make_unique<MoqtBidiStreamTestWrapper>(
      ResponseStream(kSubscribeByte));
  MoqtSubscribe request = DefaultSubscribe();
  MockTrackPublisher* track = CreateTrackPublisher();
  MoqtObjectListener* listener;
  EXPECT_CALL(*track, AddObjectListener)
      .WillOnce(
          [&](MoqtObjectListener* listener_ptr) { listener = listener_ptr; });
  bidi_wrapper_->ReceiveMessage(request);

  EXPECT_CALL(mock_bidi_stream_,
              Writev(ControlMessageOfType(MoqtMessageType::kSubscribeOk), _));
  listener->OnSubscribeAccepted();
  EXPECT_TRUE(MoqtSessionPeer::RequestIdIsLivePublisher(&session_,
                                                        kDefaultPeerRequestId));
}

TEST_F(MoqtSessionTest, AsynchronousSubscribeReturnsError) {
  bidi_wrapper_ = std::make_unique<MoqtBidiStreamTestWrapper>(
      ResponseStream(kSubscribeByte));
  MoqtSubscribe request = DefaultSubscribe();
  MockTrackPublisher* track = CreateTrackPublisher();
  MoqtObjectListener* listener;
  EXPECT_CALL(*track, AddObjectListener)
      .WillOnce(
          [&](MoqtObjectListener* listener_ptr) { listener = listener_ptr; });
  bidi_wrapper_->ReceiveMessage(request);
  EXPECT_CALL(mock_bidi_stream_,
              Writev(ControlMessageOfType(MoqtMessageType::kRequestError), _))
      .WillOnce([](absl::Span<quiche::QuicheMemSlice>,
                   const webtransport::StreamWriteOptions& options) {
        EXPECT_TRUE(options.send_fin());
        return absl::OkStatus();
      });
  listener->OnSubscribeRejected(MoqtRequestErrorInfo(
      RequestErrorCode::kInternalError, std::nullopt, "Test error"));
}

TEST_F(MoqtSessionTest, SynchronousSubscribeReturnsError) {
  bidi_wrapper_ = std::make_unique<MoqtBidiStreamTestWrapper>(
      ResponseStream(kSubscribeByte));
  MoqtSubscribe request = DefaultSubscribe();
  MockTrackPublisher* track = CreateTrackPublisher();
  EXPECT_CALL(*track, AddObjectListener)
      .WillOnce([&](MoqtObjectListener* listener) {
        EXPECT_CALL(*track, RemoveObjectListener);
        listener->OnSubscribeRejected(MoqtRequestErrorInfo(
            RequestErrorCode::kInternalError, std::nullopt, "Test error"));
      });
  EXPECT_CALL(mock_bidi_stream_,
              Writev(ControlMessageOfType(MoqtMessageType::kRequestError), _))
      .WillOnce([](absl::Span<quiche::QuicheMemSlice>,
                   const webtransport::StreamWriteOptions& options) {
        EXPECT_TRUE(options.send_fin());
        return absl::OkStatus();
      });
  bidi_wrapper_->ReceiveMessage(request);
}

TEST_F(MoqtSessionTest, SubscribeForPast) {
  bidi_wrapper_ = std::make_unique<MoqtBidiStreamTestWrapper>(
      ResponseStream(kSubscribeByte));
  MockTrackPublisher* track = CreateTrackPublisher();
  SetLargestId(track, Location(10, 20));
  MoqtSubscribe request = DefaultSubscribe();
  ReceiveSubscribeSynchronousOk(track, request, bidi_wrapper_.get());
}

TEST_F(MoqtSessionTest, SubscribeDoNotForward) {
  bidi_wrapper_ = std::make_unique<MoqtBidiStreamTestWrapper>(
      ResponseStream(kSubscribeByte));
  MockTrackPublisher* track = CreateTrackPublisher();
  MoqtSubscribe request = DefaultSubscribe();
  request.parameters.set_forward(false);
  request.parameters.subscription_filter.emplace(
      MoqtFilterType::kLargestObject);
  MoqtObjectListener* listener =
      ReceiveSubscribeSynchronousOk(track, request, bidi_wrapper_.get());
  // forward=false, so incoming objects are ignored.
  EXPECT_CALL(mock_session_, CanOpenNextOutgoingUnidirectionalStream())
      .Times(0);
  listener->OnNewObjectAvailable(Location(0, 0), 0, kDefaultPublisherPriority);
}

TEST_F(MoqtSessionTest, SubscribeAbsoluteStartNoDataYet) {
  bidi_wrapper_ = std::make_unique<MoqtBidiStreamTestWrapper>(
      ResponseStream(kSubscribeByte));
  MockTrackPublisher* track = CreateTrackPublisher();
  MoqtSubscribe request = DefaultSubscribe();
  request.parameters.subscription_filter.emplace(Location(1, 0));
  MoqtObjectListener* listener =
      ReceiveSubscribeSynchronousOk(track, request, bidi_wrapper_.get());
  // Window was not set to (0, 0) by SUBSCRIBE acceptance.
  EXPECT_CALL(mock_session_, CanOpenNextOutgoingUnidirectionalStream())
      .Times(0);
  listener->OnNewObjectAvailable(Location(0, 0), 0, kDefaultPublisherPriority);
}

TEST_F(MoqtSessionTest, SubscribeNextGroup) {
  bidi_wrapper_ = std::make_unique<MoqtBidiStreamTestWrapper>(
      ResponseStream(kSubscribeByte));
  MockTrackPublisher* track = CreateTrackPublisher();
  MoqtSubscribe request = DefaultSubscribe();
  request.parameters.subscription_filter.emplace(
      MoqtFilterType::kNextGroupStart);
  SetLargestId(track, Location(10, 20));
  MoqtObjectListener* listener =
      ReceiveSubscribeSynchronousOk(track, request, bidi_wrapper_.get());
  // Later objects in group 10 ignored.
  EXPECT_CALL(mock_session_, CanOpenNextOutgoingUnidirectionalStream())
      .Times(0);
  listener->OnNewObjectAvailable(Location(10, 21), 0,
                                 kDefaultPublisherPriority);
  // Group 11 is sent.
  EXPECT_CALL(mock_session_, CanOpenNextOutgoingUnidirectionalStream())
      .WillOnce(Return(false));
  listener->OnNewObjectAvailable(Location(11, 0), 0, kDefaultPublisherPriority);
}

TEST_F(MoqtSessionTest, TwoSubscribesForTrack) {
  bidi_wrapper_ = std::make_unique<MoqtBidiStreamTestWrapper>(
      ResponseStream(kSubscribeByte));
  MockTrackPublisher* track = CreateTrackPublisher();
  MoqtSubscribe request = DefaultSubscribe();
  ReceiveSubscribeSynchronousOk(track, request, bidi_wrapper_.get());

  request.request_id = 3;
  request.parameters.subscription_filter.emplace(Location(12, 0));
  webtransport::test::MockStream bidi_stream_2;
  auto bidi_wrapper_2 = std::make_unique<MoqtBidiStreamTestWrapper>(
      ResponseStream(kSubscribeByte, &bidi_stream_2));
  EXPECT_CALL(bidi_stream_2,
              Writev(ControlMessageOfType(MoqtMessageType::kRequestError), _));
  bidi_wrapper_2->ReceiveMessage(request);
}

TEST_F(MoqtSessionTest, UnsubscribeAllowsSecondSubscribe) {
  bidi_wrapper_ = std::make_unique<MoqtBidiStreamTestWrapper>(
      ResponseStream(kSubscribeByte));
  MockTrackPublisher* track = CreateTrackPublisher();
  MoqtSubscribe request = DefaultSubscribe();
  ReceiveSubscribeSynchronousOk(track, request, bidi_wrapper_.get());

  // Peer unsubscribes.
  bidi_wrapper_->stream().Reset(kResetCodeCancelled);
  bidi_wrapper_ = nullptr;
  EXPECT_FALSE(MoqtSessionPeer::RequestIdIsLivePublisher(&session_, 1));

  // Subscribe again, succeeds.
  request.request_id = 3;
  request.parameters.subscription_filter.emplace(Location(12, 0));
  bidi_wrapper_ = std::make_unique<MoqtBidiStreamTestWrapper>(
      ResponseStream(kSubscribeByte));
  ReceiveSubscribeSynchronousOk(track, request, bidi_wrapper_.get(),
                                /*track_alias=*/1);
}

TEST_F(MoqtSessionTest, RequestIdWrongLsb) {
  // TODO(martinduke): Implement this test.
}

TEST_F(MoqtSessionTest, SubscribeIdNotIncreasing) {
  MoqtSubscribe request = DefaultSubscribe();
  bidi_wrapper_ = std::make_unique<MoqtBidiStreamTestWrapper>(
      ResponseStream(kSubscribeByte));
  MockTrackPublisher* track = CreateTrackPublisher();
  EXPECT_CALL(*track, AddObjectListener);
  bidi_wrapper_->ReceiveMessage(request);

  // Second request is a protocol violation.
  request.full_track_name = FullTrackName({"dead", "beef"});
  auto publisher =
      std::make_shared<MockTrackPublisher>(request.full_track_name);
  publisher_.Add(publisher);
  webtransport::test::MockStream bidi_stream_2;
  auto bidi_wrapper_2 = std::make_unique<MoqtBidiStreamTestWrapper>(
      ResponseStream(kSubscribeByte, &bidi_stream_2));
  EXPECT_CALL(bidi_stream_2,
              Writev(ControlMessageOfType(MoqtMessageType::kRequestError), _));
  bidi_wrapper_2->ReceiveMessage(request);
}

TEST_F(MoqtSessionTest, TooManySubscribes) {
  MoqtSessionPeer::set_next_request_id(&session_,
                                       kDefaultInitialMaxRequestId - 1);
  PrepareRequestStream(bidi_wrapper_);
  EXPECT_CALL(mock_bidi_stream_,
              Writev(ControlMessageOfType(MoqtMessageType::kSubscribe), _));
  MessageParameters parameters(SubscribeForTest());
  parameters.subscription_filter.emplace(MoqtFilterType::kLargestObject);
  EXPECT_TRUE(session_.Subscribe(FullTrackName("foo", "bar"),
                                 &remote_track_visitor_, parameters));
  webtransport::test::MockStream control_stream;
  std::unique_ptr<MoqtBidiStreamTestWrapper> control_wrapper =
      MoqtSessionPeer::CreateControlStream(&session_, &control_stream);
  EXPECT_CALL(
      control_stream,
      Writev(ControlMessageOfType(MoqtMessageType::kRequestsBlocked), _))
      .Times(1);
  EXPECT_FALSE(session_.Subscribe(FullTrackName("foo2", "bar2"),
                                  &remote_track_visitor_, parameters));
  // Second time does not send requests_blocked.
  EXPECT_FALSE(session_.Subscribe(FullTrackName("foo2", "bar2"),
                                  &remote_track_visitor_, parameters));
}

TEST_F(MoqtSessionTest, SubscribeDuplicateTrackName) {
  PrepareRequestStream(bidi_wrapper_);
  EXPECT_CALL(mock_bidi_stream_,
              Writev(ControlMessageOfType(MoqtMessageType::kSubscribe), _));
  MessageParameters parameters(SubscribeForTest());
  EXPECT_TRUE(session_.Subscribe(FullTrackName("foo", "bar"),
                                 &remote_track_visitor_, parameters));
  EXPECT_FALSE(session_.Subscribe(FullTrackName("foo", "bar"),
                                  &remote_track_visitor_, parameters));
}

TEST_F(MoqtSessionTest, SubscribeWithOk) {
  PrepareRequestStream(bidi_wrapper_);
  EXPECT_CALL(mock_bidi_stream_,
              Writev(ControlMessageOfType(MoqtMessageType::kSubscribe), _));
  MessageParameters parameters(SubscribeForTest());
  session_.Subscribe(FullTrackName("foo", "bar"), &remote_track_visitor_,
                     parameters);

  MoqtSubscribeOk ok = {
      /*request_id=*/0,
      /*track_alias=*/2,
      MessageParameters(),
      TrackExtensions(),
  };
  EXPECT_CALL(remote_track_visitor_, OnReply)
      .WillOnce(
          [&](const FullTrackName& ftn,
              std::variant<SubscribeOkData, MoqtRequestErrorInfo> response) {
            EXPECT_EQ(ftn, FullTrackName("foo", "bar"));
            EXPECT_TRUE(std::holds_alternative<SubscribeOkData>(response));
          });
  bidi_wrapper_->ReceiveMessage(ok);
}

TEST_F(MoqtSessionTest, SubscribeNextGroupWithOk) {
  PrepareRequestStream(bidi_wrapper_);
  MoqtSubscribe subscribe = DefaultLocalSubscribe();
  subscribe.parameters.subscription_filter.emplace(
      MoqtFilterType::kNextGroupStart);
  EXPECT_CALL(mock_bidi_stream_,
              Writev(SerializedControlMessage(subscribe), _));
  session_.Subscribe(FullTrackName("foo", "bar"), &remote_track_visitor_,
                     subscribe.parameters);

  MoqtSubscribeOk ok = {
      /*request_id=*/0,
      /*track_alias=*/2,
      MessageParameters(),
      TrackExtensions(),
  };
  EXPECT_CALL(remote_track_visitor_, OnReply)
      .WillOnce(
          [&](const FullTrackName& ftn,
              std::variant<SubscribeOkData, MoqtRequestErrorInfo> response) {
            EXPECT_EQ(ftn, FullTrackName("foo", "bar"));
            EXPECT_TRUE(std::holds_alternative<SubscribeOkData>(response));
          });
  bidi_wrapper_->ReceiveMessage(ok);
}

TEST_F(MoqtSessionTest, OutgoingSubscribeUpdate) {
  PrepareRequestStream(bidi_wrapper_);
  EXPECT_CALL(mock_bidi_stream_,
              Writev(ControlMessageOfType(MoqtMessageType::kSubscribe), _));
  MessageParameters parameters(SubscribeForTest());
  parameters.subscription_filter.emplace(Location(1, 0), 10);
  session_.Subscribe(FullTrackName("foo", "bar"), &remote_track_visitor_,
                     parameters);
  MoqtSubscribeOk ok = {
      /*request_id=*/0,
      /*track_alias=*/2,
      MessageParameters(),
      TrackExtensions(),
  };
  EXPECT_CALL(remote_track_visitor_, OnReply);
  bidi_wrapper_->ReceiveMessage(ok);
  EXPECT_CALL(mock_bidi_stream_,
              Writev(ControlMessageOfType(MoqtMessageType::kRequestUpdate), _));
  MessageParameters update_parameters;
  update_parameters.subscription_filter.emplace(Location(2, 1), 9);
  // Set to a non-null value to ensure that the callback is called.
  bool got_response = false;
  EXPECT_TRUE(session_.SubscribeUpdate(
      FullTrackName("foo", "bar"), update_parameters,
      [&](std::variant<MessageParameters, MoqtRequestErrorInfo> info) {
        got_response = true;
        ASSERT_TRUE(std::holds_alternative<MessageParameters>(info));
        EXPECT_EQ(std::get<MessageParameters>(info), MessageParameters());
      }));
  bidi_wrapper_->ReceiveMessage(MoqtRequestOk{
      /*request_id=*/2,
      MessageParameters(),
  });
  EXPECT_TRUE(got_response);
  // Check if window is functional by receiving datagrams. Type = 8, alias = 2,
  // Location = (2,0), payload = "foo".
  char datagram[] = {0x08, 0x02, 0x02, 0x00, 0x66, 0x6f, 0x6f};
  EXPECT_CALL(remote_track_visitor_, OnObjectFragment).Times(0);
  session_.OnDatagramReceived(absl::string_view(datagram, sizeof(datagram)));
  datagram[3] = 0x01;  // Location is (2,1), in window.
  EXPECT_CALL(remote_track_visitor_, OnObjectFragment);
  session_.OnDatagramReceived(absl::string_view(datagram, sizeof(datagram)));
  datagram[2] = 0x09;  // Location is (9, 63), in window.
  datagram[3] = 0x3f;
  EXPECT_CALL(remote_track_visitor_, OnObjectFragment);
  session_.OnDatagramReceived(absl::string_view(datagram, sizeof(datagram)));
  datagram[2] = 0x0a;  // Location is (10, 0), not in window.
  EXPECT_CALL(remote_track_visitor_, OnObjectFragment).Times(0);
  session_.OnDatagramReceived(absl::string_view(datagram, sizeof(datagram)));
}

TEST_F(MoqtSessionTest, OutgoingRequestUpdateInvalid) {
  // Wrong track name.
  EXPECT_FALSE(session_.SubscribeUpdate(
      FullTrackName("foo", "bar"), MessageParameters(),
      +[](std::variant<MessageParameters, MoqtRequestErrorInfo>) {}));
}

TEST_F(MoqtSessionTest, MaxRequestIdChangesResponse) {
  MoqtSessionPeer::set_next_request_id(&session_, kDefaultInitialMaxRequestId);
  webtransport::test::MockStream control_stream;
  std::unique_ptr<MoqtBidiStreamTestWrapper> control_wrapper =
      MoqtSessionPeer::CreateControlStream(&session_, &control_stream);
  EXPECT_CALL(
      control_stream,
      Writev(ControlMessageOfType(MoqtMessageType::kRequestsBlocked), _));
  MessageParameters parameters(SubscribeForTest());
  parameters.subscription_filter.emplace(MoqtFilterType::kLargestObject);
  EXPECT_FALSE(session_.Subscribe(FullTrackName("foo", "bar"),
                                  &remote_track_visitor_, parameters));
  MoqtMaxRequestId max_request_id = {
      /*max_request_id=*/kDefaultInitialMaxRequestId + 1,
  };
  control_wrapper->ReceiveMessage(max_request_id);

  PrepareRequestStream(bidi_wrapper_);
  EXPECT_CALL(mock_bidi_stream_,
              Writev(ControlMessageOfType(MoqtMessageType::kSubscribe), _));
  EXPECT_TRUE(session_.Subscribe(FullTrackName("foo", "bar"),
                                 &remote_track_visitor_, parameters));
}

TEST_F(MoqtSessionTest, LowerMaxRequestIdIsAnError) {
  MoqtMaxRequestId max_request_id = {
      /*max_request_id=*/kDefaultInitialMaxRequestId - 1,
  };
  bidi_wrapper_ =
      MoqtSessionPeer::CreateControlStream(&session_, &mock_bidi_stream_);
  EXPECT_CALL(mock_session_,
              CloseSession(static_cast<uint64_t>(MoqtError::kProtocolViolation),
                           "MAX_REQUEST_ID has lower value than previous"))
      .Times(1);
  bidi_wrapper_->ReceiveMessage(max_request_id);
}

TEST_F(MoqtSessionTest, GrantMoreRequests) {
  webtransport::test::MockStream control_stream;
  std::unique_ptr<MoqtBidiStreamTestWrapper> control_wrapper_ =
      MoqtSessionPeer::CreateControlStream(&session_, &control_stream);
  EXPECT_CALL(control_stream,
              Writev(ControlMessageOfType(MoqtMessageType::kMaxRequestId), _));
  session_.GrantMoreRequests(1);
  // Peer subscribes to (0, 0)
  bidi_wrapper_ = std::make_unique<MoqtBidiStreamTestWrapper>(
      ResponseStream(kSubscribeByte));
  MoqtSubscribe request = DefaultSubscribe();
  request.request_id = kDefaultInitialMaxRequestId + 1;
  MockTrackPublisher* track = CreateTrackPublisher();
  ReceiveSubscribeSynchronousOk(track, request, bidi_wrapper_.get());
}

TEST_F(MoqtSessionTest, SubscribeWithError) {
  PrepareRequestStream(bidi_wrapper_);
  EXPECT_CALL(mock_bidi_stream_,
              Writev(ControlMessageOfType(MoqtMessageType::kSubscribe), _));
  MessageParameters parameters(SubscribeForTest());
  parameters.subscription_filter.emplace(MoqtFilterType::kLargestObject);
  session_.Subscribe(FullTrackName("foo", "bar"), &remote_track_visitor_,
                     parameters);

  MoqtRequestError error = {
      /*request_id=*/0,
      /*error_code=*/RequestErrorCode::kInvalidRange,
      /*retry_interval=*/std::nullopt,
      /*reason_phrase=*/"deadbeef",
  };
  EXPECT_CALL(remote_track_visitor_, OnReply)
      .WillOnce(
          [&](const FullTrackName& ftn,
              std::variant<SubscribeOkData, MoqtRequestErrorInfo> response) {
            EXPECT_EQ(ftn, FullTrackName("foo", "bar"));
            EXPECT_TRUE(
                std::holds_alternative<MoqtRequestErrorInfo>(response) &&
                std::get<MoqtRequestErrorInfo>(response).reason_phrase ==
                    "deadbeef");
          });
  EXPECT_CALL(mock_bidi_stream_, Writev(testing::IsEmpty(), _));  // FIN.
  bidi_wrapper_->ReceiveMessage(error);
}

TEST_F(MoqtSessionTest, Unsubscribe) {
  PrepareRequestStream(bidi_wrapper_);
  FullTrackName ftn = FullTrackName("foo", "bar");
  EXPECT_CALL(mock_bidi_stream_,
              Writev(ControlMessageOfType(MoqtMessageType::kSubscribe), _));
  EXPECT_TRUE(
      session_.Subscribe(ftn, &remote_track_visitor_, MessageParameters()));
  EXPECT_CALL(mock_bidi_stream_, ResetWithUserCode);
  EXPECT_CALL(remote_track_visitor_, OnPublishDone);
  session_.Unsubscribe(ftn);
  // Verify it was destroyed.
  EXPECT_CALL(mock_bidi_stream_, ResetWithUserCode).Times(0);
  EXPECT_CALL(remote_track_visitor_, OnPublishDone).Times(0);
  session_.Unsubscribe(ftn);
}

TEST_F(MoqtSessionTest, ReplyToPublishNamespaceWithOkThenPublishNamespaceDone) {
  TrackNamespace track_namespace{"foo"};
  bidi_wrapper_ =
      MoqtSessionPeer::CreateControlStream(&session_, &mock_bidi_stream_);
  MessageParameters parameters;
  parameters.authorization_tokens.emplace_back(AuthTokenType::kOutOfBand,
                                               "foo");
  MoqtPublishNamespace publish_namespace = {
      kDefaultPeerRequestId,
      track_namespace,
      parameters,
  };
  EXPECT_CALL(session_callbacks_.incoming_publish_namespace_callback,
              Call(track_namespace, std::make_optional(parameters), _))
      .WillOnce([](const TrackNamespace&,
                   const std::optional<MessageParameters>&,
                   MoqtResponseCallback callback) {
        std::move(callback)(MessageParameters());
      });
  EXPECT_CALL(mock_bidi_stream_,
              Writev(SerializedControlMessage(MoqtRequestOk{
                         kDefaultPeerRequestId, MessageParameters()}),
                     _));
  bidi_wrapper_->ReceiveMessage(publish_namespace);
  MoqtPublishNamespaceDone publish_namespace_done = {
      /*request_id=*/0,
  };
  EXPECT_CALL(session_callbacks_.incoming_publish_namespace_callback,
              Call(track_namespace, std::optional<MessageParameters>(), _))
      .WillOnce(
          [](const TrackNamespace&, const std::optional<MessageParameters>&,
             MoqtResponseCallback callback) { EXPECT_EQ(callback, nullptr); });
  bidi_wrapper_->ReceiveMessage(publish_namespace_done);
}

TEST_F(MoqtSessionTest,
       ReplyToPublishNamespaceWithOkThenPublishNamespaceCancel) {
  TrackNamespace track_namespace{"foo"};

  bidi_wrapper_ =
      MoqtSessionPeer::CreateControlStream(&session_, &mock_bidi_stream_);
  MessageParameters parameters;
  parameters.authorization_tokens.emplace_back(AuthTokenType::kOutOfBand,
                                               "foo");
  MoqtPublishNamespace publish_namespace = {
      kDefaultPeerRequestId,
      track_namespace,
      parameters,
  };
  EXPECT_CALL(session_callbacks_.incoming_publish_namespace_callback,
              Call(track_namespace, std::make_optional(parameters), _))
      .WillOnce([](const TrackNamespace&,
                   const std::optional<MessageParameters>&,
                   MoqtResponseCallback callback) {
        std::move(callback)(MessageParameters());
      });
  EXPECT_CALL(mock_bidi_stream_,
              Writev(SerializedControlMessage(MoqtRequestOk{
                         kDefaultPeerRequestId, MessageParameters()}),
                     _));
  bidi_wrapper_->ReceiveMessage(publish_namespace);
  EXPECT_CALL(mock_bidi_stream_,
              Writev(SerializedControlMessage(MoqtPublishNamespaceCancel{
                         kDefaultPeerRequestId,
                         RequestErrorCode::kInternalError, "deadbeef"}),
                     _));
  session_.PublishNamespaceCancel(track_namespace,
                                  RequestErrorCode::kInternalError, "deadbeef");
}

TEST_F(MoqtSessionTest, ReplyToPublishNamespaceWithError) {
  TrackNamespace track_namespace{"foo"};

  bidi_wrapper_ =
      MoqtSessionPeer::CreateControlStream(&session_, &mock_bidi_stream_);
  MessageParameters parameters;
  parameters.authorization_tokens.emplace_back(AuthTokenType::kOutOfBand,
                                               "foo");
  MoqtPublishNamespace publish_namespace = {
      kDefaultPeerRequestId,
      track_namespace,
      parameters,
  };
  MoqtRequestErrorInfo error = {
      RequestErrorCode::kNotSupported,
      /*retry_interval=*/std::nullopt,
      "deadbeef",
  };
  EXPECT_CALL(session_callbacks_.incoming_publish_namespace_callback,
              Call(track_namespace, std::make_optional(parameters), _))
      .WillOnce(
          [&](const TrackNamespace&, const std::optional<MessageParameters>&,
              MoqtResponseCallback callback) { std::move(callback)(error); });
  EXPECT_CALL(mock_bidi_stream_,
              Writev(SerializedControlMessage(MoqtRequestError{
                         kDefaultPeerRequestId, error.error_code,
                         error.retry_interval, error.reason_phrase}),
                     _));
  bidi_wrapper_->ReceiveMessage(publish_namespace);
}

TEST_F(MoqtSessionTest, SubscribeNamespaceLifeCycle) {
  TrackNamespace prefix({"foo"});
  bool got_callback = false;
  PrepareRequestStream(bidi_wrapper_);
  EXPECT_CALL(
      mock_bidi_stream_,
      Writev(ControlMessageOfType(MoqtMessageType::kSubscribeNamespace), _));
  std::unique_ptr<MoqtNamespaceTask> task = session_.SubscribeNamespace(
      prefix, MessageParameters(),
      [&](std::variant<MessageParameters, MoqtRequestErrorInfo> response) {
        got_callback = true;
        EXPECT_TRUE(std::holds_alternative<MessageParameters>(response));
      });
  MoqtRequestOk ok = {kDefaultLocalRequestId, MessageParameters()};
  bidi_wrapper_->ReceiveMessage(ok);
  EXPECT_TRUE(got_callback);
  EXPECT_CALL(mock_bidi_stream_, ResetWithUserCode);
}

TEST_F(MoqtSessionTest, SubscribeNamespaceError) {
  TrackNamespace prefix({"foo"});
  bool got_callback = false;
  PrepareRequestStream(bidi_wrapper_);
  EXPECT_CALL(
      mock_bidi_stream_,
      Writev(ControlMessageOfType(MoqtMessageType::kSubscribeNamespace), _));
  std::unique_ptr<MoqtNamespaceTask> task = session_.SubscribeNamespace(
      prefix, MessageParameters(),
      [&](std::variant<MessageParameters, MoqtRequestErrorInfo> response) {
        got_callback = true;
        EXPECT_TRUE(std::holds_alternative<MoqtRequestErrorInfo>(response));
        const MoqtRequestErrorInfo& error =
            std::get<MoqtRequestErrorInfo>(response);
        EXPECT_EQ(error.error_code, RequestErrorCode::kInvalidRange);
        EXPECT_EQ(error.reason_phrase, "deadbeef");
      });
  MoqtRequestError error = {kDefaultLocalRequestId,
                            RequestErrorCode::kInvalidRange, std::nullopt,
                            "deadbeef"};
  bidi_wrapper_->ReceiveMessage(error);
  EXPECT_TRUE(got_callback);
}

TEST_F(MoqtSessionTest, SubscribeOkWithBadTrackAlias) {
  PrepareRequestStream(bidi_wrapper_);
  session_.Subscribe(FullTrackName("foo", "bar"), &remote_track_visitor_,
                     MessageParameters());
  MoqtSubscribeOk subscribe_ok = {
      /*request_id=*/0,
      /*track_alias=*/2,
      MessageParameters(),
      TrackExtensions(),
  };
  bidi_wrapper_->ReceiveMessage(subscribe_ok);
  // Second subscribe, but OK has the same track alias.
  webtransport::test::MockStream bidi_stream_2;
  std::unique_ptr<MoqtBidiStreamTestWrapper> bidi_wrapper_2 =
      MoqtSessionPeer::CreateControlStream(&session_, &bidi_stream_2);
  PrepareRequestStream(bidi_wrapper_2, &bidi_stream_2);
  session_.Subscribe(FullTrackName("foo2", "bar2"), &remote_track_visitor_,
                     MessageParameters());
  subscribe_ok.request_id += 2;
  EXPECT_CALL(
      mock_session_,
      CloseSession(static_cast<uint64_t>(MoqtError::kDuplicateTrackAlias),
                   "Track alias already exists"));
  bidi_wrapper_2->ReceiveMessage(subscribe_ok);
}

TEST_F(MoqtSessionTest, ReceiveUnsubscribe) {
  MockTrackPublisher* track = CreateTrackPublisher();
  MoqtSubscribe request = DefaultSubscribe();
  const MoqtPriority kLocalDefaultPriority = 0x20;
  bidi_wrapper_ = std::make_unique<MoqtBidiStreamTestWrapper>(
      ResponseStream(kSubscribeByte));
  TrackExtensions extensions(std::nullopt, std::nullopt, kLocalDefaultPriority,
                             std::nullopt, std::nullopt, std::nullopt);
  EXPECT_CALL(*track, extensions)
      .WillRepeatedly(testing::ReturnRef(extensions));
  MoqtObjectListener* listener = ReceiveSubscribeSynchronousOk(
      track, request, bidi_wrapper_.get(), /*track_alias=*/0, extensions);
  EXPECT_CALL(*track, RemoveObjectListener(listener));
  bidi_wrapper_->stream().OnResetStreamReceived(kResetCodeCancelled);
}

TEST_F(MoqtSessionTest, ReceiveDatagram) {
  FullTrackName ftn("foo", "bar");
  const MoqtPriority kPeerDefaultPriority = 0x20;
  PrepareRequestStream(bidi_wrapper_);
  std::string payload = "deadbeef";
  EXPECT_CALL(mock_bidi_stream_,
              Writev(ControlMessageOfType(MoqtMessageType::kSubscribe), _));
  session_.Subscribe(ftn, &remote_track_visitor_, MessageParameters());
  MoqtSubscribeOk ok;
  ok.request_id = 0;
  ok.track_alias = 2;
  ok.extensions =
      TrackExtensions(std::nullopt, std::nullopt, kPeerDefaultPriority,
                      std::nullopt, std::nullopt, std::nullopt);
  EXPECT_CALL(remote_track_visitor_, OnReply);
  bidi_wrapper_->ReceiveMessage(ok);

  MoqtObject object = {
      /*track_alias=*/2,
      /*group_sequence=*/0,
      /*object_sequence=*/0,
      /*publisher_priority=*/0,
      /*extension_headers=*/"",
      /*object_status=*/MoqtObjectStatus::kNormal,
      /*subgroup_id=*/std::nullopt,
      /*first_object_in_subgroup=*/std::nullopt,
      /*payload_length=*/8,
  };
  char datagram[] = {0x00, 0x02, 0x00, 0x00, 0x00, 0x64, 0x65,
                     0x61, 0x64, 0x62, 0x65, 0x65, 0x66};
  EXPECT_CALL(remote_track_visitor_, OnObjectFragment)
      .WillOnce([&](const FullTrackName& track_name,
                    const PublishedObjectMetadata& metadata,
                    absl::string_view received_payload, uint64_t offset) {
        EXPECT_EQ(track_name, ftn);
        EXPECT_EQ(metadata.location,
                  Location(object.group_id, object.object_id));
        EXPECT_EQ(metadata.subgroup, object.subgroup_id);
        EXPECT_EQ(metadata.publisher_priority, object.publisher_priority);
        EXPECT_EQ(metadata.status, object.object_status);
        EXPECT_EQ(metadata.payload_length, payload.length());
        EXPECT_EQ(payload, received_payload);
        EXPECT_EQ(offset, 0);
      });
  session_.OnDatagramReceived(absl::string_view(datagram, sizeof(datagram)));
}

TEST_F(MoqtSessionTest, UsePeerDefaultPriority) {
  FullTrackName ftn("foo", "bar");
  const MoqtPriority kPeerDefaultPriority = 0x20;
  PrepareRequestStream(bidi_wrapper_);
  EXPECT_CALL(mock_bidi_stream_,
              Writev(ControlMessageOfType(MoqtMessageType::kSubscribe), _));
  session_.Subscribe(ftn, &remote_track_visitor_, MessageParameters());
  MoqtSubscribeOk ok;
  ok.request_id = 0;
  ok.track_alias = 2;
  ok.extensions =
      TrackExtensions(std::nullopt, std::nullopt, kPeerDefaultPriority,
                      std::nullopt, std::nullopt, std::nullopt);
  EXPECT_CALL(remote_track_visitor_, OnReply);
  bidi_wrapper_->ReceiveMessage(ok);
  // Omit priority from a datagram.
  char datagram[] = {0x0c, 0x02, 0x05, 0x64, 0x65, 0x61,
                     0x64, 0x62, 0x65, 0x65, 0x66};
  EXPECT_CALL(remote_track_visitor_, OnObjectFragment)
      .WillOnce([&](const FullTrackName&,
                    const PublishedObjectMetadata& metadata, absl::string_view,
                    uint64_t offset) {
        EXPECT_EQ(metadata.publisher_priority, kPeerDefaultPriority);
        EXPECT_EQ(metadata.payload_length, 8u);
        EXPECT_EQ(offset, 0);
      });
  session_.OnDatagramReceived(absl::string_view(datagram, sizeof(datagram)));
  // Omit priority from a stream.
  webtransport::test::InMemoryStream in_memory_stream(2);
  std::unique_ptr<webtransport::StreamVisitor> stream_visitor =
      MoqtSessionPeer::CreateIncomingStreamVisitor(&session_,
                                                   &in_memory_stream);
  in_memory_stream.SetVisitor(std::move(stream_visitor));
  char stream_data[] = {0x30, 0x02, 0x06, 0x00, 0x03, 0x66, 0x6f, 0x6f};
  EXPECT_CALL(remote_track_visitor_, OnObjectFragment)
      .WillOnce([&](const FullTrackName&,
                    const PublishedObjectMetadata& metadata, absl::string_view,
                    uint64_t offset) {
        EXPECT_EQ(metadata.publisher_priority, kPeerDefaultPriority);
        EXPECT_EQ(metadata.payload_length, 3u);
        EXPECT_EQ(offset, 0);
      });
  in_memory_stream.Receive(absl::string_view(stream_data, sizeof(stream_data)),
                           false);
}

TEST_F(MoqtSessionTest, OmitPublisherPriority) {
  MoqtSubscribe request = DefaultSubscribe();
  const MoqtPriority kLocalDefaultPriority = 0x20;
  bidi_wrapper_ = std::make_unique<MoqtBidiStreamTestWrapper>(
      ResponseStream(kSubscribeByte));
  // Create the publisher and the SUBSCRIBE with kLocalDefaultPriority.
  MockTrackPublisher* track = CreateTrackPublisher();
  std::make_shared<MockTrackPublisher>(request.full_track_name);
  TrackExtensions extensions(std::nullopt, std::nullopt, kLocalDefaultPriority,
                             std::nullopt, std::nullopt, std::nullopt);
  EXPECT_CALL(*track, extensions)
      .WillRepeatedly(testing::ReturnRef(extensions));
  MoqtObjectListener* listener = ReceiveSubscribeSynchronousOk(
      track, request, bidi_wrapper_.get(), /*track_alias=*/0, extensions);

  // Deliver an object with kLocalDefaultPriority; stream_type will omit
  // the priority.
  EXPECT_CALL(mock_session_, CanOpenNextOutgoingUnidirectionalStream())
      .WillOnce(Return(true));
  EXPECT_CALL(mock_session_, OpenOutgoingUnidirectionalStream())
      .WillOnce(Return(&mock_uni_stream_));
  EXPECT_CALL(mock_uni_stream_, GetStreamId()).WillRepeatedly(Return(1));
  std::unique_ptr<webtransport::StreamVisitor> stream_visitor;
  EXPECT_CALL(mock_uni_stream_, SetVisitor)
      .WillOnce([&](std::unique_ptr<webtransport::StreamVisitor> visitor) {
        stream_visitor = std::move(visitor);
      });
  EXPECT_CALL(mock_uni_stream_, SetPriority);
  EXPECT_CALL(mock_uni_stream_, visitor()).WillRepeatedly([&]() {
    return stream_visitor.get();
  });
  EXPECT_CALL(mock_uni_stream_, CanWrite).WillRepeatedly(Return(true));
  EXPECT_CALL(*track, GetCachedObject(_, _, _, _))
      .WillOnce(Return(PublishedObject{
          PublishedObjectMetadata{
              Location(0, 0), 0, "", MoqtObjectStatus::kNormal,
              kLocalDefaultPriority, true, 8, MoqtSessionPeer::Now(&session_)},
          PayloadFromString("deadbeef")}))
      .WillOnce(Return(std::nullopt));
  EXPECT_CALL(mock_uni_stream_, Writev)
      .WillOnce([&](absl::Span<quiche::QuicheMemSlice> data,
                    const webtransport::StreamWriteOptions& options) {
        // The stream type omits the priority.
        EXPECT_TRUE(static_cast<const uint8_t>(data[0].AsStringView()[0]) &
                    MoqtDataStreamType::kDefaultPriority);
        return absl::OkStatus();
      });
  listener->OnNewObjectAvailable(Location(0, 0), 0, kLocalDefaultPriority);
  // Send a datagram with the default priority.
  EXPECT_CALL(*track, GetCachedObject(_, _, _, _))
      .WillOnce(Return(PublishedObject{
          PublishedObjectMetadata{Location(0, 1), std::nullopt, "",
                                  MoqtObjectStatus::kNormal,
                                  kLocalDefaultPriority, std::nullopt, 8,
                                  MoqtSessionPeer::Now(&session_)},
          PayloadFromString("deadbeef")}));
  EXPECT_CALL(mock_session_, SendOrQueueDatagram)
      .WillOnce([](absl::string_view datagram) {
        EXPECT_TRUE(static_cast<const uint8_t>(datagram[0]) &
                    MoqtDatagramType::kDefaultPriority);
        return webtransport::DatagramStatus{
            webtransport::DatagramStatusCode::kSuccess, ""};
      });
  listener->OnNewObjectAvailable(Location(0, 1), std::nullopt,
                                 kLocalDefaultPriority);
  // Non-default priority
  EXPECT_CALL(*track, GetCachedObject(_, _, _, _))
      .WillOnce(Return(PublishedObject{
          PublishedObjectMetadata{Location(0, 2), std::nullopt, "",
                                  MoqtObjectStatus::kNormal,
                                  kLocalDefaultPriority + 1, std::nullopt, 8,
                                  MoqtSessionPeer::Now(&session_)},
          PayloadFromString("deadbeef")}));
  EXPECT_CALL(mock_session_, SendOrQueueDatagram)
      .WillOnce([](absl::string_view datagram) {
        EXPECT_FALSE(static_cast<const uint8_t>(datagram[0]) &
                     MoqtDatagramType::kDefaultPriority);
        return webtransport::DatagramStatus{
            webtransport::DatagramStatusCode::kSuccess, ""};
      });
  listener->OnNewObjectAvailable(Location(0, 2), std::nullopt,
                                 kLocalDefaultPriority + 1);
}

TEST_F(MoqtSessionTest, DatagramOutOfWindow) {
  FullTrackName ftn("foo", "bar");
  const MoqtPriority kPeerDefaultPriority = 0x20;
  PrepareRequestStream(bidi_wrapper_);
  EXPECT_CALL(mock_bidi_stream_,
              Writev(ControlMessageOfType(MoqtMessageType::kSubscribe), _));
  MessageParameters params;
  params.subscription_filter.emplace(Location(1, 0));
  session_.Subscribe(ftn, &remote_track_visitor_, params);
  MoqtSubscribeOk ok;
  ok.request_id = 0;
  ok.track_alias = 2;
  ok.extensions =
      TrackExtensions(std::nullopt, std::nullopt, kPeerDefaultPriority,
                      std::nullopt, std::nullopt, std::nullopt);
  EXPECT_CALL(remote_track_visitor_, OnReply);
  bidi_wrapper_->ReceiveMessage(ok);
  char datagram[] = {0x01, 0x02, 0x00, 0x00, 0x80, 0x00, 0x08, 0x64,
                     0x65, 0x61, 0x64, 0x62, 0x65, 0x65, 0x66};
  EXPECT_CALL(remote_track_visitor_, OnObjectFragment).Times(0);
  session_.OnDatagramReceived(absl::string_view(datagram, sizeof(datagram)));
}

TEST_F(MoqtSessionTest, UpdateTrackPriority) {
  session_.UpdateTrackPriority(0, std::nullopt, MoqtTrackPriority{0x40, 0x82});
  EXPECT_EQ(MoqtSessionPeer::NextQueuedRequestIdToServer(&session_), 0);
  // Same track, higher priority.
  session_.UpdateTrackPriority(0, MoqtTrackPriority{0x40, 0x82},
                               MoqtTrackPriority{0x40, 0x80});
  EXPECT_EQ(MoqtSessionPeer::NextQueuedRequestIdToServer(&session_), 0);
  // New track, higher priority.
  session_.UpdateTrackPriority(2, std::nullopt, MoqtTrackPriority{0x20, 0x82});
  EXPECT_EQ(MoqtSessionPeer::NextQueuedRequestIdToServer(&session_), 2);
  // Pop request ID 2 from the queue.  The subscription doesn't really exist, so
  // nothing else happens.
  EXPECT_CALL(mock_session_, CanOpenNextOutgoingUnidirectionalStream())
      .WillOnce(Return(true))
      .WillOnce(Return(false));
  session_.OnCanCreateNewOutgoingUnidirectionalStream();
  EXPECT_EQ(MoqtSessionPeer::NextQueuedRequestIdToServer(&session_), 0);
  // There's another stream for request ID 2.
  session_.UpdateTrackPriority(2, std::nullopt, MoqtTrackPriority{0x20, 0x81});
  EXPECT_EQ(MoqtSessionPeer::NextQueuedRequestIdToServer(&session_), 2);
  // The subscriber demotes track 2. Track 0 is first now due to higher
  // publisher priority.
  session_.UpdateTrackPriority(2, MoqtTrackPriority{0x20, 0x81},
                               MoqtTrackPriority{0x40, 0x81});
  EXPECT_EQ(MoqtSessionPeer::NextQueuedRequestIdToServer(&session_), 0);
  EXPECT_CALL(mock_session_, CanOpenNextOutgoingUnidirectionalStream())
      .WillOnce(Return(true))
      .WillOnce(Return(false));
  session_.OnCanCreateNewOutgoingUnidirectionalStream();
  // The subscription will update with the first stream. It's lower priority
  // than request ID 2.
  session_.UpdateTrackPriority(0, std::nullopt, MoqtTrackPriority{0x40, 0x82});
  EXPECT_EQ(MoqtSessionPeer::NextQueuedRequestIdToServer(&session_), 2);
}

// Helper functions to handle the many EXPECT_CALLs for FETCH processing and
// delivery.
namespace {
// Handles all the mock calls for the first object available for a FETCH.
void ExpectStreamOpen(
    webtransport::test::MockSession& session, MockFetchTask* fetch_task,
    webtransport::test::MockStream& data_stream,
    std::unique_ptr<webtransport::StreamVisitor>& stream_visitor) {
  EXPECT_CALL(session, CanOpenNextOutgoingUnidirectionalStream)
      .WillOnce(Return(true))
      .WillRepeatedly(Return(false));
  EXPECT_CALL(session, OpenOutgoingUnidirectionalStream())
      .WillOnce(Return(&data_stream));
  EXPECT_CALL(data_stream, SetVisitor)
      .WillOnce([&](std::unique_ptr<webtransport::StreamVisitor> visitor) {
        stream_visitor = std::move(visitor);
      });
  EXPECT_CALL(data_stream, SetPriority).Times(1);
}

// Sets expectations to send one object at the start of the stream, and then
// return a different status on the second GetNextObject call. |second_result|
// cannot be kSuccess.
void ExpectSendObject(MockFetchTask* fetch_task,
                      webtransport::test::MockStream& data_stream,
                      MoqtObjectStatus status, Location location,
                      absl::string_view payload,
                      MoqtFetchTask::GetNextObjectResult second_result) {
  // Nothing is sent for status = kObjectDoesNotExist. Do not use this function.
  QUICHE_DCHECK(status != MoqtObjectStatus::kObjectDoesNotExist);
  QUICHE_DCHECK(second_result != MoqtFetchTask::GetNextObjectResult::kSuccess);
  EXPECT_CALL(data_stream, CanWrite).WillRepeatedly(Return(true));
  EXPECT_CALL(*fetch_task, GetNextObject)
      .WillOnce([=](PublishedObject& output) {
        output.metadata.location = location;
        output.metadata.subgroup = 0;
        output.metadata.status = status;
        output.metadata.publisher_priority = 128;
        output.metadata.payload_length = payload.length();
        output.payload = PayloadFromString(payload);
        output.fin_after_this = true;  // should be ignored.
        return MoqtFetchTask::GetNextObjectResult::kSuccess;
      })
      .WillOnce([=](PublishedObject& /*output*/) { return second_result; });
  if (second_result == MoqtFetchTask::GetNextObjectResult::kEof) {
    EXPECT_CALL(data_stream, Writev)
        .WillOnce([](absl::Span<quiche::QuicheMemSlice> data,
                     const webtransport::StreamWriteOptions& options) {
          quic::QuicDataReader reader(data[0].AsStringView());
          uint64_t type;
          EXPECT_TRUE(reader.ReadMoqVarInt(&type));
          EXPECT_EQ(type, MoqtDataStreamType::Fetch().value());
          EXPECT_FALSE(options.send_fin());  // fin_after_this is ignored.
          return absl::OkStatus();
        })
        .WillOnce([](absl::Span<quiche::QuicheMemSlice> data,
                     const webtransport::StreamWriteOptions& options) {
          EXPECT_TRUE(data.empty());
          EXPECT_TRUE(options.send_fin());
          return absl::OkStatus();
        });
    return;
  }
  EXPECT_CALL(data_stream, Writev)
      .WillOnce([](absl::Span<quiche::QuicheMemSlice> data,
                   const webtransport::StreamWriteOptions& options) {
        quic::QuicDataReader reader(data[0].AsStringView());
        uint64_t type;
        EXPECT_TRUE(reader.ReadMoqVarInt(&type));
        EXPECT_EQ(type, MoqtDataStreamType::Fetch().value());
        EXPECT_FALSE(options.send_fin());  // fin_after_this is ignored.
        return absl::OkStatus();
      });
  if (second_result == MoqtFetchTask::GetNextObjectResult::kError) {
    EXPECT_CALL(data_stream, ResetWithUserCode);
  }
}
}  // namespace

// All callbacks are called asynchronously.
TEST_F(MoqtSessionTest, ProcessFetchGetEverythingFromUpstream) {
  bidi_wrapper_ =
      MoqtSessionPeer::CreateControlStream(&session_, &mock_bidi_stream_);
  MoqtFetch fetch = DefaultFetch();
  MockTrackPublisher* track = CreateTrackPublisher();

  // No callbacks are synchronous. MockFetchTask will store the callbacks.
  auto fetch_task_ptr = std::make_unique<MockFetchTask>();
  MockFetchTask* fetch_task = fetch_task_ptr.get();
  EXPECT_CALL(*track, StandaloneFetch)
      .WillOnce(Return(std::move(fetch_task_ptr)));
  bidi_wrapper_->ReceiveMessage(fetch);

  // Compose and send the FETCH_OK.
  MoqtFetchOk expected_ok;
  expected_ok.request_id = fetch.request_id;
  expected_ok.end_of_track = false;
  expected_ok.end_location = Location(1, 4);
  EXPECT_CALL(mock_bidi_stream_,
              Writev(SerializedControlMessage(expected_ok), _));
  fetch_task->CallFetchResponseCallback(expected_ok);
  // Data arrives.
  webtransport::test::MockStream data_stream;
  std::unique_ptr<webtransport::StreamVisitor> stream_visitor;
  ExpectStreamOpen(mock_session_, fetch_task, data_stream, stream_visitor);
  ExpectSendObject(fetch_task, data_stream, MoqtObjectStatus::kNormal,
                   Location(0, 0), "foo",
                   MoqtFetchTask::GetNextObjectResult::kPending);
  fetch_task->CallObjectsAvailableCallback();
}

// All callbacks are called synchronously. All relevant data is cached (or this
// is the original publisher).
TEST_F(MoqtSessionTest, ProcessFetchWholeRangeIsPresent) {
  bidi_wrapper_ =
      MoqtSessionPeer::CreateControlStream(&session_, &mock_bidi_stream_);
  MoqtFetch fetch = DefaultFetch();
  MockTrackPublisher* track = CreateTrackPublisher();

  MoqtFetchOk expected_ok;
  expected_ok.request_id = fetch.request_id;
  expected_ok.end_of_track = false;
  expected_ok.end_location = Location(1, 4);
  auto fetch_task_ptr =
      std::make_unique<MockFetchTask>(expected_ok, std::nullopt, true);
  MockFetchTask* fetch_task = fetch_task_ptr.get();
  EXPECT_CALL(*track, StandaloneFetch)
      .WillOnce(Return(std::move(fetch_task_ptr)));
  EXPECT_CALL(mock_bidi_stream_,
              Writev(SerializedControlMessage(expected_ok), _));
  webtransport::test::MockStream data_stream;
  std::unique_ptr<webtransport::StreamVisitor> stream_visitor;
  ExpectStreamOpen(mock_session_, fetch_task, data_stream, stream_visitor);
  ExpectSendObject(fetch_task, data_stream, MoqtObjectStatus::kNormal,
                   Location(0, 0), "foo",
                   MoqtFetchTask::GetNextObjectResult::kPending);
  // Everything spins upon message receipt. FetchTask is generating the
  // necessary callbacks.
  bidi_wrapper_->ReceiveMessage(fetch);
}

TEST_F(MoqtSessionTest, SendFragmentedFetchObject) {
  using ::testing::ByMove;
  bidi_wrapper_ =
      MoqtSessionPeer::CreateControlStream(&session_, &mock_bidi_stream_);
  MoqtFetch fetch = DefaultFetch();
  fetch.request_id = 3;  // Use an odd ID for peer request in client session.
  MockTrackPublisher* track = CreateTrackPublisher();

  // Disable synchronous callback to have more control.
  auto fetch_task_ptr =
      std::make_unique<MockFetchTask>(std::nullopt, std::nullopt, false);
  MockFetchTask* fetch_task = fetch_task_ptr.get();
  EXPECT_CALL(*track, StandaloneFetch)
      .WillOnce(Return(ByMove(std::move(fetch_task_ptr))));

  // Receive FETCH, send FETCH_OK.
  bidi_wrapper_->ReceiveMessage(fetch);
  // FETCH_OK responding to the request.
  MoqtFetchOk expected_ok;
  expected_ok.request_id = fetch.request_id;
  expected_ok.end_of_track = false;
  expected_ok.end_location = Location(1, 0);
  EXPECT_CALL(mock_bidi_stream_,
              Writev(SerializedControlMessage(expected_ok), _));
  fetch_task->CallFetchResponseCallback(expected_ok);

  std::unique_ptr<webtransport::StreamVisitor> stream_visitor;
  EXPECT_CALL(mock_session_, CanOpenNextOutgoingUnidirectionalStream)
      .WillRepeatedly(Return(true));
  EXPECT_CALL(mock_session_, OpenOutgoingUnidirectionalStream())
      .WillOnce(Return(&mock_uni_stream_));
  EXPECT_CALL(mock_uni_stream_, SetVisitor)
      .WillOnce([&](std::unique_ptr<webtransport::StreamVisitor> visitor) {
        stream_visitor = std::move(visitor);
      });
  EXPECT_CALL(mock_uni_stream_, SetPriority);
  EXPECT_CALL(mock_uni_stream_, CanWrite).WillRepeatedly(Return(true));
  // Trigger stream opening (calls SetObjectAvailableCallback with lambda1).
  // Setting the stream visitor will cause a second call to the callback.
  PublishedObjectMetadata metadata = {
      Location(0, 0), 0, "", MoqtObjectStatus::kNormal, 128, true, 10};
  EXPECT_CALL(*fetch_task, GetNextObject)
      .WillOnce([&](PublishedObject& output) {
        output.metadata = metadata;
        output.payload = PayloadFromString("part1");
        return MoqtFetchTask::GetNextObjectResult::kSuccess;
      })
      .WillOnce(Return(MoqtFetchTask::GetNextObjectResult::kPending));
  EXPECT_CALL(mock_uni_stream_, Writev)
      .WillOnce([&](absl::Span<const quiche::QuicheMemSlice> data,
                    const webtransport::StreamWriteOptions& options) {
        EXPECT_EQ(data.size(), 2);
        EXPECT_EQ(data[1].AsStringView(), "part1");
        return absl::OkStatus();
      });
  fetch_task->CallObjectsAvailableCallback();
  // lambda1 ran, mock_uni_stream_ captured, stream_visitor set.
  ASSERT_NE(stream_visitor, nullptr);

  // The second fragment is available.
  EXPECT_CALL(*fetch_task, GetNextObject)
      .WillOnce([&](PublishedObject& output) {
        output.metadata = metadata;
        output.payload = PayloadFromString("part2");
        return MoqtFetchTask::GetNextObjectResult::kSuccess;
      })
      .WillRepeatedly(Return(MoqtFetchTask::GetNextObjectResult::kPending));
  EXPECT_CALL(mock_uni_stream_, Writev)
      .WillOnce([&](absl::Span<const quiche::QuicheMemSlice> data,
                    const webtransport::StreamWriteOptions& options) {
        EXPECT_EQ(data.size(), 1);  // No header.
        EXPECT_EQ(data[0].AsStringView(), "part2");
        return absl::OkStatus();
      });
  fetch_task->CallObjectsAvailableCallback();
}

// The publisher has the first object locally, but has to go upstream to get
// the rest.
TEST_F(MoqtSessionTest, FetchReturnsObjectBeforeOk) {
  bidi_wrapper_ =
      MoqtSessionPeer::CreateControlStream(&session_, &mock_bidi_stream_);
  MoqtFetch fetch = DefaultFetch();
  MockTrackPublisher* track = CreateTrackPublisher();

  // Object returns synchronously.
  auto fetch_task_ptr =
      std::make_unique<MockFetchTask>(std::nullopt, std::nullopt, true);
  MockFetchTask* fetch_task = fetch_task_ptr.get();
  EXPECT_CALL(*track, StandaloneFetch)
      .WillOnce(Return(std::move(fetch_task_ptr)));
  webtransport::test::MockStream data_stream;
  std::unique_ptr<webtransport::StreamVisitor> stream_visitor;
  ExpectStreamOpen(mock_session_, fetch_task, data_stream, stream_visitor);
  ExpectSendObject(fetch_task, data_stream, MoqtObjectStatus::kNormal,
                   Location(0, 0), "foo",
                   MoqtFetchTask::GetNextObjectResult::kPending);
  bidi_wrapper_->ReceiveMessage(fetch);

  MoqtFetchOk expected_ok;
  expected_ok.request_id = fetch.request_id;
  expected_ok.end_of_track = false;
  expected_ok.end_location = Location(1, 4);
  EXPECT_CALL(mock_bidi_stream_,
              Writev(SerializedControlMessage(expected_ok), _));
  fetch_task->CallFetchResponseCallback(expected_ok);
}

TEST_F(MoqtSessionTest, FetchReturnsObjectBeforeError) {
  bidi_wrapper_ =
      MoqtSessionPeer::CreateControlStream(&session_, &mock_bidi_stream_);
  MoqtFetch fetch = DefaultFetch();
  MockTrackPublisher* track = CreateTrackPublisher();

  auto fetch_task_ptr =
      std::make_unique<MockFetchTask>(std::nullopt, std::nullopt, true);
  MockFetchTask* fetch_task = fetch_task_ptr.get();
  EXPECT_CALL(*track, StandaloneFetch)
      .WillOnce(Return(std::move(fetch_task_ptr)));
  webtransport::test::MockStream data_stream;
  std::unique_ptr<webtransport::StreamVisitor> stream_visitor;
  ExpectStreamOpen(mock_session_, fetch_task, data_stream, stream_visitor);
  ExpectSendObject(fetch_task, data_stream, MoqtObjectStatus::kNormal,
                   Location(0, 0), "foo",
                   MoqtFetchTask::GetNextObjectResult::kPending);
  bidi_wrapper_->ReceiveMessage(fetch);

  MoqtRequestError expected_error{
      fetch.request_id, RequestErrorCode::kDoesNotExist, std::nullopt, "foo"};
  EXPECT_CALL(mock_bidi_stream_,
              Writev(SerializedControlMessage(expected_error), _));
  fetch_task->CallFetchResponseCallback(expected_error);
}

TEST_F(MoqtSessionTest, InvalidFetch) {
  bidi_wrapper_ =
      MoqtSessionPeer::CreateControlStream(&session_, &mock_bidi_stream_);
  MockTrackPublisher* track = CreateTrackPublisher();
  MoqtFetch fetch = DefaultFetch();
  EXPECT_CALL(*track, StandaloneFetch)
      .WillOnce(Return(std::make_unique<MockFetchTask>()));
  bidi_wrapper_->ReceiveMessage(fetch);
  EXPECT_CALL(mock_session_,
              CloseSession(static_cast<uint64_t>(MoqtError::kInvalidRequestId),
                           "Duplicate request ID"))
      .Times(1);
  bidi_wrapper_->ReceiveMessage(fetch);
}

TEST_F(MoqtSessionTest, FetchFails) {
  bidi_wrapper_ =
      MoqtSessionPeer::CreateControlStream(&session_, &mock_bidi_stream_);
  MoqtFetch fetch = DefaultFetch();
  MockTrackPublisher* track = CreateTrackPublisher();

  auto fetch_task_ptr = std::make_unique<MockFetchTask>();
  MockFetchTask* fetch_task = fetch_task_ptr.get();
  EXPECT_CALL(*track, StandaloneFetch)
      .WillOnce(Return(std::move(fetch_task_ptr)));
  EXPECT_CALL(*fetch_task, GetStatus())
      .WillRepeatedly(Return(absl::Status(absl::StatusCode::kInternal, "foo")));
  EXPECT_CALL(mock_bidi_stream_,
              Writev(ControlMessageOfType(MoqtMessageType::kRequestError), _));
  bidi_wrapper_->ReceiveMessage(fetch);
}

TEST_F(MoqtSessionTest, FullFetchDeliveryWithFlowControl) {
  bidi_wrapper_ =
      MoqtSessionPeer::CreateControlStream(&session_, &mock_bidi_stream_);
  MoqtFetch fetch = DefaultFetch();
  MockTrackPublisher* track = CreateTrackPublisher();

  auto fetch_task_ptr =
      std::make_unique<MockFetchTask>(std::nullopt, std::nullopt, true);
  MockFetchTask* fetch_task = fetch_task_ptr.get();
  EXPECT_CALL(*track, StandaloneFetch)
      .WillOnce(Return(std::move(fetch_task_ptr)));

  bidi_wrapper_->ReceiveMessage(fetch);
  EXPECT_CALL(mock_session_, CanOpenNextOutgoingUnidirectionalStream())
      .WillOnce(Return(false));
  fetch_task->CallObjectsAvailableCallback();

  // Stream opens, but with no credit.
  webtransport::test::MockStream data_stream;
  std::unique_ptr<webtransport::StreamVisitor> stream_visitor;
  ExpectStreamOpen(mock_session_, fetch_task, data_stream, stream_visitor);
  EXPECT_CALL(data_stream, CanWrite()).WillOnce(Return(false));
  session_.OnCanCreateNewOutgoingUnidirectionalStream();
  // Object with FIN
  ExpectSendObject(fetch_task, data_stream, MoqtObjectStatus::kNormal,
                   Location(0, 0), "foo",
                   MoqtFetchTask::GetNextObjectResult::kEof);
  stream_visitor->OnCanWrite();
}

TEST_F(MoqtSessionTest, IncomingRelativeJoiningFetch) {
  MoqtSubscribe subscribe = DefaultSubscribe();
  // Give it the latest object filter.
  subscribe.parameters.subscription_filter.emplace(
      MoqtFilterType::kLargestObject);
  bidi_wrapper_ = std::make_unique<MoqtBidiStreamTestWrapper>(
      ResponseStream(kSubscribeByte));
  MockTrackPublisher* track = CreateTrackPublisher();
  SetLargestId(track, Location(4, 10));
  ReceiveSubscribeSynchronousOk(track, subscribe, bidi_wrapper_.get());

  webtransport::test::MockStream control_stream;
  std::unique_ptr<MoqtBidiStreamTestWrapper> control_wrapper =
      MoqtSessionPeer::CreateControlStream(&session_, &control_stream);
  ASSERT_TRUE(MoqtSessionPeer::RequestIdIsLivePublisher(&session_,
                                                        subscribe.request_id));
  MoqtFetch fetch = DefaultFetch();
  fetch.request_id = 3;
  fetch.fetch = JoiningFetchRelative(1, 2);
  EXPECT_CALL(*track, StandaloneFetch(Location(2, 0), Location(4, 10), _))
      .WillOnce(Return(std::make_unique<MockFetchTask>()));
  control_wrapper->ReceiveMessage(fetch);
}

TEST_F(MoqtSessionTest, IncomingAbsoluteJoiningFetch) {
  MoqtSubscribe subscribe = DefaultSubscribe();
  // Give it the latest object filter.
  subscribe.parameters.subscription_filter.emplace(
      MoqtFilterType::kLargestObject);
  bidi_wrapper_ = std::make_unique<MoqtBidiStreamTestWrapper>(
      ResponseStream(kSubscribeByte));
  MockTrackPublisher* track = CreateTrackPublisher();
  SetLargestId(track, Location(4, 10));
  ReceiveSubscribeSynchronousOk(track, subscribe, bidi_wrapper_.get());

  ASSERT_TRUE(MoqtSessionPeer::RequestIdIsLivePublisher(&session_,
                                                        subscribe.request_id));
  webtransport::test::MockStream control_stream;
  std::unique_ptr<MoqtBidiStreamTestWrapper> control_wrapper =
      MoqtSessionPeer::CreateControlStream(&session_, &control_stream);
  MoqtFetch fetch = DefaultFetch();
  fetch.request_id = 3;
  fetch.fetch = JoiningFetchAbsolute(1, 2);
  EXPECT_CALL(*track, StandaloneFetch(Location(2, 0), Location(4, 10), _))
      .WillOnce(Return(std::make_unique<MockFetchTask>()));
  control_wrapper->ReceiveMessage(fetch);
}

TEST_F(MoqtSessionTest, IncomingJoiningFetchBadRequestId) {
  bidi_wrapper_ =
      MoqtSessionPeer::CreateControlStream(&session_, &mock_bidi_stream_);
  MoqtFetch fetch = DefaultFetch();
  fetch.fetch = JoiningFetchRelative(1, 2);
  MoqtRequestError expected_error = {
      /*request_id=*/1,
      RequestErrorCode::kInvalidJoiningRequestId,
      /*retry_interval=*/std::nullopt,
      "Joining Fetch for non-existent request",
  };
  EXPECT_CALL(mock_bidi_stream_,
              Writev(SerializedControlMessage(expected_error), _));
  bidi_wrapper_->ReceiveMessage(fetch);
}

TEST_F(MoqtSessionTest, IncomingJoiningFetchForwardZero) {
  MoqtSubscribe subscribe = DefaultSubscribe();
  subscribe.parameters.set_forward(false);
  bidi_wrapper_ = std::make_unique<MoqtBidiStreamTestWrapper>(
      ResponseStream(kSubscribeByte));
  MockTrackPublisher* track = CreateTrackPublisher();
  SetLargestId(track, Location(2, 10));
  ReceiveSubscribeSynchronousOk(track, subscribe, bidi_wrapper_.get());

  webtransport::test::MockStream control_stream;
  std::unique_ptr<MoqtBidiStreamTestWrapper> control_wrapper =
      MoqtSessionPeer::CreateControlStream(&session_, &control_stream);
  MoqtFetch fetch = DefaultFetch();
  fetch.request_id = 3;
  fetch.fetch = JoiningFetchRelative(1, 2);
  EXPECT_CALL(mock_session_,
              CloseSession(static_cast<uint64_t>(MoqtError::kProtocolViolation),
                           "Joining Fetch for non-forwarding subscribe"))
      .Times(1);
  control_wrapper->ReceiveMessage(fetch);
}

TEST_F(MoqtSessionTest, SendJoiningFetch) {
  PrepareRequestStream(bidi_wrapper_);
  webtransport::test::MockStream control_stream;
  std::unique_ptr<MoqtBidiStreamTestWrapper> control_wrapper =
      MoqtSessionPeer::CreateControlStream(&session_, &control_stream);
  MoqtSubscribe expected_subscribe(
      0, FullTrackName("foo", "bar"),
      MessageParameters(MoqtFilterType::kLargestObject));
  MoqtFetch expected_fetch = {
      /*request_id=*/2,
      /*fetch=*/JoiningFetchRelative(0, 1),
      MessageParameters(),
  };
  EXPECT_CALL(mock_bidi_stream_,
              Writev(SerializedControlMessage(expected_subscribe), _));
  EXPECT_CALL(control_stream,
              Writev(SerializedControlMessage(expected_fetch), _));
  EXPECT_TRUE(session_.RelativeJoiningFetch(expected_subscribe.full_track_name,
                                            &remote_track_visitor_, nullptr, 1,
                                            MessageParameters()));
}

TEST_F(MoqtSessionTest, SendJoiningFetchNoFlowControl) {
  PrepareRequestStream(bidi_wrapper_);
  webtransport::test::MockStream control_stream;
  std::unique_ptr<MoqtBidiStreamTestWrapper> control_wrapper =
      MoqtSessionPeer::CreateControlStream(&session_, &control_stream);
  EXPECT_CALL(mock_bidi_stream_,
              Writev(ControlMessageOfType(MoqtMessageType::kSubscribe), _));
  EXPECT_CALL(control_stream,
              Writev(ControlMessageOfType(MoqtMessageType::kFetch), _));
  EXPECT_TRUE(session_.RelativeJoiningFetch(FullTrackName("foo", "bar"),
                                            &remote_track_visitor_, 0,
                                            MessageParameters()));

  EXPECT_CALL(remote_track_visitor_, OnReply).Times(1);
  MessageParameters parameters;
  parameters.largest_object = Location(2, 0);
  bidi_wrapper_->ReceiveMessage(
      MoqtSubscribeOk(0, 2, parameters, TrackExtensions()));
  control_wrapper->ReceiveMessage(MoqtFetchOk(
      2, false, Location(2, 0), MessageParameters(), TrackExtensions()));
  // Packet arrives on FETCH stream.
  MoqtObject object = {
      /*request_id=*/2,
      /*group_id, object_id=*/2,
      0,
      /*publisher_priority=*/128,
      /*extension_headers=*/"",
      /*status=*/MoqtObjectStatus::kNormal,
      /*subgroup=*/0,
      /*first_object_in_subgroup=*/true,
      /*payload_length=*/3,
  };
  MoqtFramer framer(true, quic::Perspective::IS_SERVER);
  std::optional<PublishedObjectMetadata> metadata;
  quiche::QuicheBuffer header = framer.SerializeObjectHeader(
      object, MoqtDataStreamType::Fetch(), metadata);
  webtransport::test::InMemoryStream data_stream(kIncomingUniStreamId);
  data_stream.SetVisitor(
      MoqtSessionPeer::CreateIncomingStreamVisitor(&session_, &data_stream));
  data_stream.Receive(header.AsStringView(), false);
  EXPECT_CALL(remote_track_visitor_, OnObjectFragment).Times(1);
  // Last object of the FETCH causes FETCH_CANCEL.
  EXPECT_CALL(control_stream,
              Writev(ControlMessageOfType(MoqtMessageType::kFetchCancel), _));
  data_stream.Receive("foo", false);
}

TEST_F(MoqtSessionTest, IncomingSubscribeNamespace) {
  TrackNamespace prefix{"foo"};
  MessageParameters parameters;
  parameters.authorization_tokens.emplace_back(AuthTokenType::kOutOfBand,
                                               "foo");

  MoqtSubscribeNamespace subscribe_namespace = {/*request_id=*/1, prefix,
                                                parameters};
  quiche::QuicheWeakPtr<MockNamespaceTask> task;
  MoqtRequestOk expected_ok(/*request_id=*/1);
  expected_ok.parameters.expires = quic::QuicTimeDelta::FromSeconds(60);
  EXPECT_CALL(session_callbacks_.incoming_subscribe_namespace_callback,
              Call(prefix, parameters, _))
      .WillOnce([&](const TrackNamespace& prefix, const MessageParameters&,
                    MoqtResponseCallback response_callback) {
        std::move(response_callback)(expected_ok.parameters);
        auto task_ptr = std::make_unique<MockNamespaceTask>(prefix);
        task = task_ptr->GetWeakPtr();
        return task_ptr;
      });
  bidi_wrapper_ = std::make_unique<MoqtBidiStreamTestWrapper>(
      ResponseStream(kSubscribeNamespaceByte));
  EXPECT_CALL(mock_bidi_stream_,
              Writev(SerializedControlMessage(expected_ok), _))
      .WillOnce(Return(absl::OkStatus()));
  bidi_wrapper_->ReceiveMessage(subscribe_namespace);

  // Deliver a NAMESPACE
  ASSERT_TRUE(task.IsValid());
  EXPECT_CALL(*task.GetIfAvailable(), GetNextSuffix)
      .WillOnce([](TrackNamespace& prefix, TransactionType& type) {
        prefix = TrackNamespace({"bar"});
        type = TransactionType::kAdd;
        return GetNextResult::kSuccess;
      })
      .WillOnce(Return(GetNextResult::kPending));
  MoqtNamespace expected_namespace = {
      TrackNamespace({"bar"}),
  };
  EXPECT_CALL(mock_bidi_stream_,
              Writev(SerializedControlMessage(expected_namespace), _))
      .WillOnce(Return(absl::OkStatus()));
  task.GetIfAvailable()->InvokeCallback();

  // Unsubscribe
  bidi_wrapper_.reset();
  EXPECT_FALSE(task.IsValid());
}

TEST_F(MoqtSessionTest, IncomingSubscribeNamespaceWithSynchronousError) {
  TrackNamespace prefix{"foo"};
  MessageParameters parameters;
  parameters.authorization_tokens.emplace_back(AuthTokenType::kOutOfBand,
                                               "foo");
  bidi_wrapper_ = std::make_unique<MoqtBidiStreamTestWrapper>(
      ResponseStream(kSubscribeNamespaceByte));
  MoqtSubscribeNamespace subscribe_namespace = {/*request_id=*/1, prefix,
                                                parameters};
  EXPECT_CALL(session_callbacks_.incoming_subscribe_namespace_callback,
              Call(prefix, parameters, _))
      .WillOnce([&](const TrackNamespace&, const MessageParameters&,
                    MoqtResponseCallback response_callback) {
        std::move(response_callback)(MoqtRequestErrorInfo{
            RequestErrorCode::kUnauthorized, std::nullopt, "foo"});
        return nullptr;
      });
  EXPECT_CALL(mock_bidi_stream_,
              Writev(ControlMessageOfType(MoqtMessageType::kRequestError), _))
      .WillOnce([](absl::Span<quiche::QuicheMemSlice>,
                   const webtransport::StreamWriteOptions& options) {
        EXPECT_TRUE(options.send_fin());
        return absl::OkStatus();
      });
  bidi_wrapper_->ReceiveMessage(subscribe_namespace);
}

TEST_F(MoqtSessionTest, IncomingSubscribeNamespaceWithPrefixOverlap) {
  TrackNamespace foo{"foo"}, foobar{"foo", "bar"};
  MessageParameters parameters;
  parameters.authorization_tokens.emplace_back(AuthTokenType::kOutOfBand,
                                               "foo");
  bidi_wrapper_ = std::make_unique<MoqtBidiStreamTestWrapper>(
      ResponseStream(kSubscribeNamespaceByte));
  MoqtSubscribeNamespace subscribe_namespace = {/*request_id=*/1, foo,
                                                parameters};
  EXPECT_CALL(session_callbacks_.incoming_subscribe_namespace_callback,
              Call(foo, parameters, _))
      .WillOnce([&](const TrackNamespace& prefix, const MessageParameters&,
                    MoqtResponseCallback response_callback) {
        std::move(response_callback)(MessageParameters());
        auto task_ptr = std::make_unique<MockNamespaceTask>(prefix);
        return task_ptr;
      });
  EXPECT_CALL(mock_bidi_stream_,
              Writev(ControlMessageOfType(MoqtMessageType::kRequestOk), _))
      .WillOnce(Return(absl::OkStatus()));
  bidi_wrapper_->ReceiveMessage(subscribe_namespace);

  subscribe_namespace.request_id += 2;
  subscribe_namespace.track_namespace_prefix = foobar;
  webtransport::test::MockStream bidi_stream_2;
  auto bidi_wrapper_2 = std::make_unique<MoqtBidiStreamTestWrapper>(
      ResponseStream(kSubscribeNamespaceByte, &bidi_stream_2));
  EXPECT_CALL(bidi_stream_2,
              Writev(ControlMessageOfType(MoqtMessageType::kRequestError), _))
      .WillOnce([](absl::Span<quiche::QuicheMemSlice>,
                   const webtransport::StreamWriteOptions& options) {
        EXPECT_TRUE(options.send_fin());
        return absl::OkStatus();
      });
  bidi_wrapper_2->ReceiveMessage(subscribe_namespace);
}

TEST_F(MoqtSessionTest, FetchThenOkThenCancel) {
  bidi_wrapper_ =
      MoqtSessionPeer::CreateControlStream(&session_, &mock_bidi_stream_);
  std::unique_ptr<MoqtFetchTask> fetch_task;
  session_.Fetch(
      FullTrackName("foo", "bar"),
      [&](std::unique_ptr<MoqtFetchTask> task) {
        fetch_task = std::move(task);
      },
      Location(0, 0), 4, std::nullopt, MessageParameters());
  MoqtFetchOk ok = {
      /*request_id=*/0,
      /*end_of_track=*/false, Location(3, 25),
      MessageParameters(),    TrackExtensions(),
  };
  bidi_wrapper_->ReceiveMessage(ok);
  ASSERT_NE(fetch_task, nullptr);
  EXPECT_TRUE(fetch_task->GetStatus().ok());
  PublishedObject object;
  EXPECT_EQ(fetch_task->GetNextObject(object),
            MoqtFetchTask::GetNextObjectResult::kPending);
  // Cancel the fetch.
  EXPECT_CALL(mock_bidi_stream_,
              Writev(ControlMessageOfType(MoqtMessageType::kFetchCancel), _));
  fetch_task.reset();
}

TEST_F(MoqtSessionTest, FetchThenError) {
  bidi_wrapper_ =
      MoqtSessionPeer::CreateControlStream(&session_, &mock_bidi_stream_);
  std::unique_ptr<MoqtFetchTask> fetch_task;
  session_.Fetch(
      FullTrackName("foo", "bar"),
      [&](std::unique_ptr<MoqtFetchTask> task) {
        fetch_task = std::move(task);
      },
      Location(0, 0), 4, std::nullopt, MessageParameters());
  MoqtRequestError error = {
      /*request_id=*/0,
      RequestErrorCode::kUnauthorized,
      /*retry_interval=*/std::nullopt,
      "No username provided",
  };
  bidi_wrapper_->ReceiveMessage(error);
  ASSERT_NE(fetch_task, nullptr);
  EXPECT_TRUE(absl::IsPermissionDenied(fetch_task->GetStatus()));
  EXPECT_EQ(fetch_task->GetStatus().message(), "No username provided");
}

// The application takes objects as they arrive.
TEST_F(MoqtSessionTest, IncomingFetchObjectsGreedyApp) {
  bidi_wrapper_ =
      MoqtSessionPeer::CreateControlStream(&session_, &mock_bidi_stream_);
  std::unique_ptr<MoqtFetchTask> fetch_task;
  uint64_t expected_object_id = 0;
  session_.Fetch(
      FullTrackName("foo", "bar"),
      [&](std::unique_ptr<MoqtFetchTask> task) {
        fetch_task = std::move(task);
        fetch_task->SetObjectAvailableCallback([&]() {
          PublishedObject object;
          MoqtFetchTask::GetNextObjectResult result;
          do {
            result = fetch_task->GetNextObject(object);
            if (result == MoqtFetchTask::GetNextObjectResult::kSuccess) {
              EXPECT_EQ(object.metadata.location.object, expected_object_id);
              ++expected_object_id;
            }
            if (result == MoqtFetchTask::GetNextObjectResult::kError) {
              break;
            }
          } while (result != MoqtFetchTask::GetNextObjectResult::kPending);
        });
      },
      Location(0, 0), 4, std::nullopt, MessageParameters());
  // Build queue of packets to arrive.
  std::queue<quiche::QuicheBuffer> headers;
  std::queue<std::string> payloads;
  MoqtObject object = {
      /*request_id=*/0,
      /*group_id, object_id=*/0,
      0,
      /*publisher_priority=*/128,
      /*extension_headers=*/"",
      /*status=*/MoqtObjectStatus::kNormal,
      /*subgroup=*/0,
      /*first_object_in_subgroup=*/true,
      /*payload_length=*/3,
  };
  MoqtFramer framer(true, quic::Perspective::IS_SERVER);
  std::optional<PublishedObjectMetadata> metadata;
  for (int i = 0; i < 4; ++i) {
    object.object_id = i;
    headers.push(framer.SerializeObjectHeader(
        object, MoqtDataStreamType::Fetch(), metadata));
    metadata = PublishedObjectMetadata();
    metadata->location.object = i;  // only object ID matters.
    payloads.push("foo");
  }

  // Open stream, deliver two objects before FETCH_OK. Neither should be read.
  webtransport::test::InMemoryStream data_stream(kIncomingUniStreamId);
  data_stream.SetVisitor(
      MoqtSessionPeer::CreateIncomingStreamVisitor(&session_, &data_stream));
  for (int i = 0; i < 2; ++i) {
    data_stream.Receive(headers.front().AsStringView(), false);
    data_stream.Receive(payloads.front(), false);
    headers.pop();
    payloads.pop();
  }
  EXPECT_EQ(fetch_task, nullptr);
  EXPECT_GT(data_stream.ReadableBytes(), 0);

  // FETCH_OK arrives, objects are delivered.
  MoqtFetchOk ok = {
      /*request_id=*/0,
      /*end_of_track=*/false,
      /*end_location=*/Location(3, 25),
      MessageParameters(),
      TrackExtensions(),
  };
  bidi_wrapper_->ReceiveMessage(ok);
  ASSERT_NE(fetch_task, nullptr);
  EXPECT_EQ(expected_object_id, 2);

  // Deliver the rest of the objects.
  for (int i = 2; i < 4; ++i) {
    data_stream.Receive(headers.front().AsStringView(), false);
    data_stream.Receive(payloads.front(), false);
    headers.pop();
    payloads.pop();
  }
  EXPECT_EQ(expected_object_id, 4);
}

TEST_F(MoqtSessionTest, IncomingFetchObjectsSlowApp) {
  bidi_wrapper_ =
      MoqtSessionPeer::CreateControlStream(&session_, &mock_bidi_stream_);
  std::unique_ptr<MoqtFetchTask> fetch_task;
  uint64_t expected_object_id = 0;
  bool objects_available = false;
  session_.Fetch(
      FullTrackName("foo", "bar"),
      [&](std::unique_ptr<MoqtFetchTask> task) {
        fetch_task = std::move(task);
        fetch_task->SetObjectAvailableCallback(
            [&]() { objects_available = true; });
      },
      Location(0, 0), 4, std::nullopt, MessageParameters());
  // Build queue of packets to arrive.
  std::queue<quiche::QuicheBuffer> headers;
  std::queue<std::string> payloads;
  MoqtObject object = {
      /*request_id=*/0,
      /*group_id, object_id=*/0,
      0,
      /*publisher_priority=*/128,
      /*extension_headers=*/"",
      /*status=*/MoqtObjectStatus::kNormal,
      /*subgroup=*/0,
      /*first_object_in_subgroup=*/true,
      /*payload_length=*/3,
  };
  MoqtFramer framer(true, quic::Perspective::IS_SERVER);
  std::optional<PublishedObjectMetadata> metadata;
  for (int i = 0; i < 4; ++i) {
    object.object_id = i;
    headers.push(framer.SerializeObjectHeader(
        object, MoqtDataStreamType::Fetch(), metadata));
    metadata = PublishedObjectMetadata();
    metadata->location.object = i;  // only object ID matters.
    payloads.push("foo");
  }

  // Open stream, deliver two objects before FETCH_OK. Neither should be read.
  webtransport::test::InMemoryStream data_stream(kIncomingUniStreamId);
  data_stream.SetVisitor(
      MoqtSessionPeer::CreateIncomingStreamVisitor(&session_, &data_stream));
  for (int i = 0; i < 2; ++i) {
    data_stream.Receive(headers.front().AsStringView(), false);
    data_stream.Receive(payloads.front(), false);
    headers.pop();
    payloads.pop();
  }
  EXPECT_EQ(fetch_task, nullptr);
  EXPECT_GT(data_stream.ReadableBytes(), 0);

  // FETCH_OK arrives, objects are available.
  MoqtFetchOk ok = {
      /*request_id=*/0,
      /*end_of_track=*/false, Location(3, 25),
      MessageParameters(),    TrackExtensions(),
  };
  bidi_wrapper_->ReceiveMessage(ok);
  ASSERT_NE(fetch_task, nullptr);
  EXPECT_TRUE(objects_available);

  // Get the objects
  MoqtFetchTask::GetNextObjectResult result;
  do {
    PublishedObject new_object;
    result = fetch_task->GetNextObject(new_object);
    if (result == MoqtFetchTask::GetNextObjectResult::kSuccess) {
      EXPECT_EQ(new_object.metadata.location.object, expected_object_id);
      ++expected_object_id;
    }
  } while (result != MoqtFetchTask::GetNextObjectResult::kPending);
  EXPECT_EQ(expected_object_id, 2);
  objects_available = false;

  // Deliver the rest of the objects.
  for (int i = 2; i < 4; ++i) {
    data_stream.Receive(headers.front().AsStringView(), false);
    data_stream.Receive(payloads.front(), false);
    headers.pop();
    payloads.pop();
  }
  EXPECT_TRUE(objects_available);
  EXPECT_EQ(expected_object_id, 2);  // Not delivered yet.
  // Get the objects
  do {
    PublishedObject new_object;
    result = fetch_task->GetNextObject(new_object);
    if (result == MoqtFetchTask::GetNextObjectResult::kSuccess) {
      EXPECT_EQ(new_object.metadata.location.object, expected_object_id);
      ++expected_object_id;
    }
  } while (result != MoqtFetchTask::GetNextObjectResult::kPending);
  EXPECT_EQ(expected_object_id, 4);
}

TEST_F(MoqtSessionTest, DeliveryTimeoutParameter) {
  MoqtSubscribe request = DefaultSubscribe();
  request.parameters.delivery_timeout = quic::QuicTimeDelta::FromSeconds(1);
  bidi_wrapper_ = std::make_unique<MoqtBidiStreamTestWrapper>(
      ResponseStream(kSubscribeByte));
  MockTrackPublisher* track = CreateTrackPublisher();
  ReceiveSubscribeSynchronousOk(track, request, bidi_wrapper_.get());
  std::optional<quic::QuicTimeDelta> delivery_timeout =
      MoqtSessionPeer::GetDeliveryTimeout(&session_, request.request_id);
  EXPECT_TRUE(delivery_timeout.has_value() &&
              *delivery_timeout == quic::QuicTimeDelta::FromSeconds(1));
}

TEST_F(MoqtSessionTest, ReceiveGoAwayEnforcement) {
  bidi_wrapper_ =
      MoqtSessionPeer::CreateControlStream(&session_, &mock_bidi_stream_);
  EXPECT_CALL(session_callbacks_.goaway_received_callback, Call("foo"));
  bidi_wrapper_->ReceiveMessage(MoqtGoAway("foo"));
  // New requests not allowed.
  EXPECT_CALL(mock_bidi_stream_, Writev).Times(0);
  MessageParameters parameters = SubscribeForTest();
  parameters.subscription_filter.emplace(MoqtFilterType::kLargestObject);
  EXPECT_FALSE(session_.Subscribe(FullTrackName("foo", "bar"),
                                  &remote_track_visitor_, parameters));
  TrackNamespace prefix({"foo"});
  EXPECT_EQ(session_.SubscribeNamespace(
                prefix, MessageParameters(),
                +[](std::variant<MessageParameters, MoqtRequestErrorInfo>) {}),
            nullptr);
  session_.PublishNamespace(
      TrackNamespace{"foo"}, MessageParameters(),
      +[](std::variant<MessageParameters, MoqtRequestErrorInfo>) {},
      +[](MoqtRequestErrorInfo) {});
  EXPECT_FALSE(session_.Fetch(
      FullTrackName{TrackNamespace({"foo"}), "bar"},
      +[](std::unique_ptr<MoqtFetchTask>) {}, Location(0, 0), 5, std::nullopt,
      MessageParameters()));
  // Error on additional GOAWAY.
  EXPECT_CALL(mock_session_,
              CloseSession(static_cast<uint64_t>(MoqtError::kProtocolViolation),
                           "Received multiple GOAWAY messages"))
      .Times(1);
  bool reported_error = false;
  EXPECT_CALL(session_callbacks_.session_terminated_callback, Call(_))
      .WillOnce([&](absl::string_view error_message) {
        reported_error = true;
        EXPECT_EQ(error_message, "Received multiple GOAWAY messages");
      });
  bidi_wrapper_->ReceiveMessage(MoqtGoAway("foo"));
}

TEST_F(MoqtSessionTest, SendGoAwayEnforcement) {
  bidi_wrapper_ =
      MoqtSessionPeer::CreateControlStream(&session_, &mock_bidi_stream_);
  CreateTrackPublisher();
  EXPECT_CALL(mock_bidi_stream_,
              Writev(ControlMessageOfType(MoqtMessageType::kGoAway), _));
  session_.GoAway("");

  EXPECT_CALL(mock_bidi_stream_,
              Writev(ControlMessageOfType(MoqtMessageType::kRequestError), _));
  bidi_wrapper_->ReceiveMessage(
      MoqtPublishNamespace(3, TrackNamespace({"foo"}), MessageParameters()));
  EXPECT_CALL(mock_bidi_stream_,
              Writev(ControlMessageOfType(MoqtMessageType::kRequestError), _));
  MoqtFetch fetch = DefaultFetch();
  fetch.request_id = 5;
  bidi_wrapper_->ReceiveMessage(fetch);

  // All new bidi streams types are immediately rejected.
  webtransport::test::MockStream new_request_stream;
  EXPECT_CALL(mock_session_, AcceptIncomingBidirectionalStream)
      .WillOnce(Return(&new_request_stream))
      .WillOnce(Return(nullptr));
  EXPECT_CALL(new_request_stream, CanWrite()).WillOnce(Return(true));
  EXPECT_CALL(new_request_stream,
              Writev(ControlMessageOfType(MoqtMessageType::kRequestError), _))
      .WillOnce([](absl::Span<quiche::QuicheMemSlice>,
                   const webtransport::StreamWriteOptions& options) {
        EXPECT_TRUE(options.send_fin());
        return absl::OkStatus();
      });
  session_.OnIncomingBidirectionalStreamAvailable();

  // If a new stream can't be written, reset it.
  webtransport::test::MockStream new_request_stream_2;
  EXPECT_CALL(mock_session_, AcceptIncomingBidirectionalStream)
      .WillOnce(Return(&new_request_stream_2))
      .WillOnce(Return(nullptr));
  EXPECT_CALL(new_request_stream_2, CanWrite()).WillOnce(Return(false));
  EXPECT_CALL(new_request_stream_2, ResetWithUserCode);
  session_.OnIncomingBidirectionalStreamAvailable();

  // Block all outgoing PUBLISH_NAMESPACE, GOAWAY,etc.
  MessageParameters parameters = SubscribeForTest();
  parameters.subscription_filter.emplace(MoqtFilterType::kLargestObject);
  EXPECT_FALSE(session_.Subscribe(FullTrackName({"foo"}, "bar"),
                                  &remote_track_visitor_, parameters));
  TrackNamespace prefix({"foo"});
  EXPECT_EQ(session_.SubscribeNamespace(
                prefix, MessageParameters(),
                +[](std::variant<MessageParameters, MoqtRequestErrorInfo>) {}),
            nullptr);
  session_.PublishNamespace(
      TrackNamespace{"foo"}, MessageParameters(),
      +[](std::variant<MessageParameters, MoqtRequestErrorInfo>) {},
      +[](MoqtRequestErrorInfo) {});
  EXPECT_FALSE(session_.Fetch(
      FullTrackName(TrackNamespace({"foo"}), "bar"),
      +[](std::unique_ptr<MoqtFetchTask>) {}, Location(0, 0), 5, std::nullopt,
      MessageParameters()));
  session_.GoAway("");
  // GoAway timer fires.
  auto* goaway_alarm =
      absl::down_cast<quic::test::MockAlarmFactory::TestAlarm*>(
          MoqtSessionPeer::GetGoAwayTimeoutAlarm(&session_));
  EXPECT_CALL(mock_session_,
              CloseSession(static_cast<webtransport::SessionErrorCode>(
                               MoqtError::kGoawayTimeout),
                           _));
  goaway_alarm->Fire();
}

TEST_F(MoqtSessionTest, ClientCannotSendNewSessionUri) {
  // session_ is a client session.
  bidi_wrapper_ =
      MoqtSessionPeer::CreateControlStream(&session_, &mock_bidi_stream_);
  // Client GOAWAY not sent.
  EXPECT_CALL(mock_bidi_stream_, Writev).Times(0);
  session_.GoAway("foo");
}

TEST_F(MoqtSessionTest, ServerCannotReceiveNewSessionUri) {
  webtransport::test::MockSession mock_session;
  MoqtSession session(&mock_session,
                      MoqtSessionParameters(quic::Perspective::IS_SERVER),
                      std::make_unique<quic::test::TestAlarmFactory>(),
                      session_callbacks_.AsSessionCallbacks());
  bidi_wrapper_ =
      MoqtSessionPeer::CreateControlStream(&session, &mock_bidi_stream_);
  EXPECT_CALL(
      mock_session,
      CloseSession(static_cast<uint64_t>(MoqtError::kProtocolViolation),
                   "Received GOAWAY with new_session_uri on the server"))
      .Times(1);
  bool reported_error = false;
  EXPECT_CALL(session_callbacks_.session_terminated_callback, Call(_))
      .WillOnce([&](absl::string_view error_message) {
        reported_error = true;
        EXPECT_EQ(error_message,
                  "Received GOAWAY with new_session_uri on the server");
      });
  bidi_wrapper_->ReceiveMessage(MoqtGoAway("foo"));
  EXPECT_TRUE(reported_error);
}

TEST_F(MoqtSessionTest, IncomingTrackStatusThenSynchronousOk) {
  bidi_wrapper_ = std::make_unique<MoqtBidiStreamTestWrapper>(
      ResponseStream(kTrackStatusByte));
  auto* track = CreateTrackPublisher();

  MoqtTrackStatus track_status = DefaultSubscribe();
  EXPECT_CALL(*track, AddObjectListener)
      .WillOnce([&](MoqtObjectListener* listener) {
        EXPECT_CALL(*track, expiration)
            .WillRepeatedly(
                Return(quic::QuicTimeDelta::FromMilliseconds(10000)));
        EXPECT_CALL(*track, largest_location)
            .WillRepeatedly(Return(Location(5, 30)));
        MoqtRequestOk expected_ok;
        expected_ok.request_id = track_status.request_id;
        expected_ok.parameters.expires =
            quic::QuicTimeDelta::FromMilliseconds(10000);
        expected_ok.parameters.largest_object = Location(5, 30);
        EXPECT_CALL(mock_bidi_stream_,
                    Writev(SerializedControlMessage(expected_ok), _));
        EXPECT_CALL(*track, RemoveObjectListener);
        listener->OnSubscribeAccepted();
      });
  bidi_wrapper_->ReceiveMessage(track_status);
}

TEST_F(MoqtSessionTest, IncomingTrackStatusThenAsynchronousOk) {
  bidi_wrapper_ = std::make_unique<MoqtBidiStreamTestWrapper>(
      ResponseStream(kTrackStatusByte));
  auto* track = CreateTrackPublisher();

  MoqtTrackStatus track_status = DefaultSubscribe();
  MoqtObjectListener* listener = nullptr;
  EXPECT_CALL(*track, AddObjectListener)
      .WillOnce(testing::SaveArg<0>(&listener));
  bidi_wrapper_->ReceiveMessage(track_status);
  ASSERT_NE(listener, nullptr);
  EXPECT_CALL(*track, expiration)
      .WillRepeatedly(Return(quic::QuicTimeDelta::FromMilliseconds(10000)));
  EXPECT_CALL(*track, largest_location).WillRepeatedly(Return(Location(5, 30)));
  MoqtRequestOk expected_ok;
  expected_ok.request_id = track_status.request_id;
  expected_ok.parameters.expires = quic::QuicTimeDelta::FromMilliseconds(10000);
  expected_ok.parameters.largest_object = Location(5, 30);
  EXPECT_CALL(mock_bidi_stream_,
              Writev(SerializedControlMessage(expected_ok), _));
  EXPECT_CALL(*track, RemoveObjectListener(listener));
  listener->OnSubscribeAccepted();
}

TEST_F(MoqtSessionTest, IncomingTrackStatusThenSynchronousError) {
  bidi_wrapper_ = std::make_unique<MoqtBidiStreamTestWrapper>(
      ResponseStream(kTrackStatusByte));
  auto* track = CreateTrackPublisher();

  MoqtTrackStatus track_status = DefaultSubscribe();
  bool executed_AddObjectListener = false;
  EXPECT_CALL(*track, AddObjectListener)
      .WillOnce([&](MoqtObjectListener* listener) {
        EXPECT_CALL(
            mock_bidi_stream_,
            Writev(ControlMessageOfType(MoqtMessageType::kRequestError), _));
        EXPECT_CALL(*track, RemoveObjectListener);
        listener->OnSubscribeRejected(MoqtRequestErrorInfo(
            RequestErrorCode::kInternalError, std::nullopt, "Test error"));
        executed_AddObjectListener = true;
      });
  bidi_wrapper_->ReceiveMessage(track_status);
  EXPECT_TRUE(executed_AddObjectListener);
}

TEST_F(MoqtSessionTest, IncomingTrackStatusThenAsynchronousError) {
  bidi_wrapper_ = std::make_unique<MoqtBidiStreamTestWrapper>(
      ResponseStream(kTrackStatusByte));
  auto* track = CreateTrackPublisher();

  MoqtTrackStatus track_status = DefaultSubscribe();
  MoqtObjectListener* listener;
  EXPECT_CALL(*track, AddObjectListener)
      .WillOnce(testing::SaveArg<0>(&listener));
  bidi_wrapper_->ReceiveMessage(track_status);
  ASSERT_NE(listener, nullptr);
  EXPECT_CALL(mock_bidi_stream_,
              Writev(ControlMessageOfType(MoqtMessageType::kRequestError), _));
  EXPECT_CALL(*track, RemoveObjectListener(listener));
  listener->OnSubscribeRejected(MoqtRequestErrorInfo(
      RequestErrorCode::kInternalError, std::nullopt, "Test error"));
}

TEST_F(MoqtSessionTest, FinReportedToVisitor) {
  PrepareRequestStream(bidi_wrapper_);
  EXPECT_CALL(mock_bidi_stream_,
              Writev(ControlMessageOfType(MoqtMessageType::kSubscribe), _));
  MessageParameters parameters = SubscribeForTest();
  parameters.subscription_filter.emplace(MoqtFilterType::kLargestObject);
  EXPECT_TRUE(session_.Subscribe(FullTrackName("foo", "bar"),
                                 &remote_track_visitor_, parameters));
  MoqtSubscribeOk ok = {/*request_id=*/0, /*track_alias=*/2,
                        MessageParameters(), TrackExtensions()};
  EXPECT_CALL(remote_track_visitor_, OnReply)
      .WillOnce(
          [&](const FullTrackName& ftn,
              std::variant<SubscribeOkData, MoqtRequestErrorInfo> response) {
            EXPECT_EQ(ftn, FullTrackName("foo", "bar"));
            EXPECT_TRUE(std::holds_alternative<SubscribeOkData>(response));
          });
  bidi_wrapper_->ReceiveMessage(ok);
  MoqtObject object = {
      /*track_alias=*/2,
      /*group_id=*/0,
      /*object_id=*/0,
      /*publisher_priority=*/7,
      /*extension_headers=*/"",
      /*object_status=*/MoqtObjectStatus::kEndOfGroup,
      /*subgroup_id=*/0,
      /*first_object_in_subgroup=*/true,
      /*payload_length=*/0,
  };
  EXPECT_CALL(mock_uni_stream_, GetStreamId())
      .WillRepeatedly(Return(kIncomingUniStreamId));
  EXPECT_CALL(mock_session_, GetStreamById(kIncomingUniStreamId))
      .WillRepeatedly(Return(&mock_uni_stream_));
  std::unique_ptr<webtransport::StreamVisitor> data_stream;
  DeliverObject(object, /*fin=*/true, mock_session_, &mock_uni_stream_,
                data_stream, &remote_track_visitor_);
  // The data stream died and destroyed the visitor (IncomingDataStream).
  EXPECT_CALL(remote_track_visitor_,
              OnStreamFin(FullTrackName("foo", "bar"), DataStreamIndex(0, 0)));
  data_stream.reset();
}

TEST_F(MoqtSessionTest, ResetReportedToVisitor) {
  PrepareRequestStream(bidi_wrapper_);
  EXPECT_CALL(mock_bidi_stream_,
              Writev(ControlMessageOfType(MoqtMessageType::kSubscribe), _));
  MessageParameters parameters = SubscribeForTest();
  parameters.subscription_filter.emplace(MoqtFilterType::kLargestObject);
  EXPECT_TRUE(session_.Subscribe(FullTrackName("foo", "bar"),
                                 &remote_track_visitor_, parameters));
  MoqtSubscribeOk ok = {/*request_id=*/0, /*track_alias=*/2,
                        MessageParameters(), TrackExtensions()};
  EXPECT_CALL(remote_track_visitor_, OnReply)
      .WillOnce(
          [&](const FullTrackName& ftn,
              std::variant<SubscribeOkData, MoqtRequestErrorInfo> response) {
            EXPECT_EQ(ftn, FullTrackName("foo", "bar"));
            EXPECT_TRUE(std::holds_alternative<SubscribeOkData>(response));
          });
  bidi_wrapper_->ReceiveMessage(ok);
  MoqtObject object = {
      /*track_alias=*/2,
      /*group_id=*/0,
      /*object_id=*/0,
      /*publisher_priority=*/7,
      /*extension_headers=*/"",
      /*object_status=*/MoqtObjectStatus::kEndOfGroup,
      /*subgroup_id=*/0,
      /*first_object_in_subgroup=*/true,
      /*payload_length=*/0,
  };
  EXPECT_CALL(mock_uni_stream_, GetStreamId())
      .WillRepeatedly(Return(kIncomingUniStreamId));
  EXPECT_CALL(mock_session_, GetStreamById(kIncomingUniStreamId))
      .WillRepeatedly(Return(&mock_uni_stream_));
  std::unique_ptr<webtransport::StreamVisitor> data_stream;
  DeliverObject(object, /*fin=*/false, mock_session_, &mock_uni_stream_,
                data_stream, &remote_track_visitor_);
  // The data stream died and destroyed the visitor (IncomingDataStream).
  data_stream->OnResetStreamReceived(kResetCodeCancelled);
  EXPECT_CALL(remote_track_visitor_, OnStreamReset(FullTrackName("foo", "bar"),
                                                   DataStreamIndex(0, 0)));
  data_stream.reset();
}

TEST_F(MoqtSessionTest, IncomingPublishNamespaceCleanup) {
  bidi_wrapper_ =
      MoqtSessionPeer::CreateControlStream(&session_, &mock_bidi_stream_);
  // Register two incoming PUBLISH_NAMESPACE.
  MoqtPublishNamespace publish_namespace{
      /*request_id=*/1, TrackNamespace{"foo"}, MessageParameters()};
  MoqtRequestOk expected_ok = {/*request_id=*/1, MessageParameters()};
  expected_ok.parameters.expires = quic::QuicTimeDelta::FromSeconds(60);
  EXPECT_CALL(session_callbacks_.incoming_publish_namespace_callback,
              Call(TrackNamespace{"foo"}, _, _))
      .WillOnce([&](const TrackNamespace&,
                    const std::optional<MessageParameters>&,
                    MoqtResponseCallback callback) {
        std::move(callback)(expected_ok.parameters);
      });
  EXPECT_CALL(mock_bidi_stream_,
              Writev(SerializedControlMessage(expected_ok), _));
  bidi_wrapper_->ReceiveMessage(publish_namespace);

  publish_namespace = MoqtPublishNamespace(
      /*request_id=*/3, TrackNamespace{"bar"}, MessageParameters());
  EXPECT_CALL(session_callbacks_.incoming_publish_namespace_callback,
              Call(TrackNamespace{"bar"}, _, _))
      .WillOnce([&](const TrackNamespace&,
                    const std::optional<MessageParameters>&,
                    MoqtResponseCallback callback) {
        std::move(callback)(MessageParameters());
      });
  EXPECT_CALL(mock_bidi_stream_,
              Writev(ControlMessageOfType(MoqtMessageType::kRequestOk), _));
  bidi_wrapper_->ReceiveMessage(publish_namespace);

  // Revoke "bar"
  MoqtPublishNamespaceDone done{/*request_id=*/3};
  EXPECT_CALL(
      session_callbacks_.incoming_publish_namespace_callback,
      Call(TrackNamespace{"bar"}, std::optional<MessageParameters>(), _))
      .WillOnce(
          [](const TrackNamespace&, const std::optional<MessageParameters>&,
             MoqtResponseCallback callback) { EXPECT_EQ(callback, nullptr); });
  bidi_wrapper_->ReceiveMessage(done);

  // Destroying the session should revoke "foo".
  EXPECT_CALL(
      session_callbacks_.incoming_publish_namespace_callback,
      Call(TrackNamespace{"foo"}, std::optional<MessageParameters>(), _))
      .WillOnce(
          [](const TrackNamespace&, const std::optional<MessageParameters>&,
             MoqtResponseCallback callback) { EXPECT_EQ(callback, nullptr); });
  // Test teardown will destroy session_, triggering removal of "foo".
}

TEST_F(MoqtSessionTest, WrongSubprotocol) {
  EXPECT_CALL(mock_session_, GetNegotiatedSubprotocol)
      .WillOnce(
          Return(std::optional<std::string>(kUnrecognizedVersionForTests)));
  EXPECT_CALL(mock_session_, CloseSession);
  EXPECT_CALL(session_callbacks_.session_terminated_callback, Call);
  session_.OnSessionReady();
}

TEST_F(MoqtSessionTest, NoSubprotocol) {
  EXPECT_CALL(mock_session_, GetNegotiatedSubprotocol)
      .WillOnce(Return(std::optional<std::string>()));
  EXPECT_CALL(mock_session_, CloseSession);
  EXPECT_CALL(session_callbacks_.session_terminated_callback, Call);
  session_.OnSessionReady();
}


TEST_F(MoqtSessionTest, ClientSetupNotAllowedOnControlStream) {
  // While technically on the Control stream, when it arrives, it's an
  // UnknownBidiStream
  bidi_wrapper_ =
      MoqtSessionPeer::CreateControlStream(&session_, &mock_bidi_stream_);
  EXPECT_CALL(mock_session_, CloseSession);
  EXPECT_CALL(session_callbacks_.session_terminated_callback, Call);
  bidi_wrapper_->ReceiveMessage(
      MoqtSetup(SetupParameters("/", "example.com", 0)));
}

TEST_F(MoqtSessionTest, NamespaceNotAllowedOnControlStream) {
  bidi_wrapper_ =
      MoqtSessionPeer::CreateControlStream(&session_, &mock_bidi_stream_);
  EXPECT_CALL(mock_session_, CloseSession);
  EXPECT_CALL(session_callbacks_.session_terminated_callback, Call);
  bidi_wrapper_->ReceiveMessage(MoqtNamespace());
}

TEST_F(MoqtSessionTest, NamespaceDoneNotAllowedOnControlStream) {
  bidi_wrapper_ =
      MoqtSessionPeer::CreateControlStream(&session_, &mock_bidi_stream_);
  EXPECT_CALL(mock_session_, CloseSession);
  EXPECT_CALL(session_callbacks_.session_terminated_callback, Call);
  bidi_wrapper_->ReceiveMessage(MoqtNamespaceDone());
}

TEST_F(MoqtSessionTest, IncomingRequestUpdateTriggersRequestOk) {
  MoqtSubscribe subscribe = DefaultSubscribe();
  MockTrackPublisher* track = CreateTrackPublisher();
  bidi_wrapper_ = std::make_unique<MoqtBidiStreamTestWrapper>(
      ResponseStream(kSubscribeByte));
  ReceiveSubscribeSynchronousOk(track, subscribe, bidi_wrapper_.get(), 0);
  EXPECT_CALL(mock_bidi_stream_,
              Writev(ControlMessageOfType(MoqtMessageType::kRequestOk), _));
  bidi_wrapper_->ReceiveMessage(MoqtRequestUpdate{3, 1, MessageParameters()});
}

TEST_F(MoqtSessionTest, IncomingRequestUpdateTriggersRequestError) {
  bidi_wrapper_ =
      MoqtSessionPeer::CreateControlStream(&session_, &mock_bidi_stream_);
  EXPECT_CALL(mock_bidi_stream_,
              Writev(ControlMessageOfType(MoqtMessageType::kRequestError), _));
  bidi_wrapper_->ReceiveMessage(MoqtRequestUpdate{3, 1, MessageParameters()});
}

TEST_F(MoqtSessionTest, StopSendingBlocksSubgroup) {
  MoqtSubscribe subscribe = DefaultSubscribe();
  MockTrackPublisher* track = CreateTrackPublisher();
  bidi_wrapper_ = std::make_unique<MoqtBidiStreamTestWrapper>(
      ResponseStream(kSubscribeByte));
  MoqtObjectListener* listener =
      ReceiveSubscribeSynchronousOk(track, subscribe, bidi_wrapper_.get(), 0);
  EXPECT_CALL(mock_session_, CanOpenNextOutgoingUnidirectionalStream)
      .WillOnce(Return(true));
  EXPECT_CALL(mock_session_, OpenOutgoingUnidirectionalStream)
      .WillOnce(Return(&mock_uni_stream_));
  std::unique_ptr<webtransport::StreamVisitor> data_stream_visitor;
  EXPECT_CALL(mock_uni_stream_, SetVisitor)
      .WillOnce([&](std::unique_ptr<webtransport::StreamVisitor> visitor) {
        data_stream_visitor = std::move(visitor);
      });
  EXPECT_CALL(mock_uni_stream_, GetStreamId())
      .WillRepeatedly(Return(kOutgoingUniStreamId));
  EXPECT_CALL(mock_session_, GetStreamById(kOutgoingUniStreamId))
      .WillRepeatedly(Return(&mock_uni_stream_));
  EXPECT_CALL(mock_uni_stream_, visitor).WillRepeatedly([&]() {
    return data_stream_visitor.get();
  });
  EXPECT_CALL(mock_uni_stream_, CanWrite).WillRepeatedly(Return(true));
  EXPECT_CALL(*track, GetCachedObject(0, Optional(1), 0, 0))
      .WillOnce(Return(PublishedObject{
          PublishedObjectMetadata{Location(0, 0), 1, "",
                                  MoqtObjectStatus::kNormal, 0x80, true, 0,
                                  MoqtSessionPeer::Now(&session_)},
          PayloadFromString(""), false}));
  EXPECT_CALL(*track, GetCachedObject(0, Optional(1), 1, 0))
      .WillOnce(Return(std::nullopt));
  SetLargestId(track, Location(0, 0));
  EXPECT_CALL(mock_uni_stream_, Writev).WillOnce(Return(absl::OkStatus()));
  listener->OnNewObjectAvailable(Location(0, 0), 1, 0x80);

  EXPECT_CALL(mock_uni_stream_, ResetWithUserCode(kResetCodeCancelled));
  data_stream_visitor->OnStopSendingReceived(kResetCodeCancelled);
  // New object in the same subgroup should not be sent.
  EXPECT_CALL(*track, GetCachedObject).Times(0);
  EXPECT_CALL(mock_uni_stream_, Writev).Times(0);
  listener->OnNewObjectAvailable(Location(0, 1), 1, 0x80);
}

TEST_F(MoqtSessionTest, PublishSuccess) {
  CreateTrackPublisher();
  std::shared_ptr<MoqtTrackPublisher> track_publisher =
      publisher_.GetTrack(kDefaultTrackName());

  PrepareRequestStream(bidi_wrapper_);
  // Verify PUBLISH message is sent on the publish stream.
  EXPECT_CALL(mock_bidi_stream_,
              Writev(ControlMessageOfType(MoqtMessageType::kPublish), _))
      .WillOnce(Return(absl::OkStatus()));

  std::optional<std::variant<MessageParameters, MoqtRequestErrorInfo>> response;
  ASSERT_TRUE(session_.Publish(
      track_publisher, MessageParameters(), TrackExtensions(),
      [&](std::variant<MessageParameters, MoqtRequestErrorInfo> resp) {
        response = resp;
      }));

  MoqtRequestOk request_ok;
  request_ok.request_id = 0;
  request_ok.parameters.delivery_timeout = quic::QuicTimeDelta::FromSeconds(2);
  bidi_wrapper_->ReceiveMessage(request_ok);

  ASSERT_TRUE(response.has_value());
  EXPECT_TRUE(std::holds_alternative<MessageParameters>(*response));
  EXPECT_EQ(std::get<MessageParameters>(*response).delivery_timeout,
            quic::QuicTimeDelta::FromSeconds(2));
}

TEST_F(MoqtSessionTest, PublishCannotOpenStream) {
  CreateTrackPublisher();
  std::shared_ptr<MoqtTrackPublisher> track_publisher =
      publisher_.GetTrack(kDefaultTrackName());
  EXPECT_CALL(mock_session_, CanOpenNextOutgoingBidirectionalStream())
      .WillOnce(Return(false));
  EXPECT_FALSE(session_.Publish(
      track_publisher, MessageParameters(), TrackExtensions(),
      [&](std::variant<MessageParameters, MoqtRequestErrorInfo> response) {}));
}

TEST_F(MoqtSessionTest, PublishAfterGoaway) {
  bidi_wrapper_ =
      MoqtSessionPeer::CreateControlStream(&session_, &mock_bidi_stream_);
  MoqtGoAway goaway;
  goaway.new_session_uri = "";
  bidi_wrapper_->ReceiveMessage(goaway);
  CreateTrackPublisher();
  std::shared_ptr<MoqtTrackPublisher> track_publisher =
      publisher_.GetTrack(kDefaultTrackName());
  EXPECT_FALSE(session_.Publish(
      track_publisher, MessageParameters(), TrackExtensions(),
      [&](std::variant<MessageParameters, MoqtRequestErrorInfo>) {}));
}

TEST_F(MoqtSessionTest, IncomingPublishAbortsPendingSubscribe) {
  PrepareRequestStream(bidi_wrapper_);
  EXPECT_CALL(mock_bidi_stream_,
              Writev(ControlMessageOfType(MoqtMessageType::kSubscribe), _));
  MessageParameters parameters(SubscribeForTest());
  session_.Subscribe(kDefaultTrackName(), &remote_track_visitor_, parameters);

  // Configure incoming publish callback to accept. Return nullptr because this
  // should never be called.
  bool incoming_publish_callback_called = false;
  session_.callbacks().incoming_publish_callback =
      [&](const FullTrackName&, const MessageParameters&,
          const TrackExtensions&, MoqtResponseCallback callback) {
        incoming_publish_callback_called = true;
        return nullptr;
      };

  // Prepare PUBLISH message.
  MoqtPublish publish{1, kDefaultTrackName(), 10, MessageParameters(),
                      TrackExtensions()};
  webtransport::test::MockStream publish_stream;
  std::unique_ptr<MoqtBidiStreamTestWrapper> publish_wrapper =
      std::make_unique<MoqtBidiStreamTestWrapper>(
          ResponseStream(kPublishByte, &publish_stream));
  EXPECT_CALL(mock_bidi_stream_, ResetWithUserCode(kResetCodeCancelled));
  MoqtRequestOk expected_request_ok;
  expected_request_ok.request_id = publish.request_id;
  expected_request_ok.parameters = parameters;  // params from the SUBSCRIBE.
  // group_order can be in SUBSCRIBE but not REQUEST_OK.
  expected_request_ok.parameters.group_order = std::nullopt;
  EXPECT_CALL(publish_stream,
              Writev(SerializedControlMessage(expected_request_ok), _));
  // remote_track_visitor_ is reused, not destroyed.
  EXPECT_CALL(remote_track_visitor_, OnReply);
  publish_wrapper->ReceiveMessage(publish);
  EXPECT_FALSE(incoming_publish_callback_called);
  // Verify it was aborted immediately (not at teardown).
  EXPECT_TRUE(
      testing::Mock::VerifyAndClearExpectations(&remote_track_visitor_));
}

TEST_F(MoqtSessionTest, IncrementRequestId) {
  // Set up writable control stream.
  webtransport::test::InMemoryStreamWithWriteBuffer control_stream(0);
  EXPECT_CALL(mock_session_, GetNegotiatedSubprotocol)
      .WillOnce(Return(std::string(kDefaultMoqtVersion)));
  EXPECT_CALL(mock_session_, CanOpenNextOutgoingBidirectionalStream)
      .WillOnce(Return(true));
  EXPECT_CALL(mock_session_, OpenOutgoingBidirectionalStream)
      .WillOnce(Return(&control_stream));
  session_.OnSessionReady();
  control_stream.write_buffer().clear();

  // Helper lambda to parse request ID from written_data.
  auto get_request_id =
      [&](webtransport::test::InMemoryStreamWithWriteBuffer& stream) {
        quiche::QuicheDataReader reader(stream.write_buffer());
        uint64_t type;
        uint16_t length;
        uint64_t request_id;
        bool type_read = reader.ReadMoqVarInt(&type);
        bool length_read = reader.ReadUInt16(&length);
        bool req_id_read = reader.ReadMoqVarInt(&request_id);
        EXPECT_TRUE(type_read) << "Failed to read type, written_data.size()="
                               << stream.write_buffer().length();
        EXPECT_TRUE(length_read);
        EXPECT_TRUE(req_id_read);
        return request_id;
      };

  uint64_t next_request_id = 0;
  // 1. SubscribeNamespace
  webtransport::test::InMemoryStreamWithWriteBuffer sub_ns_stream(4);
  EXPECT_CALL(mock_session_, CanOpenNextOutgoingBidirectionalStream())
      .WillOnce(Return(true));
  EXPECT_CALL(mock_session_, OpenOutgoingBidirectionalStream())
      .WillOnce(Return(&sub_ns_stream));
  TrackNamespace namespace1({"namespace1"});
  std::unique_ptr<MoqtNamespaceTask> task1 = session_.SubscribeNamespace(
      namespace1, MessageParameters(),
      [](std::variant<MessageParameters, MoqtRequestErrorInfo>) {});
  ASSERT_NE(task1, nullptr);
  EXPECT_EQ(get_request_id(sub_ns_stream), next_request_id);
  next_request_id += 2;

  // 2. PublishNamespace
  TrackNamespace namespace2({"namespace2"});
  bool p1 = session_.PublishNamespace(
      namespace2, MessageParameters(),
      [](std::variant<MessageParameters, MoqtRequestErrorInfo>) {},
      [](MoqtRequestErrorInfo) {});
  EXPECT_TRUE(p1);
  EXPECT_EQ(next_request_id, get_request_id(control_stream));
  next_request_id += 2;
  control_stream.write_buffer().clear();

  // 3. PublishNamespaceUpdate
  MessageParameters params_update;
  bool p_update = session_.PublishNamespaceUpdate(
      namespace2, params_update,
      [](std::variant<MessageParameters, MoqtRequestErrorInfo>) {});
  EXPECT_TRUE(p_update);
  EXPECT_EQ(get_request_id(control_stream), next_request_id);
  next_request_id += 2;
  control_stream.write_buffer().clear();

  // 4. Subscribe
  webtransport::test::InMemoryStreamWithWriteBuffer sub_stream(5);
  EXPECT_CALL(mock_session_, CanOpenNextOutgoingBidirectionalStream)
      .WillOnce(Return(true));
  EXPECT_CALL(mock_session_, OpenOutgoingBidirectionalStream)
      .WillOnce(Return(&sub_stream));
  FullTrackName track_name1("namespace2", "track1");
  bool s1 = session_.Subscribe(track_name1, &remote_track_visitor_,
                               MessageParameters());
  EXPECT_TRUE(s1);
  EXPECT_EQ(get_request_id(sub_stream), next_request_id);
  next_request_id += 2;
  sub_stream.write_buffer().clear();

  // 5. SubscribeUpdate
  bool s_update = session_.SubscribeUpdate(
      track_name1, MessageParameters(),
      [](std::variant<MessageParameters, MoqtRequestErrorInfo>) {});
  EXPECT_TRUE(s_update);
  EXPECT_EQ(get_request_id(sub_stream), next_request_id);
  next_request_id += 2;
  sub_stream.write_buffer().clear();

  // 6. Fetch
  FullTrackName fetch_track("namespace2", "fetch_track");
  bool f1 = session_.Fetch(
      fetch_track, [](std::unique_ptr<MoqtFetchTask>) {}, Location(0, 0), 1,
      std::nullopt, MessageParameters());
  EXPECT_TRUE(f1);
  EXPECT_EQ(get_request_id(control_stream), next_request_id);
  next_request_id += 2;
  control_stream.write_buffer().clear();

  // 7. SubscribeNamespace (duplicating the first call)
  webtransport::test::InMemoryStreamWithWriteBuffer sub_ns_stream_2(8);
  EXPECT_CALL(mock_session_, CanOpenNextOutgoingBidirectionalStream)
      .WillOnce(Return(true));
  EXPECT_CALL(mock_session_, OpenOutgoingBidirectionalStream)
      .WillOnce(Return(&sub_ns_stream_2));
  TrackNamespace namespace_dup({"namespace_dup"});
  std::unique_ptr<MoqtNamespaceTask> task_dup = session_.SubscribeNamespace(
      namespace_dup, MessageParameters(),
      [](std::variant<MessageParameters, MoqtRequestErrorInfo>) {});
  ASSERT_NE(task_dup, nullptr);
  EXPECT_EQ(next_request_id, get_request_id(sub_ns_stream_2));
  sub_ns_stream_2.write_buffer().clear();
}

}  // namespace test

}  // namespace moqt
