summaryrefslogtreecommitdiffstats
path: root/chrome/browser/net/gaia/token_service_unittest.h
blob: 674baf0b84242e466c3a4cfa2976890f4e6a9965 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// This file defines a unit test harness for the profile's token service.

#ifndef CHROME_BROWSER_NET_GAIA_TOKEN_SERVICE_UNITTEST_H_
#define CHROME_BROWSER_NET_GAIA_TOKEN_SERVICE_UNITTEST_H_
#pragma once

#include "chrome/browser/net/gaia/token_service.h"
#include "chrome/browser/password_manager/encryptor.h"
#include "chrome/browser/webdata/web_data_service.h"
#include "chrome/common/net/gaia/gaia_auth_consumer.h"
#include "chrome/test/signaling_task.h"
#include "chrome/test/test_notification_tracker.h"
#include "chrome/test/testing_profile.h"
#include "testing/gtest/include/gtest/gtest.h"

// TestNotificationTracker doesn't do a deep copy on the notification details.
// We have to in order to read it out, or we have a bad ptr, since the details
// are a reference on the stack.
class TokenAvailableTracker : public TestNotificationTracker {
 public:
  const TokenService::TokenAvailableDetails& details() {
    return details_;
  }

 private:
  virtual void Observe(NotificationType type,
                       const NotificationSource& source,
                       const NotificationDetails& details) {
    TestNotificationTracker::Observe(type, source, details);
    if (type == NotificationType::TOKEN_AVAILABLE) {
      Details<const TokenService::TokenAvailableDetails> full = details;
      details_ = *full.ptr();
    }
  }

  TokenService::TokenAvailableDetails details_;
};

class TokenFailedTracker : public TestNotificationTracker {
 public:
  const TokenService::TokenRequestFailedDetails& details() {
    return details_;
  }

 private:
  virtual void Observe(NotificationType type,
                       const NotificationSource& source,
                       const NotificationDetails& details) {
    TestNotificationTracker::Observe(type, source, details);
    if (type == NotificationType::TOKEN_REQUEST_FAILED) {
      Details<const TokenService::TokenRequestFailedDetails> full = details;
      details_ = *full.ptr();
    }
  }

  TokenService::TokenRequestFailedDetails details_;
};

class TokenServiceTestHarness : public testing::Test {
 public:
  TokenServiceTestHarness()
      : ui_thread_(BrowserThread::UI, &message_loop_),
        db_thread_(BrowserThread::DB) {
  }

  virtual void SetUp() {
#if defined(OS_MACOSX)
    Encryptor::UseMockKeychain(true);
#endif
    credentials_.sid = "sid";
    credentials_.lsid = "lsid";
    credentials_.token = "token";
    credentials_.data = "data";

    ASSERT_TRUE(db_thread_.Start());

    profile_.reset(new TestingProfile());
    profile_->CreateWebDataService(false);
    WaitForDBLoadCompletion();

    success_tracker_.ListenFor(NotificationType::TOKEN_AVAILABLE,
                               Source<TokenService>(&service_));
    failure_tracker_.ListenFor(NotificationType::TOKEN_REQUEST_FAILED,
                               Source<TokenService>(&service_));

    service_.Initialize("test", profile_.get());

    URLFetcher::set_factory(NULL);
  }

  virtual void TearDown() {
    // You have to destroy the profile before the db_thread_ stops.
    if (profile_.get()) {
      profile_.reset(NULL);
    }

    db_thread_.Stop();
    MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask);
    MessageLoop::current()->Run();
  }

  void WaitForDBLoadCompletion() {
    // The WebDB does all work on the DB thread. This will add an event
    // to the end of the DB thread, so when we reach this task, all DB
    // operations should be complete.
    WaitableEvent done(false, false);
    BrowserThread::PostTask(
        BrowserThread::DB, FROM_HERE, new SignalingTask(&done));
    done.Wait();

    // Notifications should be returned from the DB thread onto the UI thread.
    message_loop_.RunAllPending();
  }

  MessageLoopForUI message_loop_;
  BrowserThread ui_thread_;  // Mostly so DCHECKS pass.
  BrowserThread db_thread_;  // WDS on here

  TokenService service_;
  TokenAvailableTracker success_tracker_;
  TokenFailedTracker failure_tracker_;
  GaiaAuthConsumer::ClientLoginResult credentials_;
  scoped_ptr<TestingProfile> profile_;
};

#endif  // CHROME_BROWSER_NET_GAIA_TOKEN_SERVICE_UNITTEST_H_