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/translate/core/browser/translate_script.h"
6 
7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "base/macros.h"
10 #include "base/strings/stringprintf.h"
11 #include "base/test/bind.h"
12 #include "base/test/task_environment.h"
13 #include "base/threading/thread_task_runner_handle.h"
14 #include "build/build_config.h"
15 #include "components/translate/core/browser/translate_download_manager.h"
16 #include "components/translate/core/common/translate_switches.h"
17 #include "components/variations/variations_ids_provider.h"
18 #include "net/base/load_flags.h"
19 #include "net/base/url_util.h"
20 #include "net/http/http_request_headers.h"
21 #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
22 #include "services/network/test/test_url_loader_factory.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24 #include "url/gurl.h"
25 
26 namespace translate {
27 
28 class TranslateScriptTest : public testing::Test {
29  public:
TranslateScriptTest()30   TranslateScriptTest()
31       : test_shared_loader_factory_(
32             base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
33                 &test_url_loader_factory_)) {}
34 
35  protected:
SetUp()36   void SetUp() override {
37     variations::VariationsIdsProvider::GetInstance()->ResetForTesting();
38     script_ = std::make_unique<TranslateScript>();
39     auto* translate_download_manager = TranslateDownloadManager::GetInstance();
40     translate_download_manager->set_application_locale("en");
41     translate_download_manager->set_url_loader_factory(
42         test_shared_loader_factory_);
43   }
44 
TearDown()45   void TearDown() override {
46     script_.reset();
47     TranslateDownloadManager::GetInstance()->ResetForTesting();
48   }
49 
Request()50   void Request() {
51     script_->Request(base::BindRepeating(&TranslateScriptTest::OnComplete,
52                                          base::Unretained(this)),
53                      /*is_incognito=*/false);
54   }
55 
GetData()56   const std::string& GetData() { return script_->data(); }
57 
RunUntilIdle()58   void RunUntilIdle() { task_environment_.RunUntilIdle(); }
59 
GetTestURLLoaderFactory()60   network::TestURLLoaderFactory* GetTestURLLoaderFactory() {
61     return &test_url_loader_factory_;
62   }
63 
64  private:
OnComplete(bool success,const std::string & script)65   void OnComplete(bool success, const std::string& script) {
66     // No op.
67   }
68 
69   // Sets up the task scheduling/task-runner environment for each test.
70   base::test::TaskEnvironment task_environment_;
71 
72   // The translate script.
73   std::unique_ptr<TranslateScript> script_;
74 
75   // Factory to create programmatic URL loaders.
76   network::TestURLLoaderFactory test_url_loader_factory_;
77   scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_;
78 
79   DISALLOW_COPY_AND_ASSIGN(TranslateScriptTest);
80 };
81 
TEST_F(TranslateScriptTest,CheckScriptParameters)82 TEST_F(TranslateScriptTest, CheckScriptParameters) {
83   network::ResourceRequest last_resource_request;
84   GetTestURLLoaderFactory()->SetInterceptor(
85       base::BindLambdaForTesting([&](const network::ResourceRequest& request) {
86         last_resource_request = request;
87       }));
88 
89   Request();
90 
91   GURL expected_url(TranslateScript::kScriptURL);
92   GURL url = last_resource_request.url;
93   EXPECT_TRUE(url.is_valid());
94   EXPECT_EQ(expected_url.GetOrigin().spec(), url.GetOrigin().spec());
95   EXPECT_EQ(expected_url.path(), url.path());
96 
97   EXPECT_EQ(network::mojom::CredentialsMode::kOmit,
98             last_resource_request.credentials_mode);
99 
100   std::string expected_extra_headers =
101       base::StringPrintf("%s\r\n\r\n", TranslateScript::kRequestHeader);
102   net::HttpRequestHeaders extra_headers = last_resource_request.headers;
103   EXPECT_EQ(expected_extra_headers, extra_headers.ToString());
104 
105   std::string always_use_ssl;
106   net::GetValueForKeyInQuery(
107       url, TranslateScript::kAlwaysUseSslQueryName, &always_use_ssl);
108   EXPECT_EQ(std::string(TranslateScript::kAlwaysUseSslQueryValue),
109             always_use_ssl);
110 
111   std::string callback;
112   net::GetValueForKeyInQuery(
113       url, TranslateScript::kCallbackQueryName, &callback);
114   EXPECT_EQ(std::string(TranslateScript::kCallbackQueryValue), callback);
115 
116 #if !defined(OS_IOS)
117   // iOS does not have specific loaders for the isolated world.
118   std::string css_loader_callback;
119   net::GetValueForKeyInQuery(
120       url, TranslateScript::kCssLoaderCallbackQueryName, &css_loader_callback);
121   EXPECT_EQ(std::string(TranslateScript::kCssLoaderCallbackQueryValue),
122             css_loader_callback);
123 
124   std::string javascript_loader_callback;
125   net::GetValueForKeyInQuery(
126       url,
127       TranslateScript::kJavascriptLoaderCallbackQueryName,
128       &javascript_loader_callback);
129   EXPECT_EQ(std::string(TranslateScript::kJavascriptLoaderCallbackQueryValue),
130             javascript_loader_callback);
131 #endif  // !defined(OS_IOS)
132 }
133 
TEST_F(TranslateScriptTest,CheckScriptURL)134 TEST_F(TranslateScriptTest, CheckScriptURL) {
135   const std::string script_url("http://www.tamurayukari.com/mero-n.js");
136   base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
137   command_line->AppendSwitchASCII(translate::switches::kTranslateScriptURL,
138                                   script_url);
139 
140   network::ResourceRequest last_resource_request;
141   GetTestURLLoaderFactory()->SetInterceptor(
142       base::BindLambdaForTesting([&](const network::ResourceRequest& request) {
143         last_resource_request = request;
144       }));
145 
146   Request();
147 
148   GURL expected_url(script_url);
149   GURL url = last_resource_request.url;
150   EXPECT_TRUE(url.is_valid());
151   EXPECT_EQ(expected_url.GetOrigin().spec(), url.GetOrigin().spec());
152   EXPECT_EQ(expected_url.path(), url.path());
153 }
154 
TEST_F(TranslateScriptTest,CheckResponse)155 TEST_F(TranslateScriptTest, CheckResponse) {
156   const std::string test_response =
157       "(function() { console.log(\"Hello, world!\"); }());";
158   GURL full_url = TranslateScript::GetTranslateScriptURL();
159   GetTestURLLoaderFactory()->AddResponse(full_url.spec(), test_response);
160 
161   Request();
162   RunUntilIdle();
163 
164   EXPECT_NE(std::string::npos, GetData().find(test_response));
165 }
166 
167 }  // namespace translate
168