credential_manager_client_browsertest.cc revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
1// Copyright 2014 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 "components/password_manager/content/common/credential_manager_messages.h"
6#include "components/password_manager/content/renderer/credential_manager_client.h"
7#include "content/public/test/render_view_test.h"
8#include "ipc/ipc_test_sink.h"
9#include "testing/gtest/include/gtest/gtest.h"
10#include "third_party/WebKit/public/platform/WebCredential.h"
11#include "third_party/WebKit/public/platform/WebCredentialManagerClient.h"
12#include "third_party/WebKit/public/platform/WebCredentialManagerError.h"
13
14namespace password_manager {
15
16namespace {
17
18class CredentialManagerClientTest : public content::RenderViewTest {
19 public:
20  CredentialManagerClientTest()
21      : callback_errored_(false), callback_succeeded_(false) {}
22  virtual ~CredentialManagerClientTest() {}
23
24  virtual void SetUp() OVERRIDE {
25    content::RenderViewTest::SetUp();
26    credential_.reset(new blink::WebCredential("", "", GURL()));
27    client_.reset(new CredentialManagerClient(view_));
28  }
29
30  virtual void TearDown() OVERRIDE {
31    credential_.reset();
32    content::RenderViewTest::TearDown();
33  }
34
35  IPC::TestSink& sink() { return render_thread_->sink(); }
36
37  blink::WebCredential* credential() { return credential_.get(); }
38
39  // The browser's response to any of the messages the client sends must contain
40  // a request ID so that the client knows which request is being serviced. This
41  // method grabs the ID from an outgoing |message_id| message, and sets the
42  // |request_id| param to its value. If no request ID can be found, the method
43  // returns false, and the |request_id| is set to -1.
44  //
45  // Clears any pending messages upon return.
46  bool ExtractRequestId(uint32 message_id, int& request_id) {
47    request_id = -1;
48    const IPC::Message* message = sink().GetFirstMessageMatching(message_id);
49    if (!message)
50      return false;
51
52    switch (message_id) {
53      case CredentialManagerHostMsg_NotifyFailedSignIn::ID: {
54        Tuple2<int, CredentialInfo> param;
55        CredentialManagerHostMsg_NotifyFailedSignIn::Read(message, &param);
56        request_id = param.a;
57        break;
58      }
59
60      case CredentialManagerHostMsg_NotifySignedIn::ID: {
61        Tuple2<int, CredentialInfo> param;
62        CredentialManagerHostMsg_NotifySignedIn::Read(message, &param);
63        request_id = param.a;
64        break;
65      }
66
67      case CredentialManagerHostMsg_NotifySignedOut::ID: {
68        Tuple1<int> param;
69        CredentialManagerHostMsg_NotifySignedOut::Read(message, &param);
70        request_id = param.a;
71        break;
72      }
73
74      case CredentialManagerHostMsg_RequestCredential::ID: {
75        Tuple3<int, bool, std::vector<GURL> > param;
76        CredentialManagerHostMsg_RequestCredential::Read(message, &param);
77        request_id = param.a;
78        break;
79      }
80
81      default:
82        break;
83    }
84    sink().ClearMessages();
85    return request_id != -1;
86  }
87
88  bool callback_errored() const { return callback_errored_; }
89  void set_callback_errored(bool state) { callback_errored_ = state; }
90  bool callback_succeeded() const { return callback_succeeded_; }
91  void set_callback_succeeded(bool state) { callback_succeeded_ = state; }
92
93 protected:
94  scoped_ptr<CredentialManagerClient> client_;
95
96  // True if a message's callback's 'onSuccess'/'onError' methods were called,
97  // false otherwise. We put these on the test object rather than on the
98  // Test*Callbacks objects because ownership of those objects passes into the
99  // client, which destroys the callbacks after calling them to resolve the
100  // pending Blink-side Promise.
101  bool callback_errored_;
102  bool callback_succeeded_;
103
104  scoped_ptr<blink::WebCredential> credential_;
105};
106
107class TestNotificationCallbacks
108    : public blink::WebCredentialManagerClient::NotificationCallbacks {
109 public:
110  explicit TestNotificationCallbacks(CredentialManagerClientTest* test)
111      : test_(test) {}
112
113  virtual ~TestNotificationCallbacks() {}
114
115  virtual void onSuccess() OVERRIDE { test_->set_callback_succeeded(true); }
116
117  virtual void onError(blink::WebCredentialManagerError* reason) OVERRIDE {
118    test_->set_callback_errored(true);
119  }
120
121 private:
122  CredentialManagerClientTest* test_;
123};
124
125class TestRequestCallbacks
126    : public blink::WebCredentialManagerClient::RequestCallbacks {
127 public:
128  explicit TestRequestCallbacks(CredentialManagerClientTest* test)
129      : test_(test) {}
130
131  virtual ~TestRequestCallbacks() {}
132
133  virtual void onSuccess(blink::WebCredential*) OVERRIDE {
134    test_->set_callback_succeeded(true);
135  }
136
137  virtual void onError(blink::WebCredentialManagerError* reason) OVERRIDE {
138    test_->set_callback_errored(true);
139  }
140
141 private:
142  CredentialManagerClientTest* test_;
143};
144
145}  // namespace
146
147TEST_F(CredentialManagerClientTest, SendNotifyFailedSignIn) {
148  int request_id;
149  EXPECT_FALSE(ExtractRequestId(CredentialManagerHostMsg_NotifyFailedSignIn::ID,
150                                request_id));
151
152  scoped_ptr<TestNotificationCallbacks> callbacks(
153      new TestNotificationCallbacks(this));
154  client_->dispatchFailedSignIn(*credential(), callbacks.release());
155
156  EXPECT_TRUE(ExtractRequestId(CredentialManagerHostMsg_NotifyFailedSignIn::ID,
157                               request_id));
158
159  client_->OnAcknowledgeFailedSignIn(request_id);
160  EXPECT_TRUE(callback_succeeded());
161  EXPECT_FALSE(callback_errored());
162}
163
164TEST_F(CredentialManagerClientTest, SendNotifySignedIn) {
165  int request_id;
166  EXPECT_FALSE(ExtractRequestId(CredentialManagerHostMsg_NotifySignedIn::ID,
167                                request_id));
168
169  scoped_ptr<TestNotificationCallbacks> callbacks(
170      new TestNotificationCallbacks(this));
171  client_->dispatchSignedIn(*credential(), callbacks.release());
172
173  EXPECT_TRUE(ExtractRequestId(CredentialManagerHostMsg_NotifySignedIn::ID,
174                               request_id));
175
176  client_->OnAcknowledgeSignedIn(request_id);
177  EXPECT_TRUE(callback_succeeded());
178  EXPECT_FALSE(callback_errored());
179}
180
181TEST_F(CredentialManagerClientTest, SendNotifySignedOut) {
182  int request_id;
183  EXPECT_FALSE(ExtractRequestId(CredentialManagerHostMsg_NotifySignedOut::ID,
184                                request_id));
185
186  scoped_ptr<TestNotificationCallbacks> callbacks(
187      new TestNotificationCallbacks(this));
188  client_->dispatchSignedOut(callbacks.release());
189
190  EXPECT_TRUE(ExtractRequestId(CredentialManagerHostMsg_NotifySignedOut::ID,
191                               request_id));
192
193  client_->OnAcknowledgeSignedOut(request_id);
194  EXPECT_TRUE(callback_succeeded());
195  EXPECT_FALSE(callback_errored());
196}
197
198TEST_F(CredentialManagerClientTest, SendRequestCredential) {
199  int request_id;
200  EXPECT_FALSE(ExtractRequestId(CredentialManagerHostMsg_RequestCredential::ID,
201                                request_id));
202
203  scoped_ptr<TestRequestCallbacks> callbacks(new TestRequestCallbacks(this));
204  std::vector<GURL> federations;
205  client_->dispatchRequest(false, federations, callbacks.release());
206
207  EXPECT_TRUE(ExtractRequestId(CredentialManagerHostMsg_RequestCredential::ID,
208                               request_id));
209
210  CredentialInfo info;
211  client_->OnSendCredential(request_id, info);
212  EXPECT_TRUE(callback_succeeded());
213  EXPECT_FALSE(callback_errored());
214}
215
216}  // namespace password_manager
217