Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / jingle / notifier / communicator / single_login_attempt_unittest.cc
1 // Copyright (c) 2012 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 "jingle/notifier/communicator/single_login_attempt.h"
6
7 #include <cstddef>
8
9 #include "base/compiler_specific.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/message_loop/message_loop.h"
12 #include "jingle/notifier/base/const_communicator.h"
13 #include "jingle/notifier/base/fake_base_task.h"
14 #include "jingle/notifier/communicator/login_settings.h"
15 #include "net/dns/mock_host_resolver.h"
16 #include "net/url_request/url_request_test_util.h"
17 #include "talk/xmpp/constants.h"
18 #include "talk/xmpp/xmppengine.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20 #include "third_party/webrtc/libjingle/xmllite/xmlelement.h"
21
22 namespace buzz {
23 class XmppTaskParentInterface;
24 }  // namespace buzz
25
26 namespace notifier {
27
28 namespace {
29
30 enum DelegateState {
31   IDLE, CONNECTED, REDIRECTED, CREDENTIALS_REJECTED, SETTINGS_EXHAUSTED
32 };
33
34 class FakeDelegate : public SingleLoginAttempt::Delegate {
35  public:
36   FakeDelegate() : state_(IDLE) {}
37
38   virtual void OnConnect(
39       base::WeakPtr<buzz::XmppTaskParentInterface> base_task) OVERRIDE {
40     state_ = CONNECTED;
41     base_task_ = base_task;
42   }
43
44   virtual void OnRedirect(const ServerInformation& redirect_server) OVERRIDE {
45     state_ = REDIRECTED;
46     redirect_server_ = redirect_server;
47   }
48
49   virtual void OnCredentialsRejected() OVERRIDE {
50     state_ = CREDENTIALS_REJECTED;
51   }
52
53   virtual void OnSettingsExhausted() OVERRIDE {
54     state_ = SETTINGS_EXHAUSTED;
55   }
56
57   DelegateState state() const { return state_; }
58
59   base::WeakPtr<buzz::XmppTaskParentInterface> base_task() const {
60     return base_task_;
61   }
62
63   const ServerInformation& redirect_server() const {
64     return redirect_server_;
65   }
66
67  private:
68   DelegateState state_;
69   base::WeakPtr<buzz::XmppTaskParentInterface> base_task_;
70   ServerInformation redirect_server_;
71 };
72
73 class MyTestURLRequestContext : public net::TestURLRequestContext {
74  public:
75   MyTestURLRequestContext() : TestURLRequestContext(true) {
76     context_storage_.set_host_resolver(
77         scoped_ptr<net::HostResolver>(new net::HangingHostResolver()));
78     Init();
79   }
80   virtual ~MyTestURLRequestContext() {}
81 };
82
83 class SingleLoginAttemptTest : public ::testing::Test {
84  protected:
85   SingleLoginAttemptTest()
86       : login_settings_(
87           buzz::XmppClientSettings(),
88           new net::TestURLRequestContextGetter(
89               base::MessageLoopProxy::current(),
90               scoped_ptr<net::TestURLRequestContext>(
91                   new MyTestURLRequestContext())),
92           ServerList(
93               1,
94               ServerInformation(
95                   net::HostPortPair("example.com", 100), SUPPORTS_SSLTCP)),
96           false /* try_ssltcp_first */,
97           "auth_mechanism"),
98         attempt_(new SingleLoginAttempt(login_settings_, &fake_delegate_)) {}
99
100   virtual void TearDown() OVERRIDE {
101     message_loop_.RunUntilIdle();
102   }
103
104   void FireRedirect(buzz::XmlElement* redirect_error) {
105     attempt_->OnError(buzz::XmppEngine::ERROR_STREAM, 0, redirect_error);
106   }
107
108   virtual ~SingleLoginAttemptTest() {
109     attempt_.reset();
110     message_loop_.RunUntilIdle();
111   }
112
113  private:
114   base::MessageLoop message_loop_;
115   const LoginSettings login_settings_;
116
117  protected:
118   scoped_ptr<SingleLoginAttempt> attempt_;
119   FakeDelegate fake_delegate_;
120   FakeBaseTask fake_base_task_;
121 };
122
123 // Fire OnConnect and make sure the base task gets passed to the
124 // delegate properly.
125 TEST_F(SingleLoginAttemptTest, Basic) {
126   attempt_->OnConnect(fake_base_task_.AsWeakPtr());
127   EXPECT_EQ(CONNECTED, fake_delegate_.state());
128   EXPECT_EQ(fake_base_task_.AsWeakPtr().get(),
129             fake_delegate_.base_task().get());
130 }
131
132 // Fire OnErrors and make sure the delegate gets the
133 // OnSettingsExhausted() event.
134 TEST_F(SingleLoginAttemptTest, Error) {
135   for (int i = 0; i < 2; ++i) {
136     EXPECT_EQ(IDLE, fake_delegate_.state());
137     attempt_->OnError(buzz::XmppEngine::ERROR_NONE, 0, NULL);
138   }
139   EXPECT_EQ(SETTINGS_EXHAUSTED, fake_delegate_.state());
140 }
141
142 // Fire OnErrors but replace the last one with OnConnect, and make
143 // sure the delegate still gets the OnConnect message.
144 TEST_F(SingleLoginAttemptTest, ErrorThenSuccess) {
145   attempt_->OnError(buzz::XmppEngine::ERROR_NONE, 0, NULL);
146   attempt_->OnConnect(fake_base_task_.AsWeakPtr());
147   EXPECT_EQ(CONNECTED, fake_delegate_.state());
148   EXPECT_EQ(fake_base_task_.AsWeakPtr().get(),
149             fake_delegate_.base_task().get());
150 }
151
152 buzz::XmlElement* MakeRedirectError(const std::string& redirect_server) {
153   buzz::XmlElement* stream_error =
154       new buzz::XmlElement(buzz::QN_STREAM_ERROR, true);
155   stream_error->AddElement(
156       new buzz::XmlElement(buzz::QN_XSTREAM_SEE_OTHER_HOST, true));
157   buzz::XmlElement* text =
158       new buzz::XmlElement(buzz::QN_XSTREAM_TEXT, true);
159   stream_error->AddElement(text);
160   text->SetBodyText(redirect_server);
161   return stream_error;
162 }
163
164 // Fire a redirect and make sure the delegate gets the proper redirect
165 // server info.
166 TEST_F(SingleLoginAttemptTest, Redirect) {
167   const ServerInformation redirect_server(
168       net::HostPortPair("example.com", 1000),
169       SUPPORTS_SSLTCP);
170
171   scoped_ptr<buzz::XmlElement> redirect_error(
172       MakeRedirectError(redirect_server.server.ToString()));
173   FireRedirect(redirect_error.get());
174
175   EXPECT_EQ(REDIRECTED, fake_delegate_.state());
176   EXPECT_TRUE(fake_delegate_.redirect_server().Equals(redirect_server));
177 }
178
179 // Fire a redirect with the host only and make sure the delegate gets
180 // the proper redirect server info with the default XMPP port.
181 TEST_F(SingleLoginAttemptTest, RedirectHostOnly) {
182   const ServerInformation redirect_server(
183       net::HostPortPair("example.com", kDefaultXmppPort),
184       SUPPORTS_SSLTCP);
185
186   scoped_ptr<buzz::XmlElement> redirect_error(
187       MakeRedirectError(redirect_server.server.host()));
188   FireRedirect(redirect_error.get());
189
190   EXPECT_EQ(REDIRECTED, fake_delegate_.state());
191   EXPECT_TRUE(fake_delegate_.redirect_server().Equals(redirect_server));
192 }
193
194 // Fire a redirect with a zero port and make sure the delegate gets
195 // the proper redirect server info with the default XMPP port.
196 TEST_F(SingleLoginAttemptTest, RedirectZeroPort) {
197   const ServerInformation redirect_server(
198       net::HostPortPair("example.com", kDefaultXmppPort),
199       SUPPORTS_SSLTCP);
200
201   scoped_ptr<buzz::XmlElement> redirect_error(
202       MakeRedirectError(redirect_server.server.host() + ":0"));
203   FireRedirect(redirect_error.get());
204
205   EXPECT_EQ(REDIRECTED, fake_delegate_.state());
206   EXPECT_TRUE(fake_delegate_.redirect_server().Equals(redirect_server));
207 }
208
209 // Fire a redirect with an invalid port and make sure the delegate
210 // gets the proper redirect server info with the default XMPP port.
211 TEST_F(SingleLoginAttemptTest, RedirectInvalidPort) {
212   const ServerInformation redirect_server(
213       net::HostPortPair("example.com", kDefaultXmppPort),
214       SUPPORTS_SSLTCP);
215
216   scoped_ptr<buzz::XmlElement> redirect_error(
217       MakeRedirectError(redirect_server.server.host() + ":invalidport"));
218   FireRedirect(redirect_error.get());
219
220   EXPECT_EQ(REDIRECTED, fake_delegate_.state());
221   EXPECT_TRUE(fake_delegate_.redirect_server().Equals(redirect_server));
222 }
223
224 // Fire an empty redirect and make sure the delegate does not get a
225 // redirect.
226 TEST_F(SingleLoginAttemptTest, RedirectEmpty) {
227   scoped_ptr<buzz::XmlElement> redirect_error(MakeRedirectError(std::string()));
228   FireRedirect(redirect_error.get());
229   EXPECT_EQ(IDLE, fake_delegate_.state());
230 }
231
232 // Fire a redirect with a missing text element and make sure the
233 // delegate does not get a redirect.
234 TEST_F(SingleLoginAttemptTest, RedirectMissingText) {
235   scoped_ptr<buzz::XmlElement> redirect_error(MakeRedirectError(std::string()));
236   redirect_error->RemoveChildAfter(redirect_error->FirstChild());
237   FireRedirect(redirect_error.get());
238   EXPECT_EQ(IDLE, fake_delegate_.state());
239 }
240
241 // Fire a redirect with a missing see-other-host element and make sure
242 // the delegate does not get a redirect.
243 TEST_F(SingleLoginAttemptTest, RedirectMissingSeeOtherHost) {
244   scoped_ptr<buzz::XmlElement> redirect_error(MakeRedirectError(std::string()));
245   redirect_error->RemoveChildAfter(NULL);
246   FireRedirect(redirect_error.get());
247   EXPECT_EQ(IDLE, fake_delegate_.state());
248 }
249
250 // Fire 'Unauthorized' errors and make sure the delegate gets the
251 // OnCredentialsRejected() event.
252 TEST_F(SingleLoginAttemptTest, CredentialsRejected) {
253   attempt_->OnError(buzz::XmppEngine::ERROR_UNAUTHORIZED, 0, NULL);
254   EXPECT_EQ(CREDENTIALS_REJECTED, fake_delegate_.state());
255 }
256
257 }  // namespace
258
259 }  // namespace notifier