Add test for PR-Answer functionality

Bug: None
Change-Id: I29bf1e40d47361917eb6f52424df23f7697bde0d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/360721
Commit-Queue: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Jonas Oreland <jonaso@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#42859}
diff --git a/pc/peer_connection_integrationtest.cc b/pc/peer_connection_integrationtest.cc
index dbbe9e8..8362c8b 100644
--- a/pc/peer_connection_integrationtest.cc
+++ b/pc/peer_connection_integrationtest.cc
@@ -3872,6 +3872,21 @@
   EXPECT_TRUE_WAIT(NacksReceivedCount(*caller()) > 0, kDefaultTimeout);
 }
 
+TEST_F(PeerConnectionIntegrationTestUnifiedPlan, PrAnswerStateTransitions) {
+  RTCConfiguration config;
+  ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
+  ConnectFakeSignaling();
+  caller()->pc()->AddTransceiver(caller()->CreateLocalAudioTrack());
+  callee()->SetAnswerWithPrAnswer(true);
+  caller()->CreateAndSetAndSignalOffer();
+  ASSERT_FALSE(HasFailure());
+  EXPECT_EQ(caller()->pc()->signaling_state(),
+            PeerConnectionInterface::kHaveRemotePrAnswer);
+  EXPECT_EQ(callee()->pc()->signaling_state(),
+            PeerConnectionInterface::kHaveLocalPrAnswer);
+  // Note: there should be code here for applying the permanent answer.
+}
+
 }  // namespace
 
 }  // namespace webrtc
diff --git a/pc/test/integration_test_helpers.h b/pc/test/integration_test_helpers.h
index dbce979..458aa3a 100644
--- a/pc/test/integration_test_helpers.h
+++ b/pc/test/integration_test_helpers.h
@@ -455,6 +455,10 @@
     return data_observers_;
   }
 
+  std::unique_ptr<SessionDescriptionInterface> CreateAnswerForTest() {
+    return CreateAnswer();
+  }
+
   int audio_frames_received() const {
     return fake_audio_capture_module_->frames_received();
   }
@@ -654,6 +658,10 @@
     candidates_expected_ = candidate_count;
   }
 
+  // For testing PR-Answer functionality
+  // If true, an offer will get a pr-answer back.
+  void SetAnswerWithPrAnswer(bool value) { answer_with_pr_answer_ = value; }
+
  private:
   // Constructor used by friend class PeerConnectionIntegrationBaseTest.
   explicit PeerConnectionIntegrationWrapper(const std::string& debug_name)
@@ -740,13 +748,19 @@
     }
     auto answer = CreateAnswer();
     ASSERT_NE(nullptr, answer);
+    if (answer_with_pr_answer_) {
+      std::string answer_string;
+      answer->ToString(&answer_string);
+      answer = CreateSessionDescription(SdpType::kPrAnswer, answer_string);
+    }
     EXPECT_TRUE(SetLocalDescriptionAndSendSdpMessage(std::move(answer)));
   }
 
-  void HandleIncomingAnswer(const std::string& msg) {
-    RTC_LOG(LS_INFO) << debug_name_ << ": HandleIncomingAnswer";
+  void HandleIncomingAnswer(SdpType type, const std::string& msg) {
+    RTC_LOG(LS_INFO) << debug_name_ << ": HandleIncomingAnswer of type "
+                     << SdpTypeToString(type);
     std::unique_ptr<SessionDescriptionInterface> desc =
-        CreateSessionDescription(SdpType::kAnswer, msg);
+        CreateSessionDescription(type, msg);
     if (received_sdp_munger_) {
       received_sdp_munger_(desc->description());
     }
@@ -888,7 +902,7 @@
     if (type == SdpType::kOffer) {
       HandleIncomingOffer(msg);
     } else {
-      HandleIncomingAnswer(msg);
+      HandleIncomingAnswer(type, msg);
     }
   }
 
@@ -1083,6 +1097,8 @@
   uint64_t audio_concealed_stat_ = 0;
   std::string rtp_stats_id_;
 
+  bool answer_with_pr_answer_ = false;
+
   ScopedTaskSafety task_safety_;
 
   friend class PeerConnectionIntegrationBaseTest;