Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / ui / webui / local_discovery / local_discovery_ui_browsertest.cc
blob44bb6ba91ca1fdaee18ed71f5693c9c1258b5750
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, 0x01, // 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 const uint8 kAnnouncePacketRegistered[] = {
164 // Header
165 0x00, 0x00, // ID is zeroed out
166 0x80, 0x00, // Standard query response, RA, no error
167 0x00, 0x00, // No questions (for simplicity)
168 0x00, 0x01, // 1 RR (answers)
169 0x00, 0x00, // 0 authority RRs
170 0x00, 0x00, // 0 additional RRs
172 0x09, 'm', 'y', 'S', 'e', 'r', 'v', 'i', 'c', 'e',
173 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't',
174 0x04, '_', 't', 'c', 'p',
175 0x05, 'l', 'o', 'c', 'a', 'l',
176 0x00,
177 0x00, 0x10, // TYPE is TXT.
178 0x00, 0x01, // CLASS is IN.
179 0x00, 0x00, // TTL (4 bytes) is 32768 seconds.
180 0x01, 0x00,
181 0x00, 0x3b, // RDLENGTH is 76 bytes.
182 0x0a, 'i', 'd', '=', 's', 'o', 'm', 'e', '_', 'i', 'd',
183 0x10, 't', 'y', '=', 'S', 'a', 'm', 'p', 'l', 'e', ' ',
184 'd', 'e', 'v', 'i', 'c', 'e',
185 0x1e, 'n', 'o', 't', 'e', '=',
186 'S', 'a', 'm', 'p', 'l', 'e', ' ', 'd', 'e', 'v', 'i', 'c', 'e', ' ',
187 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'i', 'o', 'n',
190 const char kResponseInfo[] = "{"
191 " \"x-privet-token\" : \"MyPrivetToken\""
192 "}";
194 const char kResponseInfoWithID[] = "{"
195 " \"x-privet-token\" : \"MyPrivetToken\","
196 " \"id\" : \"my_id\""
197 "}";
199 const char kResponseRegisterStart[] = "{"
200 " \"action\": \"start\","
201 " \"user\": \"user@host.com\""
202 "}";
204 const char kResponseRegisterClaimTokenNoConfirm[] = "{"
205 " \"action\": \"getClaimToken\","
206 " \"user\": \"user@host.com\","
207 " \"error\": \"pending_user_action\","
208 " \"timeout\": 1"
209 "}";
211 const char kResponseRegisterClaimTokenConfirm[] = "{"
212 " \"action\": \"getClaimToken\","
213 " \"user\": \"user@host.com\","
214 " \"token\": \"MySampleToken\","
215 " \"claim_url\": \"http://someurl.com/\""
216 "}";
218 const char kResponseCloudPrintConfirm[] = "{ \"success\": true }";
220 const char kResponseRegisterComplete[] = "{"
221 " \"action\": \"complete\","
222 " \"user\": \"user@host.com\","
223 " \"device_id\": \"my_id\""
224 "}";
226 const char kResponseGaiaToken[] = "{"
227 " \"access_token\": \"at1\","
228 " \"expires_in\": 3600,"
229 " \"token_type\": \"Bearer\""
230 "}";
232 const char kResponseGaiaId[] = "{"
233 " \"id\": \"12345\""
234 "}";
236 const char kURLInfo[] = "http://1.2.3.4:8888/privet/info";
238 const char kURLRegisterStart[] =
239 "http://1.2.3.4:8888/privet/register?action=start&user=user%40host.com";
241 const char kURLRegisterClaimToken[] =
242 "http://1.2.3.4:8888/privet/register?action=getClaimToken&"
243 "user=user%40host.com";
245 const char kURLCloudPrintConfirm[] =
246 "https://www.google.com/cloudprint/confirm?token=MySampleToken";
248 const char kURLRegisterComplete[] =
249 "http://1.2.3.4:8888/privet/register?action=complete&user=user%40host.com";
251 const char kURLGaiaToken[] =
252 "https://accounts.google.com/o/oauth2/token";
254 const char kSampleUser[] = "user@host.com";
256 class TestMessageLoopCondition {
257 public:
258 TestMessageLoopCondition() : signaled_(false),
259 waiting_(false) {
262 ~TestMessageLoopCondition() {
265 // Signal a waiting method that it can continue executing.
266 void Signal() {
267 signaled_ = true;
268 if (waiting_)
269 base::MessageLoop::current()->Quit();
272 // Pause execution and recursively run the message loop until |Signal()| is
273 // called. Do not pause if |Signal()| has already been called.
274 void Wait() {
275 while (!signaled_) {
276 waiting_ = true;
277 base::MessageLoop::current()->Run();
278 waiting_ = false;
280 signaled_ = false;
283 private:
284 bool signaled_;
285 bool waiting_;
287 DISALLOW_COPY_AND_ASSIGN(TestMessageLoopCondition);
290 class MockableFakeURLFetcherCreator {
291 public:
292 MockableFakeURLFetcherCreator() {
295 ~MockableFakeURLFetcherCreator() {
298 MOCK_METHOD1(OnCreateFakeURLFetcher, void(const std::string& url));
300 scoped_ptr<net::FakeURLFetcher> CreateFakeURLFetcher(
301 const GURL& url,
302 net::URLFetcherDelegate* delegate,
303 const std::string& response_data,
304 net::HttpStatusCode response_code,
305 net::URLRequestStatus::Status status) {
306 OnCreateFakeURLFetcher(url.spec());
307 return scoped_ptr<net::FakeURLFetcher>(new net::FakeURLFetcher(
308 url, delegate, response_data, response_code, status));
311 net::FakeURLFetcherFactory::FakeURLFetcherCreator callback() {
312 return base::Bind(&MockableFakeURLFetcherCreator::CreateFakeURLFetcher,
313 base::Unretained(this));
317 class LocalDiscoveryUITest : public WebUIBrowserTest {
318 public:
319 LocalDiscoveryUITest() : fake_fetcher_factory_(
320 &fetcher_impl_factory_,
321 fake_url_fetcher_creator_.callback()) {
323 virtual ~LocalDiscoveryUITest() {
326 virtual void SetUpOnMainThread() OVERRIDE {
327 WebUIBrowserTest::SetUpOnMainThread();
329 test_service_discovery_client_ = new TestServiceDiscoveryClient();
330 test_service_discovery_client_->Start();
331 EXPECT_CALL(*test_service_discovery_client_, OnSendTo(
332 std::string((const char*)kQueryData,
333 sizeof(kQueryData))))
334 .Times(AtLeast(2))
335 .WillOnce(InvokeWithoutArgs(&condition_devices_listed_,
336 &TestMessageLoopCondition::Signal))
337 .WillRepeatedly(Return());
339 SigninManagerBase* signin_manager =
340 SigninManagerFactory::GetForProfile(browser()->profile());
342 DCHECK(signin_manager);
343 signin_manager->SetAuthenticatedUsername(kSampleUser);
345 fake_fetcher_factory().SetFakeResponse(
346 GURL(kURLInfo),
347 kResponseInfo,
348 net::HTTP_OK,
349 net::URLRequestStatus::SUCCESS);
351 fake_fetcher_factory().SetFakeResponse(
352 GURL(kURLRegisterStart),
353 kResponseRegisterStart,
354 net::HTTP_OK,
355 net::URLRequestStatus::SUCCESS);
357 fake_fetcher_factory().SetFakeResponse(
358 GURL(kURLRegisterClaimToken),
359 kResponseRegisterClaimTokenNoConfirm,
360 net::HTTP_OK,
361 net::URLRequestStatus::SUCCESS);
363 fake_fetcher_factory().SetFakeResponse(
364 GURL(kURLCloudPrintConfirm),
365 kResponseCloudPrintConfirm,
366 net::HTTP_OK,
367 net::URLRequestStatus::SUCCESS);
369 fake_fetcher_factory().SetFakeResponse(
370 GURL(kURLRegisterComplete),
371 kResponseRegisterComplete,
372 net::HTTP_OK,
373 net::URLRequestStatus::SUCCESS);
375 fake_fetcher_factory().SetFakeResponse(
376 GURL(kURLGaiaToken),
377 kResponseGaiaToken,
378 net::HTTP_OK,
379 net::URLRequestStatus::SUCCESS);
381 EXPECT_CALL(fake_url_fetcher_creator(), OnCreateFakeURLFetcher(
382 kURLGaiaToken))
383 .Times(AnyNumber());
385 fake_fetcher_factory().SetFakeResponse(
386 GaiaUrls::GetInstance()->oauth_user_info_url(),
387 kResponseGaiaId,
388 net::HTTP_OK,
389 net::URLRequestStatus::SUCCESS);
391 EXPECT_CALL(fake_url_fetcher_creator(), OnCreateFakeURLFetcher(
392 GaiaUrls::GetInstance()->oauth_user_info_url().spec()))
393 .Times(AnyNumber());
395 ProfileOAuth2TokenService* token_service =
396 ProfileOAuth2TokenServiceFactory::GetForProfile(browser()->profile());
398 token_service->UpdateCredentials("user@host.com", "MyFakeToken");
400 AddLibrary(base::FilePath(FILE_PATH_LITERAL("local_discovery_ui_test.js")));
403 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
404 WebUIBrowserTest::SetUpCommandLine(command_line);
407 void RunFor(base::TimeDelta time_period) {
408 base::CancelableCallback<void()> callback(base::Bind(
409 &base::MessageLoop::Quit, base::Unretained(
410 base::MessageLoop::current())));
411 base::MessageLoop::current()->PostDelayedTask(
412 FROM_HERE, callback.callback(), time_period);
414 base::MessageLoop::current()->Run();
415 callback.Cancel();
418 TestServiceDiscoveryClient* test_service_discovery_client() {
419 return test_service_discovery_client_.get();
422 TestMessageLoopCondition& condition_devices_listed() {
423 return condition_devices_listed_;
426 net::FakeURLFetcherFactory& fake_fetcher_factory() {
427 return fake_fetcher_factory_;
430 MockableFakeURLFetcherCreator& fake_url_fetcher_creator() {
431 return fake_url_fetcher_creator_;
434 private:
435 scoped_refptr<TestServiceDiscoveryClient> test_service_discovery_client_;
436 TestMessageLoopCondition condition_devices_listed_;
438 net::URLFetcherImplFactory fetcher_impl_factory_;
439 StrictMock<MockableFakeURLFetcherCreator> fake_url_fetcher_creator_;
440 net::FakeURLFetcherFactory fake_fetcher_factory_;
442 DISALLOW_COPY_AND_ASSIGN(LocalDiscoveryUITest);
445 IN_PROC_BROWSER_TEST_F(LocalDiscoveryUITest, EmptyTest) {
446 ui_test_utils::NavigateToURL(browser(), GURL(
447 chrome::kChromeUIDevicesURL));
448 condition_devices_listed().Wait();
449 EXPECT_TRUE(WebUIBrowserTest::RunJavascriptTest("checkNoDevices"));
452 IN_PROC_BROWSER_TEST_F(LocalDiscoveryUITest, AddRowTest) {
453 ui_test_utils::NavigateToURL(browser(), GURL(
454 chrome::kChromeUIDevicesURL));
455 condition_devices_listed().Wait();
457 test_service_discovery_client()->SimulateReceive(
458 kAnnouncePacket, sizeof(kAnnouncePacket));
460 base::MessageLoop::current()->RunUntilIdle();
462 EXPECT_TRUE(WebUIBrowserTest::RunJavascriptTest("checkOneDevice"));
464 test_service_discovery_client()->SimulateReceive(
465 kGoodbyePacket, sizeof(kGoodbyePacket));
467 RunFor(base::TimeDelta::FromMilliseconds(1100));
469 EXPECT_TRUE(WebUIBrowserTest::RunJavascriptTest("checkNoDevices"));
473 IN_PROC_BROWSER_TEST_F(LocalDiscoveryUITest, RegisterTest) {
474 TestMessageLoopCondition condition_token_claimed;
476 ui_test_utils::NavigateToURL(browser(), GURL(
477 chrome::kChromeUIDevicesURL));
478 condition_devices_listed().Wait();
480 test_service_discovery_client()->SimulateReceive(
481 kAnnouncePacket, sizeof(kAnnouncePacket));
483 base::MessageLoop::current()->RunUntilIdle();
485 EXPECT_TRUE(WebUIBrowserTest::RunJavascriptTest("checkOneDevice"));
487 EXPECT_TRUE(WebUIBrowserTest::RunJavascriptTest("registerShowOverlay"));
490 InSequence s;
491 EXPECT_CALL(fake_url_fetcher_creator(), OnCreateFakeURLFetcher(kURLInfo));
492 EXPECT_CALL(fake_url_fetcher_creator(), OnCreateFakeURLFetcher(
493 kURLRegisterStart));
494 EXPECT_CALL(fake_url_fetcher_creator(), OnCreateFakeURLFetcher(
495 kURLRegisterClaimToken))
496 .WillOnce(InvokeWithoutArgs(&condition_token_claimed,
497 &TestMessageLoopCondition::Signal));
500 EXPECT_TRUE(WebUIBrowserTest::RunJavascriptTest("registerBegin"));
502 condition_token_claimed.Wait();
504 EXPECT_TRUE(WebUIBrowserTest::RunJavascriptTest("expectPageAdding1"));
506 fake_fetcher_factory().SetFakeResponse(
507 GURL(kURLRegisterClaimToken),
508 kResponseRegisterClaimTokenConfirm,
509 net::HTTP_OK,
510 net::URLRequestStatus::SUCCESS);
512 fake_fetcher_factory().SetFakeResponse(
513 GURL(kURLInfo),
514 kResponseInfoWithID,
515 net::HTTP_OK,
516 net::URLRequestStatus::SUCCESS);
519 InSequence s;
520 EXPECT_CALL(fake_url_fetcher_creator(), OnCreateFakeURLFetcher(
521 kURLRegisterClaimToken));
522 EXPECT_CALL(fake_url_fetcher_creator(), OnCreateFakeURLFetcher(
523 kURLCloudPrintConfirm));
524 EXPECT_CALL(fake_url_fetcher_creator(), OnCreateFakeURLFetcher(
525 kURLRegisterComplete));
526 EXPECT_CALL(fake_url_fetcher_creator(), OnCreateFakeURLFetcher(kURLInfo))
527 .WillOnce(InvokeWithoutArgs(&condition_token_claimed,
528 &TestMessageLoopCondition::Signal));
531 condition_token_claimed.Wait();
533 test_service_discovery_client()->SimulateReceive(
534 kAnnouncePacketRegistered, sizeof(kAnnouncePacketRegistered));
536 base::MessageLoop::current()->RunUntilIdle();
538 EXPECT_TRUE(WebUIBrowserTest::RunJavascriptTest("expectRegisterDone"));
541 } // namespace
543 } // namespace local_discovery