/*
 *  Copyright 2018 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "pc/jsep_transport_controller.h"

#include <cstdint>
#include <map>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>

#include "api/candidate.h"
#include "api/crypto/crypto_options.h"
#include "api/dtls_transport_interface.h"
#include "api/environment/environment.h"
#include "api/environment/environment_factory.h"
#include "api/field_trials.h"
#include "api/ice_transport_interface.h"
#include "api/jsep.h"
#include "api/make_ref_counted.h"
#include "api/peer_connection_interface.h"
#include "api/rtc_error.h"
#include "api/scoped_refptr.h"
#include "api/test/rtc_error_matchers.h"
#include "api/transport/data_channel_transport_interface.h"
#include "api/transport/enums.h"
#include "api/units/time_delta.h"
#include "call/payload_type.h"
#include "call/payload_type_picker.h"
#include "media/base/codec.h"
#include "media/base/media_constants.h"
#include "p2p/base/ice_transport_internal.h"
#include "p2p/base/p2p_constants.h"
#include "p2p/base/port_allocator.h"
#include "p2p/base/transport_description.h"
#include "p2p/base/transport_info.h"
#include "p2p/dtls/dtls_transport_factory.h"
#include "p2p/dtls/dtls_transport_internal.h"
#include "p2p/dtls/fake_dtls_transport.h"
#include "p2p/test/fake_ice_transport.h"
#include "pc/dtls_transport.h"
#include "pc/rtp_transport_internal.h"
#include "pc/session_description.h"
#include "pc/transport_stats.h"
#include "rtc_base/checks.h"
#include "rtc_base/copy_on_write_buffer.h"
#include "rtc_base/fake_ssl_identity.h"
#include "rtc_base/logging.h"
#include "rtc_base/net_helper.h"
#include "rtc_base/rtc_certificate.h"
#include "rtc_base/socket_address.h"
#include "rtc_base/ssl_certificate.h"
#include "rtc_base/ssl_fingerprint.h"
#include "rtc_base/ssl_identity.h"
#include "rtc_base/ssl_stream_adapter.h"
#include "rtc_base/task_queue_for_test.h"
#include "rtc_base/third_party/sigslot/sigslot.h"
#include "rtc_base/thread.h"
#include "test/create_test_field_trials.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/wait_until.h"

namespace webrtc {
namespace {

constexpr TimeDelta kTimeout = TimeDelta::Millis(100);
const char kIceUfrag1[] = "u0001";
const char kIcePwd1[] = "TESTICEPWD00000000000001";
const char kIceUfrag2[] = "u0002";
const char kIcePwd2[] = "TESTICEPWD00000000000002";
const char kIceUfrag3[] = "u0003";
const char kIcePwd3[] = "TESTICEPWD00000000000003";
const char kIceUfrag4[] = "u0004";
const char kIcePwd4[] = "TESTICEPWD00000000000004";
const char kAudioMid1[] = "audio1";
const char kAudioMid2[] = "audio2";
const char kVideoMid1[] = "video1";
const char kVideoMid2[] = "video2";
const char kDataMid1[] = "data1";

class FakeIceTransportFactory : public IceTransportFactory {
 public:
  ~FakeIceTransportFactory() override = default;
  scoped_refptr<IceTransportInterface> CreateIceTransport(
      const std::string& transport_name,
      int component,
      IceTransportInit init) override {
    return make_ref_counted<FakeIceTransportWrapper>(
        std::make_unique<FakeIceTransport>(transport_name, component));
  }
};

class FakeDtlsTransportFactory : public DtlsTransportFactory {
 public:
  std::unique_ptr<DtlsTransportInternal> CreateDtlsTransport(
      IceTransportInternal* ice,
      const CryptoOptions& crypto_options,
      SSLProtocolVersion max_version) override {
    return std::make_unique<FakeDtlsTransport>(
        static_cast<FakeIceTransport*>(ice));
  }
};

class JsepTransportControllerTest : public JsepTransportController::Observer,
                                    public ::testing::Test,
                                    public sigslot::has_slots<> {
 public:
  JsepTransportControllerTest()
      : env_(CreateEnvironment(&field_trials_)),
        signaling_thread_(Thread::Current()) {
    fake_ice_transport_factory_ = std::make_unique<FakeIceTransportFactory>();
    fake_dtls_transport_factory_ = std::make_unique<FakeDtlsTransportFactory>();
  }

  void CreateJsepTransportController(JsepTransportController::Config config,
                                     Thread* network_thread = Thread::Current(),
                                     PortAllocator* port_allocator = nullptr) {
    config.transport_observer = this;
    config.rtcp_handler = [](const CopyOnWriteBuffer& packet,
                             int64_t packet_time_us) {
      RTC_DCHECK_NOTREACHED();
    };
    config.ice_transport_factory = fake_ice_transport_factory_.get();
    config.dtls_transport_factory = fake_dtls_transport_factory_.get();
    config.on_dtls_handshake_error_ = [](SSLHandshakeError s) {};
    transport_controller_ = std::make_unique<JsepTransportController>(
        env_, network_thread, port_allocator,
        /*async_resolver_factory=*/nullptr,
        /*lna_permission_factory=*/nullptr, payload_type_picker_,
        std::move(config));
    SendTask(network_thread, [&] { ConnectTransportControllerSignals(); });
  }

  void ConnectTransportControllerSignals() {
    transport_controller_->SubscribeIceConnectionState(
        [this](IceConnectionState s) {
          JsepTransportControllerTest::OnConnectionState(s);
        });
    transport_controller_->SubscribeConnectionState(
        [this](PeerConnectionInterface::PeerConnectionState s) {
          JsepTransportControllerTest::OnCombinedConnectionState(s);
        });
    transport_controller_->SubscribeStandardizedIceConnectionState(
        [this](PeerConnectionInterface::IceConnectionState s) {
          JsepTransportControllerTest::OnStandardizedIceConnectionState(s);
        });
    transport_controller_->SubscribeIceGatheringState(
        [this](IceGatheringState s) {
          JsepTransportControllerTest::OnGatheringState(s);
        });
    transport_controller_->SubscribeIceCandidateGathered(
        [this](const std::string& transport,
               const std::vector<Candidate>& candidates) {
          JsepTransportControllerTest::OnCandidatesGathered(transport,
                                                            candidates);
        });
  }

  std::unique_ptr<SessionDescription> CreateSessionDescriptionWithoutBundle() {
    auto description = std::make_unique<SessionDescription>();
    AddAudioSection(description.get(), kAudioMid1, kIceUfrag1, kIcePwd1,
                    ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
    AddVideoSection(description.get(), kVideoMid1, kIceUfrag1, kIcePwd1,
                    ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
    return description;
  }

  std::unique_ptr<SessionDescription>
  CreateSessionDescriptionWithBundleGroup() {
    auto description = CreateSessionDescriptionWithoutBundle();
    ContentGroup bundle_group(GROUP_TYPE_BUNDLE);
    bundle_group.AddContentName(kAudioMid1);
    bundle_group.AddContentName(kVideoMid1);
    description->AddGroup(bundle_group);

    return description;
  }

  std::unique_ptr<SessionDescription>
  CreateSessionDescriptionWithBundledData() {
    auto description = CreateSessionDescriptionWithoutBundle();
    AddDataSection(description.get(), kDataMid1, MediaProtocolType::kSctp,
                   kIceUfrag1, kIcePwd1, ICEMODE_FULL, CONNECTIONROLE_ACTPASS,
                   nullptr);
    ContentGroup bundle_group(GROUP_TYPE_BUNDLE);
    bundle_group.AddContentName(kAudioMid1);
    bundle_group.AddContentName(kVideoMid1);
    bundle_group.AddContentName(kDataMid1);
    description->AddGroup(bundle_group);
    return description;
  }

  void AddAudioSection(SessionDescription* description,
                       const std::string& mid,
                       const std::string& ufrag,
                       const std::string& pwd,
                       IceMode ice_mode,
                       ConnectionRole conn_role,
                       scoped_refptr<RTCCertificate> cert) {
    std::unique_ptr<AudioContentDescription> audio(
        new AudioContentDescription());
    // Set RTCP-mux to be true because the default policy is "mux required".
    audio->set_rtcp_mux(true);
    description->AddContent(mid, MediaProtocolType::kRtp,
                            /*rejected=*/false, std::move(audio));
    AddTransportInfo(description, mid, ufrag, pwd, ice_mode, conn_role, cert);
  }

  void AddVideoSection(SessionDescription* description,
                       const std::string& mid,
                       const std::string& ufrag,
                       const std::string& pwd,
                       IceMode ice_mode,
                       ConnectionRole conn_role,
                       scoped_refptr<RTCCertificate> cert) {
    std::unique_ptr<VideoContentDescription> video(
        new VideoContentDescription());
    // Set RTCP-mux to be true because the default policy is "mux required".
    video->set_rtcp_mux(true);
    description->AddContent(mid, MediaProtocolType::kRtp,
                            /*rejected=*/false, std::move(video));
    AddTransportInfo(description, mid, ufrag, pwd, ice_mode, conn_role, cert);
  }

  void AddDataSection(SessionDescription* description,
                      const std::string& mid,
                      MediaProtocolType protocol_type,
                      const std::string& ufrag,
                      const std::string& pwd,
                      IceMode ice_mode,
                      ConnectionRole conn_role,
                      scoped_refptr<RTCCertificate> cert) {
    RTC_CHECK(protocol_type == MediaProtocolType::kSctp);
    std::unique_ptr<SctpDataContentDescription> data(
        new SctpDataContentDescription());
    data->set_rtcp_mux(true);
    description->AddContent(mid, protocol_type,
                            /*rejected=*/false, std::move(data));
    AddTransportInfo(description, mid, ufrag, pwd, ice_mode, conn_role, cert);
  }

  void AddTransportInfo(SessionDescription* description,
                        const std::string& mid,
                        const std::string& ufrag,
                        const std::string& pwd,
                        IceMode ice_mode,
                        ConnectionRole conn_role,
                        scoped_refptr<RTCCertificate> cert) {
    std::unique_ptr<SSLFingerprint> fingerprint;
    if (cert) {
      fingerprint = SSLFingerprint::CreateFromCertificate(*cert);
    }

    TransportDescription transport_desc(std::vector<std::string>(), ufrag, pwd,
                                        ice_mode, conn_role, fingerprint.get());
    description->AddTransportInfo(TransportInfo(mid, transport_desc));
  }

  IceConfig CreateIceConfig(
      TimeDelta receiving_timeout,
      ContinualGatheringPolicy continual_gathering_policy) {
    IceConfig config;
    config.receiving_timeout = receiving_timeout;
    config.continual_gathering_policy = continual_gathering_policy;
    return config;
  }

  Candidate CreateCandidate(int component = ICE_CANDIDATE_COMPONENT_RTP) {
    Candidate c;
    c.set_address(SocketAddress("192.168.1.1", 8000));
    c.set_component(component);
    c.set_protocol(UDP_PROTOCOL_NAME);
    c.set_priority(1);
    return c;
  }

  void CreateLocalDescriptionAndCompleteConnectionOnNetworkThread() {
    if (!network_thread_->IsCurrent()) {
      SendTask(network_thread_.get(), [&] {
        CreateLocalDescriptionAndCompleteConnectionOnNetworkThread();
      });
      return;
    }

    auto description = CreateSessionDescriptionWithBundleGroup();
    EXPECT_TRUE(
        transport_controller_
            ->SetLocalDescription(SdpType::kOffer, description.get(), nullptr)
            .ok());

    transport_controller_->MaybeStartGathering();
    auto fake_audio_dtls = static_cast<FakeDtlsTransport*>(
        transport_controller_->GetDtlsTransport(kAudioMid1));
    auto fake_video_dtls = static_cast<FakeDtlsTransport*>(
        transport_controller_->GetDtlsTransport(kVideoMid1));
    fake_audio_dtls->fake_ice_transport()->NotifyCandidateGathered(
        fake_audio_dtls->fake_ice_transport(), CreateCandidate());
    fake_video_dtls->fake_ice_transport()->NotifyCandidateGathered(
        fake_video_dtls->fake_ice_transport(), CreateCandidate());
    fake_audio_dtls->fake_ice_transport()->SetCandidatesGatheringComplete();
    fake_video_dtls->fake_ice_transport()->SetCandidatesGatheringComplete();
    fake_audio_dtls->fake_ice_transport()->SetConnectionCount(2);
    fake_video_dtls->fake_ice_transport()->SetConnectionCount(2);
    fake_audio_dtls->SetReceiving(true);
    fake_video_dtls->SetReceiving(true);
    fake_audio_dtls->SetWritable(true);
    fake_video_dtls->SetWritable(true);
    fake_audio_dtls->fake_ice_transport()->SetConnectionCount(1);
    fake_video_dtls->fake_ice_transport()->SetConnectionCount(1);
  }

 protected:
  void OnConnectionState(IceConnectionState state) {
    ice_signaled_on_thread_ = Thread::Current();
    connection_state_ = state;
    ++connection_state_signal_count_;
  }

  void OnStandardizedIceConnectionState(
      PeerConnectionInterface::IceConnectionState state) {
    ice_signaled_on_thread_ = Thread::Current();
    ice_connection_state_ = state;
    ++ice_connection_state_signal_count_;
  }

  void OnCombinedConnectionState(
      PeerConnectionInterface::PeerConnectionState state) {
    RTC_LOG(LS_INFO) << "OnCombinedConnectionState: "
                     << static_cast<int>(state);
    ice_signaled_on_thread_ = Thread::Current();
    combined_connection_state_ = state;
    ++combined_connection_state_signal_count_;
  }

  void OnGatheringState(IceGatheringState state) {
    ice_signaled_on_thread_ = Thread::Current();
    gathering_state_ = state;
    ++gathering_state_signal_count_;
  }

  void OnCandidatesGathered(const std::string& transport_name,
                            const Candidates& candidates) {
    ice_signaled_on_thread_ = Thread::Current();
    candidates_[transport_name].insert(candidates_[transport_name].end(),
                                       candidates.begin(), candidates.end());
    ++candidates_signal_count_;
  }

  // JsepTransportController::Observer overrides.
  bool OnTransportChanged(
      const std::string& mid,
      RtpTransportInternal* rtp_transport,
      scoped_refptr<DtlsTransport> dtls_transport,
      DataChannelTransportInterface* data_channel_transport) override {
    changed_rtp_transport_by_mid_[mid] = rtp_transport;
    if (dtls_transport) {
      changed_dtls_transport_by_mid_[mid] = dtls_transport->internal();
    } else {
      changed_dtls_transport_by_mid_[mid] = nullptr;
    }
    return true;
  }

  FieldTrials field_trials_ = CreateTestFieldTrials();
  Environment env_;
  AutoThread main_thread_;
  // Information received from signals from transport controller.
  IceConnectionState connection_state_ = kIceConnectionConnecting;
  PeerConnectionInterface::IceConnectionState ice_connection_state_ =
      PeerConnectionInterface::kIceConnectionNew;
  PeerConnectionInterface::PeerConnectionState combined_connection_state_ =
      PeerConnectionInterface::PeerConnectionState::kNew;
  bool receiving_ = false;
  IceGatheringState gathering_state_ = kIceGatheringNew;
  // transport_name => candidates
  std::map<std::string, Candidates> candidates_;
  // Counts of each signal emitted.
  int connection_state_signal_count_ = 0;
  int ice_connection_state_signal_count_ = 0;
  int combined_connection_state_signal_count_ = 0;
  int receiving_signal_count_ = 0;
  int gathering_state_signal_count_ = 0;
  int candidates_signal_count_ = 0;

  // `network_thread_` should be destroyed after `transport_controller_`
  std::unique_ptr<Thread> network_thread_;
  std::unique_ptr<FakeIceTransportFactory> fake_ice_transport_factory_;
  std::unique_ptr<FakeDtlsTransportFactory> fake_dtls_transport_factory_;
  Thread* const signaling_thread_ = nullptr;
  Thread* ice_signaled_on_thread_ = nullptr;
  // Used to verify the SignalRtpTransportChanged/SignalDtlsTransportChanged are
  // signaled correctly.
  std::map<std::string, RtpTransportInternal*> changed_rtp_transport_by_mid_;
  std::map<std::string, DtlsTransportInternal*> changed_dtls_transport_by_mid_;
  PayloadTypePicker payload_type_picker_;
  // Transport controller needs to be destroyed first, because it may issue
  // callbacks that modify the changed_*_by_mid in the destructor.
  std::unique_ptr<JsepTransportController> transport_controller_;
};

TEST_F(JsepTransportControllerTest, GetRtpTransport) {
  CreateJsepTransportController(JsepTransportController::Config());
  auto description = CreateSessionDescriptionWithoutBundle();
  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, description.get(), nullptr)
          .ok());
  auto audio_rtp_transport = transport_controller_->GetRtpTransport(kAudioMid1);
  auto video_rtp_transport = transport_controller_->GetRtpTransport(kVideoMid1);
  EXPECT_NE(nullptr, audio_rtp_transport);
  EXPECT_NE(nullptr, video_rtp_transport);
  EXPECT_NE(audio_rtp_transport, video_rtp_transport);
  // Return nullptr for non-existing ones.
  EXPECT_EQ(nullptr, transport_controller_->GetRtpTransport(kAudioMid2));
}

TEST_F(JsepTransportControllerTest, GetDtlsTransport) {
  JsepTransportController::Config config;
  config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyNegotiate;
  CreateJsepTransportController(std::move(config));
  auto description = CreateSessionDescriptionWithoutBundle();
  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, description.get(), nullptr)
          .ok());
  EXPECT_NE(nullptr, transport_controller_->GetDtlsTransport(kAudioMid1));
  EXPECT_NE(nullptr, transport_controller_->GetRtcpDtlsTransport(kAudioMid1));
  EXPECT_NE(nullptr,
            transport_controller_->LookupDtlsTransportByMid(kAudioMid1));
  EXPECT_NE(nullptr, transport_controller_->GetDtlsTransport(kVideoMid1));
  EXPECT_NE(nullptr, transport_controller_->GetRtcpDtlsTransport(kVideoMid1));
  EXPECT_NE(nullptr,
            transport_controller_->LookupDtlsTransportByMid(kVideoMid1));
  // Lookup for all MIDs should return different transports (no bundle)
  EXPECT_NE(transport_controller_->LookupDtlsTransportByMid(kAudioMid1),
            transport_controller_->LookupDtlsTransportByMid(kVideoMid1));
  // Return nullptr for non-existing ones.
  EXPECT_EQ(nullptr, transport_controller_->GetDtlsTransport(kVideoMid2));
  EXPECT_EQ(nullptr, transport_controller_->GetRtcpDtlsTransport(kVideoMid2));
  EXPECT_EQ(nullptr,
            transport_controller_->LookupDtlsTransportByMid(kVideoMid2));
  // Take a pointer to a transport, shut down the transport controller,
  // and verify that the resulting container is empty.
  auto dtls_transport =
      transport_controller_->LookupDtlsTransportByMid(kVideoMid1);
  DtlsTransport* my_transport =
      static_cast<DtlsTransport*>(dtls_transport.get());
  EXPECT_NE(nullptr, my_transport->internal());
  transport_controller_.reset();
  EXPECT_EQ(nullptr, my_transport->internal());
}

TEST_F(JsepTransportControllerTest, GetDtlsTransportWithRtcpMux) {
  JsepTransportController::Config config;
  config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
  CreateJsepTransportController(std::move(config));
  auto description = CreateSessionDescriptionWithoutBundle();
  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, description.get(), nullptr)
          .ok());
  EXPECT_NE(nullptr, transport_controller_->GetDtlsTransport(kAudioMid1));
  EXPECT_EQ(nullptr, transport_controller_->GetRtcpDtlsTransport(kAudioMid1));
  EXPECT_NE(nullptr, transport_controller_->GetDtlsTransport(kVideoMid1));
  EXPECT_EQ(nullptr, transport_controller_->GetRtcpDtlsTransport(kVideoMid1));
}

TEST_F(JsepTransportControllerTest, SetIceConfig) {
  CreateJsepTransportController(JsepTransportController::Config());
  auto description = CreateSessionDescriptionWithoutBundle();
  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, description.get(), nullptr)
          .ok());

  transport_controller_->SetIceConfig(
      CreateIceConfig(kTimeout, GATHER_CONTINUALLY));
  FakeDtlsTransport* fake_audio_dtls = static_cast<FakeDtlsTransport*>(
      transport_controller_->GetDtlsTransport(kAudioMid1));
  ASSERT_NE(nullptr, fake_audio_dtls);
  EXPECT_EQ(kTimeout,
            fake_audio_dtls->fake_ice_transport()->receiving_timeout());
  EXPECT_TRUE(fake_audio_dtls->fake_ice_transport()->gather_continually());

  // Test that value stored in controller is applied to new transports.
  AddAudioSection(description.get(), kAudioMid2, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);

  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, description.get(), nullptr)
          .ok());
  fake_audio_dtls = static_cast<FakeDtlsTransport*>(
      transport_controller_->GetDtlsTransport(kAudioMid2));
  ASSERT_NE(nullptr, fake_audio_dtls);
  EXPECT_EQ(kTimeout,
            fake_audio_dtls->fake_ice_transport()->receiving_timeout());
  EXPECT_TRUE(fake_audio_dtls->fake_ice_transport()->gather_continually());
}

// Tests the getter and setter of the ICE restart flag.
TEST_F(JsepTransportControllerTest, NeedIceRestart) {
  CreateJsepTransportController(JsepTransportController::Config());
  auto description = CreateSessionDescriptionWithoutBundle();
  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, description.get(), nullptr)
          .ok());
  // TODO(tommi): Note that _now_ we set `remote`. (was not set before).
  EXPECT_TRUE(transport_controller_
                  ->SetRemoteDescription(SdpType::kAnswer, description.get(),
                                         description.get())
                  .ok());

  // Initially NeedsIceRestart should return false.
  EXPECT_FALSE(transport_controller_->NeedsIceRestart(kAudioMid1));
  EXPECT_FALSE(transport_controller_->NeedsIceRestart(kVideoMid1));
  // Set the needs-ice-restart flag and verify NeedsIceRestart starts returning
  // true.
  transport_controller_->SetNeedsIceRestartFlag();
  EXPECT_TRUE(transport_controller_->NeedsIceRestart(kAudioMid1));
  EXPECT_TRUE(transport_controller_->NeedsIceRestart(kVideoMid1));
  // For a nonexistent transport, false should be returned.
  EXPECT_FALSE(transport_controller_->NeedsIceRestart(kVideoMid2));

  // Reset the ice_ufrag/ice_pwd for audio.
  auto audio_transport_info = description->GetTransportInfoByName(kAudioMid1);
  audio_transport_info->description.ice_ufrag = kIceUfrag2;
  audio_transport_info->description.ice_pwd = kIcePwd2;
  EXPECT_TRUE(transport_controller_
                  ->SetLocalDescription(SdpType::kOffer, description.get(),
                                        description.get())
                  .ok());
  // Because the ICE is only restarted for audio, NeedsIceRestart is expected to
  // return false for audio and true for video.
  EXPECT_FALSE(transport_controller_->NeedsIceRestart(kAudioMid1));
  EXPECT_TRUE(transport_controller_->NeedsIceRestart(kVideoMid1));
}

TEST_F(JsepTransportControllerTest, MaybeStartGathering) {
  CreateJsepTransportController(JsepTransportController::Config());
  auto description = CreateSessionDescriptionWithBundleGroup();
  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, description.get(), nullptr)
          .ok());
  // After setting the local description, we should be able to start gathering
  // candidates.
  transport_controller_->MaybeStartGathering();
  EXPECT_THAT(WaitUntil([&] { return kIceGatheringGathering; },
                        ::testing::Eq(gathering_state_), {.timeout = kTimeout}),
              IsRtcOk());
  EXPECT_EQ(1, gathering_state_signal_count_);
}

TEST_F(JsepTransportControllerTest, AddRemoveRemoteCandidates) {
  CreateJsepTransportController(JsepTransportController::Config());
  auto description = CreateSessionDescriptionWithoutBundle();
  transport_controller_->SetLocalDescription(SdpType::kOffer, description.get(),
                                             nullptr);
  transport_controller_->SetRemoteDescription(
      SdpType::kAnswer, description.get(), description.get());
  auto fake_audio_dtls = static_cast<FakeDtlsTransport*>(
      transport_controller_->GetDtlsTransport(kAudioMid1));
  ASSERT_NE(nullptr, fake_audio_dtls);
  Candidates candidates;
  candidates.push_back(CreateCandidate());
  EXPECT_TRUE(
      transport_controller_->AddRemoteCandidates(kAudioMid1, candidates).ok());
  EXPECT_EQ(1U,
            fake_audio_dtls->fake_ice_transport()->remote_candidates().size());

  IceCandidate ice_candidate(kAudioMid1, -1, candidates[0]);
  EXPECT_TRUE(transport_controller_->RemoveRemoteCandidate(&ice_candidate));
  EXPECT_EQ(0U,
            fake_audio_dtls->fake_ice_transport()->remote_candidates().size());
}

TEST_F(JsepTransportControllerTest, SetAndGetLocalCertificate) {
  CreateJsepTransportController(JsepTransportController::Config());

  scoped_refptr<RTCCertificate> certificate1 =
      RTCCertificate::Create(SSLIdentity::Create("session1", KT_DEFAULT));
  scoped_refptr<RTCCertificate> returned_certificate;

  auto description = std::make_unique<SessionDescription>();
  AddAudioSection(description.get(), kAudioMid1, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, certificate1);

  // Apply the local certificate.
  EXPECT_TRUE(transport_controller_->SetLocalCertificate(certificate1));
  // Apply the local description.
  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, description.get(), nullptr)
          .ok());
  returned_certificate = transport_controller_->GetLocalCertificate(kAudioMid1);
  EXPECT_TRUE(returned_certificate);
  EXPECT_EQ(certificate1->identity()->certificate().ToPEMString(),
            returned_certificate->identity()->certificate().ToPEMString());

  // Should fail if called for a nonexistant transport.
  EXPECT_EQ(nullptr, transport_controller_->GetLocalCertificate(kVideoMid1));

  // Shouldn't be able to change the identity once set.
  scoped_refptr<RTCCertificate> certificate2 =
      RTCCertificate::Create(SSLIdentity::Create("session2", KT_DEFAULT));
  EXPECT_FALSE(transport_controller_->SetLocalCertificate(certificate2));
}

TEST_F(JsepTransportControllerTest, GetRemoteSSLCertChain) {
  CreateJsepTransportController(JsepTransportController::Config());
  auto description = CreateSessionDescriptionWithBundleGroup();
  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, description.get(), nullptr)
          .ok());
  FakeSSLCertificate fake_certificate("fake_data");

  auto fake_audio_dtls = static_cast<FakeDtlsTransport*>(
      transport_controller_->GetDtlsTransport(kAudioMid1));
  fake_audio_dtls->SetRemoteSSLCertificate(&fake_certificate);
  std::unique_ptr<SSLCertChain> returned_cert_chain =
      transport_controller_->GetRemoteSSLCertChain(kAudioMid1);
  ASSERT_TRUE(returned_cert_chain);
  ASSERT_EQ(1u, returned_cert_chain->GetSize());
  EXPECT_EQ(fake_certificate.ToPEMString(),
            returned_cert_chain->Get(0).ToPEMString());

  // Should fail if called for a nonexistant transport.
  EXPECT_FALSE(transport_controller_->GetRemoteSSLCertChain(kAudioMid2));
}

TEST_F(JsepTransportControllerTest, GetDtlsRole) {
  CreateJsepTransportController(JsepTransportController::Config());
  auto offer_certificate =
      RTCCertificate::Create(SSLIdentity::Create("offer", KT_DEFAULT));
  auto answer_certificate =
      RTCCertificate::Create(SSLIdentity::Create("answer", KT_DEFAULT));
  transport_controller_->SetLocalCertificate(offer_certificate);

  auto offer_desc = std::make_unique<SessionDescription>();
  AddAudioSection(offer_desc.get(), kAudioMid1, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, offer_certificate);
  auto answer_desc = std::make_unique<SessionDescription>();
  AddAudioSection(answer_desc.get(), kAudioMid1, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_PASSIVE, answer_certificate);

  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, offer_desc.get(), nullptr)
          .ok());

  std::optional<SSLRole> role = transport_controller_->GetDtlsRole(kAudioMid1);
  // The DTLS role is not decided yet.
  EXPECT_FALSE(role);
  EXPECT_TRUE(transport_controller_
                  ->SetRemoteDescription(SdpType::kAnswer, offer_desc.get(),
                                         answer_desc.get())
                  .ok());
  role = transport_controller_->GetDtlsRole(kAudioMid1);

  ASSERT_TRUE(role);
  EXPECT_EQ(SSL_CLIENT, *role);
}

TEST_F(JsepTransportControllerTest, GetStats) {
  CreateJsepTransportController(JsepTransportController::Config());
  auto description = CreateSessionDescriptionWithBundleGroup();
  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, description.get(), nullptr)
          .ok());

  TransportStats stats;
  EXPECT_TRUE(transport_controller_->GetStats(kAudioMid1, &stats));
  EXPECT_EQ(kAudioMid1, stats.transport_name);
  EXPECT_EQ(1u, stats.channel_stats.size());
  // Return false for non-existing transport.
  EXPECT_FALSE(transport_controller_->GetStats(kAudioMid2, &stats));
}

TEST_F(JsepTransportControllerTest, SignalConnectionStateFailed) {
  CreateJsepTransportController(JsepTransportController::Config());
  auto description = CreateSessionDescriptionWithoutBundle();
  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, description.get(), nullptr)
          .ok());

  auto fake_ice = static_cast<FakeIceTransport*>(
      transport_controller_->GetDtlsTransport(kAudioMid1)->ice_transport());
  fake_ice->SetCandidatesGatheringComplete();
  fake_ice->SetConnectionCount(1);
  // The connection stats will be failed if there is no active connection.
  fake_ice->SetConnectionCount(0);
  EXPECT_THAT(
      WaitUntil([&] { return kIceConnectionFailed; },
                ::testing::Eq(connection_state_), {.timeout = kTimeout}),
      IsRtcOk());
  EXPECT_EQ(1, connection_state_signal_count_);
  EXPECT_THAT(
      WaitUntil([&] { return PeerConnectionInterface::kIceConnectionFailed; },
                ::testing::Eq(ice_connection_state_), {.timeout = kTimeout}),
      IsRtcOk());
  EXPECT_EQ(1, ice_connection_state_signal_count_);
  EXPECT_THAT(
      WaitUntil(
          [&] { return PeerConnectionInterface::PeerConnectionState::kFailed; },
          ::testing::Eq(combined_connection_state_), {.timeout = kTimeout}),
      IsRtcOk());
  EXPECT_EQ(1, combined_connection_state_signal_count_);
}

TEST_F(JsepTransportControllerTest,
       SignalConnectionStateConnectedNoMediaTransport) {
  CreateJsepTransportController(JsepTransportController::Config());
  auto description = CreateSessionDescriptionWithoutBundle();
  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, description.get(), nullptr)
          .ok());

  auto fake_audio_dtls = static_cast<FakeDtlsTransport*>(
      transport_controller_->GetDtlsTransport(kAudioMid1));
  auto fake_video_dtls = static_cast<FakeDtlsTransport*>(
      transport_controller_->GetDtlsTransport(kVideoMid1));

  // First, have one transport connect, and another fail, to ensure that
  // the first transport connecting didn't trigger a "connected" state signal.
  // We should only get a signal when all are connected.
  fake_audio_dtls->fake_ice_transport()->SetConnectionCount(1);
  fake_audio_dtls->SetWritable(true);
  fake_audio_dtls->fake_ice_transport()->SetCandidatesGatheringComplete();
  // Decrease the number of the connection to trigger the signal.
  fake_video_dtls->fake_ice_transport()->SetConnectionCount(1);
  fake_video_dtls->fake_ice_transport()->SetConnectionCount(0);
  fake_video_dtls->fake_ice_transport()->SetCandidatesGatheringComplete();

  EXPECT_THAT(
      WaitUntil([&] { return kIceConnectionFailed; },
                ::testing::Eq(connection_state_), {.timeout = kTimeout}),
      IsRtcOk());
  EXPECT_EQ(1, connection_state_signal_count_);
  EXPECT_THAT(
      WaitUntil([&] { return PeerConnectionInterface::kIceConnectionFailed; },
                ::testing::Eq(ice_connection_state_), {.timeout = kTimeout}),
      IsRtcOk());
  EXPECT_EQ(2, ice_connection_state_signal_count_);
  EXPECT_THAT(
      WaitUntil(
          [&] { return PeerConnectionInterface::PeerConnectionState::kFailed; },
          ::testing::Eq(combined_connection_state_), {.timeout = kTimeout}),
      IsRtcOk());
  EXPECT_EQ(2, combined_connection_state_signal_count_);

  fake_audio_dtls->SetDtlsState(DtlsTransportState::kConnected);
  fake_video_dtls->SetDtlsState(DtlsTransportState::kConnected);
  // Set the connection count to be 2 and the webrtc::FakeIceTransport will set
  // the transport state to be STATE_CONNECTING.
  fake_video_dtls->fake_ice_transport()->SetConnectionCount(2);
  fake_video_dtls->SetWritable(true);
  EXPECT_THAT(
      WaitUntil([&] { return kIceConnectionConnected; },
                ::testing::Eq(connection_state_), {.timeout = kTimeout}),
      IsRtcOk());
  EXPECT_EQ(2, connection_state_signal_count_);
  EXPECT_THAT(
      WaitUntil(
          [&] { return PeerConnectionInterface::kIceConnectionConnected; },
          ::testing::Eq(ice_connection_state_), {.timeout = kTimeout}),
      IsRtcOk());
  EXPECT_EQ(3, ice_connection_state_signal_count_);
  EXPECT_THAT(
      WaitUntil(
          [&] {
            return PeerConnectionInterface::PeerConnectionState::kConnected;
          },
          ::testing::Eq(combined_connection_state_), {.timeout = kTimeout}),
      IsRtcOk());
  EXPECT_EQ(3, combined_connection_state_signal_count_);
}

TEST_F(JsepTransportControllerTest, SignalConnectionStateComplete) {
  CreateJsepTransportController(JsepTransportController::Config());
  auto description = CreateSessionDescriptionWithoutBundle();
  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, description.get(), nullptr)
          .ok());

  auto fake_audio_dtls = static_cast<FakeDtlsTransport*>(
      transport_controller_->GetDtlsTransport(kAudioMid1));
  auto fake_video_dtls = static_cast<FakeDtlsTransport*>(
      transport_controller_->GetDtlsTransport(kVideoMid1));

  // First, have one transport connect, and another fail, to ensure that
  // the first transport connecting didn't trigger a "connected" state signal.
  // We should only get a signal when all are connected.
  fake_audio_dtls->fake_ice_transport()->SetTransportState(
      IceTransportState::kCompleted,
      IceTransportStateInternal::STATE_COMPLETED);
  fake_audio_dtls->SetWritable(true);
  fake_audio_dtls->fake_ice_transport()->SetCandidatesGatheringComplete();

  EXPECT_THAT(
      WaitUntil([&] { return PeerConnectionInterface::kIceConnectionChecking; },
                ::testing::Eq(ice_connection_state_), {.timeout = kTimeout}),
      IsRtcOk());
  EXPECT_EQ(1, ice_connection_state_signal_count_);
  EXPECT_THAT(
      WaitUntil(
          [&] {
            return PeerConnectionInterface::PeerConnectionState::kConnecting;
          },
          ::testing::Eq(combined_connection_state_), {.timeout = kTimeout}),
      IsRtcOk());
  EXPECT_EQ(1, combined_connection_state_signal_count_);

  fake_video_dtls->fake_ice_transport()->SetTransportState(
      IceTransportState::kFailed, IceTransportStateInternal::STATE_FAILED);
  fake_video_dtls->fake_ice_transport()->SetCandidatesGatheringComplete();

  EXPECT_THAT(
      WaitUntil([&] { return kIceConnectionFailed; },
                ::testing::Eq(connection_state_), {.timeout = kTimeout}),
      IsRtcOk());
  EXPECT_EQ(1, connection_state_signal_count_);
  EXPECT_THAT(
      WaitUntil([&] { return PeerConnectionInterface::kIceConnectionFailed; },
                ::testing::Eq(ice_connection_state_), {.timeout = kTimeout}),
      IsRtcOk());
  EXPECT_EQ(2, ice_connection_state_signal_count_);
  EXPECT_THAT(
      WaitUntil(
          [&] { return PeerConnectionInterface::PeerConnectionState::kFailed; },
          ::testing::Eq(combined_connection_state_), {.timeout = kTimeout}),
      IsRtcOk());
  EXPECT_EQ(2, combined_connection_state_signal_count_);

  fake_audio_dtls->SetDtlsState(DtlsTransportState::kConnected);
  fake_video_dtls->SetDtlsState(DtlsTransportState::kConnected);
  // Set the connection count to be 1 and the webrtc::FakeIceTransport will set
  // the transport state to be STATE_COMPLETED.
  fake_video_dtls->fake_ice_transport()->SetTransportState(
      IceTransportState::kCompleted,
      IceTransportStateInternal::STATE_COMPLETED);
  fake_video_dtls->SetWritable(true);
  EXPECT_THAT(
      WaitUntil([&] { return kIceConnectionCompleted; },
                ::testing::Eq(connection_state_), {.timeout = kTimeout}),
      IsRtcOk());
  EXPECT_EQ(3, connection_state_signal_count_);
  EXPECT_THAT(
      WaitUntil(
          [&] { return PeerConnectionInterface::kIceConnectionCompleted; },
          ::testing::Eq(ice_connection_state_), {.timeout = kTimeout}),
      IsRtcOk());
  EXPECT_EQ(3, ice_connection_state_signal_count_);
  EXPECT_THAT(
      WaitUntil(
          [&] {
            return PeerConnectionInterface::PeerConnectionState::kConnected;
          },
          ::testing::Eq(combined_connection_state_), {.timeout = kTimeout}),
      IsRtcOk());
  EXPECT_EQ(3, combined_connection_state_signal_count_);
}

TEST_F(JsepTransportControllerTest, SignalIceGatheringStateGathering) {
  CreateJsepTransportController(JsepTransportController::Config());
  auto description = CreateSessionDescriptionWithoutBundle();
  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, description.get(), nullptr)
          .ok());

  auto fake_audio_dtls = static_cast<FakeDtlsTransport*>(
      transport_controller_->GetDtlsTransport(kAudioMid1));
  fake_audio_dtls->fake_ice_transport()->MaybeStartGathering();
  // Should be in the gathering state as soon as any transport starts gathering.
  EXPECT_THAT(WaitUntil([&] { return kIceGatheringGathering; },
                        ::testing::Eq(gathering_state_), {.timeout = kTimeout}),
              IsRtcOk());
  EXPECT_EQ(1, gathering_state_signal_count_);
}

TEST_F(JsepTransportControllerTest, SignalIceGatheringStateComplete) {
  CreateJsepTransportController(JsepTransportController::Config());
  auto description = CreateSessionDescriptionWithoutBundle();
  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, description.get(), nullptr)
          .ok());

  auto fake_audio_dtls = static_cast<FakeDtlsTransport*>(
      transport_controller_->GetDtlsTransport(kAudioMid1));
  auto fake_video_dtls = static_cast<FakeDtlsTransport*>(
      transport_controller_->GetDtlsTransport(kVideoMid1));

  fake_audio_dtls->fake_ice_transport()->MaybeStartGathering();
  EXPECT_THAT(WaitUntil([&] { return kIceGatheringGathering; },
                        ::testing::Eq(gathering_state_), {.timeout = kTimeout}),
              IsRtcOk());
  EXPECT_EQ(1, gathering_state_signal_count_);

  // Have one transport finish gathering, to make sure gathering
  // completion wasn't signalled if only one transport finished gathering.
  fake_audio_dtls->fake_ice_transport()->SetCandidatesGatheringComplete();
  EXPECT_EQ(1, gathering_state_signal_count_);

  fake_video_dtls->fake_ice_transport()->MaybeStartGathering();
  EXPECT_THAT(WaitUntil([&] { return kIceGatheringGathering; },
                        ::testing::Eq(gathering_state_), {.timeout = kTimeout}),
              IsRtcOk());
  EXPECT_EQ(1, gathering_state_signal_count_);

  fake_video_dtls->fake_ice_transport()->SetCandidatesGatheringComplete();
  EXPECT_THAT(WaitUntil([&] { return kIceGatheringComplete; },
                        ::testing::Eq(gathering_state_), {.timeout = kTimeout}),
              IsRtcOk());
  EXPECT_EQ(2, gathering_state_signal_count_);
}

// Test that when the last transport that hasn't finished connecting and/or
// gathering is destroyed, the aggregate state jumps to "completed". This can
// happen if, for example, we have an audio and video transport, the audio
// transport completes, then we start bundling video on the audio transport.
TEST_F(JsepTransportControllerTest,
       SignalingWhenLastIncompleteTransportDestroyed) {
  CreateJsepTransportController(JsepTransportController::Config());
  auto description = CreateSessionDescriptionWithBundleGroup();
  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, description.get(), nullptr)
          .ok());

  auto fake_audio_dtls = static_cast<FakeDtlsTransport*>(
      transport_controller_->GetDtlsTransport(kAudioMid1));
  auto fake_video_dtls = static_cast<FakeDtlsTransport*>(
      transport_controller_->GetDtlsTransport(kVideoMid1));
  EXPECT_NE(fake_audio_dtls, fake_video_dtls);

  fake_audio_dtls->fake_ice_transport()->MaybeStartGathering();
  EXPECT_THAT(WaitUntil([&] { return kIceGatheringGathering; },
                        ::testing::Eq(gathering_state_), {.timeout = kTimeout}),
              IsRtcOk());
  EXPECT_EQ(1, gathering_state_signal_count_);

  // Let the audio transport complete.
  fake_audio_dtls->SetWritable(true);
  fake_audio_dtls->fake_ice_transport()->SetCandidatesGatheringComplete();
  fake_audio_dtls->fake_ice_transport()->SetConnectionCount(1);
  fake_audio_dtls->SetDtlsState(DtlsTransportState::kConnected);
  EXPECT_EQ(1, gathering_state_signal_count_);

  // Set the remote description and enable the bundle.
  EXPECT_TRUE(transport_controller_
                  ->SetRemoteDescription(SdpType::kAnswer, description.get(),
                                         description.get())
                  .ok());
  // The BUNDLE should be enabled, the incomplete video transport should be
  // deleted and the states should be updated.
  fake_video_dtls = static_cast<FakeDtlsTransport*>(
      transport_controller_->GetDtlsTransport(kVideoMid1));
  EXPECT_EQ(fake_audio_dtls, fake_video_dtls);
  EXPECT_THAT(
      WaitUntil([&] { return kIceConnectionCompleted; },
                ::testing::Eq(connection_state_), {.timeout = kTimeout}),
      IsRtcOk());
  EXPECT_EQ(PeerConnectionInterface::kIceConnectionCompleted,
            ice_connection_state_);
  EXPECT_EQ(PeerConnectionInterface::PeerConnectionState::kConnected,
            combined_connection_state_);
  EXPECT_THAT(WaitUntil([&] { return kIceGatheringComplete; },
                        ::testing::Eq(gathering_state_), {.timeout = kTimeout}),
              IsRtcOk());
  EXPECT_EQ(2, gathering_state_signal_count_);
}

// Test that states immediately return to "new" if all transports are
// discarded. This should happen at offer time, even though the transport
// controller may keep the transport alive in case of rollback.
TEST_F(JsepTransportControllerTest,
       IceStatesReturnToNewWhenTransportsDiscarded) {
  CreateJsepTransportController(JsepTransportController::Config());
  auto description = std::make_unique<SessionDescription>();
  AddAudioSection(description.get(), kAudioMid1, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, description.get(), nullptr)
          .ok());
  EXPECT_TRUE(transport_controller_
                  ->SetRemoteDescription(SdpType::kAnswer, description.get(),
                                         description.get())
                  .ok());

  // Trigger and verify initial non-new states.
  auto fake_audio_dtls = static_cast<FakeDtlsTransport*>(
      transport_controller_->GetDtlsTransport(kAudioMid1));
  fake_audio_dtls->fake_ice_transport()->MaybeStartGathering();
  fake_audio_dtls->fake_ice_transport()->SetTransportState(
      IceTransportState::kChecking,
      IceTransportStateInternal::STATE_CONNECTING);
  EXPECT_THAT(
      WaitUntil([&] { return PeerConnectionInterface::kIceConnectionChecking; },
                ::testing::Eq(ice_connection_state_), {.timeout = kTimeout}),
      IsRtcOk());
  EXPECT_EQ(1, ice_connection_state_signal_count_);
  EXPECT_THAT(
      WaitUntil(
          [&] {
            return PeerConnectionInterface::PeerConnectionState::kConnecting;
          },
          ::testing::Eq(combined_connection_state_), {.timeout = kTimeout}),
      IsRtcOk());
  EXPECT_EQ(1, combined_connection_state_signal_count_);
  EXPECT_THAT(WaitUntil([&] { return kIceGatheringGathering; },
                        ::testing::Eq(gathering_state_), {.timeout = kTimeout}),
              IsRtcOk());
  EXPECT_EQ(1, gathering_state_signal_count_);

  // Reject m= section which should disconnect the transport and return states
  // to "new".
  description->contents()[0].rejected = true;
  EXPECT_TRUE(transport_controller_
                  ->SetRemoteDescription(SdpType::kOffer, description.get(),
                                         description.get())
                  .ok());
  EXPECT_THAT(
      WaitUntil([&] { return PeerConnectionInterface::kIceConnectionNew; },
                ::testing::Eq(ice_connection_state_), {.timeout = kTimeout}),
      IsRtcOk());
  EXPECT_EQ(2, ice_connection_state_signal_count_);
  EXPECT_THAT(
      WaitUntil(
          [&] { return PeerConnectionInterface::PeerConnectionState::kNew; },
          ::testing::Eq(combined_connection_state_), {.timeout = kTimeout}),
      IsRtcOk());
  EXPECT_EQ(2, combined_connection_state_signal_count_);
  EXPECT_THAT(WaitUntil([&] { return kIceGatheringNew; },
                        ::testing::Eq(gathering_state_), {.timeout = kTimeout}),
              IsRtcOk());
  EXPECT_EQ(2, gathering_state_signal_count_);

  // For good measure, rollback the offer and verify that states return to
  // their previous values.
  EXPECT_TRUE(transport_controller_->RollbackTransports().ok());
  EXPECT_THAT(
      WaitUntil([&] { return PeerConnectionInterface::kIceConnectionChecking; },
                ::testing::Eq(ice_connection_state_), {.timeout = kTimeout}),
      IsRtcOk());
  EXPECT_EQ(3, ice_connection_state_signal_count_);
  EXPECT_THAT(
      WaitUntil(
          [&] {
            return PeerConnectionInterface::PeerConnectionState::kConnecting;
          },
          ::testing::Eq(combined_connection_state_), {.timeout = kTimeout}),
      IsRtcOk());
  EXPECT_EQ(3, combined_connection_state_signal_count_);
  EXPECT_THAT(WaitUntil([&] { return kIceGatheringGathering; },
                        ::testing::Eq(gathering_state_), {.timeout = kTimeout}),
              IsRtcOk());
  EXPECT_EQ(3, gathering_state_signal_count_);
}

TEST_F(JsepTransportControllerTest, SignalCandidatesGathered) {
  CreateJsepTransportController(JsepTransportController::Config());
  auto description = CreateSessionDescriptionWithBundleGroup();
  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, description.get(), nullptr)
          .ok());
  transport_controller_->MaybeStartGathering();

  auto fake_audio_dtls = static_cast<FakeDtlsTransport*>(
      transport_controller_->GetDtlsTransport(kAudioMid1));
  fake_audio_dtls->fake_ice_transport()->NotifyCandidateGathered(
      fake_audio_dtls->fake_ice_transport(), CreateCandidate());
  EXPECT_THAT(
      WaitUntil([&] { return 1; }, ::testing::Eq(candidates_signal_count_),
                {.timeout = kTimeout}),
      IsRtcOk());
  EXPECT_EQ(1u, candidates_[kAudioMid1].size());
}

TEST_F(JsepTransportControllerTest, IceSignalingOccursOnNetworkThread) {
  network_thread_ = Thread::CreateWithSocketServer();
  network_thread_->Start();
  EXPECT_EQ(ice_signaled_on_thread_, nullptr);
  CreateJsepTransportController(JsepTransportController::Config(),
                                network_thread_.get(),
                                /*port_allocator=*/nullptr);
  CreateLocalDescriptionAndCompleteConnectionOnNetworkThread();

  // connecting --> connected --> completed
  EXPECT_THAT(
      WaitUntil([&] { return kIceConnectionCompleted; },
                ::testing::Eq(connection_state_), {.timeout = kTimeout}),
      IsRtcOk());
  EXPECT_EQ(2, connection_state_signal_count_);

  // new --> gathering --> complete
  EXPECT_THAT(WaitUntil([&] { return kIceGatheringComplete; },
                        ::testing::Eq(gathering_state_), {.timeout = kTimeout}),
              IsRtcOk());
  EXPECT_EQ(2, gathering_state_signal_count_);

  EXPECT_THAT(WaitUntil([&] { return candidates_[kAudioMid1].size(); },
                        ::testing::Eq(1u), {.timeout = kTimeout}),
              IsRtcOk());
  EXPECT_THAT(WaitUntil([&] { return candidates_[kVideoMid1].size(); },
                        ::testing::Eq(1u), {.timeout = kTimeout}),
              IsRtcOk());
  EXPECT_EQ(2, candidates_signal_count_);

  EXPECT_EQ(ice_signaled_on_thread_, network_thread_.get());

  SendTask(network_thread_.get(), [&] { transport_controller_.reset(); });
}

// Test that if the TransportController was created with the
// `redetermine_role_on_ice_restart` parameter set to false, the role is *not*
// redetermined on an ICE restart.
TEST_F(JsepTransportControllerTest, IceRoleNotRedetermined) {
  JsepTransportController::Config config;
  config.redetermine_role_on_ice_restart = false;

  CreateJsepTransportController(std::move(config));
  // Let the `transport_controller_` be the controlled side initially.
  auto remote_offer = std::make_unique<SessionDescription>();
  AddAudioSection(remote_offer.get(), kAudioMid1, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  auto local_answer = std::make_unique<SessionDescription>();
  AddAudioSection(local_answer.get(), kAudioMid1, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_PASSIVE, nullptr);

  EXPECT_TRUE(
      transport_controller_
          ->SetRemoteDescription(SdpType::kOffer, nullptr, remote_offer.get())
          .ok());
  EXPECT_TRUE(transport_controller_
                  ->SetLocalDescription(SdpType::kAnswer, local_answer.get(),
                                        remote_offer.get())
                  .ok());

  auto fake_dtls = static_cast<FakeDtlsTransport*>(
      transport_controller_->GetDtlsTransport(kAudioMid1));
  EXPECT_EQ(ICEROLE_CONTROLLED, fake_dtls->fake_ice_transport()->GetIceRole());

  // New offer will trigger the ICE restart.
  auto restart_local_offer = std::make_unique<SessionDescription>();
  AddAudioSection(restart_local_offer.get(), kAudioMid1, kIceUfrag3, kIcePwd3,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  EXPECT_TRUE(transport_controller_
                  ->SetLocalDescription(SdpType::kOffer,
                                        restart_local_offer.get(),
                                        remote_offer.get())
                  .ok());
  EXPECT_EQ(ICEROLE_CONTROLLED, fake_dtls->fake_ice_transport()->GetIceRole());
}

// Tests ICE-Lite mode in remote answer.
TEST_F(JsepTransportControllerTest, SetIceRoleWhenIceLiteInRemoteAnswer) {
  CreateJsepTransportController(JsepTransportController::Config());
  auto local_offer = std::make_unique<SessionDescription>();
  AddAudioSection(local_offer.get(), kAudioMid1, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, local_offer.get(), nullptr)
          .ok());
  auto fake_dtls = static_cast<FakeDtlsTransport*>(
      transport_controller_->GetDtlsTransport(kAudioMid1));
  EXPECT_EQ(ICEROLE_CONTROLLING, fake_dtls->fake_ice_transport()->GetIceRole());
  EXPECT_EQ(ICEMODE_FULL, fake_dtls->fake_ice_transport()->remote_ice_mode());

  auto remote_answer = std::make_unique<SessionDescription>();
  AddAudioSection(remote_answer.get(), kAudioMid1, kIceUfrag2, kIcePwd2,
                  ICEMODE_LITE, CONNECTIONROLE_PASSIVE, nullptr);
  EXPECT_TRUE(transport_controller_
                  ->SetRemoteDescription(SdpType::kAnswer, local_offer.get(),
                                         remote_answer.get())
                  .ok());
  EXPECT_EQ(ICEROLE_CONTROLLING, fake_dtls->fake_ice_transport()->GetIceRole());
  EXPECT_EQ(ICEMODE_LITE, fake_dtls->fake_ice_transport()->remote_ice_mode());
}

// Tests that the ICE role remains "controlling" if a subsequent offer that
// does an ICE restart is received from an ICE lite endpoint. Regression test
// for: https://crbug.com/710760
TEST_F(JsepTransportControllerTest,
       IceRoleIsControllingAfterIceRestartFromIceLiteEndpoint) {
  CreateJsepTransportController(JsepTransportController::Config());
  auto remote_offer = std::make_unique<SessionDescription>();
  AddAudioSection(remote_offer.get(), kAudioMid1, kIceUfrag1, kIcePwd1,
                  ICEMODE_LITE, CONNECTIONROLE_ACTPASS, nullptr);
  auto local_answer = std::make_unique<SessionDescription>();
  AddAudioSection(local_answer.get(), kAudioMid1, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_PASSIVE, nullptr);
  // Initial Offer/Answer exchange. If the remote offerer is ICE-Lite, then the
  // local side is the controlling.
  EXPECT_TRUE(
      transport_controller_
          ->SetRemoteDescription(SdpType::kOffer, nullptr, remote_offer.get())
          .ok());
  EXPECT_TRUE(transport_controller_
                  ->SetLocalDescription(SdpType::kAnswer, local_answer.get(),
                                        remote_offer.get())
                  .ok());
  auto fake_dtls = static_cast<FakeDtlsTransport*>(
      transport_controller_->GetDtlsTransport(kAudioMid1));
  EXPECT_EQ(ICEROLE_CONTROLLING, fake_dtls->fake_ice_transport()->GetIceRole());

  // In the subsequence remote offer triggers an ICE restart.
  auto remote_offer2 = std::make_unique<SessionDescription>();
  AddAudioSection(remote_offer2.get(), kAudioMid1, kIceUfrag2, kIcePwd2,
                  ICEMODE_LITE, CONNECTIONROLE_ACTPASS, nullptr);
  EXPECT_TRUE(transport_controller_
                  ->SetRemoteDescription(SdpType::kOffer, local_answer.get(),
                                         remote_offer2.get())
                  .ok());
  auto local_answer2 = std::make_unique<SessionDescription>();
  AddAudioSection(local_answer2.get(), kAudioMid1, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_PASSIVE, nullptr);
  EXPECT_TRUE(transport_controller_
                  ->SetLocalDescription(SdpType::kAnswer, local_answer2.get(),
                                        remote_offer2.get())
                  .ok());
  fake_dtls = static_cast<FakeDtlsTransport*>(
      transport_controller_->GetDtlsTransport(kAudioMid1));
  // The local side is still the controlling role since the remote side is using
  // ICE-Lite.
  EXPECT_EQ(ICEROLE_CONTROLLING, fake_dtls->fake_ice_transport()->GetIceRole());
}

// Tests that the SDP has more than one audio/video m= sections.
TEST_F(JsepTransportControllerTest, MultipleMediaSectionsOfSameTypeWithBundle) {
  CreateJsepTransportController(JsepTransportController::Config());
  ContentGroup bundle_group(GROUP_TYPE_BUNDLE);
  bundle_group.AddContentName(kAudioMid1);
  bundle_group.AddContentName(kAudioMid2);
  bundle_group.AddContentName(kVideoMid1);
  bundle_group.AddContentName(kDataMid1);

  auto local_offer = std::make_unique<SessionDescription>();
  AddAudioSection(local_offer.get(), kAudioMid1, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddAudioSection(local_offer.get(), kAudioMid2, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(local_offer.get(), kVideoMid1, kIceUfrag3, kIcePwd3,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddDataSection(local_offer.get(), kDataMid1, MediaProtocolType::kSctp,
                 kIceUfrag1, kIcePwd1, ICEMODE_FULL, CONNECTIONROLE_ACTPASS,
                 nullptr);

  auto remote_answer = std::make_unique<SessionDescription>();
  AddAudioSection(remote_answer.get(), kAudioMid1, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_PASSIVE, nullptr);
  AddAudioSection(remote_answer.get(), kAudioMid2, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_PASSIVE, nullptr);
  AddVideoSection(remote_answer.get(), kVideoMid1, kIceUfrag3, kIcePwd3,
                  ICEMODE_FULL, CONNECTIONROLE_PASSIVE, nullptr);
  AddDataSection(remote_answer.get(), kDataMid1, MediaProtocolType::kSctp,
                 kIceUfrag1, kIcePwd1, ICEMODE_FULL, CONNECTIONROLE_PASSIVE,
                 nullptr);

  local_offer->AddGroup(bundle_group);
  remote_answer->AddGroup(bundle_group);

  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, local_offer.get(), nullptr)
          .ok());
  EXPECT_TRUE(transport_controller_
                  ->SetRemoteDescription(SdpType::kAnswer, local_offer.get(),
                                         remote_answer.get())
                  .ok());
  // Verify that all the sections are bundled on kAudio1.
  auto transport1 = transport_controller_->GetRtpTransport(kAudioMid1);
  auto transport2 = transport_controller_->GetRtpTransport(kAudioMid2);
  auto transport3 = transport_controller_->GetRtpTransport(kVideoMid1);
  auto transport4 = transport_controller_->GetRtpTransport(kDataMid1);
  EXPECT_EQ(transport1, transport2);
  EXPECT_EQ(transport1, transport3);
  EXPECT_EQ(transport1, transport4);

  EXPECT_EQ(transport_controller_->LookupDtlsTransportByMid(kAudioMid1),
            transport_controller_->LookupDtlsTransportByMid(kVideoMid1));

  // Verify the OnRtpTransport/DtlsTransportChanged signals are fired correctly.
  auto it = changed_rtp_transport_by_mid_.find(kAudioMid2);
  ASSERT_TRUE(it != changed_rtp_transport_by_mid_.end());
  EXPECT_EQ(transport1, it->second);
  it = changed_rtp_transport_by_mid_.find(kAudioMid2);
  ASSERT_TRUE(it != changed_rtp_transport_by_mid_.end());
  EXPECT_EQ(transport1, it->second);
  it = changed_rtp_transport_by_mid_.find(kVideoMid1);
  ASSERT_TRUE(it != changed_rtp_transport_by_mid_.end());
  EXPECT_EQ(transport1, it->second);
  // Verify the DtlsTransport for the SCTP data channel is reset correctly.
  auto it2 = changed_dtls_transport_by_mid_.find(kDataMid1);
  ASSERT_TRUE(it2 != changed_dtls_transport_by_mid_.end());
}

TEST_F(JsepTransportControllerTest, MultipleBundleGroups) {
  static const char kMid1Audio[] = "1_audio";
  static const char kMid2Video[] = "2_video";
  static const char kMid3Audio[] = "3_audio";
  static const char kMid4Video[] = "4_video";

  CreateJsepTransportController(JsepTransportController::Config());
  ContentGroup bundle_group1(GROUP_TYPE_BUNDLE);
  bundle_group1.AddContentName(kMid1Audio);
  bundle_group1.AddContentName(kMid2Video);
  ContentGroup bundle_group2(GROUP_TYPE_BUNDLE);
  bundle_group2.AddContentName(kMid3Audio);
  bundle_group2.AddContentName(kMid4Video);

  auto local_offer = std::make_unique<SessionDescription>();
  AddAudioSection(local_offer.get(), kMid1Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(local_offer.get(), kMid2Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddAudioSection(local_offer.get(), kMid3Audio, kIceUfrag3, kIcePwd3,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(local_offer.get(), kMid4Video, kIceUfrag4, kIcePwd4,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  local_offer->AddGroup(bundle_group1);
  local_offer->AddGroup(bundle_group2);

  auto remote_answer = std::make_unique<SessionDescription>();
  AddAudioSection(remote_answer.get(), kMid1Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(remote_answer.get(), kMid2Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddAudioSection(remote_answer.get(), kMid3Audio, kIceUfrag3, kIcePwd3,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(remote_answer.get(), kMid4Video, kIceUfrag4, kIcePwd4,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  remote_answer->AddGroup(bundle_group1);
  remote_answer->AddGroup(bundle_group2);

  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, local_offer.get(), nullptr)
          .ok());
  EXPECT_TRUE(transport_controller_
                  ->SetRemoteDescription(SdpType::kAnswer, local_offer.get(),
                                         remote_answer.get())
                  .ok());

  // Verify that (kMid1Audio,kMid2Video) and (kMid3Audio,kMid4Video) form two
  // distinct bundled groups.
  auto mid1_transport = transport_controller_->GetRtpTransport(kMid1Audio);
  auto mid2_transport = transport_controller_->GetRtpTransport(kMid2Video);
  auto mid3_transport = transport_controller_->GetRtpTransport(kMid3Audio);
  auto mid4_transport = transport_controller_->GetRtpTransport(kMid4Video);
  EXPECT_EQ(mid1_transport, mid2_transport);
  EXPECT_EQ(mid3_transport, mid4_transport);
  EXPECT_NE(mid1_transport, mid3_transport);

  auto it = changed_rtp_transport_by_mid_.find(kMid1Audio);
  ASSERT_TRUE(it != changed_rtp_transport_by_mid_.end());
  EXPECT_EQ(it->second, mid1_transport);

  it = changed_rtp_transport_by_mid_.find(kMid2Video);
  ASSERT_TRUE(it != changed_rtp_transport_by_mid_.end());
  EXPECT_EQ(it->second, mid2_transport);

  it = changed_rtp_transport_by_mid_.find(kMid3Audio);
  ASSERT_TRUE(it != changed_rtp_transport_by_mid_.end());
  EXPECT_EQ(it->second, mid3_transport);

  it = changed_rtp_transport_by_mid_.find(kMid4Video);
  ASSERT_TRUE(it != changed_rtp_transport_by_mid_.end());
  EXPECT_EQ(it->second, mid4_transport);
}

TEST_F(JsepTransportControllerTest,
       MultipleBundleGroupsInOfferButOnlyASingleGroupInAnswer) {
  static const char kMid1Audio[] = "1_audio";
  static const char kMid2Video[] = "2_video";
  static const char kMid3Audio[] = "3_audio";
  static const char kMid4Video[] = "4_video";

  CreateJsepTransportController(JsepTransportController::Config());
  ContentGroup bundle_group1(GROUP_TYPE_BUNDLE);
  bundle_group1.AddContentName(kMid1Audio);
  bundle_group1.AddContentName(kMid2Video);
  ContentGroup bundle_group2(GROUP_TYPE_BUNDLE);
  bundle_group2.AddContentName(kMid3Audio);
  bundle_group2.AddContentName(kMid4Video);

  auto local_offer = std::make_unique<SessionDescription>();
  AddAudioSection(local_offer.get(), kMid1Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(local_offer.get(), kMid2Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddAudioSection(local_offer.get(), kMid3Audio, kIceUfrag3, kIcePwd3,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(local_offer.get(), kMid4Video, kIceUfrag4, kIcePwd4,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  // The offer has both groups.
  local_offer->AddGroup(bundle_group1);
  local_offer->AddGroup(bundle_group2);

  auto remote_answer = std::make_unique<SessionDescription>();
  AddAudioSection(remote_answer.get(), kMid1Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(remote_answer.get(), kMid2Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddAudioSection(remote_answer.get(), kMid3Audio, kIceUfrag3, kIcePwd3,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(remote_answer.get(), kMid4Video, kIceUfrag4, kIcePwd4,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  // The answer only has a single group! This is what happens when talking to an
  // endpoint that does not have support for multiple BUNDLE groups.
  remote_answer->AddGroup(bundle_group1);

  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, local_offer.get(), nullptr)
          .ok());
  EXPECT_TRUE(transport_controller_
                  ->SetRemoteDescription(SdpType::kAnswer, local_offer.get(),
                                         remote_answer.get())
                  .ok());

  // Verify that (kMid1Audio,kMid2Video) form a bundle group, but that
  // kMid3Audio and kMid4Video are unbundled.
  auto mid1_transport = transport_controller_->GetRtpTransport(kMid1Audio);
  auto mid2_transport = transport_controller_->GetRtpTransport(kMid2Video);
  auto mid3_transport = transport_controller_->GetRtpTransport(kMid3Audio);
  auto mid4_transport = transport_controller_->GetRtpTransport(kMid4Video);
  EXPECT_EQ(mid1_transport, mid2_transport);
  EXPECT_NE(mid3_transport, mid4_transport);
  EXPECT_NE(mid1_transport, mid3_transport);
  EXPECT_NE(mid1_transport, mid4_transport);
}

TEST_F(JsepTransportControllerTest, MultipleBundleGroupsIllegallyChangeGroup) {
  static const char kMid1Audio[] = "1_audio";
  static const char kMid2Video[] = "2_video";
  static const char kMid3Audio[] = "3_audio";
  static const char kMid4Video[] = "4_video";

  CreateJsepTransportController(JsepTransportController::Config());
  // Offer groups (kMid1Audio,kMid2Video) and (kMid3Audio,kMid4Video).
  ContentGroup offer_bundle_group1(GROUP_TYPE_BUNDLE);
  offer_bundle_group1.AddContentName(kMid1Audio);
  offer_bundle_group1.AddContentName(kMid2Video);
  ContentGroup offer_bundle_group2(GROUP_TYPE_BUNDLE);
  offer_bundle_group2.AddContentName(kMid3Audio);
  offer_bundle_group2.AddContentName(kMid4Video);
  // Answer groups (kMid1Audio,kMid4Video) and (kMid3Audio,kMid2Video), i.e. the
  // second group members have switched places. This should get rejected.
  ContentGroup answer_bundle_group1(GROUP_TYPE_BUNDLE);
  answer_bundle_group1.AddContentName(kMid1Audio);
  answer_bundle_group1.AddContentName(kMid4Video);
  ContentGroup answer_bundle_group2(GROUP_TYPE_BUNDLE);
  answer_bundle_group2.AddContentName(kMid3Audio);
  answer_bundle_group2.AddContentName(kMid2Video);

  auto local_offer = std::make_unique<SessionDescription>();
  AddAudioSection(local_offer.get(), kMid1Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(local_offer.get(), kMid2Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddAudioSection(local_offer.get(), kMid3Audio, kIceUfrag3, kIcePwd3,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(local_offer.get(), kMid4Video, kIceUfrag4, kIcePwd4,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  local_offer->AddGroup(offer_bundle_group1);
  local_offer->AddGroup(offer_bundle_group2);

  auto remote_answer = std::make_unique<SessionDescription>();
  AddAudioSection(remote_answer.get(), kMid1Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(remote_answer.get(), kMid2Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddAudioSection(remote_answer.get(), kMid3Audio, kIceUfrag3, kIcePwd3,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(remote_answer.get(), kMid4Video, kIceUfrag4, kIcePwd4,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  remote_answer->AddGroup(answer_bundle_group1);
  remote_answer->AddGroup(answer_bundle_group2);

  // Accept offer.
  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, local_offer.get(), nullptr)
          .ok());
  // Reject answer!
  EXPECT_FALSE(transport_controller_
                   ->SetRemoteDescription(SdpType::kAnswer, local_offer.get(),
                                          remote_answer.get())
                   .ok());
}

TEST_F(JsepTransportControllerTest, MultipleBundleGroupsInvalidSubsets) {
  static const char kMid1Audio[] = "1_audio";
  static const char kMid2Video[] = "2_video";
  static const char kMid3Audio[] = "3_audio";
  static const char kMid4Video[] = "4_video";

  CreateJsepTransportController(JsepTransportController::Config());
  // Offer groups (kMid1Audio,kMid2Video) and (kMid3Audio,kMid4Video).
  ContentGroup offer_bundle_group1(GROUP_TYPE_BUNDLE);
  offer_bundle_group1.AddContentName(kMid1Audio);
  offer_bundle_group1.AddContentName(kMid2Video);
  ContentGroup offer_bundle_group2(GROUP_TYPE_BUNDLE);
  offer_bundle_group2.AddContentName(kMid3Audio);
  offer_bundle_group2.AddContentName(kMid4Video);
  // Answer groups (kMid1Audio) and (kMid2Video), i.e. the second group was
  // moved from the first group. This should get rejected.
  ContentGroup answer_bundle_group1(GROUP_TYPE_BUNDLE);
  answer_bundle_group1.AddContentName(kMid1Audio);
  ContentGroup answer_bundle_group2(GROUP_TYPE_BUNDLE);
  answer_bundle_group2.AddContentName(kMid2Video);

  auto local_offer = std::make_unique<SessionDescription>();
  AddAudioSection(local_offer.get(), kMid1Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(local_offer.get(), kMid2Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddAudioSection(local_offer.get(), kMid3Audio, kIceUfrag3, kIcePwd3,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(local_offer.get(), kMid4Video, kIceUfrag4, kIcePwd4,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  local_offer->AddGroup(offer_bundle_group1);
  local_offer->AddGroup(offer_bundle_group2);

  auto remote_answer = std::make_unique<SessionDescription>();
  AddAudioSection(remote_answer.get(), kMid1Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(remote_answer.get(), kMid2Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddAudioSection(remote_answer.get(), kMid3Audio, kIceUfrag3, kIcePwd3,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(remote_answer.get(), kMid4Video, kIceUfrag4, kIcePwd4,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  remote_answer->AddGroup(answer_bundle_group1);
  remote_answer->AddGroup(answer_bundle_group2);

  // Accept offer.
  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, local_offer.get(), nullptr)
          .ok());
  // Reject answer!
  EXPECT_FALSE(transport_controller_
                   ->SetRemoteDescription(SdpType::kAnswer, local_offer.get(),
                                          remote_answer.get())
                   .ok());
}

TEST_F(JsepTransportControllerTest, MultipleBundleGroupsInvalidOverlap) {
  static const char kMid1Audio[] = "1_audio";
  static const char kMid2Video[] = "2_video";
  static const char kMid3Audio[] = "3_audio";

  CreateJsepTransportController(JsepTransportController::Config());
  // Offer groups (kMid1Audio,kMid3Audio) and (kMid2Video,kMid3Audio), i.e.
  // kMid3Audio is in both groups - this is illegal.
  ContentGroup offer_bundle_group1(GROUP_TYPE_BUNDLE);
  offer_bundle_group1.AddContentName(kMid1Audio);
  offer_bundle_group1.AddContentName(kMid3Audio);
  ContentGroup offer_bundle_group2(GROUP_TYPE_BUNDLE);
  offer_bundle_group2.AddContentName(kMid2Video);
  offer_bundle_group2.AddContentName(kMid3Audio);

  auto offer = std::make_unique<SessionDescription>();
  AddAudioSection(offer.get(), kMid1Audio, kIceUfrag1, kIcePwd1, ICEMODE_FULL,
                  CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(offer.get(), kMid2Video, kIceUfrag2, kIcePwd2, ICEMODE_FULL,
                  CONNECTIONROLE_ACTPASS, nullptr);
  AddAudioSection(offer.get(), kMid3Audio, kIceUfrag3, kIcePwd3, ICEMODE_FULL,
                  CONNECTIONROLE_ACTPASS, nullptr);
  offer->AddGroup(offer_bundle_group1);
  offer->AddGroup(offer_bundle_group2);

  // Reject offer, both if set as local or remote.
  EXPECT_FALSE(transport_controller_
                   ->SetLocalDescription(SdpType::kOffer, offer.get(), nullptr)
                   .ok());
  EXPECT_FALSE(
      transport_controller_
          ->SetRemoteDescription(SdpType::kOffer, offer.get(), offer.get())
          .ok());
}

TEST_F(JsepTransportControllerTest, MultipleBundleGroupsUnbundleFirstMid) {
  static const char kMid1Audio[] = "1_audio";
  static const char kMid2Audio[] = "2_audio";
  static const char kMid3Audio[] = "3_audio";
  static const char kMid4Video[] = "4_video";
  static const char kMid5Video[] = "5_video";
  static const char kMid6Video[] = "6_video";

  CreateJsepTransportController(JsepTransportController::Config());
  // Offer groups (kMid1Audio,kMid2Audio,kMid3Audio) and
  // (kMid4Video,kMid5Video,kMid6Video).
  ContentGroup offer_bundle_group1(GROUP_TYPE_BUNDLE);
  offer_bundle_group1.AddContentName(kMid1Audio);
  offer_bundle_group1.AddContentName(kMid2Audio);
  offer_bundle_group1.AddContentName(kMid3Audio);
  ContentGroup offer_bundle_group2(GROUP_TYPE_BUNDLE);
  offer_bundle_group2.AddContentName(kMid4Video);
  offer_bundle_group2.AddContentName(kMid5Video);
  offer_bundle_group2.AddContentName(kMid6Video);
  // Answer groups (kMid2Audio,kMid3Audio) and (kMid5Video,kMid6Video), i.e.
  // we've moved the first MIDs out of the groups.
  ContentGroup answer_bundle_group1(GROUP_TYPE_BUNDLE);
  answer_bundle_group1.AddContentName(kMid2Audio);
  answer_bundle_group1.AddContentName(kMid3Audio);
  ContentGroup answer_bundle_group2(GROUP_TYPE_BUNDLE);
  answer_bundle_group2.AddContentName(kMid5Video);
  answer_bundle_group2.AddContentName(kMid6Video);

  auto local_offer = std::make_unique<SessionDescription>();
  AddAudioSection(local_offer.get(), kMid1Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddAudioSection(local_offer.get(), kMid2Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddAudioSection(local_offer.get(), kMid3Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(local_offer.get(), kMid4Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(local_offer.get(), kMid5Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(local_offer.get(), kMid6Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  local_offer->AddGroup(offer_bundle_group1);
  local_offer->AddGroup(offer_bundle_group2);

  auto remote_answer = std::make_unique<SessionDescription>();
  AddAudioSection(remote_answer.get(), kMid1Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddAudioSection(remote_answer.get(), kMid2Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddAudioSection(remote_answer.get(), kMid3Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(remote_answer.get(), kMid4Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(remote_answer.get(), kMid5Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(remote_answer.get(), kMid6Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  remote_answer->AddGroup(answer_bundle_group1);
  remote_answer->AddGroup(answer_bundle_group2);

  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, local_offer.get(), nullptr)
          .ok());
  EXPECT_TRUE(transport_controller_
                  ->SetRemoteDescription(SdpType::kAnswer, local_offer.get(),
                                         remote_answer.get())
                  .ok());

  auto mid1_transport = transport_controller_->GetRtpTransport(kMid1Audio);
  auto mid2_transport = transport_controller_->GetRtpTransport(kMid2Audio);
  auto mid3_transport = transport_controller_->GetRtpTransport(kMid3Audio);
  auto mid4_transport = transport_controller_->GetRtpTransport(kMid4Video);
  auto mid5_transport = transport_controller_->GetRtpTransport(kMid5Video);
  auto mid6_transport = transport_controller_->GetRtpTransport(kMid6Video);
  EXPECT_NE(mid1_transport, mid2_transport);
  EXPECT_EQ(mid2_transport, mid3_transport);
  EXPECT_NE(mid4_transport, mid5_transport);
  EXPECT_EQ(mid5_transport, mid6_transport);
  EXPECT_NE(mid1_transport, mid4_transport);
  EXPECT_NE(mid2_transport, mid5_transport);
}

TEST_F(JsepTransportControllerTest, MultipleBundleGroupsChangeFirstMid) {
  static const char kMid1Audio[] = "1_audio";
  static const char kMid2Audio[] = "2_audio";
  static const char kMid3Audio[] = "3_audio";
  static const char kMid4Video[] = "4_video";
  static const char kMid5Video[] = "5_video";
  static const char kMid6Video[] = "6_video";

  CreateJsepTransportController(JsepTransportController::Config());
  // Offer groups (kMid1Audio,kMid2Audio,kMid3Audio) and
  // (kMid4Video,kMid5Video,kMid6Video).
  ContentGroup offer_bundle_group1(GROUP_TYPE_BUNDLE);
  offer_bundle_group1.AddContentName(kMid1Audio);
  offer_bundle_group1.AddContentName(kMid2Audio);
  offer_bundle_group1.AddContentName(kMid3Audio);
  ContentGroup offer_bundle_group2(GROUP_TYPE_BUNDLE);
  offer_bundle_group2.AddContentName(kMid4Video);
  offer_bundle_group2.AddContentName(kMid5Video);
  offer_bundle_group2.AddContentName(kMid6Video);
  // Answer groups (kMid2Audio,kMid1Audio,kMid3Audio) and
  // (kMid5Video,kMid6Video,kMid4Video), i.e. we've changed which MID is first
  // but accept the whole group.
  ContentGroup answer_bundle_group1(GROUP_TYPE_BUNDLE);
  answer_bundle_group1.AddContentName(kMid2Audio);
  answer_bundle_group1.AddContentName(kMid1Audio);
  answer_bundle_group1.AddContentName(kMid3Audio);
  ContentGroup answer_bundle_group2(GROUP_TYPE_BUNDLE);
  answer_bundle_group2.AddContentName(kMid5Video);
  answer_bundle_group2.AddContentName(kMid6Video);
  answer_bundle_group2.AddContentName(kMid4Video);

  auto local_offer = std::make_unique<SessionDescription>();
  AddAudioSection(local_offer.get(), kMid1Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddAudioSection(local_offer.get(), kMid2Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddAudioSection(local_offer.get(), kMid3Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(local_offer.get(), kMid4Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(local_offer.get(), kMid5Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(local_offer.get(), kMid6Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  local_offer->AddGroup(offer_bundle_group1);
  local_offer->AddGroup(offer_bundle_group2);

  auto remote_answer = std::make_unique<SessionDescription>();
  AddAudioSection(remote_answer.get(), kMid1Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddAudioSection(remote_answer.get(), kMid2Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddAudioSection(remote_answer.get(), kMid3Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(remote_answer.get(), kMid4Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(remote_answer.get(), kMid5Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(remote_answer.get(), kMid6Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  remote_answer->AddGroup(answer_bundle_group1);
  remote_answer->AddGroup(answer_bundle_group2);

  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, local_offer.get(), nullptr)
          .ok());

  // The fact that we accept this answer is actually a bug. If we accept the
  // first MID to be in the group, we should also accept that it is the tagged
  // one.
  // TODO(https://crbug.com/webrtc/12699): When this issue is fixed, change this
  // to EXPECT_FALSE and remove the below expectations about transports.
  EXPECT_TRUE(transport_controller_
                  ->SetRemoteDescription(SdpType::kAnswer, local_offer.get(),
                                         remote_answer.get())
                  .ok());
  auto mid1_transport = transport_controller_->GetRtpTransport(kMid1Audio);
  auto mid2_transport = transport_controller_->GetRtpTransport(kMid2Audio);
  auto mid3_transport = transport_controller_->GetRtpTransport(kMid3Audio);
  auto mid4_transport = transport_controller_->GetRtpTransport(kMid4Video);
  auto mid5_transport = transport_controller_->GetRtpTransport(kMid5Video);
  auto mid6_transport = transport_controller_->GetRtpTransport(kMid6Video);
  EXPECT_NE(mid1_transport, mid4_transport);
  EXPECT_EQ(mid1_transport, mid2_transport);
  EXPECT_EQ(mid2_transport, mid3_transport);
  EXPECT_EQ(mid4_transport, mid5_transport);
  EXPECT_EQ(mid5_transport, mid6_transport);
}

TEST_F(JsepTransportControllerTest,
       MultipleBundleGroupsSectionsAddedInSubsequentOffer) {
  static const char kMid1Audio[] = "1_audio";
  static const char kMid2Audio[] = "2_audio";
  static const char kMid3Audio[] = "3_audio";
  static const char kMid4Video[] = "4_video";
  static const char kMid5Video[] = "5_video";
  static const char kMid6Video[] = "6_video";

  CreateJsepTransportController(JsepTransportController::Config());
  // Start by grouping (kMid1Audio,kMid2Audio) and (kMid4Video,kMid4f5Video).
  ContentGroup bundle_group1(GROUP_TYPE_BUNDLE);
  bundle_group1.AddContentName(kMid1Audio);
  bundle_group1.AddContentName(kMid2Audio);
  ContentGroup bundle_group2(GROUP_TYPE_BUNDLE);
  bundle_group2.AddContentName(kMid4Video);
  bundle_group2.AddContentName(kMid5Video);

  auto local_offer = std::make_unique<SessionDescription>();
  AddAudioSection(local_offer.get(), kMid1Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddAudioSection(local_offer.get(), kMid2Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(local_offer.get(), kMid4Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(local_offer.get(), kMid5Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  local_offer->AddGroup(bundle_group1);
  local_offer->AddGroup(bundle_group2);

  auto remote_answer = std::make_unique<SessionDescription>();
  AddAudioSection(remote_answer.get(), kMid1Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddAudioSection(remote_answer.get(), kMid2Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(remote_answer.get(), kMid4Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(remote_answer.get(), kMid5Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  remote_answer->AddGroup(bundle_group1);
  remote_answer->AddGroup(bundle_group2);

  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, local_offer.get(), nullptr)
          .ok());
  EXPECT_TRUE(transport_controller_
                  ->SetRemoteDescription(SdpType::kAnswer, local_offer.get(),
                                         remote_answer.get())
                  .ok());

  // Add kMid3Audio and kMid6Video to the respective audio/video bundle groups.
  ContentGroup new_bundle_group1(GROUP_TYPE_BUNDLE);
  bundle_group1.AddContentName(kMid3Audio);
  ContentGroup new_bundle_group2(GROUP_TYPE_BUNDLE);
  bundle_group2.AddContentName(kMid6Video);

  auto subsequent_offer = std::make_unique<SessionDescription>();
  AddAudioSection(subsequent_offer.get(), kMid1Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddAudioSection(subsequent_offer.get(), kMid2Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddAudioSection(subsequent_offer.get(), kMid3Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(subsequent_offer.get(), kMid4Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(subsequent_offer.get(), kMid5Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(subsequent_offer.get(), kMid6Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  subsequent_offer->AddGroup(bundle_group1);
  subsequent_offer->AddGroup(bundle_group2);
  EXPECT_TRUE(transport_controller_
                  ->SetLocalDescription(SdpType::kOffer, subsequent_offer.get(),
                                        remote_answer.get())
                  .ok());
  auto mid1_transport = transport_controller_->GetRtpTransport(kMid1Audio);
  auto mid2_transport = transport_controller_->GetRtpTransport(kMid2Audio);
  auto mid3_transport = transport_controller_->GetRtpTransport(kMid3Audio);
  auto mid4_transport = transport_controller_->GetRtpTransport(kMid4Video);
  auto mid5_transport = transport_controller_->GetRtpTransport(kMid5Video);
  auto mid6_transport = transport_controller_->GetRtpTransport(kMid6Video);
  EXPECT_NE(mid1_transport, mid4_transport);
  EXPECT_EQ(mid1_transport, mid2_transport);
  EXPECT_EQ(mid2_transport, mid3_transport);
  EXPECT_EQ(mid4_transport, mid5_transport);
  EXPECT_EQ(mid5_transport, mid6_transport);
}

TEST_F(JsepTransportControllerTest,
       MultipleBundleGroupsCombinedInSubsequentOffer) {
  static const char kMid1Audio[] = "1_audio";
  static const char kMid2Audio[] = "2_audio";
  static const char kMid3Video[] = "3_video";
  static const char kMid4Video[] = "4_video";

  CreateJsepTransportController(JsepTransportController::Config());
  // Start by grouping (kMid1Audio,kMid2Audio) and (kMid3Video,kMid4Video).
  ContentGroup bundle_group1(GROUP_TYPE_BUNDLE);
  bundle_group1.AddContentName(kMid1Audio);
  bundle_group1.AddContentName(kMid2Audio);
  ContentGroup bundle_group2(GROUP_TYPE_BUNDLE);
  bundle_group2.AddContentName(kMid3Video);
  bundle_group2.AddContentName(kMid4Video);

  auto local_offer = std::make_unique<SessionDescription>();
  AddAudioSection(local_offer.get(), kMid1Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddAudioSection(local_offer.get(), kMid2Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(local_offer.get(), kMid3Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(local_offer.get(), kMid4Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  local_offer->AddGroup(bundle_group1);
  local_offer->AddGroup(bundle_group2);

  auto remote_answer = std::make_unique<SessionDescription>();
  AddAudioSection(remote_answer.get(), kMid1Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddAudioSection(remote_answer.get(), kMid2Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(remote_answer.get(), kMid3Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(remote_answer.get(), kMid4Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  remote_answer->AddGroup(bundle_group1);
  remote_answer->AddGroup(bundle_group2);

  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, local_offer.get(), nullptr)
          .ok());
  EXPECT_TRUE(transport_controller_
                  ->SetRemoteDescription(SdpType::kAnswer, local_offer.get(),
                                         remote_answer.get())
                  .ok());

  // Switch to grouping (kMid1Audio,kMid2Audio,kMid3Video,kMid4Video).
  // This is a illegal without first removing m= sections from their groups.
  ContentGroup new_bundle_group(GROUP_TYPE_BUNDLE);
  new_bundle_group.AddContentName(kMid1Audio);
  new_bundle_group.AddContentName(kMid2Audio);
  new_bundle_group.AddContentName(kMid3Video);
  new_bundle_group.AddContentName(kMid4Video);

  auto subsequent_offer = std::make_unique<SessionDescription>();
  AddAudioSection(subsequent_offer.get(), kMid1Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddAudioSection(subsequent_offer.get(), kMid2Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(subsequent_offer.get(), kMid3Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(subsequent_offer.get(), kMid4Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  subsequent_offer->AddGroup(new_bundle_group);
  EXPECT_FALSE(transport_controller_
                   ->SetLocalDescription(SdpType::kOffer,
                                         subsequent_offer.get(),
                                         remote_answer.get())
                   .ok());
}

TEST_F(JsepTransportControllerTest,
       MultipleBundleGroupsSplitInSubsequentOffer) {
  static const char kMid1Audio[] = "1_audio";
  static const char kMid2Audio[] = "2_audio";
  static const char kMid3Video[] = "3_video";
  static const char kMid4Video[] = "4_video";

  CreateJsepTransportController(JsepTransportController::Config());
  // Start by grouping (kMid1Audio,kMid2Audio,kMid3Video,kMid4Video).
  ContentGroup bundle_group(GROUP_TYPE_BUNDLE);
  bundle_group.AddContentName(kMid1Audio);
  bundle_group.AddContentName(kMid2Audio);
  bundle_group.AddContentName(kMid3Video);
  bundle_group.AddContentName(kMid4Video);

  auto local_offer = std::make_unique<SessionDescription>();
  AddAudioSection(local_offer.get(), kMid1Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddAudioSection(local_offer.get(), kMid2Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(local_offer.get(), kMid3Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(local_offer.get(), kMid4Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  local_offer->AddGroup(bundle_group);

  auto remote_answer = std::make_unique<SessionDescription>();
  AddAudioSection(remote_answer.get(), kMid1Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddAudioSection(remote_answer.get(), kMid2Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(remote_answer.get(), kMid3Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(remote_answer.get(), kMid4Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  remote_answer->AddGroup(bundle_group);

  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, local_offer.get(), nullptr)
          .ok());
  EXPECT_TRUE(transport_controller_
                  ->SetRemoteDescription(SdpType::kAnswer, local_offer.get(),
                                         remote_answer.get())
                  .ok());

  // Switch to grouping (kMid1Audio,kMid2Audio) and (kMid3Video,kMid4Video).
  // This is a illegal without first removing m= sections from their groups.
  ContentGroup new_bundle_group1(GROUP_TYPE_BUNDLE);
  new_bundle_group1.AddContentName(kMid1Audio);
  new_bundle_group1.AddContentName(kMid2Audio);
  ContentGroup new_bundle_group2(GROUP_TYPE_BUNDLE);
  new_bundle_group2.AddContentName(kMid3Video);
  new_bundle_group2.AddContentName(kMid4Video);

  auto subsequent_offer = std::make_unique<SessionDescription>();
  AddAudioSection(subsequent_offer.get(), kMid1Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddAudioSection(subsequent_offer.get(), kMid2Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(subsequent_offer.get(), kMid3Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(subsequent_offer.get(), kMid4Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  subsequent_offer->AddGroup(new_bundle_group1);
  subsequent_offer->AddGroup(new_bundle_group2);
  EXPECT_FALSE(transport_controller_
                   ->SetLocalDescription(SdpType::kOffer,
                                         subsequent_offer.get(),
                                         remote_answer.get())
                   .ok());
}

TEST_F(JsepTransportControllerTest,
       MultipleBundleGroupsShuffledInSubsequentOffer) {
  static const char kMid1Audio[] = "1_audio";
  static const char kMid2Audio[] = "2_audio";
  static const char kMid3Video[] = "3_video";
  static const char kMid4Video[] = "4_video";

  CreateJsepTransportController(JsepTransportController::Config());
  // Start by grouping (kMid1Audio,kMid2Audio) and (kMid3Video,kMid4Video).
  ContentGroup bundle_group1(GROUP_TYPE_BUNDLE);
  bundle_group1.AddContentName(kMid1Audio);
  bundle_group1.AddContentName(kMid2Audio);
  ContentGroup bundle_group2(GROUP_TYPE_BUNDLE);
  bundle_group2.AddContentName(kMid3Video);
  bundle_group2.AddContentName(kMid4Video);

  auto local_offer = std::make_unique<SessionDescription>();
  AddAudioSection(local_offer.get(), kMid1Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddAudioSection(local_offer.get(), kMid2Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(local_offer.get(), kMid3Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(local_offer.get(), kMid4Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  local_offer->AddGroup(bundle_group1);
  local_offer->AddGroup(bundle_group2);

  auto remote_answer = std::make_unique<SessionDescription>();
  AddAudioSection(remote_answer.get(), kMid1Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddAudioSection(remote_answer.get(), kMid2Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(remote_answer.get(), kMid3Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(remote_answer.get(), kMid4Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  remote_answer->AddGroup(bundle_group1);
  remote_answer->AddGroup(bundle_group2);

  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, local_offer.get(), nullptr)
          .ok());
  EXPECT_TRUE(transport_controller_
                  ->SetRemoteDescription(SdpType::kAnswer, local_offer.get(),
                                         remote_answer.get())
                  .ok());

  // Switch to grouping (kMid1Audio,kMid3Video) and (kMid2Audio,kMid3Video).
  // This is a illegal without first removing m= sections from their groups.
  ContentGroup new_bundle_group1(GROUP_TYPE_BUNDLE);
  new_bundle_group1.AddContentName(kMid1Audio);
  new_bundle_group1.AddContentName(kMid3Video);
  ContentGroup new_bundle_group2(GROUP_TYPE_BUNDLE);
  new_bundle_group2.AddContentName(kMid2Audio);
  new_bundle_group2.AddContentName(kMid4Video);

  auto subsequent_offer = std::make_unique<SessionDescription>();
  AddAudioSection(subsequent_offer.get(), kMid1Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddAudioSection(subsequent_offer.get(), kMid2Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(subsequent_offer.get(), kMid3Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(subsequent_offer.get(), kMid4Video, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  subsequent_offer->AddGroup(new_bundle_group1);
  subsequent_offer->AddGroup(new_bundle_group2);
  EXPECT_FALSE(transport_controller_
                   ->SetLocalDescription(SdpType::kOffer,
                                         subsequent_offer.get(),
                                         remote_answer.get())
                   .ok());
}

// Tests that only a subset of all the m= sections are bundled.
TEST_F(JsepTransportControllerTest, BundleSubsetOfMediaSections) {
  CreateJsepTransportController(JsepTransportController::Config());
  ContentGroup bundle_group(GROUP_TYPE_BUNDLE);
  bundle_group.AddContentName(kAudioMid1);
  bundle_group.AddContentName(kVideoMid1);

  auto local_offer = std::make_unique<SessionDescription>();
  AddAudioSection(local_offer.get(), kAudioMid1, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddAudioSection(local_offer.get(), kAudioMid2, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(local_offer.get(), kVideoMid1, kIceUfrag3, kIcePwd3,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);

  auto remote_answer = std::make_unique<SessionDescription>();
  AddAudioSection(remote_answer.get(), kAudioMid1, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_PASSIVE, nullptr);
  AddAudioSection(remote_answer.get(), kAudioMid2, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_PASSIVE, nullptr);
  AddVideoSection(remote_answer.get(), kVideoMid1, kIceUfrag3, kIcePwd3,
                  ICEMODE_FULL, CONNECTIONROLE_PASSIVE, nullptr);

  local_offer->AddGroup(bundle_group);
  remote_answer->AddGroup(bundle_group);
  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, local_offer.get(), nullptr)
          .ok());
  EXPECT_TRUE(transport_controller_
                  ->SetRemoteDescription(SdpType::kAnswer, local_offer.get(),
                                         remote_answer.get())
                  .ok());

  // Verifiy that only `kAudio1` and `kVideo1` are bundled.
  auto transport1 = transport_controller_->GetRtpTransport(kAudioMid1);
  auto transport2 = transport_controller_->GetRtpTransport(kAudioMid2);
  auto transport3 = transport_controller_->GetRtpTransport(kVideoMid1);
  EXPECT_NE(transport1, transport2);
  EXPECT_EQ(transport1, transport3);

  auto it = changed_rtp_transport_by_mid_.find(kVideoMid1);
  ASSERT_TRUE(it != changed_rtp_transport_by_mid_.end());
  EXPECT_EQ(transport1, it->second);
  it = changed_rtp_transport_by_mid_.find(kAudioMid2);
  EXPECT_TRUE(transport2 == it->second);
}

// Tests that the initial offer/answer only have data section and audio/video
// sections are added in the subsequent offer.
TEST_F(JsepTransportControllerTest, BundleOnDataSectionInSubsequentOffer) {
  CreateJsepTransportController(JsepTransportController::Config());
  ContentGroup bundle_group(GROUP_TYPE_BUNDLE);
  bundle_group.AddContentName(kDataMid1);

  auto local_offer = std::make_unique<SessionDescription>();
  AddDataSection(local_offer.get(), kDataMid1, MediaProtocolType::kSctp,
                 kIceUfrag1, kIcePwd1, ICEMODE_FULL, CONNECTIONROLE_ACTPASS,
                 nullptr);
  auto remote_answer = std::make_unique<SessionDescription>();
  AddDataSection(remote_answer.get(), kDataMid1, MediaProtocolType::kSctp,
                 kIceUfrag1, kIcePwd1, ICEMODE_FULL, CONNECTIONROLE_PASSIVE,
                 nullptr);
  local_offer->AddGroup(bundle_group);
  remote_answer->AddGroup(bundle_group);

  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, local_offer.get(), nullptr)
          .ok());
  EXPECT_TRUE(transport_controller_
                  ->SetRemoteDescription(SdpType::kAnswer, local_offer.get(),
                                         remote_answer.get())
                  .ok());
  auto data_transport = transport_controller_->GetRtpTransport(kDataMid1);

  // Add audio/video sections in subsequent offer.
  AddAudioSection(local_offer.get(), kAudioMid1, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(local_offer.get(), kVideoMid1, kIceUfrag3, kIcePwd3,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddAudioSection(remote_answer.get(), kAudioMid1, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_PASSIVE, nullptr);
  AddVideoSection(remote_answer.get(), kVideoMid1, kIceUfrag3, kIcePwd3,
                  ICEMODE_FULL, CONNECTIONROLE_PASSIVE, nullptr);

  // Reset the bundle group and do another offer/answer exchange.
  bundle_group.AddContentName(kAudioMid1);
  bundle_group.AddContentName(kVideoMid1);
  local_offer->RemoveGroupByName(GROUP_TYPE_BUNDLE);
  local_offer->AddGroup(bundle_group);

  EXPECT_TRUE(transport_controller_
                  ->SetLocalDescription(SdpType::kOffer, local_offer.get(),
                                        remote_answer.get())
                  .ok());
  remote_answer->RemoveGroupByName(GROUP_TYPE_BUNDLE);
  remote_answer->AddGroup(bundle_group);
  EXPECT_TRUE(transport_controller_
                  ->SetRemoteDescription(SdpType::kAnswer, local_offer.get(),
                                         remote_answer.get())
                  .ok());

  auto audio_transport = transport_controller_->GetRtpTransport(kAudioMid1);
  auto video_transport = transport_controller_->GetRtpTransport(kVideoMid1);
  EXPECT_EQ(data_transport, audio_transport);
  EXPECT_EQ(data_transport, video_transport);
}

TEST_F(JsepTransportControllerTest, VideoDataRejectedInAnswer) {
  CreateJsepTransportController(JsepTransportController::Config());
  ContentGroup bundle_group(GROUP_TYPE_BUNDLE);
  bundle_group.AddContentName(kAudioMid1);
  bundle_group.AddContentName(kVideoMid1);
  bundle_group.AddContentName(kDataMid1);

  auto local_offer = std::make_unique<SessionDescription>();
  AddAudioSection(local_offer.get(), kAudioMid1, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(local_offer.get(), kVideoMid1, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddDataSection(local_offer.get(), kDataMid1, MediaProtocolType::kSctp,
                 kIceUfrag3, kIcePwd3, ICEMODE_FULL, CONNECTIONROLE_ACTPASS,
                 nullptr);

  auto remote_answer = std::make_unique<SessionDescription>();
  AddAudioSection(remote_answer.get(), kAudioMid1, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_PASSIVE, nullptr);
  AddVideoSection(remote_answer.get(), kVideoMid1, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_PASSIVE, nullptr);
  AddDataSection(remote_answer.get(), kDataMid1, MediaProtocolType::kSctp,
                 kIceUfrag3, kIcePwd3, ICEMODE_FULL, CONNECTIONROLE_PASSIVE,
                 nullptr);
  // Reject video and data section.
  remote_answer->contents()[1].rejected = true;
  remote_answer->contents()[2].rejected = true;

  local_offer->AddGroup(bundle_group);
  remote_answer->AddGroup(bundle_group);

  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, local_offer.get(), nullptr)
          .ok());
  EXPECT_TRUE(transport_controller_
                  ->SetRemoteDescription(SdpType::kAnswer, local_offer.get(),
                                         remote_answer.get())
                  .ok());

  // Verify the RtpTransport/DtlsTransport is destroyed correctly.
  EXPECT_EQ(nullptr, transport_controller_->GetRtpTransport(kVideoMid1));
  EXPECT_EQ(nullptr, transport_controller_->GetDtlsTransport(kDataMid1));
  // Verify the signals are fired correctly.
  auto it = changed_rtp_transport_by_mid_.find(kVideoMid1);
  ASSERT_TRUE(it != changed_rtp_transport_by_mid_.end());
  EXPECT_EQ(nullptr, it->second);
  auto it2 = changed_dtls_transport_by_mid_.find(kDataMid1);
  ASSERT_TRUE(it2 != changed_dtls_transport_by_mid_.end());
  EXPECT_EQ(nullptr, it2->second);
}

// Tests that changing the bundled MID in subsequent offer/answer exchange is
// not supported.
// TODO(bugs.webrtc.org/6704): Change this test to expect success once issue is
// fixed
TEST_F(JsepTransportControllerTest, ChangeBundledMidNotSupported) {
  CreateJsepTransportController(JsepTransportController::Config());
  ContentGroup bundle_group(GROUP_TYPE_BUNDLE);
  bundle_group.AddContentName(kAudioMid1);
  bundle_group.AddContentName(kVideoMid1);

  auto local_offer = std::make_unique<SessionDescription>();
  AddAudioSection(local_offer.get(), kAudioMid1, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(local_offer.get(), kVideoMid1, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);

  auto remote_answer = std::make_unique<SessionDescription>();
  AddAudioSection(remote_answer.get(), kAudioMid1, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_PASSIVE, nullptr);
  AddVideoSection(remote_answer.get(), kVideoMid1, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_PASSIVE, nullptr);

  local_offer->AddGroup(bundle_group);
  remote_answer->AddGroup(bundle_group);
  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, local_offer.get(), nullptr)
          .ok());
  EXPECT_TRUE(transport_controller_
                  ->SetRemoteDescription(SdpType::kAnswer, local_offer.get(),
                                         remote_answer.get())
                  .ok());
  EXPECT_EQ(transport_controller_->GetRtpTransport(kAudioMid1),
            transport_controller_->GetRtpTransport(kVideoMid1));

  // Reorder the bundle group.
  EXPECT_TRUE(bundle_group.RemoveContentName(kAudioMid1));
  bundle_group.AddContentName(kAudioMid1);
  EXPECT_TRUE(transport_controller_
                  ->SetLocalDescription(SdpType::kOffer, local_offer.get(),
                                        remote_answer.get())
                  .ok());
  // The answerer uses the new bundle group and now the bundle mid is changed to
  // `kVideo1`.
  remote_answer->RemoveGroupByName(GROUP_TYPE_BUNDLE);
  remote_answer->AddGroup(bundle_group);
  EXPECT_FALSE(transport_controller_
                   ->SetRemoteDescription(SdpType::kAnswer, local_offer.get(),
                                          remote_answer.get())
                   .ok());
}
// Test that rejecting only the first m= section of a BUNDLE group is treated as
// an error, but rejecting all of them works as expected.
TEST_F(JsepTransportControllerTest, RejectFirstContentInBundleGroup) {
  CreateJsepTransportController(JsepTransportController::Config());
  ContentGroup bundle_group(GROUP_TYPE_BUNDLE);
  bundle_group.AddContentName(kAudioMid1);
  bundle_group.AddContentName(kVideoMid1);
  bundle_group.AddContentName(kDataMid1);

  auto local_offer = std::make_unique<SessionDescription>();
  AddAudioSection(local_offer.get(), kAudioMid1, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(local_offer.get(), kVideoMid1, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddDataSection(local_offer.get(), kDataMid1, MediaProtocolType::kSctp,
                 kIceUfrag3, kIcePwd3, ICEMODE_FULL, CONNECTIONROLE_ACTPASS,
                 nullptr);

  auto remote_answer = std::make_unique<SessionDescription>();
  AddAudioSection(remote_answer.get(), kAudioMid1, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_PASSIVE, nullptr);
  AddVideoSection(remote_answer.get(), kVideoMid1, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_PASSIVE, nullptr);
  AddDataSection(remote_answer.get(), kDataMid1, MediaProtocolType::kSctp,
                 kIceUfrag3, kIcePwd3, ICEMODE_FULL, CONNECTIONROLE_PASSIVE,
                 nullptr);
  // Reject audio content in answer.
  remote_answer->contents()[0].rejected = true;

  local_offer->AddGroup(bundle_group);
  remote_answer->AddGroup(bundle_group);

  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, local_offer.get(), nullptr)
          .ok());
  EXPECT_FALSE(transport_controller_
                   ->SetRemoteDescription(SdpType::kAnswer, local_offer.get(),
                                          remote_answer.get())
                   .ok());

  // Reject all the contents.
  remote_answer->contents()[1].rejected = true;
  remote_answer->contents()[2].rejected = true;
  EXPECT_TRUE(transport_controller_
                  ->SetRemoteDescription(SdpType::kAnswer, local_offer.get(),
                                         remote_answer.get())
                  .ok());
  EXPECT_EQ(nullptr, transport_controller_->GetRtpTransport(kAudioMid1));
  EXPECT_EQ(nullptr, transport_controller_->GetRtpTransport(kVideoMid1));
  EXPECT_EQ(nullptr, transport_controller_->GetDtlsTransport(kDataMid1));
}

// Tests that applying non-RTCP-mux offer would fail when kRtcpMuxPolicyRequire
// is used.
TEST_F(JsepTransportControllerTest, ApplyNonRtcpMuxOfferWhenMuxingRequired) {
  JsepTransportController::Config config;
  config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
  CreateJsepTransportController(std::move(config));
  auto local_offer = std::make_unique<SessionDescription>();
  AddAudioSection(local_offer.get(), kAudioMid1, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);

  local_offer->contents()[0].media_description()->set_rtcp_mux(false);
  // Applying a non-RTCP-mux offer is expected to fail.
  EXPECT_FALSE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, local_offer.get(), nullptr)
          .ok());
}

// Tests that applying non-RTCP-mux answer would fail when kRtcpMuxPolicyRequire
// is used.
TEST_F(JsepTransportControllerTest, ApplyNonRtcpMuxAnswerWhenMuxingRequired) {
  JsepTransportController::Config config;
  config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire;
  CreateJsepTransportController(std::move(config));
  auto local_offer = std::make_unique<SessionDescription>();
  AddAudioSection(local_offer.get(), kAudioMid1, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, local_offer.get(), nullptr)
          .ok());

  auto remote_answer = std::make_unique<SessionDescription>();
  AddAudioSection(remote_answer.get(), kAudioMid1, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_PASSIVE, nullptr);
  // Applying a non-RTCP-mux answer is expected to fail.
  remote_answer->contents()[0].media_description()->set_rtcp_mux(false);
  EXPECT_FALSE(transport_controller_
                   ->SetRemoteDescription(SdpType::kAnswer, local_offer.get(),
                                          remote_answer.get())
                   .ok());
}

// This tests that the BUNDLE group in answer should be a subset of the offered
// group.
TEST_F(JsepTransportControllerTest,
       AddContentToBundleGroupInAnswerNotSupported) {
  CreateJsepTransportController(JsepTransportController::Config());
  auto local_offer = CreateSessionDescriptionWithoutBundle();
  auto remote_answer = CreateSessionDescriptionWithoutBundle();

  ContentGroup offer_bundle_group(GROUP_TYPE_BUNDLE);
  offer_bundle_group.AddContentName(kAudioMid1);
  local_offer->AddGroup(offer_bundle_group);

  ContentGroup answer_bundle_group(GROUP_TYPE_BUNDLE);
  answer_bundle_group.AddContentName(kAudioMid1);
  answer_bundle_group.AddContentName(kVideoMid1);
  remote_answer->AddGroup(answer_bundle_group);
  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, local_offer.get(), nullptr)
          .ok());
  EXPECT_FALSE(transport_controller_
                   ->SetRemoteDescription(SdpType::kAnswer, local_offer.get(),
                                          remote_answer.get())
                   .ok());
}

// This tests that the BUNDLE group with non-existing MID should be rejectd.
TEST_F(JsepTransportControllerTest, RejectBundleGroupWithNonExistingMid) {
  CreateJsepTransportController(JsepTransportController::Config());
  auto local_offer = CreateSessionDescriptionWithoutBundle();
  auto remote_answer = CreateSessionDescriptionWithoutBundle();

  ContentGroup invalid_bundle_group(GROUP_TYPE_BUNDLE);
  // The BUNDLE group is invalid because there is no data section in the
  // description.
  invalid_bundle_group.AddContentName(kDataMid1);
  local_offer->AddGroup(invalid_bundle_group);
  remote_answer->AddGroup(invalid_bundle_group);

  EXPECT_FALSE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, local_offer.get(), nullptr)
          .ok());
  EXPECT_FALSE(transport_controller_
                   ->SetRemoteDescription(SdpType::kAnswer, local_offer.get(),
                                          remote_answer.get())
                   .ok());
}

// This tests that an answer shouldn't be able to remove an m= section from an
// established group without rejecting it.
TEST_F(JsepTransportControllerTest, RemoveContentFromBundleGroup) {
  CreateJsepTransportController(JsepTransportController::Config());

  auto local_offer = CreateSessionDescriptionWithBundleGroup();
  auto remote_answer = CreateSessionDescriptionWithBundleGroup();
  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, local_offer.get(), nullptr)
          .ok());
  EXPECT_TRUE(transport_controller_
                  ->SetRemoteDescription(SdpType::kAnswer, local_offer.get(),
                                         remote_answer.get())
                  .ok());

  // Do an re-offer/answer.
  EXPECT_TRUE(transport_controller_
                  ->SetLocalDescription(SdpType::kOffer, local_offer.get(),
                                        remote_answer.get())
                  .ok());
  auto new_answer = CreateSessionDescriptionWithoutBundle();
  ContentGroup new_bundle_group(GROUP_TYPE_BUNDLE);
  //  The answer removes video from the BUNDLE group without rejecting it is
  //  invalid.
  new_bundle_group.AddContentName(kAudioMid1);
  new_answer->AddGroup(new_bundle_group);

  // Applying invalid answer is expected to fail.
  EXPECT_FALSE(transport_controller_
                   ->SetRemoteDescription(SdpType::kAnswer, local_offer.get(),
                                          new_answer.get())
                   .ok());

  // Rejected the video content.
  auto video_content = new_answer->GetContentByName(kVideoMid1);
  ASSERT_TRUE(video_content);
  video_content->rejected = true;
  EXPECT_TRUE(transport_controller_
                  ->SetRemoteDescription(SdpType::kAnswer, local_offer.get(),
                                         new_answer.get())
                  .ok());
}

// Test that the JsepTransportController can process a new local and remote
// description that changes the tagged BUNDLE group with the max-bundle policy
// specified.
// This is a regression test for bugs.webrtc.org/9954
TEST_F(JsepTransportControllerTest, ChangeTaggedMediaSectionMaxBundle) {
  CreateJsepTransportController(JsepTransportController::Config());

  auto local_offer = std::make_unique<SessionDescription>();
  AddAudioSection(local_offer.get(), kAudioMid1, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  ContentGroup bundle_group(GROUP_TYPE_BUNDLE);
  bundle_group.AddContentName(kAudioMid1);
  local_offer->AddGroup(bundle_group);
  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, local_offer.get(), nullptr)
          .ok());

  std::unique_ptr<SessionDescription> remote_answer(local_offer->Clone());
  EXPECT_TRUE(transport_controller_
                  ->SetRemoteDescription(SdpType::kAnswer, local_offer.get(),
                                         remote_answer.get())
                  .ok());

  std::unique_ptr<SessionDescription> local_reoffer(local_offer->Clone());
  local_reoffer->contents()[0].rejected = true;
  AddVideoSection(local_reoffer.get(), kVideoMid1, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  local_reoffer->RemoveGroupByName(GROUP_TYPE_BUNDLE);
  ContentGroup new_bundle_group(GROUP_TYPE_BUNDLE);
  new_bundle_group.AddContentName(kVideoMid1);
  local_reoffer->AddGroup(new_bundle_group);

  EXPECT_TRUE(transport_controller_
                  ->SetLocalDescription(SdpType::kOffer, local_reoffer.get(),
                                        remote_answer.get())
                  .ok());
  std::unique_ptr<SessionDescription> remote_reanswer(local_reoffer->Clone());
  EXPECT_TRUE(transport_controller_
                  ->SetRemoteDescription(SdpType::kAnswer, local_reoffer.get(),
                                         remote_reanswer.get())
                  .ok());
}

TEST_F(JsepTransportControllerTest, RollbackRestoresRejectedTransport) {
  static const char kMid1Audio[] = "1_audio";

  // Perform initial offer/answer.
  CreateJsepTransportController(JsepTransportController::Config());
  auto local_offer = std::make_unique<SessionDescription>();
  AddAudioSection(local_offer.get(), kMid1Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  std::unique_ptr<SessionDescription> remote_answer(local_offer->Clone());
  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, local_offer.get(), nullptr)
          .ok());
  EXPECT_TRUE(transport_controller_
                  ->SetRemoteDescription(SdpType::kAnswer, local_offer.get(),
                                         remote_answer.get())
                  .ok());

  auto mid1_transport = transport_controller_->GetRtpTransport(kMid1Audio);

  // Apply a reoffer which rejects the m= section, causing the transport to be
  // set to null.
  auto local_reoffer = std::make_unique<SessionDescription>();
  AddAudioSection(local_reoffer.get(), kMid1Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  local_reoffer->contents()[0].rejected = true;

  EXPECT_TRUE(transport_controller_
                  ->SetLocalDescription(SdpType::kOffer, local_reoffer.get(),
                                        remote_answer.get())
                  .ok());
  auto old_mid1_transport = mid1_transport;
  mid1_transport = transport_controller_->GetRtpTransport(kMid1Audio);
  EXPECT_EQ(nullptr, mid1_transport);

  // Rolling back shouldn't just create a new transport for MID 1, it should
  // restore the old transport.
  EXPECT_TRUE(transport_controller_->RollbackTransports().ok());
  mid1_transport = transport_controller_->GetRtpTransport(kMid1Audio);
  EXPECT_EQ(old_mid1_transport, mid1_transport);
}

// If an offer with a modified BUNDLE group causes a MID->transport mapping to
// change, rollback should restore the previous mapping.
TEST_F(JsepTransportControllerTest, RollbackRestoresPreviousTransportMapping) {
  static const char kMid1Audio[] = "1_audio";
  static const char kMid2Audio[] = "2_audio";
  static const char kMid3Audio[] = "3_audio";

  // Perform an initial offer/answer to establish a (kMid1Audio,kMid2Audio)
  // group.
  CreateJsepTransportController(JsepTransportController::Config());
  ContentGroup bundle_group(GROUP_TYPE_BUNDLE);
  bundle_group.AddContentName(kMid1Audio);
  bundle_group.AddContentName(kMid2Audio);

  auto local_offer = std::make_unique<SessionDescription>();
  AddAudioSection(local_offer.get(), kMid1Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(local_offer.get(), kMid2Audio, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddAudioSection(local_offer.get(), kMid3Audio, kIceUfrag3, kIcePwd3,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  local_offer->AddGroup(bundle_group);

  std::unique_ptr<SessionDescription> remote_answer(local_offer->Clone());

  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, local_offer.get(), nullptr)
          .ok());
  EXPECT_TRUE(transport_controller_
                  ->SetRemoteDescription(SdpType::kAnswer, local_offer.get(),
                                         remote_answer.get())
                  .ok());

  auto mid1_transport = transport_controller_->GetRtpTransport(kMid1Audio);
  auto mid2_transport = transport_controller_->GetRtpTransport(kMid2Audio);
  auto mid3_transport = transport_controller_->GetRtpTransport(kMid3Audio);
  EXPECT_EQ(mid1_transport, mid2_transport);
  EXPECT_NE(mid1_transport, mid3_transport);

  // Apply a reoffer adding kMid3Audio to the group; transport mapping should
  // change, even without an answer, since this is an existing group.
  bundle_group.AddContentName(kMid3Audio);
  auto local_reoffer = std::make_unique<SessionDescription>();
  AddAudioSection(local_reoffer.get(), kMid1Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(local_reoffer.get(), kMid2Audio, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddAudioSection(local_reoffer.get(), kMid3Audio, kIceUfrag3, kIcePwd3,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  local_reoffer->AddGroup(bundle_group);

  EXPECT_TRUE(transport_controller_
                  ->SetLocalDescription(SdpType::kOffer, local_reoffer.get(),
                                        remote_answer.get())
                  .ok());

  // Store the old transport pointer and verify that the offer actually changed
  // transports.
  auto old_mid3_transport = mid3_transport;
  mid1_transport = transport_controller_->GetRtpTransport(kMid1Audio);
  mid2_transport = transport_controller_->GetRtpTransport(kMid2Audio);
  mid3_transport = transport_controller_->GetRtpTransport(kMid3Audio);
  EXPECT_EQ(mid1_transport, mid2_transport);
  EXPECT_EQ(mid1_transport, mid3_transport);

  // Rolling back shouldn't just create a new transport for MID 3, it should
  // restore the old transport.
  EXPECT_TRUE(transport_controller_->RollbackTransports().ok());
  mid3_transport = transport_controller_->GetRtpTransport(kMid3Audio);
  EXPECT_EQ(old_mid3_transport, mid3_transport);
}

// Test that if an offer adds a MID to a specific BUNDLE group and is then
// rolled back, it can be added to a different BUNDLE group in a new offer.
// This is effectively testing that rollback resets the BundleManager state.
TEST_F(JsepTransportControllerTest, RollbackAndAddToDifferentBundleGroup) {
  static const char kMid1Audio[] = "1_audio";
  static const char kMid2Audio[] = "2_audio";
  static const char kMid3Audio[] = "3_audio";

  // Perform an initial offer/answer to establish two bundle groups, each with
  // one MID.
  CreateJsepTransportController(JsepTransportController::Config());
  ContentGroup bundle_group1(GROUP_TYPE_BUNDLE);
  bundle_group1.AddContentName(kMid1Audio);
  ContentGroup bundle_group2(GROUP_TYPE_BUNDLE);
  bundle_group2.AddContentName(kMid2Audio);

  auto local_offer = std::make_unique<SessionDescription>();
  AddAudioSection(local_offer.get(), kMid1Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(local_offer.get(), kMid2Audio, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  local_offer->AddGroup(bundle_group1);
  local_offer->AddGroup(bundle_group2);

  std::unique_ptr<SessionDescription> remote_answer(local_offer->Clone());

  EXPECT_TRUE(
      transport_controller_
          ->SetLocalDescription(SdpType::kOffer, local_offer.get(), nullptr)
          .ok());
  EXPECT_TRUE(transport_controller_
                  ->SetRemoteDescription(SdpType::kAnswer, local_offer.get(),
                                         remote_answer.get())
                  .ok());

  // Apply an offer that adds kMid3Audio to the first BUNDLE group.,
  ContentGroup modified_bundle_group1(GROUP_TYPE_BUNDLE);
  modified_bundle_group1.AddContentName(kMid1Audio);
  modified_bundle_group1.AddContentName(kMid3Audio);
  auto subsequent_offer_1 = std::make_unique<SessionDescription>();
  AddAudioSection(subsequent_offer_1.get(), kMid1Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(subsequent_offer_1.get(), kMid2Audio, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(subsequent_offer_1.get(), kMid3Audio, kIceUfrag3, kIcePwd3,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  subsequent_offer_1->AddGroup(modified_bundle_group1);
  subsequent_offer_1->AddGroup(bundle_group2);

  EXPECT_TRUE(transport_controller_
                  ->SetLocalDescription(SdpType::kOffer,
                                        subsequent_offer_1.get(),
                                        remote_answer.get())
                  .ok());

  auto mid1_transport = transport_controller_->GetRtpTransport(kMid1Audio);
  auto mid2_transport = transport_controller_->GetRtpTransport(kMid2Audio);
  auto mid3_transport = transport_controller_->GetRtpTransport(kMid3Audio);
  EXPECT_NE(mid1_transport, mid2_transport);
  EXPECT_EQ(mid1_transport, mid3_transport);

  // Rollback and expect the transport to be reset.
  EXPECT_TRUE(transport_controller_->RollbackTransports().ok());
  EXPECT_EQ(nullptr, transport_controller_->GetRtpTransport(kMid3Audio));

  // Apply an offer that adds kMid3Audio to the second BUNDLE group.,
  ContentGroup modified_bundle_group2(GROUP_TYPE_BUNDLE);
  modified_bundle_group2.AddContentName(kMid2Audio);
  modified_bundle_group2.AddContentName(kMid3Audio);
  auto subsequent_offer_2 = std::make_unique<SessionDescription>();
  AddAudioSection(subsequent_offer_2.get(), kMid1Audio, kIceUfrag1, kIcePwd1,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(subsequent_offer_2.get(), kMid2Audio, kIceUfrag2, kIcePwd2,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(subsequent_offer_2.get(), kMid3Audio, kIceUfrag3, kIcePwd3,
                  ICEMODE_FULL, CONNECTIONROLE_ACTPASS, nullptr);
  subsequent_offer_2->AddGroup(bundle_group1);
  subsequent_offer_2->AddGroup(modified_bundle_group2);

  EXPECT_TRUE(transport_controller_
                  ->SetLocalDescription(SdpType::kOffer,
                                        subsequent_offer_2.get(),
                                        remote_answer.get())
                  .ok());

  mid1_transport = transport_controller_->GetRtpTransport(kMid1Audio);
  mid2_transport = transport_controller_->GetRtpTransport(kMid2Audio);
  mid3_transport = transport_controller_->GetRtpTransport(kMid3Audio);
  EXPECT_NE(mid1_transport, mid2_transport);
  EXPECT_EQ(mid2_transport, mid3_transport);
}

// Test that a bundle-only offer without rtcp-mux in the bundle-only section
// is accepted.
TEST_F(JsepTransportControllerTest, BundleOnlySectionDoesNotNeedRtcpMux) {
  CreateJsepTransportController(JsepTransportController::Config());
  ContentGroup bundle_group(GROUP_TYPE_BUNDLE);
  bundle_group.AddContentName(kAudioMid1);
  bundle_group.AddContentName(kVideoMid1);

  auto offer = std::make_unique<SessionDescription>();
  AddAudioSection(offer.get(), kAudioMid1, kIceUfrag1, kIcePwd1, ICEMODE_FULL,
                  CONNECTIONROLE_ACTPASS, nullptr);
  AddVideoSection(offer.get(), kVideoMid1, kIceUfrag1, kIcePwd1, ICEMODE_FULL,
                  CONNECTIONROLE_ACTPASS, nullptr);
  offer->AddGroup(bundle_group);

  // Remove rtcp-mux and set bundle-only on the second content.
  offer->contents()[1].media_description()->set_rtcp_mux(false);
  offer->contents()[1].bundle_only = true;

  EXPECT_TRUE(transport_controller_
                  ->SetRemoteDescription(SdpType::kOffer, nullptr, offer.get())
                  .ok());
}

// Test that with max-bundle a single unbundled m-line is accepted.
TEST_F(JsepTransportControllerTest,
       MaxBundleDoesNotRequireBundleForFirstMline) {
  auto config = JsepTransportController::Config();
  config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle;
  CreateJsepTransportController(std::move(config));

  auto offer = std::make_unique<SessionDescription>();
  AddAudioSection(offer.get(), kAudioMid1, kIceUfrag1, kIcePwd1, ICEMODE_FULL,
                  CONNECTIONROLE_ACTPASS, nullptr);
  EXPECT_TRUE(transport_controller_
                  ->SetRemoteDescription(SdpType::kOffer, nullptr, offer.get())
                  .ok());
}

TEST_F(JsepTransportControllerTest, SuggestPayloadTypeBasic) {
  auto config = JsepTransportController::Config();
  CreateJsepTransportController(std::move(config));
  Codec pcmu_codec = CreateAudioCodec(-1, kPcmuCodecName, 8000, 1);
  RTCErrorOr<PayloadType> pcmu_pt =
      transport_controller_->SuggestPayloadType("mid", pcmu_codec);
  ASSERT_TRUE(pcmu_pt.ok());
  EXPECT_EQ(pcmu_pt.value(), PayloadType(0));
}

TEST_F(JsepTransportControllerTest, SuggestPayloadTypeReusesRemotePayloadType) {
  auto config = JsepTransportController::Config();
  CreateJsepTransportController(std::move(config));
  const PayloadType remote_lyra_pt(99);
  Codec remote_lyra_codec = CreateAudioCodec(remote_lyra_pt, "lyra", 8000, 1);
  auto offer = std::make_unique<SessionDescription>();
  AddAudioSection(offer.get(), kAudioMid1, kIceUfrag1, kIcePwd1, ICEMODE_FULL,
                  CONNECTIONROLE_ACTPASS, nullptr);
  offer->contents()[0].media_description()->set_codecs({remote_lyra_codec});
  EXPECT_TRUE(transport_controller_
                  ->SetRemoteDescription(SdpType::kOffer, nullptr, offer.get())
                  .ok());
  Codec local_lyra_codec = CreateAudioCodec(-1, "lyra", 8000, 1);
  RTCErrorOr<PayloadType> lyra_pt =
      transport_controller_->SuggestPayloadType(kAudioMid1, local_lyra_codec);
  ASSERT_TRUE(lyra_pt.ok());
  EXPECT_EQ(lyra_pt.value(), remote_lyra_pt);
}

TEST_F(JsepTransportControllerTest,
       SuggestPayloadTypeAvoidsRemoteLocalConflict) {
  auto config = JsepTransportController::Config();
  CreateJsepTransportController(std::move(config));
  // libwebrtc will normally allocate 110 to DTMF/48000
  const PayloadType remote_opus_pt(110);
  Codec remote_opus_codec = CreateAudioCodec(remote_opus_pt, "opus", 48000, 2);
  auto offer = std::make_unique<SessionDescription>();
  AddAudioSection(offer.get(), kAudioMid1, kIceUfrag1, kIcePwd1, ICEMODE_FULL,
                  CONNECTIONROLE_ACTPASS, nullptr);
  offer->contents()[0].media_description()->set_codecs({remote_opus_codec});
  EXPECT_TRUE(transport_controller_
                  ->SetRemoteDescription(SdpType::kOffer, nullptr, offer.get())
                  .ok());
  // Check that we get the Opus codec back with the remote PT
  Codec local_opus_codec = CreateAudioCodec(-1, "opus", 48000, 2);
  RTCErrorOr<PayloadType> local_opus_pt =
      transport_controller_->SuggestPayloadType(kAudioMid1, local_opus_codec);
  EXPECT_EQ(local_opus_pt.value(), remote_opus_pt);
  // Check that we don't get 110 allocated for DTMF, since it's in use for opus
  Codec local_other_codec = CreateAudioCodec(-1, kDtmfCodecName, 48000, 1);
  RTCErrorOr<PayloadType> other_pt =
      transport_controller_->SuggestPayloadType(kAudioMid1, local_other_codec);
  ASSERT_TRUE(other_pt.ok());
  EXPECT_NE(other_pt.value(), remote_opus_pt);
}

}  // namespace
}  // namespace webrtc
