Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / extensions / browser / api / cast_channel / cast_channel_apitest.cc
1 // Copyright 2014 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.
4
5 #include "base/bind.h"
6 #include "base/command_line.h"
7 #include "base/files/file_path.h"
8 #include "chrome/browser/extensions/extension_apitest.h"
9 #include "chrome/browser/extensions/extension_function_test_utils.h"
10 #include "chrome/browser/extensions/extension_service.h"
11 #include "chrome/browser/ui/browser.h"
12 #include "content/public/browser/browser_thread.h"
13 #include "extensions/browser/api/cast_channel/cast_channel_api.h"
14 #include "extensions/browser/api/cast_channel/cast_socket.h"
15 #include "extensions/browser/api/cast_channel/logger.h"
16 #include "extensions/common/api/cast_channel.h"
17 #include "extensions/common/switches.h"
18 #include "extensions/common/test_util.h"
19 #include "extensions/test/result_catcher.h"
20 #include "net/base/capturing_net_log.h"
21 #include "net/base/completion_callback.h"
22 #include "net/base/net_errors.h"
23 #include "testing/gmock/include/gmock/gmock.h"
24 #include "testing/gmock_mutant.h"
25
26 // TODO(mfoltz): Mock out the ApiResourceManager to resolve threading issues
27 // (crbug.com/398242) and simulate unloading of the extension.
28
29 namespace cast_channel = extensions::core_api::cast_channel;
30 using cast_channel::CastSocket;
31 using cast_channel::ChannelError;
32 using cast_channel::ErrorInfo;
33 using cast_channel::Logger;
34 using cast_channel::MessageInfo;
35 using cast_channel::ReadyState;
36 using extensions::Extension;
37
38 namespace utils = extension_function_test_utils;
39
40 using ::testing::_;
41 using ::testing::A;
42 using ::testing::DoAll;
43 using ::testing::Invoke;
44 using ::testing::InSequence;
45 using ::testing::Return;
46
47 namespace {
48
49 const char kTestExtensionId[] = "ddchlicdkolnonkihahngkmmmjnjlkkf";
50 const int64 kTimeoutMs = 10000;
51
52 static void FillMessageInfo(MessageInfo* message_info,
53                             const std::string& message) {
54   message_info->namespace_ = "foo";
55   message_info->source_id = "src";
56   message_info->destination_id = "dest";
57   message_info->data.reset(new base::StringValue(message));
58 }
59
60 ACTION_TEMPLATE(InvokeCompletionCallback,
61                 HAS_1_TEMPLATE_PARAMS(int, k),
62                 AND_1_VALUE_PARAMS(result)) {
63   ::std::tr1::get<k>(args).Run(result);
64 }
65
66 ACTION_P2(InvokeDelegateOnError, api_test, api) {
67   api_test->CallOnError(api);
68 }
69
70 class MockCastSocket : public CastSocket {
71  public:
72   explicit MockCastSocket(CastSocket::Delegate* delegate,
73                           net::IPEndPoint ip_endpoint,
74                           net::NetLog* net_log,
75                           const scoped_refptr<Logger>& logger)
76       : CastSocket(kTestExtensionId,
77                    ip_endpoint,
78                    cast_channel::CHANNEL_AUTH_TYPE_SSL,
79                    delegate,
80                    net_log,
81                    base::TimeDelta::FromMilliseconds(kTimeoutMs),
82                    logger) {}
83   virtual ~MockCastSocket() {}
84
85   MOCK_METHOD1(Connect, void(const net::CompletionCallback& callback));
86   MOCK_METHOD2(SendMessage, void(const MessageInfo& message,
87                                  const net::CompletionCallback& callback));
88   MOCK_METHOD1(Close, void(const net::CompletionCallback& callback));
89   MOCK_CONST_METHOD0(ready_state, cast_channel::ReadyState());
90   MOCK_CONST_METHOD0(error_state, cast_channel::ChannelError());
91 };
92
93 }  // namespace
94
95 class CastChannelAPITest : public ExtensionApiTest {
96  public:
97   CastChannelAPITest() {}
98
99   void SetUpCommandLine(CommandLine* command_line) override {
100     ExtensionApiTest::SetUpCommandLine(command_line);
101     command_line->AppendSwitchASCII(
102         extensions::switches::kWhitelistedExtensionID,
103         kTestExtensionId);
104   }
105
106   void SetUpMockCastSocket() {
107     extensions::CastChannelAPI* api = GetApi();
108     net::IPAddressNumber ip_number;
109     net::ParseIPLiteralToNumber("192.168.1.1", &ip_number);
110     net::IPEndPoint ip_endpoint(ip_number, 8009);
111     mock_cast_socket_ = new MockCastSocket(
112         api, ip_endpoint, &capturing_net_log_, api->GetLogger());
113     // Transfers ownership of the socket.
114     api->SetSocketForTest(
115         make_scoped_ptr<CastSocket>(mock_cast_socket_).Pass());
116   }
117
118   void SetUpOpenSendClose() {
119     SetUpMockCastSocket();
120     EXPECT_CALL(*mock_cast_socket_, error_state())
121         .WillRepeatedly(Return(cast_channel::CHANNEL_ERROR_NONE));
122     {
123       InSequence sequence;
124       EXPECT_CALL(*mock_cast_socket_, Connect(_))
125           .WillOnce(InvokeCompletionCallback<0>(net::OK));
126       EXPECT_CALL(*mock_cast_socket_, ready_state())
127           .WillOnce(Return(cast_channel::READY_STATE_OPEN));
128       EXPECT_CALL(*mock_cast_socket_, SendMessage(A<const MessageInfo&>(), _))
129           .WillOnce(InvokeCompletionCallback<1>(net::OK));
130       EXPECT_CALL(*mock_cast_socket_, ready_state())
131           .WillOnce(Return(cast_channel::READY_STATE_OPEN));
132       EXPECT_CALL(*mock_cast_socket_, Close(_))
133           .WillOnce(InvokeCompletionCallback<0>(net::OK));
134       EXPECT_CALL(*mock_cast_socket_, ready_state())
135           .WillOnce(Return(cast_channel::READY_STATE_CLOSED));
136     }
137   }
138
139   extensions::CastChannelAPI* GetApi() {
140     return extensions::CastChannelAPI::Get(profile());
141   }
142
143   void CallOnError(extensions::CastChannelAPI* api) {
144     cast_channel::LastErrors last_errors;
145     last_errors.challenge_reply_error_type =
146         cast_channel::proto::CHALLENGE_REPLY_ERROR_CERT_PARSING_FAILED;
147     last_errors.nss_error_code = -8164;
148     api->OnError(mock_cast_socket_,
149                  cast_channel::CHANNEL_ERROR_CONNECT_ERROR,
150                  last_errors);
151   }
152
153  protected:
154   void CallOnMessage(const std::string& message) {
155     content::BrowserThread::PostTask(
156         content::BrowserThread::IO,
157         FROM_HERE,
158         base::Bind(&CastChannelAPITest::DoCallOnMessage, this,
159                    GetApi(), mock_cast_socket_, message));
160   }
161
162   void DoCallOnMessage(extensions::CastChannelAPI* api,
163                        MockCastSocket* cast_socket,
164                        const std::string& message) {
165     MessageInfo message_info;
166     FillMessageInfo(&message_info, message);
167     api->OnMessage(cast_socket, message_info);
168   }
169
170   extensions::CastChannelOpenFunction* CreateOpenFunction(
171         scoped_refptr<Extension> extension) {
172     extensions::CastChannelOpenFunction* cast_channel_open_function =
173       new extensions::CastChannelOpenFunction;
174     cast_channel_open_function->set_extension(extension.get());
175     return cast_channel_open_function;
176   }
177
178   extensions::CastChannelSendFunction* CreateSendFunction(
179         scoped_refptr<Extension> extension) {
180     extensions::CastChannelSendFunction* cast_channel_send_function =
181       new extensions::CastChannelSendFunction;
182     cast_channel_send_function->set_extension(extension.get());
183     return cast_channel_send_function;
184   }
185
186   extensions::CastChannelSetAuthorityKeysFunction*
187   CreateSetAuthorityKeysFunction(scoped_refptr<Extension> extension) {
188     extensions::CastChannelSetAuthorityKeysFunction*
189         cast_channel_set_authority_keys_function =
190             new extensions::CastChannelSetAuthorityKeysFunction;
191     cast_channel_set_authority_keys_function->set_extension(extension.get());
192     return cast_channel_set_authority_keys_function;
193   }
194
195   MockCastSocket* mock_cast_socket_;
196   net::CapturingNetLog capturing_net_log_;
197 };
198
199 // TODO(munjal): Win Dbg has a workaround that makes RunExtensionSubtest
200 // always return true without actually running the test. Remove when fixed.
201 #if defined(OS_WIN) && !defined(NDEBUG)
202 #define MAYBE_TestOpenSendClose DISABLED_TestOpenSendClose
203 #else
204 #define MAYBE_TestOpenSendClose TestOpenSendClose
205 #endif
206 // Test loading extension, opening a channel with ConnectInfo, adding a
207 // listener, writing, reading, and closing.
208 IN_PROC_BROWSER_TEST_F(CastChannelAPITest, MAYBE_TestOpenSendClose) {
209   SetUpOpenSendClose();
210
211   EXPECT_TRUE(RunExtensionSubtest("cast_channel/api",
212                                   "test_open_send_close.html"));
213 }
214
215 // TODO(munjal): Win Dbg has a workaround that makes RunExtensionSubtest
216 // always return true without actually running the test. Remove when fixed.
217 #if defined(OS_WIN) && !defined(NDEBUG)
218 #define MAYBE_TestOpenSendCloseWithUrl DISABLED_TestOpenSendCloseWithUrl
219 #else
220 #define MAYBE_TestOpenSendCloseWithUrl TestOpenSendCloseWithUrl
221 #endif
222 // Test loading extension, opening a channel with a URL, adding a listener,
223 // writing, reading, and closing.
224 IN_PROC_BROWSER_TEST_F(CastChannelAPITest, MAYBE_TestOpenSendCloseWithUrl) {
225   SetUpOpenSendClose();
226
227   EXPECT_TRUE(RunExtensionSubtest("cast_channel/api",
228                                   "test_open_send_close_url.html"));
229 }
230
231 // TODO(munjal): Win Dbg has a workaround that makes RunExtensionSubtest
232 // always return true without actually running the test. Remove when fixed.
233 #if defined(OS_WIN) && !defined(NDEBUG)
234 #define MAYBE_TestOpenReceiveClose DISABLED_TestOpenReceiveClose
235 #else
236 #define MAYBE_TestOpenReceiveClose TestOpenReceiveClose
237 #endif
238 // Test loading extension, opening a channel, adding a listener,
239 // writing, reading, and closing.
240 IN_PROC_BROWSER_TEST_F(CastChannelAPITest, MAYBE_TestOpenReceiveClose) {
241   SetUpMockCastSocket();
242   EXPECT_CALL(*mock_cast_socket_, error_state())
243       .WillRepeatedly(Return(cast_channel::CHANNEL_ERROR_NONE));
244
245   {
246     InSequence sequence;
247     EXPECT_CALL(*mock_cast_socket_, Connect(_))
248         .WillOnce(InvokeCompletionCallback<0>(net::OK));
249     EXPECT_CALL(*mock_cast_socket_, ready_state())
250         .Times(3)
251         .WillRepeatedly(Return(cast_channel::READY_STATE_OPEN));
252     EXPECT_CALL(*mock_cast_socket_, Close(_))
253         .WillOnce(InvokeCompletionCallback<0>(net::OK));
254     EXPECT_CALL(*mock_cast_socket_, ready_state())
255         .WillOnce(Return(cast_channel::READY_STATE_CLOSED));
256   }
257
258   EXPECT_TRUE(RunExtensionSubtest("cast_channel/api",
259                                   "test_open_receive_close.html"));
260
261   extensions::ResultCatcher catcher;
262   CallOnMessage("some-message");
263   CallOnMessage("some-message");
264   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
265 }
266
267 // TODO(imcheng): Win Dbg has a workaround that makes RunExtensionSubtest
268 // always return true without actually running the test. Remove when fixed.
269 #if defined(OS_WIN) && !defined(NDEBUG)
270 #define MAYBE_TestGetLogs DISABLED_TestGetLogs
271 #else
272 #define MAYBE_TestGetLogs TestGetLogs
273 #endif
274 // Test loading extension, execute a open-send-close sequence, then get logs.
275 IN_PROC_BROWSER_TEST_F(CastChannelAPITest, MAYBE_TestGetLogs) {
276   SetUpOpenSendClose();
277
278   EXPECT_TRUE(RunExtensionSubtest("cast_channel/api", "test_get_logs.html"));
279 }
280
281 // TODO(munjal): Win Dbg has a workaround that makes RunExtensionSubtest
282 // always return true without actually running the test. Remove when fixed.
283 #if defined(OS_WIN) && !defined(NDEBUG)
284 #define MAYBE_TestOpenError DISABLED_TestOpenError
285 #else
286 #define MAYBE_TestOpenError TestOpenError
287 #endif
288 // Test the case when socket open results in an error.
289 IN_PROC_BROWSER_TEST_F(CastChannelAPITest, MAYBE_TestOpenError) {
290   SetUpMockCastSocket();
291
292   EXPECT_CALL(*mock_cast_socket_, Connect(_))
293       .WillOnce(DoAll(InvokeDelegateOnError(this, GetApi()),
294                       InvokeCompletionCallback<0>(net::ERR_CONNECTION_FAILED)));
295   EXPECT_CALL(*mock_cast_socket_, error_state())
296       .WillRepeatedly(Return(cast_channel::CHANNEL_ERROR_CONNECT_ERROR));
297   EXPECT_CALL(*mock_cast_socket_, ready_state())
298       .WillRepeatedly(Return(cast_channel::READY_STATE_CLOSED));
299   EXPECT_CALL(*mock_cast_socket_, Close(_))
300       .WillOnce(InvokeCompletionCallback<0>(net::OK));
301
302   EXPECT_TRUE(RunExtensionSubtest("cast_channel/api",
303                                   "test_open_error.html"));
304 }
305
306 IN_PROC_BROWSER_TEST_F(CastChannelAPITest, TestOpenInvalidConnectInfo) {
307   scoped_refptr<Extension> empty_extension =
308       extensions::test_util::CreateEmptyExtension();
309   scoped_refptr<extensions::CastChannelOpenFunction> cast_channel_open_function;
310
311   // Invalid URL
312   // TODO(mfoltz): Remove this test case when fixing crbug.com/331905
313   cast_channel_open_function = CreateOpenFunction(empty_extension);
314   std::string error(utils::RunFunctionAndReturnError(
315       cast_channel_open_function.get(), "[\"blargh\"]", browser()));
316   EXPECT_EQ(error, "Invalid connect_info (invalid Cast URL blargh)");
317
318   // Wrong type
319   // TODO(mfoltz): Remove this test case when fixing crbug.com/331905
320   cast_channel_open_function = CreateOpenFunction(empty_extension);
321   error = utils::RunFunctionAndReturnError(
322       cast_channel_open_function.get(),
323       "[123]", browser());
324   EXPECT_EQ(error, "Invalid connect_info (unknown type)");
325
326   // Invalid IP address
327   cast_channel_open_function = CreateOpenFunction(empty_extension);
328   error = utils::RunFunctionAndReturnError(
329       cast_channel_open_function.get(),
330       "[{\"ipAddress\": \"invalid_ip\", \"port\": 8009, \"auth\": \"ssl\"}]",
331       browser());
332   EXPECT_EQ(error, "Invalid connect_info (invalid IP address)");
333
334   // Invalid port
335   cast_channel_open_function = CreateOpenFunction(empty_extension);
336   error = utils::RunFunctionAndReturnError(
337       cast_channel_open_function.get(),
338       "[{\"ipAddress\": \"127.0.0.1\", \"port\": -200, \"auth\": \"ssl\"}]",
339       browser());
340   EXPECT_EQ(error, "Invalid connect_info (invalid port)");
341
342   // Auth not set
343   cast_channel_open_function = CreateOpenFunction(empty_extension);
344   error = utils::RunFunctionAndReturnError(
345       cast_channel_open_function.get(),
346       "[{\"ipAddress\": \"127.0.0.1\", \"port\": 8009}]",
347       browser());
348   EXPECT_EQ(error, "connect_info.auth is required");
349 }
350
351 IN_PROC_BROWSER_TEST_F(CastChannelAPITest, TestSendInvalidMessageInfo) {
352   scoped_refptr<Extension> empty_extension(
353       extensions::test_util::CreateEmptyExtension());
354   scoped_refptr<extensions::CastChannelSendFunction> cast_channel_send_function;
355
356   // Numbers are not supported
357   cast_channel_send_function = CreateSendFunction(empty_extension);
358   std::string error(utils::RunFunctionAndReturnError(
359       cast_channel_send_function.get(),
360       "[{\"channelId\": 1, \"url\": \"cast://127.0.0.1:8009\", "
361       "\"connectInfo\": "
362       "{\"ipAddress\": \"127.0.0.1\", \"port\": 8009, "
363       "\"auth\": \"ssl\"}, \"readyState\": \"open\"}, "
364       "{\"namespace_\": \"foo\", \"sourceId\": \"src\", "
365       "\"destinationId\": \"dest\", \"data\": 1235}]",
366       browser()));
367   EXPECT_EQ(error, "Invalid type of message_info.data");
368
369   // Missing namespace_
370   cast_channel_send_function = CreateSendFunction(empty_extension);
371   error = utils::RunFunctionAndReturnError(
372       cast_channel_send_function.get(),
373       "[{\"channelId\": 1, \"url\": \"cast://127.0.0.1:8009\", "
374       "\"connectInfo\": "
375       "{\"ipAddress\": \"127.0.0.1\", \"port\": 8009, "
376       "\"auth\": \"ssl\"}, \"readyState\": \"open\"}, "
377       "{\"namespace_\": \"\", \"sourceId\": \"src\", "
378       "\"destinationId\": \"dest\", \"data\": \"data\"}]",
379       browser());
380   EXPECT_EQ(error, "message_info.namespace_ is required");
381
382   // Missing source_id
383   cast_channel_send_function = CreateSendFunction(empty_extension);
384   error = utils::RunFunctionAndReturnError(
385       cast_channel_send_function.get(),
386       "[{\"channelId\": 1, \"url\": \"cast://127.0.0.1:8009\", "
387       "\"connectInfo\": "
388       "{\"ipAddress\": \"127.0.0.1\", \"port\": 8009, "
389       "\"auth\": \"ssl\"}, \"readyState\": \"open\"}, "
390       "{\"namespace_\": \"foo\", \"sourceId\": \"\", "
391       "\"destinationId\": \"dest\", \"data\": \"data\"}]",
392       browser());
393   EXPECT_EQ(error, "message_info.source_id is required");
394
395   // Missing destination_id
396   cast_channel_send_function = CreateSendFunction(empty_extension);
397   error = utils::RunFunctionAndReturnError(
398       cast_channel_send_function.get(),
399       "[{\"channelId\": 1, \"url\": \"cast://127.0.0.1:8009\", "
400       "\"connectInfo\": "
401       "{\"ipAddress\": \"127.0.0.1\", \"port\": 8009, "
402       "\"auth\": \"ssl\"}, \"readyState\": \"open\"}, "
403       "{\"namespace_\": \"foo\", \"sourceId\": \"src\", "
404       "\"destinationId\": \"\", \"data\": \"data\"}]",
405       browser());
406   EXPECT_EQ(error, "message_info.destination_id is required");
407 }
408
409 IN_PROC_BROWSER_TEST_F(CastChannelAPITest, TestSetAuthorityKeysInvalid) {
410   scoped_refptr<Extension> empty_extension(
411       extensions::test_util::CreateEmptyExtension());
412   scoped_refptr<extensions::CastChannelSetAuthorityKeysFunction>
413       cast_channel_set_authority_keys_function;
414   std::string errorResult = "Unable to set authority keys.";
415
416   cast_channel_set_authority_keys_function =
417       CreateSetAuthorityKeysFunction(empty_extension);
418   std::string error = utils::RunFunctionAndReturnError(
419       cast_channel_set_authority_keys_function.get(),
420       "[\"\", \"signature\"]",
421       browser());
422   EXPECT_EQ(error, errorResult);
423
424   cast_channel_set_authority_keys_function =
425       CreateSetAuthorityKeysFunction(empty_extension);
426   error = utils::RunFunctionAndReturnError(
427       cast_channel_set_authority_keys_function.get(),
428       "[\"keys\", \"\"]",
429       browser());
430   EXPECT_EQ(error, errorResult);
431
432   std::string keys =
433       "CrMCCiBSnZzWf+XraY5w3SbX2PEmWfHm5SNIv2pc9xbhP0EOcxKOAjCCAQoCggEBALwigL"
434       "2A9johADuudl41fz3DZFxVlIY0LwWHKM33aYwXs1CnuIL638dDLdZ+q6BvtxNygKRHFcEg"
435       "mVDN7BRiCVukmM3SQbY2Tv/oLjIwSoGoQqNsmzNuyrL1U2bgJ1OGGoUepzk/SneO+1RmZv"
436       "tYVMBeOcf1UAYL4IrUzuFqVR+LFwDmaaMn5gglaTwSnY0FLNYuojHetFJQ1iBJ3nGg+a0g"
437       "QBLx3SXr1ea4NvTWj3/KQ9zXEFvmP1GKhbPz//YDLcsjT5ytGOeTBYysUpr3TOmZer5ufk"
438       "0K48YcqZP6OqWRXRy9ZuvMYNyGdMrP+JIcmH1X+mFHnquAt+RIgCqSxRsCAwEAAQ==";
439   std::string signature =
440       "chCUHZKkykcwU8HzU+hm027fUTBL0dqPMtrzppwExQwK9+"
441       "XlmCjJswfce2sUUfhR1OL1tyW4hWFwu4JnuQCJ+CvmSmAh2bzRpnuSKzBfgvIDjNOAGUs7"
442       "ADaNSSWPLxp+6ko++2Dn4S9HpOt8N1v6gMWqj3Ru5IqFSQPZSvGH2ois6uE50CFayPcjQE"
443       "OVZt41noQdFd15RmKTvocoCC5tHNlaikeQ52yi0IScOlad1B1lMhoplW3rWophQaqxMumr"
444       "OcHIZ+Y+p858x5f8Pny/kuqUClmFh9B/vF07NsUHwoSL9tA5t5jCY3L5iUc/v7o3oFcW/T"
445       "gojKkX2Kg7KQ86QA==";
446
447   cast_channel_set_authority_keys_function =
448       CreateSetAuthorityKeysFunction(empty_extension);
449   error = utils::RunFunctionAndReturnError(
450       cast_channel_set_authority_keys_function.get(),
451       "[\"" + keys + "\", \"signature\"]",
452       browser());
453   EXPECT_EQ(error, errorResult);
454
455   cast_channel_set_authority_keys_function =
456       CreateSetAuthorityKeysFunction(empty_extension);
457   error = utils::RunFunctionAndReturnError(
458       cast_channel_set_authority_keys_function.get(),
459       "[\"keys\", \"" + signature + "\"]",
460       browser());
461   EXPECT_EQ(error, errorResult);
462
463   cast_channel_set_authority_keys_function =
464       CreateSetAuthorityKeysFunction(empty_extension);
465   error = utils::RunFunctionAndReturnError(
466       cast_channel_set_authority_keys_function.get(),
467       "[\"" + keys + "\", \"" + signature + "\"]",
468       browser());
469   EXPECT_EQ(error, errorResult);
470 }
471
472 IN_PROC_BROWSER_TEST_F(CastChannelAPITest, TestSetAuthorityKeysValid) {
473   scoped_refptr<Extension> empty_extension(
474       extensions::test_util::CreateEmptyExtension());
475   scoped_refptr<extensions::CastChannelSetAuthorityKeysFunction>
476       cast_channel_set_authority_keys_function;
477
478   cast_channel_set_authority_keys_function =
479       CreateSetAuthorityKeysFunction(empty_extension);
480   std::string keys =
481       "CrMCCiBSnZzWf+XraY5w3SbX2PEmWfHm5SNIv2pc9xbhP0EOcxKOAjCCAQoCggEBALwigL"
482       "2A9johADuudl41fz3DZFxVlIY0LwWHKM33aYwXs1CnuIL638dDLdZ+q6BvtxNygKRHFcEg"
483       "mVDN7BRiCVukmM3SQbY2Tv/oLjIwSoGoQqNsmzNuyrL1U2bgJ1OGGoUepzk/SneO+1RmZv"
484       "tYVMBeOcf1UAYL4IrUzuFqVR+LFwDmaaMn5gglaTwSnY0FLNYuojHetFJQ1iBJ3nGg+a0g"
485       "QBLx3SXr1ea4NvTWj3/KQ9zXEFvmP1GKhbPz//YDLcsjT5ytGOeTBYysUpr3TOmZer5ufk"
486       "0K48YcqZP6OqWRXRy9ZuvMYNyGdMrP+JIcmH1X+mFHnquAt+RIgCqSxRsCAwEAAQqzAgog"
487       "okjC6FTmVqVt6CMfHuF1b9vkB/n+1GUNYMxay2URxyASjgIwggEKAoIBAQCwDl4HOt+kX2"
488       "j3Icdk27Z27+6Lk/j2G4jhk7cX8BUeflJVdzwCjXtKbNO91sGccsizFc8RwfVGxNUgR/sw"
489       "9ORhDGjwXqs3jpvhvIHDcIp41oM0MpwZYuvknO3jZGxBHZzSi0hMI5CVs+dS6gVXzGCzuh"
490       "TkugA55EZVdM5ajnpnI9poCvrEhB60xaGianMfbsguL5qeqLEO/Yemj009SwXVNVp0TbyO"
491       "gkSW9LWVYE6l3yc9QVwHo7Q1WrOe8gUkys0xWg0mTNTT/VDhNOlMgVgwssd63YGJptQ6OI"
492       "QDtzSedz//eAdbmcGyHzVWbjo8DCXhV/aKfknAzIMRNeeRbS5lAgMBAAE=";
493   std::string signature =
494       "o83oku3jP+xjTysNBalqp/ZfJRPLt8R+IUhZMepbARFSRVizLoeFW5XyUwe6lQaC+PFFQH"
495       "SZeGZyeeGRpwCJ/lef0xh6SWJlVMWNTk5+z0U84GQdizJP/CTCeHpIwMobN+kyDajgOyfD"
496       "DLhktc6LHmSlFGG6J7B8W67oziS8ZFEdrcT9WSXFrjLVyURHjvidZD5iFtuImI6k9R9OoX"
497       "LR6SyAwpjdrL+vlHMk3Gol6KQ98YpF0ghHnN3/FFW4ibvIwjmRbp+tUV3h8TRcCOjlXVGp"
498       "bzPtNRRlTqfv7Rxm5YXkZMLmJJMZiTs5+o8FMRMTQZT4hRR3DQ+A/jofViyTGA==";
499
500   std::string args = "[\"" + keys + "\", \"" + signature + "\"]";
501   std::string error = utils::RunFunctionAndReturnError(
502       cast_channel_set_authority_keys_function.get(), args, browser());
503   EXPECT_EQ(error, std::string());
504 }
505
506 // TODO(vadimgo): Win Dbg has a workaround that makes RunExtensionSubtest
507 // always return true without actually running the test. Remove when fixed.
508 #if defined(OS_WIN) && !defined(NDEBUG)
509 #define MAYBE_TestSetAuthorityKeys DISABLED_TestSetAuthorityKeys
510 #else
511 #define MAYBE_TestSetAuthorityKeys TestSetAuthorityKeys
512 #endif
513 // Test loading extension, opening a channel with ConnectInfo, adding a
514 // listener, writing, reading, and closing.
515 IN_PROC_BROWSER_TEST_F(CastChannelAPITest, MAYBE_TestSetAuthorityKeys) {
516   EXPECT_TRUE(
517       RunExtensionSubtest("cast_channel/api", "test_authority_keys.html"));
518 }