Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / renderer / translate / translate_script_browsertest.cc
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 "base/strings/stringprintf.h"
6 #include "base/strings/utf_string_conversions.h"
7 #include "chrome/test/base/chrome_render_view_test.h"
8 #include "components/translate/core/common/translate_errors.h"
9 #include "grit/components_resources.h"
10 #include "third_party/WebKit/public/web/WebLocalFrame.h"
11 #include "third_party/WebKit/public/web/WebScriptSource.h"
12 #include "ui/base/resource/resource_bundle.h"
13 #include "v8/include/v8.h"
14
15 using blink::WebScriptSource;
16
17 namespace {
18
19 // JavaScript code to set runtime test flags.
20 const char kThrowInitializationError[] = "throwInitializationError = true";
21 const char kThrowUnexpectedScriptError[] = "throwUnexpectedScriptError = true";
22 const char kCallbackReturnBooleanError[] = "callbackReturnBooleanError = true";
23 const char kCallbackReturnNumberError[] = "callbackReturnNumberError = true";
24 const char kSetCallbackErrorCode[] = "callbackErrorCode = ";
25
26 // JavaScript code to check if any error happens.
27 const char kError[] = "cr.googleTranslate.error";
28
29 // JavaScript code to get error code.
30 const char kErrorCode[] = "cr.googleTranslate.errorCode";
31
32 // JavaScript code to check if the library is ready.
33 const char kLibReady[] = "cr.googleTranslate.libReady";
34
35 // JavaScript code to perform translation.
36 const char kTranslate[] = "cr.googleTranslate.translate('auto', 'en')";
37
38 // JavaScript code to mimic element.js provided by a translate server.
39 const char kElementJs[] =
40     "translateApiKey = '';"
41     "google = {};"
42     "google.translate = {};"
43     "google.translate.TranslateService = function() {"
44     "  if (window['throwInitializationError']) {"
45     "    throw 'API initialization error';"
46     "  }"
47     "  return {"
48     "    isAvailable: function() { return true; },"
49     "    restore: function() {},"
50     "    translatePage: function(originalLang, targetLang, cb) {"
51     "      if (window['throwUnexpectedScriptError']) {"
52     "        throw 'all your base are belong to us';"
53     "      }"
54     "      if (window['callbackReturnBooleanError']) {"
55     "        cb(0, false, true);"
56     "      }"
57     "      if (window['callbackReturnNumberError']) {"
58     "        cb(0, false, callbackErrorCode);"
59     "      }"
60     "    }"
61     "  };"
62     "};"
63     "cr.googleTranslate.onTranslateElementLoad();";
64
65 std::string GenerateSetCallbackErrorCodeScript(int code) {
66   return base::StringPrintf("%s%d", kSetCallbackErrorCode, code);
67 }
68
69 };  // namespace
70
71 // This class is for testing resource/translate.js works and reports errors
72 // correctly.
73 class TranslateScriptBrowserTest : public ChromeRenderViewTest {
74  public:
75   TranslateScriptBrowserTest() {}
76
77  protected:
78   void InjectElementLibrary() {
79     std::string script;
80     base::StringPiece translate_js = ResourceBundle::GetSharedInstance().
81         GetRawDataResource(IDR_TRANSLATE_JS);
82     translate_js.CopyToString(&script);
83     script += kElementJs;
84     ExecuteScript(script);
85   }
86
87   void ExecuteScript(const std::string& script) {
88     WebScriptSource source = WebScriptSource(base::ASCIIToUTF16(script));
89     GetMainFrame()->executeScript(source);
90   }
91
92   bool GetError() {
93     return ExecuteScriptAndGetBoolResult(kError);
94   }
95
96   double GetErrorCode() {
97     return ExecuteScriptAndGetNumberResult(kErrorCode);
98   }
99
100   bool IsLibReady() {
101     return ExecuteScriptAndGetBoolResult(kLibReady);
102   }
103
104  private:
105   void SetUp() override { ChromeRenderViewTest::SetUp(); }
106
107   void TearDown() override { ChromeRenderViewTest::TearDown(); }
108
109   double ExecuteScriptAndGetNumberResult(const std::string& script) {
110     WebScriptSource source = WebScriptSource(base::ASCIIToUTF16(script));
111     v8::HandleScope handle_scope(v8::Isolate::GetCurrent());
112     v8::Handle<v8::Value> result =
113         GetMainFrame()->executeScriptAndReturnValue(source);
114     if (result.IsEmpty() || !result->IsNumber()) {
115       NOTREACHED();
116       // TODO(toyoshim): Return NaN here and the real implementation in
117       // TranslateHelper::ExecuteScriptAndGetDoubleResult().
118       return 0.0;
119     }
120     return result->NumberValue();
121   }
122
123   bool ExecuteScriptAndGetBoolResult(const std::string& script) {
124     WebScriptSource source = WebScriptSource(base::ASCIIToUTF16(script));
125     v8::HandleScope handle_scope(v8::Isolate::GetCurrent());
126     v8::Handle<v8::Value> result =
127         GetMainFrame()->executeScriptAndReturnValue(source);
128     if (result.IsEmpty() || !result->IsBoolean()) {
129       NOTREACHED();
130       return false;
131     }
132     return result->BooleanValue();
133   }
134
135   DISALLOW_COPY_AND_ASSIGN(TranslateScriptBrowserTest);
136 };
137
138 // Test if onTranslateElementLoad() succeeds to initialize the element library.
139 TEST_F(TranslateScriptBrowserTest, ElementLoadSuccess) {
140   InjectElementLibrary();
141   EXPECT_TRUE(IsLibReady());
142   EXPECT_FALSE(GetError());
143   EXPECT_EQ(translate::TranslateErrors::NONE, GetErrorCode());
144 }
145
146 // Test if onTranslateElementLoad() fails to initialize the element library and
147 // report the right error code.
148 TEST_F(TranslateScriptBrowserTest, ElementLoadFailure) {
149   ExecuteScript(kThrowInitializationError);
150
151   InjectElementLibrary();
152   EXPECT_FALSE(IsLibReady());
153   EXPECT_TRUE(GetError());
154   EXPECT_EQ(translate::TranslateErrors::INITIALIZATION_ERROR, GetErrorCode());
155 }
156
157 // Test if cr.googleTranslate.translate() works.
158 TEST_F(TranslateScriptBrowserTest, TranslateSuccess) {
159   InjectElementLibrary();
160   EXPECT_TRUE(IsLibReady());
161   EXPECT_FALSE(GetError());
162   EXPECT_EQ(translate::TranslateErrors::NONE, GetErrorCode());
163
164   ExecuteScript(kTranslate);
165
166   EXPECT_FALSE(GetError());
167   EXPECT_EQ(translate::TranslateErrors::NONE, GetErrorCode());
168 }
169
170 // Test if cr.googleTranslate.translate() handles library exception correctly.
171 TEST_F(TranslateScriptBrowserTest, TranslateFail) {
172   ExecuteScript(kThrowUnexpectedScriptError);
173
174   InjectElementLibrary();
175   EXPECT_TRUE(IsLibReady());
176   EXPECT_FALSE(GetError());
177   EXPECT_EQ(translate::TranslateErrors::NONE, GetErrorCode());
178
179   ExecuteScript(kTranslate);
180
181   EXPECT_TRUE(GetError());
182   EXPECT_EQ(translate::TranslateErrors::UNEXPECTED_SCRIPT_ERROR,
183             GetErrorCode());
184 }
185
186 // Test if onTranslateProgress callback handles boolean type error correctly.
187 // Remove this test once server side changes the API to return a number.
188 TEST_F(TranslateScriptBrowserTest, CallbackGetBooleanError) {
189   ExecuteScript(kCallbackReturnBooleanError);
190
191   InjectElementLibrary();
192   EXPECT_TRUE(IsLibReady());
193   EXPECT_FALSE(GetError());
194   EXPECT_EQ(translate::TranslateErrors::NONE, GetErrorCode());
195
196   ExecuteScript(kTranslate);
197
198   EXPECT_TRUE(GetError());
199   EXPECT_EQ(translate::TranslateErrors::TRANSLATION_ERROR, GetErrorCode());
200 }
201
202 // Test if onTranslateProgress callback handles number type error correctly and
203 // converts it to the proper error code.
204 TEST_F(TranslateScriptBrowserTest, CallbackGetNumberError1) {
205   ExecuteScript(kCallbackReturnNumberError);
206   ExecuteScript(GenerateSetCallbackErrorCodeScript(1));
207
208   InjectElementLibrary();
209   EXPECT_TRUE(IsLibReady());
210   EXPECT_FALSE(GetError());
211   EXPECT_EQ(translate::TranslateErrors::NONE, GetErrorCode());
212
213   ExecuteScript(kTranslate);
214
215   EXPECT_TRUE(GetError());
216   EXPECT_EQ(translate::TranslateErrors::TRANSLATION_ERROR, GetErrorCode());
217 }
218
219 // Test if onTranslateProgress callback handles number type error correctly and
220 // converts it to the proper error code.
221 TEST_F(TranslateScriptBrowserTest, CallbackGetNumberError2) {
222   ExecuteScript(kCallbackReturnNumberError);
223   ExecuteScript(GenerateSetCallbackErrorCodeScript(2));
224
225   InjectElementLibrary();
226   EXPECT_TRUE(IsLibReady());
227   EXPECT_FALSE(GetError());
228   EXPECT_EQ(translate::TranslateErrors::NONE, GetErrorCode());
229
230   ExecuteScript(kTranslate);
231
232   EXPECT_TRUE(GetError());
233   EXPECT_EQ(translate::TranslateErrors::UNSUPPORTED_LANGUAGE, GetErrorCode());
234 }
235
236 // TODO(toyoshim): Add test for onLoadJavaScript.