Home | History | Annotate | Download | only in local_discovery
      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.
      4 
      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/profiles/profile.h"
     14 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
     15 #include "chrome/browser/signin/signin_manager_factory.h"
     16 #include "chrome/browser/ui/browser.h"
     17 #include "chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.h"
     18 #include "chrome/common/chrome_switches.h"
     19 #include "chrome/common/url_constants.h"
     20 #include "chrome/test/base/ui_test_utils.h"
     21 #include "chrome/test/base/web_ui_browser_test.h"
     22 #include "components/signin/core/browser/profile_oauth2_token_service.h"
     23 #include "components/signin/core/browser/signin_manager.h"
     24 #include "components/signin/core/browser/signin_manager_base.h"
     25 #include "google_apis/gaia/gaia_urls.h"
     26 #include "net/http/http_status_code.h"
     27 #include "net/url_request/test_url_fetcher_factory.h"
     28 #include "net/url_request/url_request_status.h"
     29 #include "net/url_request/url_request_test_util.h"
     30 
     31 #if defined(OS_CHROMEOS)
     32 #include "base/prefs/pref_service.h"
     33 #include "chrome/common/pref_names.h"
     34 #endif
     35 
     36 using testing::InvokeWithoutArgs;
     37 using testing::Return;
     38 using testing::AtLeast;
     39 using testing::DoDefault;
     40 using testing::DoAll;
     41 using testing::InSequence;
     42 using testing::StrictMock;
     43 using testing::AnyNumber;
     44 
     45 using testing::InvokeWithoutArgs;
     46 using testing::Return;
     47 using testing::AtLeast;
     48 
     49 namespace local_discovery {
     50 
     51 namespace {
     52 
     53 const uint8 kQueryData[] = {
     54   // Header
     55   0x00, 0x00,
     56   0x00, 0x00,               // Flags not set.
     57   0x00, 0x01,               // Set QDCOUNT (question count) to 1, all the
     58   // rest are 0 for a query.
     59   0x00, 0x00,
     60   0x00, 0x00,
     61   0x00, 0x00,
     62 
     63   // Question
     64   0x07, '_', 'p', 'r', 'i', 'v', 'e', 't',
     65   0x04, '_', 't', 'c', 'p',
     66   0x05, 'l', 'o', 'c', 'a', 'l',
     67   0x00,
     68 
     69   0x00, 0x0c,               // QTYPE: A query.
     70   0x00, 0x01,               // QCLASS: IN class. Unicast bit not set.
     71 };
     72 
     73 const uint8 kAnnouncePacket[] = {
     74   // Header
     75   0x00, 0x00,               // ID is zeroed out
     76   0x80, 0x00,               // Standard query response, no error
     77   0x00, 0x00,               // No questions (for simplicity)
     78   0x00, 0x05,               // 5 RR (answers)
     79   0x00, 0x00,               // 0 authority RRs
     80   0x00, 0x00,               // 0 additional RRs
     81 
     82   0x07, '_', 'p', 'r', 'i', 'v', 'e', 't',
     83   0x04, '_', 't', 'c', 'p',
     84   0x05, 'l', 'o', 'c', 'a', 'l',
     85   0x00,
     86   0x00, 0x0c,        // TYPE is PTR.
     87   0x00, 0x01,        // CLASS is IN.
     88   0x00, 0x00,        // TTL (4 bytes) is 32768 second.
     89   0x10, 0x00,
     90   0x00, 0x0c,        // RDLENGTH is 12 bytes.
     91   0x09, 'm', 'y', 'S', 'e', 'r', 'v', 'i', 'c', 'e',
     92   0xc0, 0x0c,
     93 
     94   0x09, 'm', 'y', 'S', 'e', 'r', 'v', 'i', 'c', 'e',
     95   0xc0, 0x0c,
     96   0x00, 0x10,        // TYPE is TXT.
     97   0x00, 0x01,        // CLASS is IN.
     98   0x00, 0x00,        // TTL (4 bytes) is 32768 seconds.
     99   0x01, 0x00,
    100   0x00, 0x41,        // RDLENGTH is 69 bytes.
    101   0x03, 'i', 'd', '=',
    102   0x10, 't', 'y', '=', 'S', 'a', 'm', 'p', 'l', 'e', ' ',
    103         'd', 'e', 'v', 'i', 'c', 'e',
    104   0x1e, 'n', 'o', 't', 'e', '=',
    105         'S', 'a', 'm', 'p', 'l', 'e', ' ', 'd', 'e', 'v', 'i', 'c', 'e', ' ',
    106         'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'i', 'o', 'n',
    107   0x0c, 't', 'y', 'p', 'e', '=', 'p', 'r', 'i', 'n', 't', 'e', 'r',
    108 
    109   0x09, 'm', 'y', 'S', 'e', 'r', 'v', 'i', 'c', 'e',
    110   0xc0, 0x0c,
    111   0x00, 0x21,        // Type is SRV
    112   0x00, 0x01,        // CLASS is IN
    113   0x00, 0x00,        // TTL (4 bytes) is 32768 second.
    114   0x10, 0x00,
    115   0x00, 0x17,        // RDLENGTH is 23
    116   0x00, 0x00,
    117   0x00, 0x00,
    118   0x22, 0xb8,        // port 8888
    119   0x09, 'm', 'y', 'S', 'e', 'r', 'v', 'i', 'c', 'e',
    120   0x05, 'l', 'o', 'c', 'a', 'l',
    121   0x00,
    122 
    123   0x09, 'm', 'y', 'S', 'e', 'r', 'v', 'i', 'c', 'e',
    124   0x05, 'l', 'o', 'c', 'a', 'l',
    125   0x00,
    126   0x00, 0x01,        // Type is A
    127   0x00, 0x01,        // CLASS is IN
    128   0x00, 0x00,        // TTL (4 bytes) is 32768 second.
    129   0x10, 0x00,
    130   0x00, 0x04,        // RDLENGTH is 4
    131   0x01, 0x02, 0x03, 0x04,  // 1.2.3.4
    132 
    133   0x09, 'm', 'y', 'S', 'e', 'r', 'v', 'i', 'c', 'e',
    134   0x05, 'l', 'o', 'c', 'a', 'l',
    135   0x00,
    136   0x00, 0x1C,        // Type is AAAA
    137   0x00, 0x01,        // CLASS is IN
    138   0x00, 0x00,        // TTL (4 bytes) is 32768 second.
    139   0x10, 0x00,
    140   0x00, 0x10,        // RDLENGTH is 16
    141   0x01, 0x02, 0x03, 0x04,  // 1.2.3.4
    142   0x01, 0x02, 0x03, 0x04,
    143   0x01, 0x02, 0x03, 0x04,
    144   0x01, 0x02, 0x03, 0x04,
    145 };
    146 
    147 
    148 const uint8 kGoodbyePacket[] = {
    149   // Header
    150   0x00, 0x00,               // ID is zeroed out
    151   0x80, 0x00,               // Standard query response, RA, no error
    152   0x00, 0x00,               // No questions (for simplicity)
    153   0x00, 0x02,               // 1 RR (answers)
    154   0x00, 0x00,               // 0 authority RRs
    155   0x00, 0x00,               // 0 additional RRs
    156 
    157   0x07, '_', 'p', 'r', 'i', 'v', 'e', 't',
    158   0x04, '_', 't', 'c', 'p',
    159   0x05, 'l', 'o', 'c', 'a', 'l',
    160   0x00,
    161   0x00, 0x0c,        // TYPE is PTR.
    162   0x00, 0x01,        // CLASS is IN.
    163   0x00, 0x00,        // TTL (4 bytes) is 0 seconds.
    164   0x00, 0x00,
    165   0x00, 0x0c,        // RDLENGTH is 12 bytes.
    166   0x09, 'm', 'y', 'S', 'e', 'r', 'v', 'i', 'c', 'e',
    167   0xc0, 0x0c,
    168 
    169 
    170   0x09, 'm', 'y', 'S', 'e', 'r', 'v', 'i', 'c', 'e',
    171   0xc0, 0x0c,
    172   0x00, 0x21,        // Type is SRV
    173   0x00, 0x01,        // CLASS is IN
    174   0x00, 0x00,        // TTL (4 bytes) is 0 seconds.
    175   0x00, 0x00,
    176   0x00, 0x17,        // RDLENGTH is 23
    177   0x00, 0x00,
    178   0x00, 0x00,
    179   0x22, 0xb8,        // port 8888
    180   0x09, 'm', 'y', 'S', 'e', 'r', 'v', 'i', 'c', 'e',
    181   0x05, 'l', 'o', 'c', 'a', 'l',
    182   0x00,
    183 };
    184 
    185 const uint8 kAnnouncePacketRegistered[] = {
    186   // Header
    187   0x00, 0x00,               // ID is zeroed out
    188   0x80, 0x00,               // Standard query response, RA, no error
    189   0x00, 0x00,               // No questions (for simplicity)
    190   0x00, 0x01,               // 1 RR (answers)
    191   0x00, 0x00,               // 0 authority RRs
    192   0x00, 0x00,               // 0 additional RRs
    193 
    194   0x09, 'm', 'y', 'S', 'e', 'r', 'v', 'i', 'c', 'e',
    195   0x07, '_', 'p', 'r', 'i', 'v', 'e', 't',
    196   0x04, '_', 't', 'c', 'p',
    197   0x05, 'l', 'o', 'c', 'a', 'l',
    198   0x00,
    199   0x00, 0x10,        // TYPE is TXT.
    200   0x00, 0x01,        // CLASS is IN.
    201   0x00, 0x00,        // TTL (4 bytes) is 32768 seconds.
    202   0x01, 0x00,
    203   0x00, 0x3b,        // RDLENGTH is 76 bytes.
    204   0x0a, 'i', 'd', '=', 's', 'o', 'm', 'e', '_', 'i', 'd',
    205   0x10, 't', 'y', '=', 'S', 'a', 'm', 'p', 'l', 'e', ' ',
    206         'd', 'e', 'v', 'i', 'c', 'e',
    207   0x1e, 'n', 'o', 't', 'e', '=',
    208         'S', 'a', 'm', 'p', 'l', 'e', ' ', 'd', 'e', 'v', 'i', 'c', 'e', ' ',
    209         'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'i', 'o', 'n',
    210 };
    211 
    212 const char kResponseInfo[] = "{"
    213     "     \"x-privet-token\" : \"MyPrivetToken\""
    214     "}";
    215 
    216 const char kResponseInfoWithID[] = "{"
    217     "     \"x-privet-token\" : \"MyPrivetToken\","
    218     "     \"id\" : \"my_id\""
    219     "}";
    220 
    221 const char kResponseRegisterStart[] = "{"
    222     "     \"action\": \"start\","
    223     "     \"user\": \"user (at) host.com\""
    224     "}";
    225 
    226 const char kResponseRegisterClaimTokenNoConfirm[] = "{"
    227     "    \"action\": \"getClaimToken\","
    228     "    \"user\": \"user (at) host.com\","
    229     "    \"error\": \"pending_user_action\","
    230     "    \"timeout\": 1"
    231     "}";
    232 
    233 const char kResponseRegisterClaimTokenConfirm[] = "{"
    234     "    \"action\": \"getClaimToken\","
    235     "    \"user\": \"user (at) host.com\","
    236     "    \"token\": \"MySampleToken\","
    237     "    \"claim_url\": \"http://someurl.com/\""
    238     "}";
    239 
    240 const char kResponseCloudPrintConfirm[] = "{ \"success\": true }";
    241 
    242 const char kResponseRegisterComplete[] = "{"
    243     "    \"action\": \"complete\","
    244     "    \"user\": \"user (at) host.com\","
    245     "    \"device_id\": \"my_id\""
    246     "}";
    247 
    248 const char kResponseGaiaToken[] = "{"
    249     "  \"access_token\": \"at1\","
    250     "  \"expires_in\": 3600,"
    251     "  \"token_type\": \"Bearer\""
    252     "}";
    253 
    254 const char kResponseGaiaId[] = "{"
    255     "  \"id\": \"12345\""
    256     "}";
    257 
    258 const char kURLInfo[] = "http://1.2.3.4:8888/privet/info";
    259 
    260 const char kURLRegisterStart[] =
    261     "http://1.2.3.4:8888/privet/register?action=start&user=user%40host.com";
    262 
    263 const char kURLRegisterClaimToken[] =
    264     "http://1.2.3.4:8888/privet/register?action=getClaimToken&"
    265     "user=user%40host.com";
    266 
    267 const char kURLCloudPrintConfirm[] =
    268     "https://www.google.com/cloudprint/confirm?token=MySampleToken";
    269 
    270 const char kURLRegisterComplete[] =
    271     "http://1.2.3.4:8888/privet/register?action=complete&user=user%40host.com";
    272 
    273 const char kURLGaiaToken[] =
    274     "https://accounts.google.com/o/oauth2/token";
    275 
    276 const char kSampleUser[] = "user (at) host.com";
    277 
    278 class TestMessageLoopCondition {
    279  public:
    280   TestMessageLoopCondition() : signaled_(false),
    281                                waiting_(false) {
    282   }
    283 
    284   ~TestMessageLoopCondition() {
    285   }
    286 
    287   // Signal a waiting method that it can continue executing.
    288   void Signal() {
    289     signaled_ = true;
    290     if (waiting_)
    291       base::MessageLoop::current()->Quit();
    292   }
    293 
    294   // Pause execution and recursively run the message loop until |Signal()| is
    295   // called. Do not pause if |Signal()| has already been called.
    296   void Wait() {
    297     while (!signaled_) {
    298       waiting_ = true;
    299       base::MessageLoop::current()->Run();
    300       waiting_ = false;
    301     }
    302     signaled_ = false;
    303   }
    304 
    305  private:
    306   bool signaled_;
    307   bool waiting_;
    308 
    309   DISALLOW_COPY_AND_ASSIGN(TestMessageLoopCondition);
    310 };
    311 
    312 class MockableFakeURLFetcherCreator {
    313  public:
    314   MockableFakeURLFetcherCreator() {
    315   }
    316 
    317   ~MockableFakeURLFetcherCreator() {
    318   }
    319 
    320   MOCK_METHOD1(OnCreateFakeURLFetcher, void(const std::string& url));
    321 
    322   scoped_ptr<net::FakeURLFetcher> CreateFakeURLFetcher(
    323       const GURL& url,
    324       net::URLFetcherDelegate* delegate,
    325       const std::string& response_data,
    326       net::HttpStatusCode response_code,
    327       net::URLRequestStatus::Status status) {
    328     OnCreateFakeURLFetcher(url.spec());
    329     return scoped_ptr<net::FakeURLFetcher>(new net::FakeURLFetcher(
    330         url, delegate, response_data, response_code, status));
    331   }
    332 
    333   net::FakeURLFetcherFactory::FakeURLFetcherCreator callback() {
    334     return base::Bind(&MockableFakeURLFetcherCreator::CreateFakeURLFetcher,
    335                       base::Unretained(this));
    336   }
    337 };
    338 
    339 class LocalDiscoveryUITest : public WebUIBrowserTest {
    340  public:
    341   LocalDiscoveryUITest() : fake_fetcher_factory_(
    342       &fetcher_impl_factory_,
    343       fake_url_fetcher_creator_.callback()) {
    344   }
    345   virtual ~LocalDiscoveryUITest() {
    346   }
    347 
    348   virtual void SetUpOnMainThread() OVERRIDE {
    349     WebUIBrowserTest::SetUpOnMainThread();
    350 
    351     test_service_discovery_client_ = new TestServiceDiscoveryClient();
    352     test_service_discovery_client_->Start();
    353     EXPECT_CALL(
    354         *test_service_discovery_client_.get(),
    355         OnSendTo(std::string((const char*)kQueryData, sizeof(kQueryData))))
    356         .Times(AtLeast(2))
    357         .WillOnce(InvokeWithoutArgs(&condition_devices_listed_,
    358                                     &TestMessageLoopCondition::Signal))
    359         .WillRepeatedly(Return());
    360 
    361     SigninManagerBase* signin_manager =
    362         SigninManagerFactory::GetForProfile(browser()->profile());
    363 
    364 #if defined(OS_CHROMEOS)
    365     // Chrome OS initializes prefs::kGoogleServicesUsername to "stub user" so
    366     // we need to override it as well.
    367     browser()->profile()->GetPrefs()->
    368         SetString(prefs::kGoogleServicesUsername, kSampleUser);
    369 #endif
    370     DCHECK(signin_manager);
    371     signin_manager->SetAuthenticatedUsername(kSampleUser);
    372 
    373     fake_fetcher_factory().SetFakeResponse(
    374         GURL(kURLInfo),
    375         kResponseInfo,
    376         net::HTTP_OK,
    377         net::URLRequestStatus::SUCCESS);
    378 
    379     fake_fetcher_factory().SetFakeResponse(
    380         GURL(kURLRegisterStart),
    381         kResponseRegisterStart,
    382         net::HTTP_OK,
    383         net::URLRequestStatus::SUCCESS);
    384 
    385     fake_fetcher_factory().SetFakeResponse(
    386         GURL(kURLRegisterClaimToken),
    387         kResponseRegisterClaimTokenNoConfirm,
    388         net::HTTP_OK,
    389         net::URLRequestStatus::SUCCESS);
    390 
    391     fake_fetcher_factory().SetFakeResponse(
    392         GURL(kURLCloudPrintConfirm),
    393         kResponseCloudPrintConfirm,
    394         net::HTTP_OK,
    395         net::URLRequestStatus::SUCCESS);
    396 
    397     fake_fetcher_factory().SetFakeResponse(
    398         GURL(kURLRegisterComplete),
    399         kResponseRegisterComplete,
    400         net::HTTP_OK,
    401         net::URLRequestStatus::SUCCESS);
    402 
    403     fake_fetcher_factory().SetFakeResponse(
    404         GURL(kURLGaiaToken),
    405         kResponseGaiaToken,
    406         net::HTTP_OK,
    407         net::URLRequestStatus::SUCCESS);
    408 
    409     EXPECT_CALL(fake_url_fetcher_creator(), OnCreateFakeURLFetcher(
    410         kURLGaiaToken))
    411         .Times(AnyNumber());
    412 
    413     fake_fetcher_factory().SetFakeResponse(
    414         GaiaUrls::GetInstance()->oauth_user_info_url(),
    415         kResponseGaiaId,
    416         net::HTTP_OK,
    417         net::URLRequestStatus::SUCCESS);
    418 
    419     EXPECT_CALL(fake_url_fetcher_creator(), OnCreateFakeURLFetcher(
    420         GaiaUrls::GetInstance()->oauth_user_info_url().spec()))
    421         .Times(AnyNumber());
    422 
    423     ProfileOAuth2TokenService* token_service =
    424         ProfileOAuth2TokenServiceFactory::GetForProfile(browser()->profile());
    425 
    426     token_service->UpdateCredentials("user (at) host.com", "MyFakeToken");
    427 
    428     AddLibrary(base::FilePath(FILE_PATH_LITERAL("local_discovery_ui_test.js")));
    429   }
    430 
    431   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
    432     WebUIBrowserTest::SetUpCommandLine(command_line);
    433   }
    434 
    435   void RunFor(base::TimeDelta time_period) {
    436     base::CancelableCallback<void()> callback(base::Bind(
    437         &base::MessageLoop::Quit, base::Unretained(
    438             base::MessageLoop::current())));
    439     base::MessageLoop::current()->PostDelayedTask(
    440         FROM_HERE, callback.callback(), time_period);
    441 
    442     base::MessageLoop::current()->Run();
    443     callback.Cancel();
    444   }
    445 
    446   TestServiceDiscoveryClient* test_service_discovery_client() {
    447     return test_service_discovery_client_.get();
    448   }
    449 
    450   TestMessageLoopCondition& condition_devices_listed() {
    451     return condition_devices_listed_;
    452   }
    453 
    454   net::FakeURLFetcherFactory& fake_fetcher_factory() {
    455     return fake_fetcher_factory_;
    456   }
    457 
    458   MockableFakeURLFetcherCreator& fake_url_fetcher_creator() {
    459     return fake_url_fetcher_creator_;
    460   }
    461 
    462  private:
    463   scoped_refptr<TestServiceDiscoveryClient> test_service_discovery_client_;
    464   TestMessageLoopCondition condition_devices_listed_;
    465 
    466   net::URLFetcherImplFactory fetcher_impl_factory_;
    467   StrictMock<MockableFakeURLFetcherCreator> fake_url_fetcher_creator_;
    468   net::FakeURLFetcherFactory fake_fetcher_factory_;
    469 
    470   DISALLOW_COPY_AND_ASSIGN(LocalDiscoveryUITest);
    471 };
    472 
    473 IN_PROC_BROWSER_TEST_F(LocalDiscoveryUITest, EmptyTest) {
    474   ui_test_utils::NavigateToURL(browser(), GURL(
    475       chrome::kChromeUIDevicesURL));
    476   condition_devices_listed().Wait();
    477   EXPECT_TRUE(WebUIBrowserTest::RunJavascriptTest("checkNoDevices"));
    478 }
    479 
    480 IN_PROC_BROWSER_TEST_F(LocalDiscoveryUITest, AddRowTest) {
    481   ui_test_utils::NavigateToURL(browser(), GURL(
    482       chrome::kChromeUIDevicesURL));
    483   condition_devices_listed().Wait();
    484 
    485   test_service_discovery_client()->SimulateReceive(
    486       kAnnouncePacket, sizeof(kAnnouncePacket));
    487 
    488   base::MessageLoop::current()->RunUntilIdle();
    489 
    490   EXPECT_TRUE(WebUIBrowserTest::RunJavascriptTest("checkOneDevice"));
    491 
    492   test_service_discovery_client()->SimulateReceive(
    493       kGoodbyePacket, sizeof(kGoodbyePacket));
    494 
    495   RunFor(base::TimeDelta::FromMilliseconds(1100));
    496 
    497   EXPECT_TRUE(WebUIBrowserTest::RunJavascriptTest("checkNoDevices"));
    498 }
    499 
    500 
    501 IN_PROC_BROWSER_TEST_F(LocalDiscoveryUITest, RegisterTest) {
    502   TestMessageLoopCondition condition_token_claimed;
    503 
    504   ui_test_utils::NavigateToURL(browser(), GURL(
    505       chrome::kChromeUIDevicesURL));
    506   condition_devices_listed().Wait();
    507 
    508   test_service_discovery_client()->SimulateReceive(
    509       kAnnouncePacket, sizeof(kAnnouncePacket));
    510 
    511   base::MessageLoop::current()->RunUntilIdle();
    512 
    513   EXPECT_TRUE(WebUIBrowserTest::RunJavascriptTest("checkOneDevice"));
    514 
    515   EXPECT_TRUE(WebUIBrowserTest::RunJavascriptTest("registerShowOverlay"));
    516 
    517   {
    518     InSequence s;
    519     EXPECT_CALL(fake_url_fetcher_creator(), OnCreateFakeURLFetcher(kURLInfo));
    520     EXPECT_CALL(fake_url_fetcher_creator(), OnCreateFakeURLFetcher(
    521         kURLRegisterStart));
    522     EXPECT_CALL(fake_url_fetcher_creator(), OnCreateFakeURLFetcher(
    523         kURLRegisterClaimToken))
    524         .WillOnce(InvokeWithoutArgs(&condition_token_claimed,
    525                                     &TestMessageLoopCondition::Signal));
    526   }
    527 
    528   EXPECT_TRUE(WebUIBrowserTest::RunJavascriptTest("registerBegin"));
    529 
    530   condition_token_claimed.Wait();
    531 
    532   EXPECT_TRUE(WebUIBrowserTest::RunJavascriptTest("expectPageAdding1"));
    533 
    534   fake_fetcher_factory().SetFakeResponse(
    535       GURL(kURLRegisterClaimToken),
    536       kResponseRegisterClaimTokenConfirm,
    537       net::HTTP_OK,
    538       net::URLRequestStatus::SUCCESS);
    539 
    540   fake_fetcher_factory().SetFakeResponse(
    541       GURL(kURLInfo),
    542       kResponseInfoWithID,
    543       net::HTTP_OK,
    544       net::URLRequestStatus::SUCCESS);
    545 
    546   {
    547     InSequence s;
    548     EXPECT_CALL(fake_url_fetcher_creator(), OnCreateFakeURLFetcher(
    549         kURLRegisterClaimToken));
    550     EXPECT_CALL(fake_url_fetcher_creator(), OnCreateFakeURLFetcher(
    551         kURLCloudPrintConfirm));
    552     EXPECT_CALL(fake_url_fetcher_creator(), OnCreateFakeURLFetcher(
    553         kURLRegisterComplete));
    554     EXPECT_CALL(fake_url_fetcher_creator(), OnCreateFakeURLFetcher(kURLInfo))
    555         .WillOnce(InvokeWithoutArgs(&condition_token_claimed,
    556                                     &TestMessageLoopCondition::Signal));
    557   }
    558 
    559   condition_token_claimed.Wait();
    560 
    561   test_service_discovery_client()->SimulateReceive(
    562       kAnnouncePacketRegistered, sizeof(kAnnouncePacketRegistered));
    563 
    564   base::MessageLoop::current()->RunUntilIdle();
    565 
    566   EXPECT_TRUE(WebUIBrowserTest::RunJavascriptTest("expectRegisterDone"));
    567 }
    568 
    569 }  // namespace
    570 
    571 }  // namespace local_discovery
    572