1// Copyright 2013 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 "chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.h"
6
7#include "base/android/jni_android.h"
8#include "base/android/jni_string.h"
9#include "base/android/scoped_java_ref.h"
10#include "base/base64.h"
11#include "base/command_line.h"
12#include "base/prefs/pref_service.h"
13#include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.h"
14#include "chrome/browser/prefs/proxy_prefs.h"
15#include "chrome/common/chrome_switches.h"
16#include "chrome/common/pref_names.h"
17#include "components/data_reduction_proxy/browser/data_reduction_proxy_settings_test_utils.h"
18#include "testing/gmock/include/gmock/gmock.h"
19#include "testing/gtest/include/gtest/gtest.h"
20#include "url/gurl.h"
21
22using testing::_;
23using testing::AnyNumber;
24using testing::Return;
25
26const char kDataReductionProxyDev[] = "http://foo-dev.com:80";
27
28using data_reduction_proxy::DataReductionProxySettings;
29
30// Used for testing the DataReductionProxySettingsAndroid class.
31class TestDataReductionProxySettingsAndroid
32    : public DataReductionProxySettingsAndroid {
33 public:
34  // Constructs an Android settings object for test that wraps the provided
35  // settings object.
36  explicit TestDataReductionProxySettingsAndroid(
37      DataReductionProxySettings* settings)
38      : DataReductionProxySettingsAndroid(),
39        settings_(settings) {}
40
41  // Returns the provided setting object. Used by wrapping methods.
42  virtual DataReductionProxySettings* Settings() OVERRIDE {
43    return settings_;
44  }
45
46  // The wrapped settings object.
47  DataReductionProxySettings* settings_;
48};
49
50template <class C>
51void data_reduction_proxy::DataReductionProxySettingsTestBase::ResetSettings(
52    bool allowed,
53    bool fallback_allowed,
54    bool alt_allowed,
55    bool promo_allowed,
56    bool holdback) {
57  int flags = 0;
58  if (allowed)
59    flags |= DataReductionProxyParams::kAllowed;
60  if (fallback_allowed)
61    flags |= DataReductionProxyParams::kFallbackAllowed;
62  if (alt_allowed)
63    flags |= DataReductionProxyParams::kAlternativeAllowed;
64  if (promo_allowed)
65    flags |= DataReductionProxyParams::kPromoAllowed;
66  if (holdback)
67    flags |= DataReductionProxyParams::kHoldback;
68  MockDataReductionProxySettings<C>* settings =
69      new MockDataReductionProxySettings<C>(flags);
70  EXPECT_CALL(*settings, GetOriginalProfilePrefs())
71      .Times(AnyNumber())
72      .WillRepeatedly(Return(&pref_service_));
73  EXPECT_CALL(*settings, GetLocalStatePrefs())
74      .Times(AnyNumber())
75      .WillRepeatedly(Return(&pref_service_));
76  EXPECT_CALL(*settings, GetURLFetcherForAvailabilityCheck()).Times(0);
77  EXPECT_CALL(*settings, LogProxyState(_, _, _)).Times(0);
78  settings_.reset(settings);
79  settings_->SetDataReductionProxyStatisticsPrefs(statistics_prefs_.get());
80}
81
82template <class C>
83void data_reduction_proxy::DataReductionProxySettingsTestBase::SetProbeResult(
84    const std::string& test_url,
85    const std::string& response,
86    ProbeURLFetchResult result,
87    bool success,
88    int expected_calls)  {
89  MockDataReductionProxySettings<C>* settings =
90      static_cast<MockDataReductionProxySettings<C>*>(settings_.get());
91  if (0 == expected_calls) {
92    EXPECT_CALL(*settings, GetURLFetcherForAvailabilityCheck()).Times(0);
93    EXPECT_CALL(*settings, RecordProbeURLFetchResult(_)).Times(0);
94  } else {
95    EXPECT_CALL(*settings, RecordProbeURLFetchResult(result)).Times(1);
96    EXPECT_CALL(*settings, GetURLFetcherForAvailabilityCheck())
97        .Times(expected_calls)
98        .WillRepeatedly(Return(new net::FakeURLFetcher(
99            GURL(test_url),
100            settings,
101            response,
102            success ? net::HTTP_OK : net::HTTP_INTERNAL_SERVER_ERROR,
103            success ? net::URLRequestStatus::SUCCESS :
104                      net::URLRequestStatus::FAILED)));
105  }
106}
107
108template void
109data_reduction_proxy::DataReductionProxySettingsTestBase::ResetSettings<
110    DataReductionProxyChromeSettings>(bool allowed,
111                                       bool fallback_allowed,
112                                       bool alt_allowed,
113                                       bool promo_allowed,
114                                       bool holdback);
115
116template void
117data_reduction_proxy::DataReductionProxySettingsTestBase::SetProbeResult<
118    DataReductionProxyChromeSettings>(const std::string& test_url,
119                                       const std::string& response,
120                                       ProbeURLFetchResult result,
121                                       bool success,
122                                       int expected_calls);
123
124class DataReductionProxySettingsAndroidTest
125    : public data_reduction_proxy::ConcreteDataReductionProxySettingsTest<
126          DataReductionProxyChromeSettings> {
127 public:
128  // DataReductionProxySettingsTest implementation:
129  virtual void SetUp() OVERRIDE {
130    env_ = base::android::AttachCurrentThread();
131    DataReductionProxySettingsAndroid::Register(env_);
132    DataReductionProxySettingsTestBase::SetUp();
133    ResetSettingsAndroid();
134  }
135
136  void ResetSettingsAndroid() {
137    settings_android_.reset(new TestDataReductionProxySettingsAndroid(
138        settings_.get()));
139  }
140
141  DataReductionProxySettings* Settings() {
142    return settings_.get();
143  }
144
145  DataReductionProxySettingsAndroid* SettingsAndroid() {
146    return settings_android_.get();
147  }
148
149  scoped_ptr<DataReductionProxySettingsAndroid> settings_android_;
150  JNIEnv* env_;
151};
152
153TEST_F(DataReductionProxySettingsAndroidTest, TestGetDataReductionProxyOrigin) {
154  // SetUp() adds the origin to the command line, which should be returned here.
155  ScopedJavaLocalRef<jstring> result =
156      SettingsAndroid()->GetDataReductionProxyOrigin(env_, NULL);
157  ASSERT_TRUE(result.obj());
158  const base::android::JavaRef<jstring>& str_ref = result;
159  EXPECT_EQ(GURL(expected_params_->DefaultOrigin()),
160            GURL(ConvertJavaStringToUTF8(str_ref)));
161}
162
163TEST_F(DataReductionProxySettingsAndroidTest,
164       TestGetDataReductionProxyDevOrigin) {
165  CommandLine::ForCurrentProcess()->AppendSwitchASCII(
166      data_reduction_proxy::switches::kDataReductionProxyDev,
167      kDataReductionProxyDev);
168  ResetSettings(true, true, false, true, false);
169  ResetSettingsAndroid();
170  ScopedJavaLocalRef<jstring> result =
171      SettingsAndroid()->GetDataReductionProxyOrigin(env_, NULL);
172  ASSERT_TRUE(result.obj());
173  const base::android::JavaRef<jstring>& str_ref = result;
174  EXPECT_EQ(GURL(kDataReductionProxyDev),
175            GURL(ConvertJavaStringToUTF8(str_ref)));
176}
177
178TEST_F(DataReductionProxySettingsAndroidTest, TestGetDailyContentLengths) {
179  ScopedJavaLocalRef<jlongArray> result =
180      SettingsAndroid()->GetDailyContentLengths(
181          env_, data_reduction_proxy::prefs::kDailyHttpOriginalContentLength);
182  ASSERT_TRUE(result.obj());
183
184  jsize java_array_len = env_->GetArrayLength(result.obj());
185  ASSERT_EQ(static_cast<jsize>(data_reduction_proxy::kNumDaysInHistory),
186            java_array_len);
187
188  jlong value;
189  for (size_t i = 0; i < data_reduction_proxy::kNumDaysInHistory; ++i) {
190    env_->GetLongArrayRegion(result.obj(), i, 1, &value);
191    ASSERT_EQ(
192        static_cast<long>(
193            (data_reduction_proxy::kNumDaysInHistory - 1 - i) * 2), value);
194  }
195}
196
197