Home | History | Annotate | Download | only in geolocation
      1 // Copyright (c) 2010 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 "content/browser/geolocation/access_token_store.h"
      6 
      7 #include "base/string_util.h"
      8 #include "base/utf_string_conversions.h"
      9 #include "chrome/test/in_process_browser_test.h"
     10 #include "chrome/test/ui_test_utils.h"
     11 #include "content/browser/browser_thread.h"
     12 
     13 namespace {
     14 
     15 // The token store factory implementation expects to be used from any well-known
     16 // chrome thread other than UI. We could use any arbitrary thread; IO is
     17 // a good choice as this is the expected usage.
     18 const BrowserThread::ID kExpectedClientThreadId = BrowserThread::IO;
     19 const char* kRefServerUrl1 = "https://test.domain.example/foo?id=bar.bar";
     20 const char* kRefServerUrl2 = "http://another.domain.example/foo?id=bar.bar#2";
     21 
     22 class GeolocationAccessTokenStoreTest
     23     : public InProcessBrowserTest {
     24  public:
     25   GeolocationAccessTokenStoreTest()
     26       : token_to_expect_(NULL), token_to_set_(NULL) {}
     27 
     28   void DoTestStepAndWaitForResults(
     29       const char* ref_url, const string16* token_to_expect,
     30       const string16* token_to_set);
     31 
     32   void OnAccessTokenStoresLoaded(
     33         AccessTokenStore::AccessTokenSet access_token_set);
     34 
     35   scoped_refptr<AccessTokenStore> token_store_;
     36   CancelableRequestConsumer request_consumer_;
     37   GURL ref_url_;
     38   const string16* token_to_expect_;
     39   const string16* token_to_set_;
     40 };
     41 
     42 void StartTestStepFromClientThread(
     43     scoped_refptr<AccessTokenStore>* store,
     44     CancelableRequestConsumerBase* consumer,
     45     AccessTokenStore::LoadAccessTokensCallbackType* callback) {
     46   ASSERT_TRUE(BrowserThread::CurrentlyOn(kExpectedClientThreadId));
     47   if (*store == NULL)
     48     (*store) = NewChromePrefsAccessTokenStore();
     49   (*store)->LoadAccessTokens(consumer, callback);
     50 }
     51 
     52 struct TokenLoadClientForTest {
     53   void NotReachedCallback(AccessTokenStore::AccessTokenSet /*tokens*/) {
     54     NOTREACHED() << "This request should have been canceled before callback";
     55   }
     56 };
     57 
     58 void RunCancelTestInClientTread() {
     59   ASSERT_TRUE(BrowserThread::CurrentlyOn(kExpectedClientThreadId));
     60   scoped_refptr<AccessTokenStore> store(NewChromePrefsAccessTokenStore());
     61   CancelableRequestConsumer consumer;
     62   TokenLoadClientForTest load_client;
     63 
     64   // Single request, canceled explicitly
     65   CancelableRequestProvider::Handle first_handle =
     66       store->LoadAccessTokens(&consumer, NewCallback(
     67           &load_client, &TokenLoadClientForTest::NotReachedCallback));
     68   EXPECT_TRUE(consumer.HasPendingRequests());
     69   // Test this handle is valid.
     70   consumer.GetClientData(store.get(), first_handle);
     71   store->CancelRequest(first_handle);
     72   EXPECT_FALSE(consumer.HasPendingRequests());
     73 
     74   // 2 requests, canceled globally.
     75   store->LoadAccessTokens(&consumer, NewCallback(
     76       &load_client, &TokenLoadClientForTest::NotReachedCallback));
     77   store->LoadAccessTokens(&consumer, NewCallback(
     78       &load_client, &TokenLoadClientForTest::NotReachedCallback));
     79   EXPECT_TRUE(consumer.HasPendingRequests());
     80   EXPECT_EQ(2u, consumer.PendingRequestCount());
     81   consumer.CancelAllRequests();
     82   EXPECT_FALSE(consumer.HasPendingRequests());
     83   EXPECT_EQ(0u, consumer.PendingRequestCount());
     84 
     85   BrowserThread::PostTask(
     86       BrowserThread::UI, FROM_HERE, new MessageLoop::QuitTask);
     87 }
     88 
     89 void GeolocationAccessTokenStoreTest::DoTestStepAndWaitForResults(
     90     const char* ref_url, const string16* token_to_expect,
     91     const string16* token_to_set) {
     92   ref_url_ = GURL(ref_url);
     93   token_to_expect_ = token_to_expect;
     94   token_to_set_ = token_to_set;
     95 
     96   BrowserThread::PostTask(
     97       kExpectedClientThreadId, FROM_HERE, NewRunnableFunction(
     98           &StartTestStepFromClientThread, &token_store_, &request_consumer_,
     99           NewCallback(this,
    100               &GeolocationAccessTokenStoreTest::OnAccessTokenStoresLoaded)));
    101   ui_test_utils::RunMessageLoop();
    102 }
    103 
    104 void GeolocationAccessTokenStoreTest::OnAccessTokenStoresLoaded(
    105     AccessTokenStore::AccessTokenSet access_token_set) {
    106   ASSERT_TRUE(BrowserThread::CurrentlyOn(kExpectedClientThreadId))
    107       << "Callback from token factory should be from the same thread as the "
    108          "LoadAccessTokenStores request was made on";
    109   EXPECT_TRUE(token_to_set_ || token_to_expect_) << "No work to do?";
    110   AccessTokenStore::AccessTokenSet::const_iterator item =
    111       access_token_set.find(ref_url_);
    112   if (!token_to_expect_) {
    113     EXPECT_TRUE(item == access_token_set.end());
    114   } else {
    115     EXPECT_FALSE(item == access_token_set.end());
    116     EXPECT_EQ(*token_to_expect_, item->second);
    117   }
    118 
    119   if (token_to_set_) {
    120     scoped_refptr<AccessTokenStore> store(
    121         NewChromePrefsAccessTokenStore());
    122     store->SaveAccessToken(ref_url_, *token_to_set_);
    123   }
    124   BrowserThread::PostTask(
    125       BrowserThread::UI, FROM_HERE, new MessageLoop::QuitTask);
    126 }
    127 
    128 IN_PROC_BROWSER_TEST_F(GeolocationAccessTokenStoreTest, SetAcrossInstances) {
    129   const string16 ref_token1 = ASCIIToUTF16("jksdfo90,'s#\"#1*(");
    130   const string16 ref_token2 = ASCIIToUTF16("\1\2\3\4\5\6\7\10\11\12=023");
    131   ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
    132 
    133   DoTestStepAndWaitForResults(kRefServerUrl1, NULL, &ref_token1);
    134   // Check it was set, and change to new value.
    135   DoTestStepAndWaitForResults(kRefServerUrl1, &ref_token1, &ref_token2);
    136   // And change back.
    137   DoTestStepAndWaitForResults(kRefServerUrl1, &ref_token2, &ref_token1);
    138   DoTestStepAndWaitForResults(kRefServerUrl1, &ref_token1, NULL);
    139 
    140   // Set a second server URL
    141   DoTestStepAndWaitForResults(kRefServerUrl2, NULL, &ref_token2);
    142   DoTestStepAndWaitForResults(kRefServerUrl2, &ref_token2, NULL);
    143   DoTestStepAndWaitForResults(kRefServerUrl1, &ref_token1, NULL);
    144 }
    145 
    146 IN_PROC_BROWSER_TEST_F(GeolocationAccessTokenStoreTest, CancelRequest) {
    147   BrowserThread::PostTask(
    148       kExpectedClientThreadId, FROM_HERE, NewRunnableFunction(
    149           RunCancelTestInClientTread));
    150   ui_test_utils::RunMessageLoop();
    151 }
    152 
    153 }  // namespace
    154