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.
5 #include "components/translate/core/browser/translate_prefs.h"
11 #include "base/prefs/scoped_user_pref_update.h"
12 #include "components/pref_registry/testing_pref_service_syncable.h"
13 #include "components/translate/core/browser/translate_download_manager.h"
14 #include "testing/gtest/include/gtest/gtest.h"
18 const char kTestLanguage
[] = "en";
24 TEST(TranslatePrefsTest
, CreateBlockedLanguages
) {
25 TranslateDownloadManager::GetInstance()->set_application_locale("en");
26 std::vector
<std::string
> blacklisted_languages
;
27 blacklisted_languages
.push_back("en");
28 blacklisted_languages
.push_back("fr");
29 // Hebrew: synonym to 'he'
30 blacklisted_languages
.push_back("iw");
31 // Haitian is not used as Accept-Language
32 blacklisted_languages
.push_back("ht");
34 std::vector
<std::string
> accept_languages
;
35 accept_languages
.push_back("en");
36 // The subcode (IT) will be ignored when merging, except for Chinese.
37 accept_languages
.push_back("it-IT");
38 accept_languages
.push_back("ja");
39 // Filippino: synonym to 'tl'
40 accept_languages
.push_back("fil");
41 // General Chinese is not used as Translate language, but not filtered
43 accept_languages
.push_back("zh");
44 // Chinese with a sub code is acceptable for the blocked-language list.
45 accept_languages
.push_back("zh-TW");
47 std::vector
<std::string
> blocked_languages
;
49 TranslatePrefs::CreateBlockedLanguages(&blocked_languages
,
50 blacklisted_languages
,
53 // The order of the elements cannot be determined.
54 std::vector
<std::string
> expected
;
55 expected
.push_back("en");
56 expected
.push_back("fr");
57 expected
.push_back("iw");
58 expected
.push_back("ht");
59 expected
.push_back("it");
60 expected
.push_back("ja");
61 expected
.push_back("tl");
62 expected
.push_back("zh");
63 expected
.push_back("zh-TW");
65 EXPECT_EQ(expected
.size(), blocked_languages
.size());
66 for (std::vector
<std::string
>::const_iterator it
= expected
.begin();
67 it
!= expected
.end(); ++it
) {
68 EXPECT_NE(blocked_languages
.end(),
69 std::find(blocked_languages
.begin(),
70 blocked_languages
.end(),
75 TEST(TranslatePrefsTest
, CreateBlockedLanguagesNonEnglishUI
) {
76 std::vector
<std::string
> blacklisted_languages
;
77 blacklisted_languages
.push_back("fr");
79 std::vector
<std::string
> accept_languages
;
80 accept_languages
.push_back("en");
81 accept_languages
.push_back("ja");
82 accept_languages
.push_back("zh");
84 // Run in an English locale.
86 TranslateDownloadManager::GetInstance()->set_application_locale("en");
87 std::vector
<std::string
> blocked_languages
;
88 TranslatePrefs::CreateBlockedLanguages(&blocked_languages
,
89 blacklisted_languages
,
91 std::vector
<std::string
> expected
;
92 expected
.push_back("en");
93 expected
.push_back("fr");
94 expected
.push_back("ja");
95 expected
.push_back("zh");
97 EXPECT_EQ(expected
.size(), blocked_languages
.size());
98 for (std::vector
<std::string
>::const_iterator it
= expected
.begin();
99 it
!= expected
.end(); ++it
) {
100 EXPECT_NE(blocked_languages
.end(),
101 std::find(blocked_languages
.begin(),
102 blocked_languages
.end(),
107 // Run in a Japanese locale.
108 // English should not be included in the result even though Accept Languages
109 // has English because the UI is not English.
111 TranslateDownloadManager::GetInstance()->set_application_locale("ja");
112 std::vector
<std::string
> blocked_languages
;
113 TranslatePrefs::CreateBlockedLanguages(&blocked_languages
,
114 blacklisted_languages
,
116 std::vector
<std::string
> expected
;
117 expected
.push_back("fr");
118 expected
.push_back("ja");
119 expected
.push_back("zh");
121 EXPECT_EQ(expected
.size(), blocked_languages
.size());
122 for (std::vector
<std::string
>::const_iterator it
= expected
.begin();
123 it
!= expected
.end(); ++it
) {
124 EXPECT_NE(blocked_languages
.end(),
125 std::find(blocked_languages
.begin(),
126 blocked_languages
.end(),
132 class TranslatePrefTest
: public testing::Test
{
134 TranslatePrefTest() : prefs_(new user_prefs::TestingPrefServiceSyncable()) {
135 #if defined(OS_CHROMEOS)
136 const char* preferred_languages_prefs
=
137 "settings.language.preferred_languages";
139 const char* preferred_languages_prefs
= NULL
;
141 translate_prefs_
.reset(new translate::TranslatePrefs(
142 prefs_
.get(), "intl.accept_languages", preferred_languages_prefs
));
143 TranslatePrefs::RegisterProfilePrefs(prefs_
->registry());
144 now_
= base::Time::Now();
145 two_days_ago_
= now_
- base::TimeDelta::FromDays(2);
148 void SetLastDeniedTime(const std::string
& language
, base::Time time
) {
149 DenialTimeUpdate
update(prefs_
.get(), language
, 2);
150 update
.AddDenialTime(time
);
153 base::Time
GetLastDeniedTime(const std::string
& language
) {
154 DenialTimeUpdate
update(prefs_
.get(), language
, 2);
155 return update
.GetOldestDenialTime();
158 scoped_ptr
<user_prefs::TestingPrefServiceSyncable
> prefs_
;
159 scoped_ptr
<translate::TranslatePrefs
> translate_prefs_
;
161 // Shared time constants.
163 base::Time two_days_ago_
;
166 TEST_F(TranslatePrefTest
, UpdateLastDeniedTime
) {
167 // Test that denials with more than 24 hours difference between them do not
168 // block the language.
169 translate_prefs_
->ResetDenialState();
170 SetLastDeniedTime(kTestLanguage
, two_days_ago_
);
171 ASSERT_FALSE(translate_prefs_
->IsTooOftenDenied(kTestLanguage
));
172 translate_prefs_
->UpdateLastDeniedTime(kTestLanguage
);
173 base::Time last_denied
= GetLastDeniedTime(kTestLanguage
);
174 EXPECT_FALSE(last_denied
.is_max());
175 EXPECT_GE(last_denied
, now_
);
176 EXPECT_LT(last_denied
- now_
, base::TimeDelta::FromSeconds(10));
177 EXPECT_FALSE(translate_prefs_
->IsTooOftenDenied(kTestLanguage
));
179 // Ensure the first use simply writes the update time.
180 translate_prefs_
->ResetDenialState();
181 translate_prefs_
->UpdateLastDeniedTime(kTestLanguage
);
182 last_denied
= GetLastDeniedTime(kTestLanguage
);
183 EXPECT_FALSE(last_denied
.is_max());
184 EXPECT_GE(last_denied
, now_
);
185 EXPECT_LT(last_denied
- now_
, base::TimeDelta::FromSeconds(10));
186 EXPECT_FALSE(translate_prefs_
->IsTooOftenDenied(kTestLanguage
));
188 // If it's denied again within the 24 hour period, language should be
189 // permanently denied.
190 translate_prefs_
->UpdateLastDeniedTime(kTestLanguage
);
191 last_denied
= GetLastDeniedTime(kTestLanguage
);
192 EXPECT_FALSE(last_denied
.is_max());
193 EXPECT_GE(last_denied
, now_
);
194 EXPECT_LT(last_denied
- now_
, base::TimeDelta::FromSeconds(10));
195 EXPECT_TRUE(translate_prefs_
->IsTooOftenDenied(kTestLanguage
));
197 // If the language is already permanently denied, don't bother updating the
199 ASSERT_TRUE(translate_prefs_
->IsTooOftenDenied(kTestLanguage
));
200 SetLastDeniedTime(kTestLanguage
, two_days_ago_
);
201 translate_prefs_
->UpdateLastDeniedTime(kTestLanguage
);
202 last_denied
= GetLastDeniedTime(kTestLanguage
);
203 EXPECT_EQ(last_denied
, two_days_ago_
);
206 // Test that the default value for non-existing entries is base::Time::Null().
207 TEST_F(TranslatePrefTest
, DenialTimeUpdate_DefaultTimeIsNull
) {
208 DenialTimeUpdate
update(prefs_
.get(), kTestLanguage
, 2);
209 EXPECT_TRUE(update
.GetOldestDenialTime().is_null());
212 // Test that non-existing entries automatically create a ListValue.
213 TEST_F(TranslatePrefTest
, DenialTimeUpdate_ForceListExistence
) {
214 DictionaryPrefUpdate
dict_update(
215 prefs_
.get(), TranslatePrefs::kPrefTranslateLastDeniedTimeForLanguage
);
216 base::DictionaryValue
* denial_dict
= dict_update
.Get();
217 ASSERT_TRUE(denial_dict
);
219 base::ListValue
* list_value
= nullptr;
220 bool has_list
= denial_dict
->GetList(kTestLanguage
, &list_value
);
221 ASSERT_FALSE(has_list
);
223 // Calling GetDenialTimes will force creation of a properly populated list.
224 DenialTimeUpdate
update(prefs_
.get(), kTestLanguage
, 2);
225 base::ListValue
* time_list
= update
.GetDenialTimes();
226 ASSERT_TRUE(time_list
);
227 EXPECT_EQ(0U, time_list
->GetSize());
230 // Test that an existing update time record (which is a double in a dict)
231 // is automatically migrated to a list of update times instead.
232 TEST_F(TranslatePrefTest
, DenialTimeUpdate_Migrate
) {
233 translate_prefs_
->ResetDenialState();
234 DictionaryPrefUpdate
dict_update(
235 prefs_
.get(), TranslatePrefs::kPrefTranslateLastDeniedTimeForLanguage
);
236 base::DictionaryValue
* denial_dict
= dict_update
.Get();
237 ASSERT_TRUE(denial_dict
);
238 denial_dict
->SetDouble(kTestLanguage
, two_days_ago_
.ToJsTime());
240 base::ListValue
* list_value
= nullptr;
241 bool has_list
= denial_dict
->GetList(kTestLanguage
, &list_value
);
242 ASSERT_FALSE(has_list
);
244 // Calling GetDenialTimes will force creation of a properly populated list.
245 DenialTimeUpdate
update(prefs_
.get(), kTestLanguage
, 2);
246 base::ListValue
* time_list
= update
.GetDenialTimes();
247 ASSERT_TRUE(time_list
);
249 has_list
= denial_dict
->GetList(kTestLanguage
, &list_value
);
250 ASSERT_TRUE(has_list
);
251 EXPECT_EQ(time_list
, list_value
);
252 EXPECT_EQ(1U, time_list
->GetSize());
253 EXPECT_EQ(two_days_ago_
, update
.GetOldestDenialTime());
256 TEST_F(TranslatePrefTest
, DenialTimeUpdate_SlidingWindow
) {
257 DenialTimeUpdate
update(prefs_
.get(), kTestLanguage
, 4);
259 update
.AddDenialTime(now_
- base::TimeDelta::FromMinutes(5));
260 EXPECT_EQ(update
.GetOldestDenialTime(),
261 now_
- base::TimeDelta::FromMinutes(5));
263 update
.AddDenialTime(now_
- base::TimeDelta::FromMinutes(4));
264 EXPECT_EQ(update
.GetOldestDenialTime(),
265 now_
- base::TimeDelta::FromMinutes(5));
267 update
.AddDenialTime(now_
- base::TimeDelta::FromMinutes(3));
268 EXPECT_EQ(update
.GetOldestDenialTime(),
269 now_
- base::TimeDelta::FromMinutes(5));
271 update
.AddDenialTime(now_
- base::TimeDelta::FromMinutes(2));
272 EXPECT_EQ(update
.GetOldestDenialTime(),
273 now_
- base::TimeDelta::FromMinutes(4));
275 update
.AddDenialTime(now_
);
276 EXPECT_EQ(update
.GetOldestDenialTime(),
277 now_
- base::TimeDelta::FromMinutes(3));
279 update
.AddDenialTime(now_
);
280 EXPECT_EQ(update
.GetOldestDenialTime(),
281 now_
- base::TimeDelta::FromMinutes(2));
284 } // namespace translate