NaCl: Update revision in DEPS, r12770 -> r12773
[chromium-blink-merge.git] / chrome / browser / ui / webui / local_discovery / local_discovery_ui_browsertest.cc
blobd6c2236e83eeef87a3caeb26e05eff4b78ba96b3
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.
5 #include "base/basictypes.h"
6 #include "base/bind.h"
7 #include "base/callback.h"
8 #include "base/command_line.h"
9 #include "base/compiler_specific.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/message_loop/message_loop.h"
12 #include "chrome/browser/local_discovery/test_service_discovery_client.h"
13 #include "chrome/browser/signin/profile_oauth2_token_service.h"
14 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
15 #include "chrome/browser/signin/signin_manager.h"
16 #include "chrome/browser/signin/signin_manager_base.h"
17 #include "chrome/browser/signin/signin_manager_factory.h"
18 #include "chrome/browser/ui/browser.h"
19 #include "chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.h"
20 #include "chrome/common/chrome_switches.h"
21 #include "chrome/common/url_constants.h"
22 #include "chrome/test/base/ui_test_utils.h"
23 #include "chrome/test/base/web_ui_browsertest.h"
24 #include "google_apis/gaia/gaia_urls.h"
25 #include "net/http/http_status_code.h"
26 #include "net/url_request/test_url_fetcher_factory.h"
27 #include "net/url_request/url_request_status.h"
28 #include "net/url_request/url_request_test_util.h"
30 using testing::InvokeWithoutArgs;
31 using testing::Return;
32 using testing::AtLeast;
33 using testing::DoDefault;
34 using testing::DoAll;
35 using testing::InSequence;
36 using testing::StrictMock;
37 using testing::AnyNumber;
39 using testing::InvokeWithoutArgs;
40 using testing::Return;
41 using testing::AtLeast;
43 namespace local_discovery {
45 namespace {
47 const uint8 kQueryData[] = {
48 // Header
49 0x00, 0x00,
50 0x00, 0x00, // Flags not set.
51 0x00, 0x01, // Set QDCOUNT (question count) to 1, all the
52 // rest are 0 for a query.
53 0x00, 0x00,
54 0x00, 0x00,
55 0x00, 0x00,
57 // Question
58 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't',
59 0x04, '_', 't', 'c', 'p',
60 0x05, 'l', 'o', 'c', 'a', 'l',
61 0x00,
63 0x00, 0x0c, // QTYPE: A query.
64 0x00, 0x01, // QCLASS: IN class. Unicast bit not set.
67 const uint8 kAnnouncePacket[] = {
68 // Header
69 0x00, 0x00, // ID is zeroed out
70 0x80, 0x00, // Standard query response, no error
71 0x00, 0x00, // No questions (for simplicity)
72 0x00, 0x05, // 5 RR (answers)
73 0x00, 0x00, // 0 authority RRs
74 0x00, 0x00, // 0 additional RRs
76 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't',
77 0x04, '_', 't', 'c', 'p',
78 0x05, 'l', 'o', 'c', 'a', 'l',
79 0x00,
80 0x00, 0x0c, // TYPE is PTR.
81 0x00, 0x01, // CLASS is IN.
82 0x00, 0x00, // TTL (4 bytes) is 32768 second.
83 0x10, 0x00,
84 0x00, 0x0c, // RDLENGTH is 12 bytes.
85 0x09, 'm', 'y', 'S', 'e', 'r', 'v', 'i', 'c', 'e',
86 0xc0, 0x0c,
88 0x09, 'm', 'y', 'S', 'e', 'r', 'v', 'i', 'c', 'e',
89 0xc0, 0x0c,
90 0x00, 0x10, // TYPE is TXT.
91 0x00, 0x01, // CLASS is IN.
92 0x00, 0x00, // TTL (4 bytes) is 32768 seconds.
93 0x01, 0x00,
94 0x00, 0x34, // RDLENGTH is 69 bytes.
95 0x03, 'i', 'd', '=',
96 0x10, 't', 'y', '=', 'S', 'a', 'm', 'p', 'l', 'e', ' ',
97 'd', 'e', 'v', 'i', 'c', 'e',
98 0x1e, 'n', 'o', 't', 'e', '=',
99 'S', 'a', 'm', 'p', 'l', 'e', ' ', 'd', 'e', 'v', 'i', 'c', 'e', ' ',
100 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'i', 'o', 'n',
102 0x09, 'm', 'y', 'S', 'e', 'r', 'v', 'i', 'c', 'e',
103 0xc0, 0x0c,
104 0x00, 0x21, // Type is SRV
105 0x00, 0x01, // CLASS is IN
106 0x00, 0x00, // TTL (4 bytes) is 32768 second.
107 0x10, 0x00,
108 0x00, 0x17, // RDLENGTH is 23
109 0x00, 0x00,
110 0x00, 0x00,
111 0x22, 0xb8, // port 8888
112 0x09, 'm', 'y', 'S', 'e', 'r', 'v', 'i', 'c', 'e',
113 0x05, 'l', 'o', 'c', 'a', 'l',
114 0x00,
116 0x09, 'm', 'y', 'S', 'e', 'r', 'v', 'i', 'c', 'e',
117 0x05, 'l', 'o', 'c', 'a', 'l',
118 0x00,
119 0x00, 0x01, // Type is A
120 0x00, 0x01, // CLASS is IN
121 0x00, 0x00, // TTL (4 bytes) is 32768 second.
122 0x10, 0x00,
123 0x00, 0x04, // RDLENGTH is 4
124 0x01, 0x02, 0x03, 0x04, // 1.2.3.4
126 0x09, 'm', 'y', 'S', 'e', 'r', 'v', 'i', 'c', 'e',
127 0x05, 'l', 'o', 'c', 'a', 'l',
128 0x00,
129 0x00, 0x1C, // Type is AAAA
130 0x00, 0x01, // CLASS is IN
131 0x00, 0x00, // TTL (4 bytes) is 32768 second.
132 0x10, 0x00,
133 0x00, 0x10, // RDLENGTH is 16
134 0x01, 0x02, 0x03, 0x04, // 1.2.3.4
135 0x01, 0x02, 0x03, 0x04,
136 0x01, 0x02, 0x03, 0x04,
137 0x01, 0x02, 0x03, 0x04,
141 const uint8 kGoodbyePacket[] = {
142 // Header
143 0x00, 0x00, // ID is zeroed out
144 0x80, 0x00, // Standard query response, RA, no error
145 0x00, 0x00, // No questions (for simplicity)
146 0x00, 0x02, // 1 RR (answers)
147 0x00, 0x00, // 0 authority RRs
148 0x00, 0x00, // 0 additional RRs
150 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't',
151 0x04, '_', 't', 'c', 'p',
152 0x05, 'l', 'o', 'c', 'a', 'l',
153 0x00,
154 0x00, 0x0c, // TYPE is PTR.
155 0x00, 0x01, // CLASS is IN.
156 0x00, 0x00, // TTL (4 bytes) is 0 seconds.
157 0x00, 0x00,
158 0x00, 0x0c, // RDLENGTH is 12 bytes.
159 0x09, 'm', 'y', 'S', 'e', 'r', 'v', 'i', 'c', 'e',
160 0xc0, 0x0c,
163 0x09, 'm', 'y', 'S', 'e', 'r', 'v', 'i', 'c', 'e',
164 0xc0, 0x0c,
165 0x00, 0x21, // Type is SRV
166 0x00, 0x01, // CLASS is IN
167 0x00, 0x00, // TTL (4 bytes) is 0 seconds.
168 0x00, 0x00,
169 0x00, 0x17, // RDLENGTH is 23
170 0x00, 0x00,
171 0x00, 0x00,
172 0x22, 0xb8, // port 8888
173 0x09, 'm', 'y', 'S', 'e', 'r', 'v', 'i', 'c', 'e',
174 0x05, 'l', 'o', 'c', 'a', 'l',
175 0x00,
178 const uint8 kAnnouncePacketRegistered[] = {
179 // Header
180 0x00, 0x00, // ID is zeroed out
181 0x80, 0x00, // Standard query response, RA, no error
182 0x00, 0x00, // No questions (for simplicity)
183 0x00, 0x01, // 1 RR (answers)
184 0x00, 0x00, // 0 authority RRs
185 0x00, 0x00, // 0 additional RRs
187 0x09, 'm', 'y', 'S', 'e', 'r', 'v', 'i', 'c', 'e',
188 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't',
189 0x04, '_', 't', 'c', 'p',
190 0x05, 'l', 'o', 'c', 'a', 'l',
191 0x00,
192 0x00, 0x10, // TYPE is TXT.
193 0x00, 0x01, // CLASS is IN.
194 0x00, 0x00, // TTL (4 bytes) is 32768 seconds.
195 0x01, 0x00,
196 0x00, 0x3b, // RDLENGTH is 76 bytes.
197 0x0a, 'i', 'd', '=', 's', 'o', 'm', 'e', '_', 'i', 'd',
198 0x10, 't', 'y', '=', 'S', 'a', 'm', 'p', 'l', 'e', ' ',
199 'd', 'e', 'v', 'i', 'c', 'e',
200 0x1e, 'n', 'o', 't', 'e', '=',
201 'S', 'a', 'm', 'p', 'l', 'e', ' ', 'd', 'e', 'v', 'i', 'c', 'e', ' ',
202 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'i', 'o', 'n',
205 const char kResponseInfo[] = "{"
206 " \"x-privet-token\" : \"MyPrivetToken\""
207 "}";
209 const char kResponseInfoWithID[] = "{"
210 " \"x-privet-token\" : \"MyPrivetToken\","
211 " \"id\" : \"my_id\""
212 "}";
214 const char kResponseRegisterStart[] = "{"
215 " \"action\": \"start\","
216 " \"user\": \"user@host.com\""
217 "}";
219 const char kResponseRegisterClaimTokenNoConfirm[] = "{"
220 " \"action\": \"getClaimToken\","
221 " \"user\": \"user@host.com\","
222 " \"error\": \"pending_user_action\","
223 " \"timeout\": 1"
224 "}";
226 const char kResponseRegisterClaimTokenConfirm[] = "{"
227 " \"action\": \"getClaimToken\","
228 " \"user\": \"user@host.com\","
229 " \"token\": \"MySampleToken\","
230 " \"claim_url\": \"http://someurl.com/\""
231 "}";
233 const char kResponseCloudPrintConfirm[] = "{ \"success\": true }";
235 const char kResponseRegisterComplete[] = "{"
236 " \"action\": \"complete\","
237 " \"user\": \"user@host.com\","
238 " \"device_id\": \"my_id\""
239 "}";
241 const char kResponseGaiaToken[] = "{"
242 " \"access_token\": \"at1\","
243 " \"expires_in\": 3600,"
244 " \"token_type\": \"Bearer\""
245 "}";
247 const char kResponseGaiaId[] = "{"
248 " \"id\": \"12345\""
249 "}";
251 const char kURLInfo[] = "http://1.2.3.4:8888/privet/info";
253 const char kURLRegisterStart[] =
254 "http://1.2.3.4:8888/privet/register?action=start&user=user%40host.com";
256 const char kURLRegisterClaimToken[] =
257 "http://1.2.3.4:8888/privet/register?action=getClaimToken&"
258 "user=user%40host.com";
260 const char kURLCloudPrintConfirm[] =
261 "https://www.google.com/cloudprint/confirm?token=MySampleToken";
263 const char kURLRegisterComplete[] =
264 "http://1.2.3.4:8888/privet/register?action=complete&user=user%40host.com";
266 const char kURLGaiaToken[] =
267 "https://accounts.google.com/o/oauth2/token";
269 const char kSampleUser[] = "user@host.com";
271 class TestMessageLoopCondition {
272 public:
273 TestMessageLoopCondition() : signaled_(false),
274 waiting_(false) {
277 ~TestMessageLoopCondition() {
280 // Signal a waiting method that it can continue executing.
281 void Signal() {
282 signaled_ = true;
283 if (waiting_)
284 base::MessageLoop::current()->Quit();
287 // Pause execution and recursively run the message loop until |Signal()| is
288 // called. Do not pause if |Signal()| has already been called.
289 void Wait() {
290 while (!signaled_) {
291 waiting_ = true;
292 base::MessageLoop::current()->Run();
293 waiting_ = false;
295 signaled_ = false;
298 private:
299 bool signaled_;
300 bool waiting_;
302 DISALLOW_COPY_AND_ASSIGN(TestMessageLoopCondition);
305 class MockableFakeURLFetcherCreator {
306 public:
307 MockableFakeURLFetcherCreator() {
310 ~MockableFakeURLFetcherCreator() {
313 MOCK_METHOD1(OnCreateFakeURLFetcher, void(const std::string& url));
315 scoped_ptr<net::FakeURLFetcher> CreateFakeURLFetcher(
316 const GURL& url,
317 net::URLFetcherDelegate* delegate,
318 const std::string& response_data,
319 net::HttpStatusCode response_code,
320 net::URLRequestStatus::Status status) {
321 OnCreateFakeURLFetcher(url.spec());
322 return scoped_ptr<net::FakeURLFetcher>(new net::FakeURLFetcher(
323 url, delegate, response_data, response_code, status));
326 net::FakeURLFetcherFactory::FakeURLFetcherCreator callback() {
327 return base::Bind(&MockableFakeURLFetcherCreator::CreateFakeURLFetcher,
328 base::Unretained(this));
332 class LocalDiscoveryUITest : public WebUIBrowserTest {
333 public:
334 LocalDiscoveryUITest() : fake_fetcher_factory_(
335 &fetcher_impl_factory_,
336 fake_url_fetcher_creator_.callback()) {
338 virtual ~LocalDiscoveryUITest() {
341 virtual void SetUpOnMainThread() OVERRIDE {
342 WebUIBrowserTest::SetUpOnMainThread();
344 test_service_discovery_client_ = new TestServiceDiscoveryClient();
345 test_service_discovery_client_->Start();
346 EXPECT_CALL(*test_service_discovery_client_, OnSendTo(
347 std::string((const char*)kQueryData,
348 sizeof(kQueryData))))
349 .Times(AtLeast(2))
350 .WillOnce(InvokeWithoutArgs(&condition_devices_listed_,
351 &TestMessageLoopCondition::Signal))
352 .WillRepeatedly(Return());
354 SigninManagerBase* signin_manager =
355 SigninManagerFactory::GetForProfile(browser()->profile());
357 DCHECK(signin_manager);
358 signin_manager->SetAuthenticatedUsername(kSampleUser);
360 fake_fetcher_factory().SetFakeResponse(
361 GURL(kURLInfo),
362 kResponseInfo,
363 net::HTTP_OK,
364 net::URLRequestStatus::SUCCESS);
366 fake_fetcher_factory().SetFakeResponse(
367 GURL(kURLRegisterStart),
368 kResponseRegisterStart,
369 net::HTTP_OK,
370 net::URLRequestStatus::SUCCESS);
372 fake_fetcher_factory().SetFakeResponse(
373 GURL(kURLRegisterClaimToken),
374 kResponseRegisterClaimTokenNoConfirm,
375 net::HTTP_OK,
376 net::URLRequestStatus::SUCCESS);
378 fake_fetcher_factory().SetFakeResponse(
379 GURL(kURLCloudPrintConfirm),
380 kResponseCloudPrintConfirm,
381 net::HTTP_OK,
382 net::URLRequestStatus::SUCCESS);
384 fake_fetcher_factory().SetFakeResponse(
385 GURL(kURLRegisterComplete),
386 kResponseRegisterComplete,
387 net::HTTP_OK,
388 net::URLRequestStatus::SUCCESS);
390 fake_fetcher_factory().SetFakeResponse(
391 GURL(kURLGaiaToken),
392 kResponseGaiaToken,
393 net::HTTP_OK,
394 net::URLRequestStatus::SUCCESS);
396 EXPECT_CALL(fake_url_fetcher_creator(), OnCreateFakeURLFetcher(
397 kURLGaiaToken))
398 .Times(AnyNumber());
400 fake_fetcher_factory().SetFakeResponse(
401 GaiaUrls::GetInstance()->oauth_user_info_url(),
402 kResponseGaiaId,
403 net::HTTP_OK,
404 net::URLRequestStatus::SUCCESS);
406 EXPECT_CALL(fake_url_fetcher_creator(), OnCreateFakeURLFetcher(
407 GaiaUrls::GetInstance()->oauth_user_info_url().spec()))
408 .Times(AnyNumber());
410 ProfileOAuth2TokenService* token_service =
411 ProfileOAuth2TokenServiceFactory::GetForProfile(browser()->profile());
413 token_service->UpdateCredentials("user@host.com", "MyFakeToken");
415 AddLibrary(base::FilePath(FILE_PATH_LITERAL("local_discovery_ui_test.js")));
418 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
419 WebUIBrowserTest::SetUpCommandLine(command_line);
422 void RunFor(base::TimeDelta time_period) {
423 base::CancelableCallback<void()> callback(base::Bind(
424 &base::MessageLoop::Quit, base::Unretained(
425 base::MessageLoop::current())));
426 base::MessageLoop::current()->PostDelayedTask(
427 FROM_HERE, callback.callback(), time_period);
429 base::MessageLoop::current()->Run();
430 callback.Cancel();
433 TestServiceDiscoveryClient* test_service_discovery_client() {
434 return test_service_discovery_client_.get();
437 TestMessageLoopCondition& condition_devices_listed() {
438 return condition_devices_listed_;
441 net::FakeURLFetcherFactory& fake_fetcher_factory() {
442 return fake_fetcher_factory_;
445 MockableFakeURLFetcherCreator& fake_url_fetcher_creator() {
446 return fake_url_fetcher_creator_;
449 private:
450 scoped_refptr<TestServiceDiscoveryClient> test_service_discovery_client_;
451 TestMessageLoopCondition condition_devices_listed_;
453 net::URLFetcherImplFactory fetcher_impl_factory_;
454 StrictMock<MockableFakeURLFetcherCreator> fake_url_fetcher_creator_;
455 net::FakeURLFetcherFactory fake_fetcher_factory_;
457 DISALLOW_COPY_AND_ASSIGN(LocalDiscoveryUITest);
460 IN_PROC_BROWSER_TEST_F(LocalDiscoveryUITest, EmptyTest) {
461 ui_test_utils::NavigateToURL(browser(), GURL(
462 chrome::kChromeUIDevicesURL));
463 condition_devices_listed().Wait();
464 EXPECT_TRUE(WebUIBrowserTest::RunJavascriptTest("checkNoDevices"));
467 IN_PROC_BROWSER_TEST_F(LocalDiscoveryUITest, AddRowTest) {
468 ui_test_utils::NavigateToURL(browser(), GURL(
469 chrome::kChromeUIDevicesURL));
470 condition_devices_listed().Wait();
472 test_service_discovery_client()->SimulateReceive(
473 kAnnouncePacket, sizeof(kAnnouncePacket));
475 base::MessageLoop::current()->RunUntilIdle();
477 EXPECT_TRUE(WebUIBrowserTest::RunJavascriptTest("checkOneDevice"));
479 test_service_discovery_client()->SimulateReceive(
480 kGoodbyePacket, sizeof(kGoodbyePacket));
482 RunFor(base::TimeDelta::FromMilliseconds(1100));
484 EXPECT_TRUE(WebUIBrowserTest::RunJavascriptTest("checkNoDevices"));
488 IN_PROC_BROWSER_TEST_F(LocalDiscoveryUITest, RegisterTest) {
489 TestMessageLoopCondition condition_token_claimed;
491 ui_test_utils::NavigateToURL(browser(), GURL(
492 chrome::kChromeUIDevicesURL));
493 condition_devices_listed().Wait();
495 test_service_discovery_client()->SimulateReceive(
496 kAnnouncePacket, sizeof(kAnnouncePacket));
498 base::MessageLoop::current()->RunUntilIdle();
500 EXPECT_TRUE(WebUIBrowserTest::RunJavascriptTest("checkOneDevice"));
502 EXPECT_TRUE(WebUIBrowserTest::RunJavascriptTest("registerShowOverlay"));
505 InSequence s;
506 EXPECT_CALL(fake_url_fetcher_creator(), OnCreateFakeURLFetcher(kURLInfo));
507 EXPECT_CALL(fake_url_fetcher_creator(), OnCreateFakeURLFetcher(
508 kURLRegisterStart));
509 EXPECT_CALL(fake_url_fetcher_creator(), OnCreateFakeURLFetcher(
510 kURLRegisterClaimToken))
511 .WillOnce(InvokeWithoutArgs(&condition_token_claimed,
512 &TestMessageLoopCondition::Signal));
515 EXPECT_TRUE(WebUIBrowserTest::RunJavascriptTest("registerBegin"));
517 condition_token_claimed.Wait();
519 EXPECT_TRUE(WebUIBrowserTest::RunJavascriptTest("expectPageAdding1"));
521 fake_fetcher_factory().SetFakeResponse(
522 GURL(kURLRegisterClaimToken),
523 kResponseRegisterClaimTokenConfirm,
524 net::HTTP_OK,
525 net::URLRequestStatus::SUCCESS);
527 fake_fetcher_factory().SetFakeResponse(
528 GURL(kURLInfo),
529 kResponseInfoWithID,
530 net::HTTP_OK,
531 net::URLRequestStatus::SUCCESS);
534 InSequence s;
535 EXPECT_CALL(fake_url_fetcher_creator(), OnCreateFakeURLFetcher(
536 kURLRegisterClaimToken));
537 EXPECT_CALL(fake_url_fetcher_creator(), OnCreateFakeURLFetcher(
538 kURLCloudPrintConfirm));
539 EXPECT_CALL(fake_url_fetcher_creator(), OnCreateFakeURLFetcher(
540 kURLRegisterComplete));
541 EXPECT_CALL(fake_url_fetcher_creator(), OnCreateFakeURLFetcher(kURLInfo))
542 .WillOnce(InvokeWithoutArgs(&condition_token_claimed,
543 &TestMessageLoopCondition::Signal));
546 condition_token_claimed.Wait();
548 test_service_discovery_client()->SimulateReceive(
549 kAnnouncePacketRegistered, sizeof(kAnnouncePacketRegistered));
551 base::MessageLoop::current()->RunUntilIdle();
553 EXPECT_TRUE(WebUIBrowserTest::RunJavascriptTest("expectRegisterDone"));
556 } // namespace
558 } // namespace local_discovery