Add testing/scripts/OWNERS
[chromium-blink-merge.git] / extensions / browser / api / cast_channel / cast_channel_apitest.cc
blob42131d991f15d376cd42bf026fe44d9e8728e70b
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.
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"
26 // TODO(mfoltz): Mock out the ApiResourceManager to resolve threading issues
27 // (crbug.com/398242) and simulate unloading of the extension.
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;
38 namespace utils = extension_function_test_utils;
40 using ::testing::_;
41 using ::testing::A;
42 using ::testing::DoAll;
43 using ::testing::Invoke;
44 using ::testing::InSequence;
45 using ::testing::Return;
47 namespace {
49 const char kTestExtensionId[] = "ddchlicdkolnonkihahngkmmmjnjlkkf";
50 const int64 kTimeoutMs = 10000;
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));
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);
66 ACTION_P2(InvokeDelegateOnError, api_test, api) {
67 api_test->CallOnError(api);
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() {}
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());
93 } // namespace
95 class CastChannelAPITest : public ExtensionApiTest {
96 public:
97 CastChannelAPITest() {}
99 void SetUpCommandLine(CommandLine* command_line) override {
100 ExtensionApiTest::SetUpCommandLine(command_line);
101 command_line->AppendSwitchASCII(
102 extensions::switches::kWhitelistedExtensionID,
103 kTestExtensionId);
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());
118 void SetUpOpenSendClose() {
119 SetUpMockCastSocket();
120 EXPECT_CALL(*mock_cast_socket_, error_state())
121 .WillRepeatedly(Return(cast_channel::CHANNEL_ERROR_NONE));
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));
139 extensions::CastChannelAPI* GetApi() {
140 return extensions::CastChannelAPI::Get(profile());
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_NSS_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);
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));
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);
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;
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;
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;
195 MockCastSocket* mock_cast_socket_;
196 net::CapturingNetLog capturing_net_log_;
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();
211 EXPECT_TRUE(RunExtensionSubtest("cast_channel/api",
212 "test_open_send_close.html"));
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();
227 EXPECT_TRUE(RunExtensionSubtest("cast_channel/api",
228 "test_open_send_close_url.html"));
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));
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));
258 EXPECT_TRUE(RunExtensionSubtest("cast_channel/api",
259 "test_open_receive_close.html"));
261 extensions::ResultCatcher catcher;
262 CallOnMessage("some-message");
263 CallOnMessage("some-message");
264 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
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();
278 EXPECT_TRUE(RunExtensionSubtest("cast_channel/api", "test_get_logs.html"));
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();
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));
302 EXPECT_TRUE(RunExtensionSubtest("cast_channel/api",
303 "test_open_error.html"));
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;
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)");
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)");
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)");
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)");
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");
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;
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");
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");
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");
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");
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.";
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);
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);
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==";
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);
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);
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);
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;
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==";
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());