| // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "base/memory/scoped_ptr.h" |
| #include "base/message_loop/message_loop.h" |
| #include "base/values.h" |
| #include "content/browser/media/webrtc_internals.h" |
| #include "content/browser/media/webrtc_internals_ui_observer.h" |
| #include "content/public/test/test_browser_thread.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace content { |
| |
| namespace { |
| |
| static const std::string kContraints = "c"; |
| static const std::string kRtcConfiguration = "r"; |
| static const std::string kUrl = "u"; |
| |
| class MockWebRtcInternalsProxy : public WebRTCInternalsUIObserver { |
| public: |
| void OnUpdate(const std::string& command, const base::Value* value) override { |
| command_ = command; |
| if (value) |
| value_.reset(value->DeepCopy()); |
| } |
| |
| std::string command() { |
| return command_; |
| } |
| |
| base::Value* value() { |
| return value_.get(); |
| } |
| |
| private: |
| std::string command_; |
| scoped_ptr<base::Value> value_; |
| }; |
| |
| class WebRtcInternalsTest : public testing::Test { |
| public: |
| WebRtcInternalsTest() : io_thread_(BrowserThread::UI, &io_loop_) { |
| WebRTCInternals::GetInstance()->ResetForTesting(); |
| } |
| |
| protected: |
| void VerifyString(const base::DictionaryValue* dict, |
| const std::string& key, |
| const std::string& expected) { |
| std::string actual; |
| EXPECT_TRUE(dict->GetString(key, &actual)); |
| EXPECT_EQ(expected, actual); |
| } |
| |
| void VerifyInt(const base::DictionaryValue* dict, |
| const std::string& key, |
| int expected) { |
| int actual; |
| EXPECT_TRUE(dict->GetInteger(key, &actual)); |
| EXPECT_EQ(expected, actual); |
| } |
| |
| void VerifyList(const base::DictionaryValue* dict, |
| const std::string& key, |
| const base::ListValue& expected) { |
| const base::ListValue* actual = NULL; |
| EXPECT_TRUE(dict->GetList(key, &actual)); |
| EXPECT_TRUE(expected.Equals(actual)); |
| } |
| |
| void VerifyGetUserMediaData(base::Value* actual_data, |
| int rid, |
| int pid, |
| const std::string& origin, |
| const std::string& audio, |
| const std::string& video) { |
| base::DictionaryValue* dict = NULL; |
| EXPECT_TRUE(actual_data->GetAsDictionary(&dict)); |
| |
| VerifyInt(dict, "rid", rid); |
| VerifyInt(dict, "pid", pid); |
| VerifyString(dict, "origin", origin); |
| VerifyString(dict, "audio", audio); |
| VerifyString(dict, "video", video); |
| } |
| |
| base::MessageLoop io_loop_; |
| TestBrowserThread io_thread_; |
| }; |
| |
| } // namespace |
| |
| TEST_F(WebRtcInternalsTest, AddRemoveObserver) { |
| scoped_ptr<MockWebRtcInternalsProxy> observer( |
| new MockWebRtcInternalsProxy()); |
| WebRTCInternals::GetInstance()->AddObserver(observer.get()); |
| WebRTCInternals::GetInstance()->RemoveObserver(observer.get()); |
| WebRTCInternals::GetInstance()->OnAddPeerConnection( |
| 0, 3, 4, kUrl, kRtcConfiguration, kContraints); |
| EXPECT_EQ("", observer->command()); |
| |
| WebRTCInternals::GetInstance()->OnRemovePeerConnection(3, 4); |
| } |
| |
| TEST_F(WebRtcInternalsTest, SendAddPeerConnectionUpdate) { |
| scoped_ptr<MockWebRtcInternalsProxy> observer( |
| new MockWebRtcInternalsProxy()); |
| WebRTCInternals::GetInstance()->AddObserver(observer.get()); |
| WebRTCInternals::GetInstance()->OnAddPeerConnection( |
| 0, 1, 2, kUrl, kRtcConfiguration, kContraints); |
| EXPECT_EQ("addPeerConnection", observer->command()); |
| |
| base::DictionaryValue* dict = NULL; |
| EXPECT_TRUE(observer->value()->GetAsDictionary(&dict)); |
| |
| VerifyInt(dict, "pid", 1); |
| VerifyInt(dict, "lid", 2); |
| VerifyString(dict, "url", kUrl); |
| VerifyString(dict, "rtcConfiguration", kRtcConfiguration); |
| VerifyString(dict, "constraints", kContraints); |
| |
| WebRTCInternals::GetInstance()->RemoveObserver(observer.get()); |
| WebRTCInternals::GetInstance()->OnRemovePeerConnection(1, 2); |
| } |
| |
| TEST_F(WebRtcInternalsTest, SendRemovePeerConnectionUpdate) { |
| scoped_ptr<MockWebRtcInternalsProxy> observer( |
| new MockWebRtcInternalsProxy()); |
| WebRTCInternals::GetInstance()->AddObserver(observer.get()); |
| WebRTCInternals::GetInstance()->OnAddPeerConnection( |
| 0, 1, 2, kUrl, kRtcConfiguration, kContraints); |
| WebRTCInternals::GetInstance()->OnRemovePeerConnection(1, 2); |
| EXPECT_EQ("removePeerConnection", observer->command()); |
| |
| base::DictionaryValue* dict = NULL; |
| EXPECT_TRUE(observer->value()->GetAsDictionary(&dict)); |
| |
| VerifyInt(dict, "pid", 1); |
| VerifyInt(dict, "lid", 2); |
| |
| WebRTCInternals::GetInstance()->RemoveObserver(observer.get()); |
| } |
| |
| TEST_F(WebRtcInternalsTest, SendUpdatePeerConnectionUpdate) { |
| scoped_ptr<MockWebRtcInternalsProxy> observer( |
| new MockWebRtcInternalsProxy()); |
| WebRTCInternals::GetInstance()->AddObserver(observer.get()); |
| WebRTCInternals::GetInstance()->OnAddPeerConnection( |
| 0, 1, 2, kUrl, kRtcConfiguration, kContraints); |
| |
| const std::string update_type = "fakeType"; |
| const std::string update_value = "fakeValue"; |
| WebRTCInternals::GetInstance()->OnUpdatePeerConnection( |
| 1, 2, update_type, update_value); |
| |
| EXPECT_EQ("updatePeerConnection", observer->command()); |
| |
| base::DictionaryValue* dict = NULL; |
| EXPECT_TRUE(observer->value()->GetAsDictionary(&dict)); |
| |
| VerifyInt(dict, "pid", 1); |
| VerifyInt(dict, "lid", 2); |
| VerifyString(dict, "type", update_type); |
| VerifyString(dict, "value", update_value); |
| |
| std::string time; |
| EXPECT_TRUE(dict->GetString("time", &time)); |
| EXPECT_FALSE(time.empty()); |
| |
| WebRTCInternals::GetInstance()->OnRemovePeerConnection(1, 2); |
| WebRTCInternals::GetInstance()->RemoveObserver(observer.get()); |
| } |
| |
| TEST_F(WebRtcInternalsTest, AddGetUserMedia) { |
| scoped_ptr<MockWebRtcInternalsProxy> observer(new MockWebRtcInternalsProxy()); |
| |
| // Add one observer before "getUserMedia". |
| WebRTCInternals::GetInstance()->AddObserver(observer.get()); |
| |
| const int rid = 1; |
| const int pid = 2; |
| const std::string audio_constraint = "aaa"; |
| const std::string video_constraint = "vvv"; |
| WebRTCInternals::GetInstance()->OnGetUserMedia( |
| rid, pid, kUrl, true, true, audio_constraint, video_constraint); |
| |
| EXPECT_EQ("addGetUserMedia", observer->command()); |
| VerifyGetUserMediaData( |
| observer->value(), rid, pid, kUrl, audio_constraint, video_constraint); |
| |
| WebRTCInternals::GetInstance()->RemoveObserver(observer.get()); |
| } |
| |
| TEST_F(WebRtcInternalsTest, SendAllUpdateWithGetUserMedia) { |
| const int rid = 1; |
| const int pid = 2; |
| const std::string audio_constraint = "aaa"; |
| const std::string video_constraint = "vvv"; |
| WebRTCInternals::GetInstance()->OnGetUserMedia( |
| rid, pid, kUrl, true, true, audio_constraint, video_constraint); |
| |
| scoped_ptr<MockWebRtcInternalsProxy> observer(new MockWebRtcInternalsProxy()); |
| // Add one observer after "getUserMedia". |
| WebRTCInternals::GetInstance()->AddObserver(observer.get()); |
| WebRTCInternals::GetInstance()->UpdateObserver(observer.get()); |
| |
| EXPECT_EQ("addGetUserMedia", observer->command()); |
| VerifyGetUserMediaData( |
| observer->value(), rid, pid, kUrl, audio_constraint, video_constraint); |
| |
| WebRTCInternals::GetInstance()->RemoveObserver(observer.get()); |
| } |
| |
| TEST_F(WebRtcInternalsTest, SendAllUpdatesWithPeerConnectionUpdate) { |
| const int rid = 0, pid = 1, lid = 2; |
| const std::string update_type = "fakeType"; |
| const std::string update_value = "fakeValue"; |
| |
| WebRTCInternals::GetInstance()->OnAddPeerConnection( |
| rid, pid, lid, kUrl, kRtcConfiguration, kContraints); |
| WebRTCInternals::GetInstance()->OnUpdatePeerConnection( |
| pid, lid, update_type, update_value); |
| |
| scoped_ptr<MockWebRtcInternalsProxy> observer(new MockWebRtcInternalsProxy()); |
| WebRTCInternals::GetInstance()->AddObserver(observer.get()); |
| |
| WebRTCInternals::GetInstance()->UpdateObserver(observer.get()); |
| |
| EXPECT_EQ("updateAllPeerConnections", observer->command()); |
| |
| base::ListValue* list = NULL; |
| EXPECT_TRUE(observer->value()->GetAsList(&list)); |
| EXPECT_EQ(1U, list->GetSize()); |
| |
| base::DictionaryValue* dict = NULL; |
| EXPECT_TRUE((*list->begin())->GetAsDictionary(&dict)); |
| |
| VerifyInt(dict, "rid", rid); |
| VerifyInt(dict, "pid", pid); |
| VerifyInt(dict, "lid", lid); |
| VerifyString(dict, "url", kUrl); |
| VerifyString(dict, "rtcConfiguration", kRtcConfiguration); |
| VerifyString(dict, "constraints", kContraints); |
| |
| base::ListValue* log = NULL; |
| EXPECT_TRUE(dict->GetList("log", &log)); |
| EXPECT_EQ(1U, log->GetSize()); |
| |
| EXPECT_TRUE((*log->begin())->GetAsDictionary(&dict)); |
| VerifyString(dict, "type", update_type); |
| VerifyString(dict, "value", update_value); |
| std::string time; |
| EXPECT_TRUE(dict->GetString("time", &time)); |
| EXPECT_FALSE(time.empty()); |
| } |
| |
| TEST_F(WebRtcInternalsTest, OnAddStats) { |
| const int rid = 0, pid = 1, lid = 2; |
| scoped_ptr<MockWebRtcInternalsProxy> observer(new MockWebRtcInternalsProxy()); |
| WebRTCInternals::GetInstance()->AddObserver(observer.get()); |
| WebRTCInternals::GetInstance()->OnAddPeerConnection( |
| rid, pid, lid, kUrl, kRtcConfiguration, kContraints); |
| |
| base::ListValue list; |
| list.AppendString("xxx"); |
| list.AppendString("yyy"); |
| WebRTCInternals::GetInstance()->OnAddStats(pid, lid, list); |
| |
| EXPECT_EQ("addStats", observer->command()); |
| base::DictionaryValue* dict = NULL; |
| EXPECT_TRUE(observer->value()->GetAsDictionary(&dict)); |
| |
| VerifyInt(dict, "pid", pid); |
| VerifyInt(dict, "lid", lid); |
| VerifyList(dict, "reports", list); |
| } |
| |
| TEST_F(WebRtcInternalsTest, AudioDebugRecordingsFileSelectionCanceled) { |
| scoped_ptr<MockWebRtcInternalsProxy> observer(new MockWebRtcInternalsProxy()); |
| WebRTCInternals::GetInstance()->AddObserver(observer.get()); |
| WebRTCInternals::GetInstance()->FileSelectionCanceled(NULL); |
| EXPECT_EQ("audioDebugRecordingsFileSelectionCancelled", observer->command()); |
| EXPECT_EQ(NULL, observer->value()); |
| } |
| |
| } // namespace content |