| // Copyright 2013 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. |
| |
| #include "chrome/browser/data_reduction_proxy/data_reduction_proxy_settings_android.h" |
| |
| #include <stddef.h> |
| |
| #include <map> |
| #include <memory> |
| #include <string> |
| |
| #include "base/android/jni_android.h" |
| #include "base/android/jni_array.h" |
| #include "base/android/jni_string.h" |
| #include "base/android/scoped_java_ref.h" |
| #include "base/base64.h" |
| #include "base/memory/ref_counted.h" |
| #include "base/message_loop/message_loop.h" |
| #include "base/strings/string_piece.h" |
| #include "base/test/scoped_feature_list.h" |
| #include "base/test/test_simple_task_runner.h" |
| #include "base/time/time.h" |
| #include "chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings.h" |
| #include "chrome/common/chrome_switches.h" |
| #include "chrome/common/pref_names.h" |
| #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.h" |
| #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.h" |
| #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h" |
| #include "components/data_reduction_proxy/core/common/data_reduction_proxy_features.h" |
| #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h" |
| #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.h" |
| #include "components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h" |
| #include "components/prefs/pref_service.h" |
| #include "components/proxy_config/proxy_prefs.h" |
| #include "net/base/proxy_server.h" |
| #include "net/socket/socket_test_util.h" |
| #include "net/url_request/url_request_context_storage.h" |
| #include "net/url_request/url_request_test_util.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "url/gurl.h" |
| |
| namespace base { |
| class Clock; |
| } |
| |
| using testing::_; |
| using testing::AnyNumber; |
| using testing::Return; |
| |
| using data_reduction_proxy::DataReductionProxySettings; |
| |
| // Used for testing the DataReductionProxySettingsAndroid class. |
| class TestDataReductionProxySettingsAndroid |
| : public DataReductionProxySettingsAndroid { |
| public: |
| // Constructs an Android settings object for test that wraps the provided |
| // settings object. |
| explicit TestDataReductionProxySettingsAndroid( |
| DataReductionProxySettings* settings) |
| : DataReductionProxySettingsAndroid(), settings_(settings) {} |
| |
| // Returns the provided setting object. Used by wrapping methods. |
| DataReductionProxySettings* Settings() override { return settings_; } |
| |
| // The wrapped settings object. |
| DataReductionProxySettings* settings_; |
| }; |
| |
| template <class C> |
| void data_reduction_proxy::DataReductionProxySettingsTestBase::ResetSettings( |
| base::Clock* clock) { |
| MockDataReductionProxySettings<C>* settings = |
| new MockDataReductionProxySettings<C>(); |
| settings->config_ = test_context_->config(); |
| test_context_->config()->ResetParamFlagsForTest(); |
| EXPECT_CALL(*settings, GetOriginalProfilePrefs()) |
| .Times(AnyNumber()) |
| .WillRepeatedly(Return(test_context_->pref_service())); |
| EXPECT_CALL(*settings, GetLocalStatePrefs()) |
| .Times(AnyNumber()) |
| .WillRepeatedly(Return(test_context_->pref_service())); |
| settings_.reset(settings); |
| settings_->data_reduction_proxy_service_ = |
| test_context_->CreateDataReductionProxyService(settings_.get()); |
| } |
| |
| template void data_reduction_proxy::DataReductionProxySettingsTestBase:: |
| ResetSettings<DataReductionProxyChromeSettings>(base::Clock* clock); |
| |
| namespace { |
| |
| class DataReductionProxyMockSettingsAndroidTest |
| : public data_reduction_proxy::ConcreteDataReductionProxySettingsTest< |
| DataReductionProxyChromeSettings> { |
| public: |
| // DataReductionProxySettingsTest implementation: |
| void SetUp() override { |
| env_ = base::android::AttachCurrentThread(); |
| DataReductionProxySettingsTestBase::SetUp(); |
| ResetSettingsAndroid(); |
| } |
| |
| void ResetSettingsAndroid() { |
| settings_android_.reset( |
| new TestDataReductionProxySettingsAndroid(settings_.get())); |
| } |
| |
| DataReductionProxySettings* Settings() { return settings_.get(); } |
| |
| DataReductionProxySettingsAndroid* SettingsAndroid() { |
| return settings_android_.get(); |
| } |
| |
| std::unique_ptr<DataReductionProxySettingsAndroid> settings_android_; |
| JNIEnv* env_; |
| }; |
| |
| TEST_F(DataReductionProxyMockSettingsAndroidTest, |
| TestGetDailyOriginalContentLengths) { |
| base::android::ScopedJavaLocalRef<jlongArray> result = |
| SettingsAndroid()->GetDailyOriginalContentLengths(env_, nullptr); |
| ASSERT_FALSE(result.is_null()); |
| |
| std::vector<int64_t> result_vector; |
| base::android::JavaLongArrayToInt64Vector(env_, result, &result_vector); |
| |
| std::vector<int64_t> expected_vector; |
| for (size_t i = data_reduction_proxy::kNumDaysInHistory; i;) |
| expected_vector.push_back(2 * static_cast<int64_t>(--i)); |
| |
| EXPECT_EQ(expected_vector, result_vector); |
| } |
| |
| TEST_F(DataReductionProxyMockSettingsAndroidTest, |
| TestGetDailyReceivedContentLengths) { |
| base::android::ScopedJavaLocalRef<jlongArray> result = |
| SettingsAndroid()->GetDailyReceivedContentLengths(env_, nullptr); |
| ASSERT_FALSE(result.is_null()); |
| |
| std::vector<int64_t> result_vector; |
| base::android::JavaLongArrayToInt64Vector(env_, result, &result_vector); |
| |
| std::vector<int64_t> expected_vector; |
| for (size_t i = data_reduction_proxy::kNumDaysInHistory; i;) |
| expected_vector.push_back(static_cast<int64_t>(--i)); |
| |
| EXPECT_EQ(expected_vector, result_vector); |
| } |
| |
| class DataReductionProxySettingsAndroidTest : public ::testing::Test { |
| public: |
| DataReductionProxySettingsAndroidTest() |
| : env_(base::android::AttachCurrentThread()), |
| context_(true), |
| context_storage_(&context_) { |
| context_.set_client_socket_factory(&mock_socket_factory_); |
| } |
| |
| void Init() { |
| drp_test_context_ = |
| data_reduction_proxy::DataReductionProxyTestContext::Builder() |
| .WithURLRequestContext(&context_) |
| .WithMockClientSocketFactory(&mock_socket_factory_) |
| .Build(); |
| |
| drp_test_context_->DisableWarmupURLFetch(); |
| drp_test_context_->AttachToURLRequestContext(&context_storage_); |
| context_.Init(); |
| |
| android_settings_.reset(new TestDataReductionProxySettingsAndroid( |
| drp_test_context_->settings())); |
| } |
| |
| JNIEnv* env() { return env_; } |
| net::TestURLRequestContext* context() { return &context_; } |
| data_reduction_proxy::DataReductionProxyTestContext* drp_test_context() { |
| return drp_test_context_.get(); |
| } |
| TestDataReductionProxySettingsAndroid* android_settings() { |
| return android_settings_.get(); |
| } |
| |
| std::string MaybeRewriteWebliteUrlAsUTF8(base::StringPiece url) { |
| return base::android::ConvertJavaStringToUTF8( |
| android_settings_->MaybeRewriteWebliteUrl( |
| env_, nullptr, base::android::ConvertUTF8ToJavaString(env_, url))); |
| } |
| |
| private: |
| base::MessageLoopForIO message_loop_; |
| JNIEnv* env_; |
| net::TestURLRequestContext context_; |
| net::URLRequestContextStorage context_storage_; |
| net::MockClientSocketFactory mock_socket_factory_; |
| std::unique_ptr<data_reduction_proxy::DataReductionProxyTestContext> |
| drp_test_context_; |
| std::unique_ptr<TestDataReductionProxySettingsAndroid> android_settings_; |
| }; |
| |
| TEST_F(DataReductionProxySettingsAndroidTest, |
| MaybeRewriteWebliteUrlDefaultParams) { |
| base::test::ScopedFeatureList scoped_list; |
| scoped_list.InitAndEnableFeature( |
| data_reduction_proxy::features::kDataReductionProxyDecidesTransform); |
| Init(); |
| drp_test_context()->EnableDataReductionProxyWithSecureProxyCheckSuccess(); |
| |
| EXPECT_EQ("http://example.com/", |
| MaybeRewriteWebliteUrlAsUTF8( |
| "http://googleweblight.com/i?u=http://example.com/")); |
| EXPECT_EQ("http://example.com/foo", |
| MaybeRewriteWebliteUrlAsUTF8( |
| "https://googleweblight.com/i?u=http://example.com/foo")); |
| EXPECT_EQ("http://example.com/", |
| MaybeRewriteWebliteUrlAsUTF8( |
| "http://googleweblight.com/i?u=http://example.com/&foo=bar")); |
| |
| EXPECT_TRUE(android_settings() |
| ->MaybeRewriteWebliteUrl(env(), nullptr, nullptr) |
| .is_null()); |
| |
| EXPECT_EQ("not a url", MaybeRewriteWebliteUrlAsUTF8("not a url")); |
| EXPECT_EQ("", MaybeRewriteWebliteUrlAsUTF8("")); |
| EXPECT_EQ("http://example.com/", |
| MaybeRewriteWebliteUrlAsUTF8("http://example.com/")); |
| |
| EXPECT_EQ("http://otherhost.com/i?u=http://example.com/", |
| MaybeRewriteWebliteUrlAsUTF8( |
| "http://otherhost.com/i?u=http://example.com/")); |
| |
| EXPECT_EQ("http://googleweblight.com/otherpath?u=http://example.com/", |
| MaybeRewriteWebliteUrlAsUTF8( |
| "http://googleweblight.com/otherpath?u=http://example.com/")); |
| |
| EXPECT_EQ("http://googleweblight.com/i?otherparam=http://example.com/", |
| MaybeRewriteWebliteUrlAsUTF8( |
| "http://googleweblight.com/i?otherparam=http://example.com/")); |
| |
| // A weblite URL that wraps an invalid URL should not be rewritten. |
| EXPECT_EQ( |
| "http://googleweblight.com/i?u=notaurl", |
| MaybeRewriteWebliteUrlAsUTF8("http://googleweblight.com/i?u=notaurl")); |
| |
| // A weblite URL that wraps an "https://" URL should not be rewritten. |
| EXPECT_EQ("http://googleweblight.com/i?u=https://example.com/", |
| MaybeRewriteWebliteUrlAsUTF8( |
| "http://googleweblight.com/i?u=https://example.com/")); |
| } |
| |
| TEST_F(DataReductionProxySettingsAndroidTest, |
| MaybeRewriteWebliteUrlWithDRPDisabled) { |
| base::test::ScopedFeatureList scoped_list; |
| scoped_list.InitAndEnableFeature( |
| data_reduction_proxy::features::kDataReductionProxyDecidesTransform); |
| Init(); |
| |
| EXPECT_EQ("http://googleweblight.com/i?u=http://example.com/", |
| MaybeRewriteWebliteUrlAsUTF8( |
| "http://googleweblight.com/i?u=http://example.com/")); |
| } |
| |
| TEST_F(DataReductionProxySettingsAndroidTest, |
| MaybeRewriteWebliteUrlWithWebliteDisabled) { |
| base::test::ScopedFeatureList scoped_list; |
| scoped_list.InitFromCommandLine( |
| "Previews" /* enable_features */, |
| "DataReductionProxyDecidesTransform" /* disable_features */); |
| Init(); |
| drp_test_context()->EnableDataReductionProxyWithSecureProxyCheckSuccess(); |
| |
| EXPECT_EQ("http://googleweblight.com/i?u=http://example.com/", |
| MaybeRewriteWebliteUrlAsUTF8( |
| "http://googleweblight.com/i?u=http://example.com/")); |
| } |
| |
| TEST_F(DataReductionProxySettingsAndroidTest, |
| MaybeRewriteWebliteUrlWithPreviewsDisabled) { |
| base::test::ScopedFeatureList scoped_list; |
| scoped_list.InitFromCommandLine( |
| "DataReductionProxyDecidesTransform" /* enable_features */, |
| "Previews" /* disable_features */); |
| Init(); |
| drp_test_context()->EnableDataReductionProxyWithSecureProxyCheckSuccess(); |
| |
| EXPECT_EQ("http://googleweblight.com/i?u=http://example.com/", |
| MaybeRewriteWebliteUrlAsUTF8( |
| "http://googleweblight.com/i?u=http://example.com/")); |
| } |
| |
| TEST_F(DataReductionProxySettingsAndroidTest, |
| MaybeRewriteWebliteUrlWithHoldbackEnabled) { |
| base::FieldTrialList field_trial_list(nullptr); |
| ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( |
| "DataCompressionProxyHoldback", "Enabled")); |
| |
| Init(); |
| drp_test_context()->EnableDataReductionProxyWithSecureProxyCheckSuccess(); |
| |
| EXPECT_EQ("http://googleweblight.com/i?u=http://example.com/", |
| MaybeRewriteWebliteUrlAsUTF8( |
| "http://googleweblight.com/i?u=http://example.com/")); |
| } |
| |
| TEST_F(DataReductionProxySettingsAndroidTest, |
| MaybeRewriteWebliteUrlWithCustomParams) { |
| base::test::ScopedFeatureList scoped_list; |
| std::map<std::string, std::string> params; |
| params["weblite_url_host_and_path"] = "testhost.net/testpath"; |
| params["weblite_url_query_param"] = "testparam"; |
| scoped_list.InitAndEnableFeatureWithParameters( |
| data_reduction_proxy::features::kDataReductionProxyDecidesTransform, |
| params); |
| Init(); |
| drp_test_context()->EnableDataReductionProxyWithSecureProxyCheckSuccess(); |
| |
| EXPECT_EQ("http://example.com/", |
| MaybeRewriteWebliteUrlAsUTF8( |
| "http://testhost.net/testpath?testparam=http://example.com/")); |
| |
| EXPECT_EQ("http://googleweblight.com/i?u=http://example.com/", |
| MaybeRewriteWebliteUrlAsUTF8( |
| "http://googleweblight.com/i?u=http://example.com/")); |
| |
| EXPECT_EQ("http://otherhost.net/testpath?testparam=http://example.com/", |
| MaybeRewriteWebliteUrlAsUTF8( |
| "http://otherhost.net/testpath?testparam=http://example.com/")); |
| |
| EXPECT_EQ("http://testhost.net/otherpath?testparam=http://example.com/", |
| MaybeRewriteWebliteUrlAsUTF8( |
| "http://testhost.net/otherpath?testparam=http://example.com/")); |
| |
| EXPECT_EQ("http://testhost.net/testpath?otherparam=http://example.com/", |
| MaybeRewriteWebliteUrlAsUTF8( |
| "http://testhost.net/testpath?otherparam=http://example.com/")); |
| } |
| |
| TEST_F(DataReductionProxySettingsAndroidTest, |
| MaybeRewriteWebliteUrlWithCustomLegacyParams) { |
| base::test::ScopedFeatureList scoped_list; |
| std::map<std::string, std::string> params; |
| params["weblite_url_host_and_path"] = "googleweblight.com/"; |
| params["weblite_url_query_param"] = "lite_url"; |
| scoped_list.InitAndEnableFeatureWithParameters( |
| data_reduction_proxy::features::kDataReductionProxyDecidesTransform, |
| params); |
| Init(); |
| drp_test_context()->EnableDataReductionProxyWithSecureProxyCheckSuccess(); |
| |
| EXPECT_EQ("http://example.com/", |
| MaybeRewriteWebliteUrlAsUTF8( |
| "http://googleweblight.com/?lite_url=http://example.com/")); |
| |
| EXPECT_EQ("http://googleweblight.com/i?u=http://example.com/", |
| MaybeRewriteWebliteUrlAsUTF8( |
| "http://googleweblight.com/i?u=http://example.com/")); |
| } |
| |
| } // namespace |