15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h"
7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/geolocation/chrome_access_token_store.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/in_process_browser_test.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/ui_test_utils.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/access_token_store.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/test_browser_thread.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::AccessTokenStore;
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The token store factory implementation expects to be used from any well-known
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// chrome thread other than UI. We could use any arbitrary thread; IO is
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a good choice as this is the expected usage.
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const BrowserThread::ID kExpectedClientThreadId = BrowserThread::IO;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* kRefServerUrl1 = "https://test.domain.example/foo?id=bar.bar";
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* kRefServerUrl2 = "http://another.domain.example/foo?id=bar.bar#2";
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* kOldDefaultNetworkProviderUrl = "https://www.google.com/loc/json";
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GeolocationAccessTokenStoreTest
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public InProcessBrowserTest {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GeolocationAccessTokenStoreTest()
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : token_to_expect_(NULL), token_to_set_(NULL) {}
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DoTestStepAndWaitForResults(
35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const char* ref_url, const base::string16* token_to_expect,
36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const base::string16* token_to_set);
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnAccessTokenStoresLoaded(
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AccessTokenStore::AccessTokenSet access_token_set,
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::URLRequestContextGetter* context_getter);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<AccessTokenStore> token_store_;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL ref_url_;
44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const base::string16* token_to_expect_;
45a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const base::string16* token_to_set_;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void StartTestStepFromClientThread(
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<AccessTokenStore>* store,
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const AccessTokenStore::LoadAccessTokensCallbackType& callback) {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(BrowserThread::CurrentlyOn(kExpectedClientThreadId));
52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (store->get() == NULL)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*store) = new ChromeAccessTokenStore();
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (*store)->LoadAccessTokens(callback);
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct TokenLoadClientForTest {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void NotReachedCallback(AccessTokenStore::AccessTokenSet /*tokens*/,
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          net::URLRequestContextGetter* /*context_getter*/) {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED() << "This request should have been canceled before callback";
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GeolocationAccessTokenStoreTest::DoTestStepAndWaitForResults(
65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const char* ref_url, const base::string16* token_to_expect,
66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16* token_to_set) {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ref_url_ = GURL(ref_url);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  token_to_expect_ = token_to_expect;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  token_to_set_ = token_to_set;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kExpectedClientThreadId, FROM_HERE,
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &StartTestStepFromClientThread,
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &token_store_,
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Bind(
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              &GeolocationAccessTokenStoreTest::OnAccessTokenStoresLoaded,
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              base::Unretained(this))));
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RunMessageLoop();
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GeolocationAccessTokenStoreTest::OnAccessTokenStoresLoaded(
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AccessTokenStore::AccessTokenSet access_token_set,
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::URLRequestContextGetter* context_getter) {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(BrowserThread::CurrentlyOn(kExpectedClientThreadId))
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << "Callback from token factory should be from the same thread as the "
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         "LoadAccessTokenStores request was made on";
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(context_getter);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AccessTokenStore::AccessTokenSet::const_iterator item =
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      access_token_set.find(ref_url_);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!token_to_expect_) {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(item == access_token_set.end());
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(item == access_token_set.end());
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(*token_to_expect_, item->second);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (token_to_set_) {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<AccessTokenStore> store(new ChromeAccessTokenStore());
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    store->SaveAccessToken(ref_url_, *token_to_set_);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      BrowserThread::UI, FROM_HERE, base::MessageLoop::QuitClosure());
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GeolocationAccessTokenStoreTest, SetAcrossInstances) {
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::string16 ref_token1 = base::ASCIIToUTF16("jksdfo90,'s#\"#1*(");
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::string16 ref_token2 =
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::ASCIIToUTF16("\1\2\3\4\5\6\7\10\11\12=023");
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoTestStepAndWaitForResults(kRefServerUrl1, NULL, &ref_token1);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check it was set, and change to new value.
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoTestStepAndWaitForResults(kRefServerUrl1, &ref_token1, &ref_token2);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // And change back.
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoTestStepAndWaitForResults(kRefServerUrl1, &ref_token2, &ref_token1);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoTestStepAndWaitForResults(kRefServerUrl1, &ref_token1, NULL);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set a second server URL
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoTestStepAndWaitForResults(kRefServerUrl2, NULL, &ref_token2);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoTestStepAndWaitForResults(kRefServerUrl2, &ref_token2, NULL);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoTestStepAndWaitForResults(kRefServerUrl1, &ref_token1, NULL);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GeolocationAccessTokenStoreTest, OldUrlRemoval) {
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::string16 ref_token1 = base::ASCIIToUTF16("jksdfo90,'s#\"#1*(");
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set a token for the old default network provider url.
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoTestStepAndWaitForResults(kOldDefaultNetworkProviderUrl,
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              NULL, &ref_token1);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that the token related to the old default network provider url
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // was deleted.
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoTestStepAndWaitForResults(kOldDefaultNetworkProviderUrl,
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              NULL, NULL);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
139