1// Copyright (c) 2011 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/bind.h" 6#include "base/bind_helpers.h" 7#include "base/strings/string_util.h" 8#include "base/strings/utf_string_conversions.h" 9#include "chrome/browser/geolocation/chrome_access_token_store.h" 10#include "chrome/test/base/in_process_browser_test.h" 11#include "chrome/test/base/ui_test_utils.h" 12#include "content/public/browser/access_token_store.h" 13#include "content/public/test/test_browser_thread.h" 14 15using content::AccessTokenStore; 16using content::BrowserThread; 17 18namespace { 19 20// The token store factory implementation expects to be used from any well-known 21// chrome thread other than UI. We could use any arbitrary thread; IO is 22// a good choice as this is the expected usage. 23const BrowserThread::ID kExpectedClientThreadId = BrowserThread::IO; 24const char* kRefServerUrl1 = "https://test.domain.example/foo?id=bar.bar"; 25const char* kRefServerUrl2 = "http://another.domain.example/foo?id=bar.bar#2"; 26const char* kOldDefaultNetworkProviderUrl = "https://www.google.com/loc/json"; 27 28class GeolocationAccessTokenStoreTest 29 : public InProcessBrowserTest { 30 public: 31 GeolocationAccessTokenStoreTest() 32 : token_to_expect_(NULL), token_to_set_(NULL) {} 33 34 void DoTestStepAndWaitForResults( 35 const char* ref_url, const base::string16* token_to_expect, 36 const base::string16* token_to_set); 37 38 void OnAccessTokenStoresLoaded( 39 AccessTokenStore::AccessTokenSet access_token_set, 40 net::URLRequestContextGetter* context_getter); 41 42 scoped_refptr<AccessTokenStore> token_store_; 43 GURL ref_url_; 44 const base::string16* token_to_expect_; 45 const base::string16* token_to_set_; 46}; 47 48void StartTestStepFromClientThread( 49 scoped_refptr<AccessTokenStore>* store, 50 const AccessTokenStore::LoadAccessTokensCallbackType& callback) { 51 ASSERT_TRUE(BrowserThread::CurrentlyOn(kExpectedClientThreadId)); 52 if (store->get() == NULL) 53 (*store) = new ChromeAccessTokenStore(); 54 (*store)->LoadAccessTokens(callback); 55} 56 57struct TokenLoadClientForTest { 58 void NotReachedCallback(AccessTokenStore::AccessTokenSet /*tokens*/, 59 net::URLRequestContextGetter* /*context_getter*/) { 60 NOTREACHED() << "This request should have been canceled before callback"; 61 } 62}; 63 64void GeolocationAccessTokenStoreTest::DoTestStepAndWaitForResults( 65 const char* ref_url, const base::string16* token_to_expect, 66 const base::string16* token_to_set) { 67 ref_url_ = GURL(ref_url); 68 token_to_expect_ = token_to_expect; 69 token_to_set_ = token_to_set; 70 71 BrowserThread::PostTask( 72 kExpectedClientThreadId, FROM_HERE, 73 base::Bind( 74 &StartTestStepFromClientThread, 75 &token_store_, 76 base::Bind( 77 &GeolocationAccessTokenStoreTest::OnAccessTokenStoresLoaded, 78 base::Unretained(this)))); 79 content::RunMessageLoop(); 80} 81 82void GeolocationAccessTokenStoreTest::OnAccessTokenStoresLoaded( 83 AccessTokenStore::AccessTokenSet access_token_set, 84 net::URLRequestContextGetter* context_getter) { 85 ASSERT_TRUE(BrowserThread::CurrentlyOn(kExpectedClientThreadId)) 86 << "Callback from token factory should be from the same thread as the " 87 "LoadAccessTokenStores request was made on"; 88 DCHECK(context_getter); 89 AccessTokenStore::AccessTokenSet::const_iterator item = 90 access_token_set.find(ref_url_); 91 if (!token_to_expect_) { 92 EXPECT_TRUE(item == access_token_set.end()); 93 } else { 94 EXPECT_FALSE(item == access_token_set.end()); 95 EXPECT_EQ(*token_to_expect_, item->second); 96 } 97 98 if (token_to_set_) { 99 scoped_refptr<AccessTokenStore> store(new ChromeAccessTokenStore()); 100 store->SaveAccessToken(ref_url_, *token_to_set_); 101 } 102 BrowserThread::PostTask( 103 BrowserThread::UI, FROM_HERE, base::MessageLoop::QuitClosure()); 104} 105 106IN_PROC_BROWSER_TEST_F(GeolocationAccessTokenStoreTest, SetAcrossInstances) { 107 const base::string16 ref_token1 = base::ASCIIToUTF16("jksdfo90,'s#\"#1*("); 108 const base::string16 ref_token2 = 109 base::ASCIIToUTF16("\1\2\3\4\5\6\7\10\11\12=023"); 110 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI)); 111 112 DoTestStepAndWaitForResults(kRefServerUrl1, NULL, &ref_token1); 113 // Check it was set, and change to new value. 114 DoTestStepAndWaitForResults(kRefServerUrl1, &ref_token1, &ref_token2); 115 // And change back. 116 DoTestStepAndWaitForResults(kRefServerUrl1, &ref_token2, &ref_token1); 117 DoTestStepAndWaitForResults(kRefServerUrl1, &ref_token1, NULL); 118 119 // Set a second server URL 120 DoTestStepAndWaitForResults(kRefServerUrl2, NULL, &ref_token2); 121 DoTestStepAndWaitForResults(kRefServerUrl2, &ref_token2, NULL); 122 DoTestStepAndWaitForResults(kRefServerUrl1, &ref_token1, NULL); 123} 124 125IN_PROC_BROWSER_TEST_F(GeolocationAccessTokenStoreTest, OldUrlRemoval) { 126 const base::string16 ref_token1 = base::ASCIIToUTF16("jksdfo90,'s#\"#1*("); 127 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI)); 128 129 // Set a token for the old default network provider url. 130 DoTestStepAndWaitForResults(kOldDefaultNetworkProviderUrl, 131 NULL, &ref_token1); 132 // Check that the token related to the old default network provider url 133 // was deleted. 134 DoTestStepAndWaitForResults(kOldDefaultNetworkProviderUrl, 135 NULL, NULL); 136} 137 138} // namespace 139