Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / components / captive_portal / captive_portal_detector_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 "components/captive_portal/captive_portal_detector.h"
6
7 #include "base/basictypes.h"
8 #include "base/bind.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/run_loop.h"
13 #include "base/time/time.h"
14 #include "components/captive_portal/captive_portal_testing_utils.h"
15 #include "net/base/net_errors.h"
16 #include "net/url_request/url_request_test_util.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "url/gurl.h"
19
20 namespace captive_portal {
21
22 namespace {
23
24 class CaptivePortalClient {
25  public:
26   explicit CaptivePortalClient(CaptivePortalDetector* captive_portal_detector)
27       : num_results_received_(0) {
28   }
29
30   void OnPortalDetectionCompleted(
31       const CaptivePortalDetector::Results& results) {
32     results_ = results;
33     ++num_results_received_;
34   }
35
36   const CaptivePortalDetector::Results& captive_portal_results() const {
37     return results_;
38   }
39
40   int num_results_received() const { return num_results_received_; }
41
42  private:
43   CaptivePortalDetector::Results results_;
44   int num_results_received_;
45
46   DISALLOW_COPY_AND_ASSIGN(CaptivePortalClient);
47 };
48
49 }  // namespace
50
51 class CaptivePortalDetectorTest : public testing::Test,
52                                   public CaptivePortalDetectorTestBase {
53  public:
54   CaptivePortalDetectorTest() {}
55   ~CaptivePortalDetectorTest() override {}
56
57   void SetUp() override {
58     CHECK(base::MessageLoopProxy::current().get());
59     scoped_refptr<net::URLRequestContextGetter> request_context_getter(
60         new net::TestURLRequestContextGetter(
61             base::MessageLoopProxy::current()));
62
63     detector_.reset(new CaptivePortalDetector(request_context_getter.get()));
64     set_detector(detector_.get());
65   }
66
67   void TearDown() override { detector_.reset(); }
68
69   void RunTest(const CaptivePortalDetector::Results& expected_results,
70                int net_error,
71                int status_code,
72                const char* response_headers) {
73     ASSERT_FALSE(FetchingURL());
74
75     GURL url(CaptivePortalDetector::kDefaultURL);
76     CaptivePortalClient client(detector());
77
78     detector()->DetectCaptivePortal(url,
79         base::Bind(&CaptivePortalClient::OnPortalDetectionCompleted,
80                    base::Unretained(&client)));
81
82     ASSERT_TRUE(FetchingURL());
83     base::RunLoop().RunUntilIdle();
84
85     CompleteURLFetch(net_error, status_code, response_headers);
86
87     EXPECT_FALSE(FetchingURL());
88     EXPECT_EQ(1, client.num_results_received());
89     EXPECT_EQ(expected_results.result, client.captive_portal_results().result);
90     EXPECT_EQ(expected_results.response_code,
91               client.captive_portal_results().response_code);
92     EXPECT_EQ(expected_results.retry_after_delta,
93               client.captive_portal_results().retry_after_delta);
94   }
95
96   void RunCancelTest() {
97     ASSERT_FALSE(FetchingURL());
98
99     GURL url(CaptivePortalDetector::kDefaultURL);
100     CaptivePortalClient client(detector());
101
102     detector()->DetectCaptivePortal(url,
103         base::Bind(&CaptivePortalClient::OnPortalDetectionCompleted,
104                    base::Unretained(&client)));
105
106     ASSERT_TRUE(FetchingURL());
107     base::RunLoop().RunUntilIdle();
108
109     detector()->Cancel();
110
111     ASSERT_FALSE(FetchingURL());
112     EXPECT_EQ(0, client.num_results_received());
113   }
114
115  private:
116   base::MessageLoop message_loop_;
117   scoped_ptr<CaptivePortalDetector> detector_;
118 };
119
120 // Test that the CaptivePortalDetector returns the expected result
121 // codes in response to a variety of probe results.
122 TEST_F(CaptivePortalDetectorTest, CaptivePortalResultCodes) {
123   CaptivePortalDetector::Results results;
124   results.result = captive_portal::RESULT_INTERNET_CONNECTED;
125   results.response_code = 204;
126
127   RunTest(results, net::OK, 204, NULL);
128
129   // The server may return an HTTP error when it's acting up.
130   results.result = captive_portal::RESULT_NO_RESPONSE;
131   results.response_code = 500;
132   RunTest(results, net::OK, 500, NULL);
133
134   // Generic network error case.
135   results.result = captive_portal::RESULT_NO_RESPONSE;
136   results.response_code = net::URLFetcher::RESPONSE_CODE_INVALID;
137   RunTest(results, net::ERR_TIMED_OUT, net::URLFetcher::RESPONSE_CODE_INVALID,
138           NULL);
139
140   // In the general captive portal case, the portal will return a page with a
141   // 200 status.
142   results.result = captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL;
143   results.response_code = 200;
144   RunTest(results, net::OK, 200, NULL);
145
146   // Some captive portals return 511 instead, to advertise their captive
147   // portal-ness.
148   results.result = captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL;
149   results.response_code = 511;
150   RunTest(results, net::OK, 511, NULL);
151 }
152
153 // Check a Retry-After header that contains a delay in seconds.
154 TEST_F(CaptivePortalDetectorTest, CaptivePortalRetryAfterSeconds) {
155   const char* retry_after = "HTTP/1.1 503 OK\nRetry-After: 101\n\n";
156   CaptivePortalDetector::Results results;
157
158   // Check that Retry-After headers work both on the first request to return a
159   // result and on subsequent requests.
160   results.result = captive_portal::RESULT_NO_RESPONSE;
161   results.response_code = 503;
162   results.retry_after_delta = base::TimeDelta::FromSeconds(101);
163   RunTest(results, net::OK, 503, retry_after);
164
165   results.result = captive_portal::RESULT_INTERNET_CONNECTED;
166   results.response_code = 204;
167   results.retry_after_delta = base::TimeDelta();
168   RunTest(results, net::OK, 204, NULL);
169 }
170
171 // Check a Retry-After header that contains a date.
172 TEST_F(CaptivePortalDetectorTest, CaptivePortalRetryAfterDate) {
173   const char* retry_after =
174       "HTTP/1.1 503 OK\nRetry-After: Tue, 17 Apr 2012 18:02:51 GMT\n\n";
175   CaptivePortalDetector::Results results;
176
177   // base has a function to get a time in the right format from a string, but
178   // not the other way around.
179   base::Time start_time;
180   ASSERT_TRUE(base::Time::FromString("Tue, 17 Apr 2012 18:02:00 GMT",
181                                      &start_time));
182   base::Time retry_after_time;
183   ASSERT_TRUE(base::Time::FromString("Tue, 17 Apr 2012 18:02:51 GMT",
184                                      &retry_after_time));
185
186   SetTime(start_time);
187
188   results.result = captive_portal::RESULT_NO_RESPONSE;
189   results.response_code = 503;
190   results.retry_after_delta = retry_after_time - start_time;
191   RunTest(results, net::OK, 503, retry_after);
192 }
193
194 // Check invalid Retry-After headers are ignored.
195 TEST_F(CaptivePortalDetectorTest, CaptivePortalRetryAfterInvalid) {
196   const char* retry_after = "HTTP/1.1 503 OK\nRetry-After: Christmas\n\n";
197   CaptivePortalDetector::Results results;
198
199   results.result = captive_portal::RESULT_NO_RESPONSE;
200   results.response_code = 503;
201   RunTest(results, net::OK, 503, retry_after);
202 }
203
204 TEST_F(CaptivePortalDetectorTest, Cancel) {
205   RunCancelTest();
206   CaptivePortalDetector::Results results;
207   results.result = captive_portal::RESULT_INTERNET_CONNECTED;
208   results.response_code = 204;
209   RunTest(results, net::OK, 204, NULL);
210 }
211
212 }  // namespace captive_portal