/*
 *  Copyright 2012 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 "p2p/base/transport_description_factory.h"

#include <cstddef>
#include <memory>
#include <string>
#include <vector>

#include "absl/strings/string_view.h"
#include "api/field_trials.h"
#include "api/scoped_refptr.h"
#include "p2p/base/ice_credentials_iterator.h"
#include "p2p/base/p2p_constants.h"
#include "p2p/base/transport_description.h"
#include "rtc_base/copy_on_write_buffer.h"
#include "rtc_base/fake_ssl_identity.h"
#include "rtc_base/rtc_certificate.h"
#include "rtc_base/ssl_certificate.h"
#include "rtc_base/ssl_fingerprint.h"
#include "rtc_base/ssl_stream_adapter.h"
#include "test/create_test_field_trials.h"
#include "test/gmock.h"
#include "test/gtest.h"

namespace webrtc {
namespace {

using ::testing::Contains;
using ::testing::Not;
using ::testing::NotNull;

class TransportDescriptionFactoryTest : public ::testing::Test {
 public:
  TransportDescriptionFactoryTest()
      : field_trials_(CreateTestFieldTrials()),
        ice_credentials_({}),
        f1_(field_trials_),
        f2_(field_trials_),
        cert1_(
            RTCCertificate::Create(std::make_unique<FakeSSLIdentity>("User1"))),
        cert2_(RTCCertificate::Create(
            std::make_unique<FakeSSLIdentity>("User2"))) {
    // By default, certificates are supplied.
    f1_.set_certificate(cert1_);
    f2_.set_certificate(cert2_);
  }

  void CheckDesc(const TransportDescription* desc,
                 absl::string_view opt,
                 absl::string_view ice_ufrag,
                 absl::string_view ice_pwd,
                 absl::string_view dtls_alg) {
    ASSERT_TRUE(desc != nullptr);
    EXPECT_EQ(!opt.empty(), desc->HasOption(opt));
    if (ice_ufrag.empty() && ice_pwd.empty()) {
      EXPECT_EQ(static_cast<size_t>(ICE_UFRAG_LENGTH), desc->ice_ufrag.size());
      EXPECT_EQ(static_cast<size_t>(ICE_PWD_LENGTH), desc->ice_pwd.size());
    } else {
      EXPECT_EQ(ice_ufrag, desc->ice_ufrag);
      EXPECT_EQ(ice_pwd, desc->ice_pwd);
    }
    if (dtls_alg.empty()) {
      EXPECT_TRUE(desc->identity_fingerprint.get() == nullptr);
    } else {
      ASSERT_TRUE(desc->identity_fingerprint.get() != nullptr);
      EXPECT_EQ(desc->identity_fingerprint->algorithm, dtls_alg);
      EXPECT_GT(desc->identity_fingerprint->digest.size(), 0U);
    }
  }

  // This test ice restart by doing two offer answer exchanges. On the second
  // exchange ice is restarted. The test verifies that the ufrag and password
  // in the offer and answer is changed.
  // If `dtls` is true, the test verifies that the finger print is not changed.
  void TestIceRestart(bool dtls) {
    if (dtls) {
      f1_.set_certificate(cert1_);
      f2_.set_certificate(cert2_);
    } else {
      SetInsecure();
    }
    TransportOptions options;
    // The initial offer / answer exchange.
    std::unique_ptr<TransportDescription> offer =
        f1_.CreateOffer(options, nullptr, &ice_credentials_);
    std::unique_ptr<TransportDescription> answer = f2_.CreateAnswer(
        offer.get(), options, true, nullptr, &ice_credentials_);

    // Create an updated offer where we restart ice.
    options.ice_restart = true;
    std::unique_ptr<TransportDescription> restart_offer =
        f1_.CreateOffer(options, offer.get(), &ice_credentials_);

    VerifyUfragAndPasswordChanged(dtls, offer.get(), restart_offer.get());

    // Create a new answer. The transport ufrag and password is changed since
    // |options.ice_restart == true|
    std::unique_ptr<TransportDescription> restart_answer = f2_.CreateAnswer(
        restart_offer.get(), options, true, answer.get(), &ice_credentials_);
    ASSERT_TRUE(restart_answer.get() != nullptr);

    VerifyUfragAndPasswordChanged(dtls, answer.get(), restart_answer.get());
  }

  void VerifyUfragAndPasswordChanged(bool dtls,
                                     const TransportDescription* org_desc,
                                     const TransportDescription* restart_desc) {
    ASSERT_THAT(org_desc, NotNull());
    ASSERT_THAT(restart_desc, NotNull());
    EXPECT_NE(org_desc->ice_pwd, restart_desc->ice_pwd);
    EXPECT_NE(org_desc->ice_ufrag, restart_desc->ice_ufrag);
    EXPECT_EQ(static_cast<size_t>(ICE_UFRAG_LENGTH),
              restart_desc->ice_ufrag.size());
    EXPECT_EQ(static_cast<size_t>(ICE_PWD_LENGTH),
              restart_desc->ice_pwd.size());
    // If DTLS is enabled, make sure the finger print is unchanged.
    if (dtls) {
      EXPECT_FALSE(
          org_desc->identity_fingerprint->GetRfc4572Fingerprint().empty());
      EXPECT_EQ(org_desc->identity_fingerprint->GetRfc4572Fingerprint(),
                restart_desc->identity_fingerprint->GetRfc4572Fingerprint());
    }
  }

  void TestIceRenomination(bool dtls) {
    if (!dtls) {
      SetInsecureNoDtls();
    }

    TransportOptions options;
    // The initial offer / answer exchange.
    std::unique_ptr<TransportDescription> offer =
        f1_.CreateOffer(options, nullptr, &ice_credentials_);
    ASSERT_THAT(offer, NotNull());
    EXPECT_THAT(offer->transport_options, Not(Contains("renomination")));

    std::unique_ptr<TransportDescription> answer = f2_.CreateAnswer(
        offer.get(), options, true, nullptr, &ice_credentials_);
    ASSERT_THAT(answer, NotNull());
    EXPECT_THAT(answer->transport_options, Not(Contains("renomination")));

    options.enable_ice_renomination = true;
    std::unique_ptr<TransportDescription> renomination_offer =
        f1_.CreateOffer(options, offer.get(), &ice_credentials_);
    ASSERT_TRUE(renomination_offer);
    EXPECT_THAT(renomination_offer->transport_options,
                Contains("renomination"));

    std::unique_ptr<TransportDescription> renomination_answer =
        f2_.CreateAnswer(renomination_offer.get(), options, true, answer.get(),
                         &ice_credentials_);
    ASSERT_TRUE(renomination_answer);
    EXPECT_THAT(renomination_answer->transport_options,
                Contains("renomination"));
  }

 protected:
  // This will enable responding to non-DTLS requests.
  void SetInsecure() {
    f1_.SetInsecureForTesting();
    f2_.SetInsecureForTesting();
  }
  // This will disable the ability to respond to DTLS requests.
  void SetInsecureNoDtls() {
    SetInsecure();
    f1_.set_certificate(nullptr);
    f2_.set_certificate(nullptr);
  }

  FieldTrials field_trials_;
  IceCredentialsIterator ice_credentials_;
  TransportDescriptionFactory f1_;
  TransportDescriptionFactory f2_;

  scoped_refptr<RTCCertificate> cert1_;
  scoped_refptr<RTCCertificate> cert2_;
};

TEST_F(TransportDescriptionFactoryTest, TestOfferDtls) {
  std::string digest_alg;
  ASSERT_TRUE(
      cert1_->GetSSLCertificate().GetSignatureDigestAlgorithm(&digest_alg));
  std::unique_ptr<TransportDescription> desc =
      f1_.CreateOffer(TransportOptions(), nullptr, &ice_credentials_);
  CheckDesc(desc.get(), "", "", "", digest_alg);
}

// Test generating an offer with DTLS fails with no identity.
TEST_F(TransportDescriptionFactoryTest, TestOfferDtlsWithNoIdentity) {
  f1_.set_certificate(nullptr);
  std::unique_ptr<TransportDescription> desc =
      f1_.CreateOffer(TransportOptions(), nullptr, &ice_credentials_);
  ASSERT_TRUE(desc.get() == nullptr);
}

// Test updating an offer with DTLS to pick ICE.
// The ICE credentials should stay the same in the new offer.
TEST_F(TransportDescriptionFactoryTest, TestOfferDtlsReofferDtls) {
  std::string digest_alg;
  ASSERT_TRUE(
      cert1_->GetSSLCertificate().GetSignatureDigestAlgorithm(&digest_alg));
  std::unique_ptr<TransportDescription> old_desc =
      f1_.CreateOffer(TransportOptions(), nullptr, &ice_credentials_);
  ASSERT_TRUE(old_desc.get() != nullptr);
  std::unique_ptr<TransportDescription> desc =
      f1_.CreateOffer(TransportOptions(), old_desc.get(), &ice_credentials_);
  CheckDesc(desc.get(), "", old_desc->ice_ufrag, old_desc->ice_pwd, digest_alg);
}

TEST_F(TransportDescriptionFactoryTest, TestAnswerDefault) {
  std::string digest_alg;
  ASSERT_TRUE(
      cert1_->GetSSLCertificate().GetSignatureDigestAlgorithm(&digest_alg));
  std::unique_ptr<TransportDescription> offer =
      f1_.CreateOffer(TransportOptions(), nullptr, &ice_credentials_);
  ASSERT_TRUE(offer.get() != nullptr);
  std::unique_ptr<TransportDescription> desc = f2_.CreateAnswer(
      offer.get(), TransportOptions(), true, nullptr, &ice_credentials_);
  CheckDesc(desc.get(), "", "", "", digest_alg);
  desc = f2_.CreateAnswer(offer.get(), TransportOptions(), true, nullptr,
                          &ice_credentials_);
  CheckDesc(desc.get(), "", "", "", digest_alg);
}

// Test that we can update an answer properly; ICE credentials shouldn't change.
TEST_F(TransportDescriptionFactoryTest, TestReanswer) {
  std::string digest_alg;
  ASSERT_TRUE(
      cert1_->GetSSLCertificate().GetSignatureDigestAlgorithm(&digest_alg));
  std::unique_ptr<TransportDescription> offer =
      f1_.CreateOffer(TransportOptions(), nullptr, &ice_credentials_);
  ASSERT_TRUE(offer.get() != nullptr);
  std::unique_ptr<TransportDescription> old_desc = f2_.CreateAnswer(
      offer.get(), TransportOptions(), true, nullptr, &ice_credentials_);
  ASSERT_TRUE(old_desc.get() != nullptr);
  std::unique_ptr<TransportDescription> desc = f2_.CreateAnswer(
      offer.get(), TransportOptions(), true, old_desc.get(), &ice_credentials_);
  ASSERT_TRUE(desc.get() != nullptr);
  CheckDesc(desc.get(), "", old_desc->ice_ufrag, old_desc->ice_pwd, digest_alg);
}

// Test that we handle answering an offer with DTLS with no DTLS.
TEST_F(TransportDescriptionFactoryTest, TestAnswerDtlsToNoDtls) {
  f2_.SetInsecureForTesting();
  f2_.set_certificate(nullptr);
  std::unique_ptr<TransportDescription> offer =
      f1_.CreateOffer(TransportOptions(), nullptr, &ice_credentials_);
  ASSERT_TRUE(offer.get() != nullptr);
  std::unique_ptr<TransportDescription> desc = f2_.CreateAnswer(
      offer.get(), TransportOptions(), true, nullptr, &ice_credentials_);
  CheckDesc(desc.get(), "", "", "", "");
}

// Test that we handle answering an offer without DTLS if we have DTLS enabled,
// but fail if we require DTLS.
TEST_F(TransportDescriptionFactoryTest, TestAnswerNoDtlsToDtls) {
  f1_.SetInsecureForTesting();
  f1_.set_certificate(nullptr);
  std::unique_ptr<TransportDescription> offer =
      f1_.CreateOffer(TransportOptions(), nullptr, &ice_credentials_);
  ASSERT_TRUE(offer.get() != nullptr);
  // Normal case.
  std::unique_ptr<TransportDescription> desc = f2_.CreateAnswer(
      offer.get(), TransportOptions(), true, nullptr, &ice_credentials_);
  ASSERT_TRUE(desc.get() == nullptr);
  // Insecure case.
  f2_.SetInsecureForTesting();
  desc = f2_.CreateAnswer(offer.get(), TransportOptions(), true, nullptr,
                          &ice_credentials_);
  CheckDesc(desc.get(), "", "", "", "");
}

// Test that we handle answering an DTLS offer with DTLS,
// even if we don't require DTLS.
TEST_F(TransportDescriptionFactoryTest, TestAnswerDtlsToDtls) {
  // f2_ produces the answer that is being checked in this test, so the
  // answer must contain fingerprint lines with cert2_'s digest algorithm.
  std::string digest_alg2;
  ASSERT_TRUE(
      cert2_->GetSSLCertificate().GetSignatureDigestAlgorithm(&digest_alg2));

  std::unique_ptr<TransportDescription> offer =
      f1_.CreateOffer(TransportOptions(), nullptr, &ice_credentials_);
  ASSERT_TRUE(offer.get() != nullptr);
  std::unique_ptr<TransportDescription> desc = f2_.CreateAnswer(
      offer.get(), TransportOptions(), true, nullptr, &ice_credentials_);
  CheckDesc(desc.get(), "", "", "", digest_alg2);

  f2_.SetInsecureForTesting();
  desc = f2_.CreateAnswer(offer.get(), TransportOptions(), true, nullptr,
                          &ice_credentials_);
  CheckDesc(desc.get(), "", "", "", digest_alg2);
}

// Test that ice ufrag and password is changed in an updated offer and answer
// if `TransportDescriptionOptions::ice_restart` is true.
TEST_F(TransportDescriptionFactoryTest, TestIceRestart) {
  TestIceRestart(false);
}

// Test that ice ufrag and password is changed in an updated offer and answer
// if `TransportDescriptionOptions::ice_restart` is true and DTLS is enabled.
TEST_F(TransportDescriptionFactoryTest, TestIceRestartWithDtls) {
  TestIceRestart(true);
}

// Test that ice renomination is set in an updated offer and answer
// if `TransportDescriptionOptions::enable_ice_renomination` is true.
TEST_F(TransportDescriptionFactoryTest, TestIceRenomination) {
  TestIceRenomination(false);
}

// Test that ice renomination is set in an updated offer and answer
// if `TransportDescriptionOptions::enable_ice_renomination` is true and DTLS
// is enabled.
TEST_F(TransportDescriptionFactoryTest, TestIceRenominationWithDtls) {
  TestIceRenomination(true);
}

// Test that offers and answers have ice-option:trickle.
TEST_F(TransportDescriptionFactoryTest, AddsTrickleIceOption) {
  TransportOptions options;
  std::unique_ptr<TransportDescription> offer =
      f1_.CreateOffer(options, nullptr, &ice_credentials_);
  ASSERT_THAT(offer, NotNull());
  EXPECT_TRUE(offer->HasOption("trickle"));
  std::unique_ptr<TransportDescription> answer =
      f2_.CreateAnswer(offer.get(), options, true, nullptr, &ice_credentials_);
  EXPECT_TRUE(answer->HasOption("trickle"));
}

TEST_F(TransportDescriptionFactoryTest, AddsGoogSpedV1OptionWhenEnabled) {
  if (!SSLStreamAdapter::IsBoringSsl()) {
    GTEST_SKIP() << "DTLS-in-STUN needs boringssl.";
  }
  FieldTrials field_trials =
      CreateTestFieldTrials("WebRTC-IceHandshakeDtls/Enabled/");
  TransportDescriptionFactory f1(field_trials);
  TransportDescriptionFactory f2(field_trials);
  f1.set_certificate(cert1_);
  f2.set_certificate(cert2_);

  TransportOptions options;
  std::unique_ptr<TransportDescription> offer =
      f1.CreateOffer(options, nullptr, &ice_credentials_);
  ASSERT_THAT(offer, NotNull());
  EXPECT_TRUE(offer->HasOption(ICE_OPTION_GOOG_SPED_V1));

  std::unique_ptr<TransportDescription> answer =
      f2.CreateAnswer(offer.get(), options, true, nullptr, &ice_credentials_);
  ASSERT_THAT(answer, NotNull());
  EXPECT_TRUE(answer->HasOption(ICE_OPTION_GOOG_SPED_V1));
}

TEST_F(TransportDescriptionFactoryTest,
       DoesNotAddGoogSpedV1OptionWhenDisabled) {
  TransportOptions options;
  std::unique_ptr<TransportDescription> offer =
      f1_.CreateOffer(options, nullptr, &ice_credentials_);
  ASSERT_THAT(offer, NotNull());
  EXPECT_FALSE(offer->HasOption(ICE_OPTION_GOOG_SPED_V1));

  std::unique_ptr<TransportDescription> answer =
      f2_.CreateAnswer(offer.get(), options, true, nullptr, &ice_credentials_);
  ASSERT_THAT(answer, NotNull());
  EXPECT_FALSE(answer->HasOption(ICE_OPTION_GOOG_SPED_V1));
}

TEST_F(TransportDescriptionFactoryTest,
       DoesNotAddGoogSpedV1OptionToAnswerIfMissingInOffer) {
  FieldTrials field_trials =
      CreateTestFieldTrials("WebRTC-IceHandshakeDtls/Enabled/");
  TransportDescriptionFactory f2(field_trials);  // Enabled for answer.
  f2.set_certificate(cert2_);

  FieldTrials disabled_trials = CreateTestFieldTrials();  // Disabled for offer.
  TransportDescriptionFactory f1_disabled(disabled_trials);
  f1_disabled.set_certificate(cert1_);

  TransportOptions options;
  std::unique_ptr<TransportDescription> offer =
      f1_disabled.CreateOffer(options, nullptr, &ice_credentials_);
  ASSERT_THAT(offer, NotNull());
  EXPECT_FALSE(offer->HasOption(ICE_OPTION_GOOG_SPED_V1));

  std::unique_ptr<TransportDescription> answer =
      f2.CreateAnswer(offer.get(), options, true, nullptr, &ice_credentials_);
  ASSERT_THAT(answer, NotNull());
  EXPECT_FALSE(answer->HasOption(ICE_OPTION_GOOG_SPED_V1));
}

TEST_F(TransportDescriptionFactoryTest,
       DoesNotAddGoogSpedV1OptionToOfferDuringRenegotiationIfMissingInCurrent) {
  FieldTrials field_trials =
      CreateTestFieldTrials("WebRTC-IceHandshakeDtls/Enabled/");
  TransportDescriptionFactory f1(field_trials);
  f1.set_certificate(cert1_);

  TransportOptions options;

  FieldTrials disabled_trials = CreateTestFieldTrials();
  TransportDescriptionFactory f1_disabled(disabled_trials);
  f1_disabled.set_certificate(cert1_);
  std::unique_ptr<TransportDescription> current_desc =
      f1_disabled.CreateOffer(options, nullptr, &ice_credentials_);
  ASSERT_THAT(current_desc, NotNull());
  ASSERT_FALSE(current_desc->HasOption(ICE_OPTION_GOOG_SPED_V1));

  std::unique_ptr<TransportDescription> new_offer =
      f1.CreateOffer(options, current_desc.get(), &ice_credentials_);
  ASSERT_THAT(new_offer, NotNull());
  EXPECT_FALSE(new_offer->HasOption(ICE_OPTION_GOOG_SPED_V1));
}

TEST_F(
    TransportDescriptionFactoryTest,
    DoesNotAddGoogSpedV1OptionToAnswerDuringRenegotiationIfMissingInCurrent) {
  if (!SSLStreamAdapter::IsBoringSsl()) {
    GTEST_SKIP() << "DTLS-in-STUN needs boringssl.";
  }
  FieldTrials field_trials =
      CreateTestFieldTrials("WebRTC-IceHandshakeDtls/Enabled/");
  TransportDescriptionFactory f1(field_trials);
  TransportDescriptionFactory f2(field_trials);
  f1.set_certificate(cert1_);
  f2.set_certificate(cert2_);

  TransportOptions options;

  std::unique_ptr<TransportDescription> offer =
      f1.CreateOffer(options, nullptr, &ice_credentials_);
  ASSERT_THAT(offer, NotNull());
  ASSERT_TRUE(offer->HasOption(ICE_OPTION_GOOG_SPED_V1));

  FieldTrials disabled_trials = CreateTestFieldTrials();
  TransportDescriptionFactory f2_disabled(disabled_trials);
  f2_disabled.set_certificate(cert2_);
  std::unique_ptr<TransportDescription> current_answer =
      f2_disabled.CreateAnswer(offer.get(), options, true, nullptr,
                               &ice_credentials_);
  ASSERT_THAT(current_answer, NotNull());
  ASSERT_FALSE(current_answer->HasOption(ICE_OPTION_GOOG_SPED_V1));

  std::unique_ptr<TransportDescription> new_answer = f2.CreateAnswer(
      offer.get(), options, true, current_answer.get(), &ice_credentials_);
  ASSERT_THAT(new_answer, NotNull());
  EXPECT_FALSE(new_answer->HasOption(ICE_OPTION_GOOG_SPED_V1));
}

TEST_F(TransportDescriptionFactoryTest, AddsDtlsInStunIceOption) {
  TransportOptions options;
  options.dtls_handshake_in_stun = true;
  std::unique_ptr<TransportDescription> offer =
      f1_.CreateOffer(options, nullptr, &ice_credentials_);
  ASSERT_THAT(offer, NotNull());
  EXPECT_TRUE(offer->HasOption("sped"));
  std::unique_ptr<TransportDescription> answer =
      f2_.CreateAnswer(offer.get(), options, true, nullptr, &ice_credentials_);
  EXPECT_TRUE(answer->HasOption("sped"));

  // An answer only signals the option when the offer did.
  options.dtls_handshake_in_stun = false;
  std::unique_ptr<TransportDescription> offer2 =
      f1_.CreateOffer(options, nullptr, &ice_credentials_);
  ASSERT_THAT(offer2, NotNull());
  EXPECT_FALSE(offer2->HasOption("sped"));
  options.dtls_handshake_in_stun = true;
  std::unique_ptr<TransportDescription> answer2 =
      f2_.CreateAnswer(offer2.get(), options, true, nullptr, &ice_credentials_);
  EXPECT_FALSE(answer2->HasOption("sped"));

  // Nor when the offer did but we are not configured for it.
  options.dtls_handshake_in_stun = true;
  std::unique_ptr<TransportDescription> offer3 =
      f1_.CreateOffer(options, nullptr, &ice_credentials_);
  ASSERT_THAT(offer3, NotNull());
  EXPECT_TRUE(offer3->HasOption("sped"));
  options.dtls_handshake_in_stun = false;
  std::unique_ptr<TransportDescription> answer3 =
      f2_.CreateAnswer(offer3.get(), options, true, nullptr, &ice_credentials_);
  EXPECT_FALSE(answer3->HasOption("sped"));
}

// Test CreateOffer with IceCredentialsIterator.
TEST_F(TransportDescriptionFactoryTest, CreateOfferIceCredentialsIterator) {
  std::vector<IceParameters> credentials = {
      IceParameters("kalle", "anka", false)};
  IceCredentialsIterator credentialsIterator(credentials);
  TransportOptions options;
  std::unique_ptr<TransportDescription> offer =
      f1_.CreateOffer(options, nullptr, &credentialsIterator);
  EXPECT_EQ(offer->GetIceParameters().ufrag, credentials[0].ufrag);
  EXPECT_EQ(offer->GetIceParameters().pwd, credentials[0].pwd);
}

// Test CreateAnswer with IceCredentialsIterator.
TEST_F(TransportDescriptionFactoryTest, CreateAnswerIceCredentialsIterator) {
  TransportOptions options;
  std::unique_ptr<TransportDescription> offer =
      f1_.CreateOffer(options, nullptr, &ice_credentials_);

  std::vector<IceParameters> credentials = {
      IceParameters("kalle", "anka", false)};
  IceCredentialsIterator credentialsIterator(credentials);
  std::unique_ptr<TransportDescription> answer = f1_.CreateAnswer(
      offer.get(), options, false, nullptr, &credentialsIterator);
  EXPECT_EQ(answer->GetIceParameters().ufrag, credentials[0].ufrag);
  EXPECT_EQ(answer->GetIceParameters().pwd, credentials[0].pwd);
}

TEST_F(TransportDescriptionFactoryTest, CreateAnswerToDtlsActpassOffer) {
  TransportOptions options;
  std::unique_ptr<TransportDescription> offer =
      f1_.CreateOffer(options, nullptr, &ice_credentials_);

  std::unique_ptr<TransportDescription> answer =
      f2_.CreateAnswer(offer.get(), options, false, nullptr, &ice_credentials_);
  EXPECT_EQ(answer->connection_role, CONNECTIONROLE_ACTIVE);
}

TEST_F(TransportDescriptionFactoryTest, CreateAnswerToDtlsActiveOffer) {
  TransportOptions options;
  std::unique_ptr<TransportDescription> offer =
      f1_.CreateOffer(options, nullptr, &ice_credentials_);
  offer->connection_role = CONNECTIONROLE_ACTIVE;

  std::unique_ptr<TransportDescription> answer =
      f2_.CreateAnswer(offer.get(), options, false, nullptr, &ice_credentials_);
  EXPECT_EQ(answer->connection_role, CONNECTIONROLE_PASSIVE);
}

TEST_F(TransportDescriptionFactoryTest, CreateAnswerToDtlsPassiveOffer) {
  TransportOptions options;
  std::unique_ptr<TransportDescription> offer =
      f1_.CreateOffer(options, nullptr, &ice_credentials_);
  offer->connection_role = CONNECTIONROLE_PASSIVE;

  std::unique_ptr<TransportDescription> answer =
      f2_.CreateAnswer(offer.get(), options, false, nullptr, &ice_credentials_);
  EXPECT_EQ(answer->connection_role, CONNECTIONROLE_ACTIVE);
}

}  // namespace
}  // namespace webrtc
