12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string>
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h"
8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/api/push_messaging/sync_setup_helper.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/extension_apitest.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/chrome_switches.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/base/ui_test_utils.h"
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/public/browser/render_frame_host.h"
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/common/extension_set.h"
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/test/result_catcher.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/dns/mock_host_resolver.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kTestExtensionId[] = "mfaehphpebmlbfdiegjnpidmibldjbjk";
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kPasswordFileForTest[] = "password-file-for-test";
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kOverrideUserDataDir[] = "override-user-data-dir";
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace extensions {
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This class provides tests specific to the push messaging
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// canary test server.  These tests require network access,
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// and should not be run by normal buildbots as part of the normal
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// checkin process.
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class PushMessagingCanaryTest : public ExtensionApiTest {
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PushMessagingCanaryTest() {
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_setup_helper_.reset(new SyncSetupHelper());
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~PushMessagingCanaryTest() {
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CommandLine* command_line = CommandLine::ForCurrentProcess();
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(command_line->HasSwitch(kPasswordFileForTest));
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath password_file =
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        command_line->GetSwitchValuePath(kPasswordFileForTest);
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(sync_setup_helper_->ReadPasswordFile(password_file));
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The test framework overrides any command line user-data-dir
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // argument with a /tmp/.org.chromium.Chromium.XXXXXX directory.
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // That happens in the ChromeTestLauncherDelegate, and affects
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // all unit tests (no opt out available).  It intentionally erases
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // any --user-data-dir switch if present and appends a new one.
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Re-override the default data dir for our test so we can persist
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // the profile for this particular test so we can persist the max
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // invalidation version between runs.
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& override_user_data_dir =
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        command_line->GetSwitchValuePath(kOverrideUserDataDir);
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(!override_user_data_dir.empty());
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    command_line->AppendSwitchPath(switches::kUserDataDir,
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   base::FilePath(override_user_data_dir));
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(INFO) << "command line file override switch is "
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              << override_user_data_dir.value();
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ExtensionApiTest::SetUp();
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void InitializeSync() {
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(sync_setup_helper_->InitializeSync(profile()));
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // InProcessBrowserTest override. Destroys the sync client and sync
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // profile created by the test.  We must clean up ProfileSyncServiceHarness
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // now before the profile is cleaned up.
775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void TearDownOnMainThread() OVERRIDE {
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_setup_helper_.reset();
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const SyncSetupHelper* sync_setup_helper() const {
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return sync_setup_helper_.get();
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Override InProcessBrowserTest. Change behavior of the default host
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // resolver to avoid DNS lookup errors, so we can make network calls.
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The resolver object lifetime is managed by sync_test_setup, not here.
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EnableDNSLookupForThisTest(
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new net::RuleBasedHostResolverProc(host_resolver()));
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void TearDownInProcessBrowserTestFixture() OVERRIDE {
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DisableDNSLookupForThisTest();
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Change behavior of the default host resolver to allow DNS lookup
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to proceed instead of being blocked by the test infrastructure.
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void EnableDNSLookupForThisTest(
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      net::RuleBasedHostResolverProc* host_resolver) {
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // mock_host_resolver_override_ takes ownership of the resolver.
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<net::RuleBasedHostResolverProc> resolver =
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new net::RuleBasedHostResolverProc(host_resolver);
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resolver->AllowDirectLookup("*.google.com");
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // On Linux, we use Chromium's NSS implementation which uses the following
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // hosts for certificate verification. Without these overrides, running the
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // integration tests on Linux causes error as we make external DNS lookups.
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resolver->AllowDirectLookup("*.thawte.com");
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resolver->AllowDirectLookup("*.geotrust.com");
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resolver->AllowDirectLookup("*.gstatic.com");
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resolver->AllowDirectLookup("*.googleapis.com");
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    mock_host_resolver_override_.reset(
115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new net::ScopedDefaultHostResolverProc(resolver.get()));
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We need to reset the DNS lookup when we finish, or the test will fail.
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void DisableDNSLookupForThisTest() {
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    mock_host_resolver_override_.reset();
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SyncSetupHelper> sync_setup_helper_;
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This test needs to make live DNS requests for access to
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // GAIA and sync server URLs under google.com. We use a scoped version
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to override the default resolver while the test is active.
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<net::ScopedDefaultHostResolverProc> mock_host_resolver_override_;
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test that a push can make a round trip through the servers.
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This test is disabled to keep it from running on trybots since
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// it requires network access, and it is not a good idea to run
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// this test as part of a checkin or nightly test.
13658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(PushMessagingCanaryTest, MANUAL_ReceivesPush) {
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  InitializeSync();
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const ExtensionSet* installed_extensions = extension_service()->extensions();
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!installed_extensions->Contains(kTestExtensionId)) {
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const Extension* extension =
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        LoadExtension(test_data_dir_.AppendASCII("push_messaging_canary"));
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(extension);
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(installed_extensions->Contains(kTestExtensionId));
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResultCatcher catcher;
1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  catcher.RestrictToBrowserContext(profile());
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const Extension* extension =
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extension_service()->extensions()->GetByID(kTestExtensionId);
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(extension);
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui_test_utils::NavigateToURL(
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser(), extension->GetResourceURL("push_messaging_canary.html"));
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const std::string& client_id = sync_setup_helper()->client_id();
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const std::string& client_secret = sync_setup_helper()->client_secret();
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const std::string& refresh_token = sync_setup_helper()->refresh_token();
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::string16& script_string = base::UTF8ToUTF16(base::StringPrintf(
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "startTestWithCredentials('%s', '%s', '%s');",
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      client_id.c_str(), client_secret.c_str(), refresh_token.c_str()));
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame()->
165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      ExecuteJavaScript(script_string);
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace extensions
171