1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 #include "base/command_line.h"
7 #include "base/files/file_path.h"
8 #include "chrome/browser/extensions/api/cast_channel/cast_channel_api.h"
9 #include "chrome/browser/extensions/api/cast_channel/cast_socket.h"
10 #include "chrome/browser/extensions/extension_apitest.h"
11 #include "chrome/browser/extensions/extension_service.h"
12 #include "chrome/common/extensions/api/cast_channel.h"
13 #include "content/public/browser/browser_thread.h"
14 #include "extensions/common/switches.h"
15 #include "net/base/capturing_net_log.h"
16 #include "net/base/completion_callback.h"
17 #include "net/base/net_errors.h"
18 #include "testing/gmock/include/gmock/gmock.h"
20 namespace cast_channel = extensions::api::cast_channel;
21 using cast_channel::CastSocket;
22 using cast_channel::ChannelError;
23 using cast_channel::MessageInfo;
24 using cast_channel::ReadyState;
28 using ::testing::Invoke;
29 using ::testing::InSequence;
30 using ::testing::Return;
34 const char kTestExtensionId[] = "ddchlicdkolnonkihahngkmmmjnjlkkf";
36 static void FillMessageInfo(MessageInfo* message_info,
37 const std::string& message) {
38 message_info->namespace_ = "foo";
39 message_info->source_id = "src";
40 message_info->destination_id = "dest";
41 message_info->data.reset(new base::StringValue(message));
44 ACTION_TEMPLATE(InvokeCompletionCallback,
45 HAS_1_TEMPLATE_PARAMS(int, k),
46 AND_1_VALUE_PARAMS(result)) {
47 ::std::tr1::get<k>(args).Run(result);
50 class MockCastSocket : public CastSocket {
52 explicit MockCastSocket(CastSocket::Delegate* delegate,
53 net::IPEndPoint ip_endpoint,
55 : CastSocket(kTestExtensionId, ip_endpoint,
56 cast_channel::CHANNEL_AUTH_TYPE_SSL, delegate, net_log) {}
57 virtual ~MockCastSocket() {}
59 virtual bool CalledOnValidThread() const OVERRIDE {
60 // Always return true in testing.
64 MOCK_METHOD1(Connect, void(const net::CompletionCallback& callback));
65 MOCK_METHOD2(SendMessage, void(const MessageInfo& message,
66 const net::CompletionCallback& callback));
67 MOCK_METHOD1(Close, void(const net::CompletionCallback& callback));
68 MOCK_CONST_METHOD0(ready_state, cast_channel::ReadyState());
69 MOCK_CONST_METHOD0(error_state, cast_channel::ChannelError());
74 class CastChannelAPITest : public ExtensionApiTest {
76 CastChannelAPITest() {}
78 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
79 ExtensionApiTest::SetUpCommandLine(command_line);
80 command_line->AppendSwitchASCII(
81 extensions::switches::kWhitelistedExtensionID,
85 void SetUpMockCastSocket() {
86 extensions::CastChannelAPI* api = GetApi();
87 net::IPAddressNumber ip_number;
88 net::ParseIPLiteralToNumber("192.168.1.1", &ip_number);
89 net::IPEndPoint ip_endpoint(ip_number, 8009);
90 mock_cast_socket_ = new MockCastSocket(api, ip_endpoint,
92 // Transfers ownership of the socket.
93 api->SetSocketForTest(
94 make_scoped_ptr<CastSocket>(mock_cast_socket_).Pass());
96 // Set expectations on error_state().
97 EXPECT_CALL(*mock_cast_socket_, error_state())
98 .WillRepeatedly(Return(cast_channel::CHANNEL_ERROR_NONE));
101 extensions::CastChannelAPI* GetApi() {
102 return extensions::CastChannelAPI::Get(profile());
106 void CallOnMessage(const std::string& message) {
107 content::BrowserThread::PostTask(
108 content::BrowserThread::IO,
110 base::Bind(&CastChannelAPITest::DoCallOnMessage, this,
111 GetApi(), mock_cast_socket_, message));
114 void DoCallOnMessage(extensions::CastChannelAPI* api,
115 MockCastSocket* cast_socket,
116 const std::string& message) {
117 MessageInfo message_info;
118 FillMessageInfo(&message_info, message);
119 api->OnMessage(cast_socket, message_info);
122 MockCastSocket* mock_cast_socket_;
123 net::CapturingNetLog capturing_net_log_;
126 // TODO(munjal): Win Dbg has a workaround that makes RunExtensionSubtest
127 // always return true without actually running the test. Remove when fixed.
128 #if defined(OS_WIN) && !defined(NDEBUG)
129 #define MAYBE_TestOpenSendClose DISABLED_TestOpenSendClose
131 #define MAYBE_TestOpenSendClose TestOpenSendClose
133 // Test loading extension, opening a channel with ConnectInfo, adding a
134 // listener, writing, reading, and closing.
135 IN_PROC_BROWSER_TEST_F(CastChannelAPITest, MAYBE_TestOpenSendClose) {
136 SetUpMockCastSocket();
140 EXPECT_CALL(*mock_cast_socket_, Connect(_))
141 .WillOnce(InvokeCompletionCallback<0>(net::OK));
142 EXPECT_CALL(*mock_cast_socket_, ready_state())
143 .WillOnce(Return(cast_channel::READY_STATE_OPEN));
144 EXPECT_CALL(*mock_cast_socket_, SendMessage(A<const MessageInfo&>(), _))
145 .WillOnce(InvokeCompletionCallback<1>(net::OK));
146 EXPECT_CALL(*mock_cast_socket_, ready_state())
147 .WillOnce(Return(cast_channel::READY_STATE_OPEN));
148 EXPECT_CALL(*mock_cast_socket_, Close(_))
149 .WillOnce(InvokeCompletionCallback<0>(net::OK));
150 EXPECT_CALL(*mock_cast_socket_, ready_state())
151 .WillOnce(Return(cast_channel::READY_STATE_CLOSED));
154 EXPECT_TRUE(RunExtensionSubtest("cast_channel/api",
155 "test_open_send_close.html"));
158 // TODO(munjal): Win Dbg has a workaround that makes RunExtensionSubtest
159 // always return true without actually running the test. Remove when fixed.
160 #if defined(OS_WIN) && !defined(NDEBUG)
161 #define MAYBE_TestOpenSendCloseWithUrl DISABLED_TestOpenSendCloseWithUrl
163 #define MAYBE_TestOpenSendCloseWithUrl TestOpenSendCloseWithUrl
165 // Test loading extension, opening a channel with a URL, adding a listener,
166 // writing, reading, and closing.
167 IN_PROC_BROWSER_TEST_F(CastChannelAPITest, MAYBE_TestOpenSendCloseWithUrl) {
168 SetUpMockCastSocket();
172 EXPECT_CALL(*mock_cast_socket_, Connect(_))
173 .WillOnce(InvokeCompletionCallback<0>(net::OK));
174 EXPECT_CALL(*mock_cast_socket_, ready_state())
175 .WillOnce(Return(cast_channel::READY_STATE_OPEN));
176 EXPECT_CALL(*mock_cast_socket_, SendMessage(A<const MessageInfo&>(), _))
177 .WillOnce(InvokeCompletionCallback<1>(net::OK));
178 EXPECT_CALL(*mock_cast_socket_, ready_state())
179 .WillOnce(Return(cast_channel::READY_STATE_OPEN));
180 EXPECT_CALL(*mock_cast_socket_, Close(_))
181 .WillOnce(InvokeCompletionCallback<0>(net::OK));
182 EXPECT_CALL(*mock_cast_socket_, ready_state())
183 .WillOnce(Return(cast_channel::READY_STATE_CLOSED));
186 EXPECT_TRUE(RunExtensionSubtest("cast_channel/api",
187 "test_open_send_close_url.html"));
190 // TODO(munjal): Win Dbg has a workaround that makes RunExtensionSubtest
191 // always return true without actually running the test. Remove when fixed.
192 #if defined(OS_WIN) && !defined(NDEBUG)
193 #define MAYBE_TestOpenReceiveClose DISABLED_TestOpenReceiveClose
195 #define MAYBE_TestOpenReceiveClose TestOpenReceiveClose
197 // Test loading extension, opening a channel, adding a listener,
198 // writing, reading, and closing.
199 IN_PROC_BROWSER_TEST_F(CastChannelAPITest, MAYBE_TestOpenReceiveClose) {
200 SetUpMockCastSocket();
204 EXPECT_CALL(*mock_cast_socket_, Connect(_))
205 .WillOnce(InvokeCompletionCallback<0>(net::OK));
206 EXPECT_CALL(*mock_cast_socket_, ready_state())
208 .WillRepeatedly(Return(cast_channel::READY_STATE_OPEN));
209 EXPECT_CALL(*mock_cast_socket_, Close(_))
210 .WillOnce(InvokeCompletionCallback<0>(net::OK));
211 EXPECT_CALL(*mock_cast_socket_, ready_state())
212 .WillOnce(Return(cast_channel::READY_STATE_CLOSED));
215 EXPECT_TRUE(RunExtensionSubtest("cast_channel/api",
216 "test_open_receive_close.html"));
218 ResultCatcher catcher;
219 CallOnMessage("some-message");
220 CallOnMessage("some-message");
221 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();