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 "chrome/browser/chromeos/locale_change_guard.h"
6
7#include <string.h>
8
9#include "base/macros.h"
10#include "testing/gtest/include/gtest/gtest.h"
11#include "ui/base/l10n/l10n_util.h"
12
13namespace {
14
15// These languages require user notification when locale is automatically
16// switched between different regions within the same language.
17const char* const kShowNotificationLanguages[] = {
18    "af",   // Afrikaans
19    "am",   // Amharic
20    "ar",   // Arabic
21    "az",   // Azerbaijani
22    "be",   // Belarusian
23    "bg",   // Bulgarian
24    "bh",   // Bihari
25    "bn",   // Bengali
26    "br",   // Breton
27    "bs",   // Bosnian
28    "ca",   // Catalan
29    "co",   // Corsican
30    "cs",   // Czech
31    "cy",   // Welsh
32    "da",   // Danish
33    "el",   // Greek
34    "eo",   // Esperanto
35    "es",   // Spanish
36    "et",   // Estonian
37    "eu",   // Basque
38    "fa",   // Persian
39    "fi",   // Finnish
40    "fil",  // Filipino
41    "fo",   // Faroese
42    "fy",   // Frisian
43    "ga",   // Irish
44    "gd",   // Scots Gaelic
45    "gl",   // Galician
46    "gn",   // Guarani
47    "gu",   // Gujarati
48    "ha",   // Hausa
49    "haw",  // Hawaiian
50    "he",   // Hebrew
51    "hi",   // Hindi
52    "hr",   // Croatian
53    "hu",   // Hungarian
54    "hy",   // Armenian
55    "ia",   // Interlingua
56    "id",   // Indonesian
57    "is",   // Icelandic
58    "ja",   // Japanese
59    "jw",   // Javanese
60    "ka",   // Georgian
61    "kk",   // Kazakh
62    "km",   // Cambodian
63    "kn",   // Kannada
64    "ko",   // Korean
65    "ku",   // Kurdish
66    "ky",   // Kyrgyz
67    "la",   // Latin
68    "ln",   // Lingala
69    "lo",   // Laothian
70    "lt",   // Lithuanian
71    "lv",   // Latvian
72    "mk",   // Macedonian
73    "ml",   // Malayalam
74    "mn",   // Mongolian
75    "mo",   // Moldavian
76    "mr",   // Marathi
77    "ms",   // Malay
78    "mt",   // Maltese
79    "nb",   // Norwegian (Bokmal)
80    "ne",   // Nepali
81    "nl",   // Dutch
82    "nn",   // Norwegian (Nynorsk)
83    "no",   // Norwegian
84    "oc",   // Occitan
85    "om",   // Oromo
86    "or",   // Oriya
87    "pa",   // Punjabi
88    "pl",   // Polish
89    "ps",   // Pashto
90    "pt",   // Portuguese
91    "qu",   // Quechua
92    "rm",   // Romansh
93    "ro",   // Romanian
94    "ru",   // Russian
95    "sd",   // Sindhi
96    "sh",   // Serbo-Croatian
97    "si",   // Sinhalese
98    "sk",   // Slovak
99    "sl",   // Slovenian
100    "sn",   // Shona
101    "so",   // Somali
102    "sq",   // Albanian
103    "sr",   // Serbian
104    "st",   // Sesotho
105    "su",   // Sundanese
106    "sv",   // Swedish
107    "sw",   // Swahili
108    "ta",   // Tamil
109    "te",   // Telugu
110    "tg",   // Tajik
111    "th",   // Thai
112    "ti",   // Tigrinya
113    "tk",   // Turkmen
114    "to",   // Tonga
115    "tr",   // Turkish
116    "tt",   // Tatar
117    "tw",   // Twi
118    "ug",   // Uighur
119    "uk",   // Ukrainian
120    "ur",   // Urdu
121    "uz",   // Uzbek
122    "vi",   // Vietnamese
123    "xh",   // Xhosa
124    "yi",   // Yiddish
125    "yo",   // Yoruba
126    "zh",   // Chinese
127    "zu",   // Zulu
128};
129
130}  // anonymous namespace
131
132namespace chromeos {
133
134TEST(LocaleChangeGuardTest, ShowNotificationLocaleChanged) {
135  // "en" is used as "global default" in many places.
136  EXPECT_TRUE(
137      LocaleChangeGuard::ShouldShowLocaleChangeNotification("en", "it"));
138  EXPECT_TRUE(
139      LocaleChangeGuard::ShouldShowLocaleChangeNotification("it", "en"));
140
141  // Between two latin locales.
142  EXPECT_TRUE(
143      LocaleChangeGuard::ShouldShowLocaleChangeNotification("fr", "it"));
144  EXPECT_TRUE(
145      LocaleChangeGuard::ShouldShowLocaleChangeNotification("it", "fr"));
146
147  // en <-> non-latin locale
148  EXPECT_TRUE(
149      LocaleChangeGuard::ShouldShowLocaleChangeNotification("en", "zh"));
150  EXPECT_TRUE(
151      LocaleChangeGuard::ShouldShowLocaleChangeNotification("zh", "en"));
152
153  // latin <-> non-latin locale
154  EXPECT_TRUE(
155      LocaleChangeGuard::ShouldShowLocaleChangeNotification("fr", "zh"));
156  EXPECT_TRUE(
157      LocaleChangeGuard::ShouldShowLocaleChangeNotification("zh", "fr"));
158
159  // same language
160  EXPECT_FALSE(
161      LocaleChangeGuard::ShouldShowLocaleChangeNotification("en", "en"));
162  EXPECT_FALSE(
163      LocaleChangeGuard::ShouldShowLocaleChangeNotification("fr", "fr"));
164  EXPECT_FALSE(
165      LocaleChangeGuard::ShouldShowLocaleChangeNotification("zh", "zh"));
166  EXPECT_FALSE(
167      LocaleChangeGuard::ShouldShowLocaleChangeNotification("en", "en-US"));
168  EXPECT_FALSE(
169      LocaleChangeGuard::ShouldShowLocaleChangeNotification("en-GB", "en-US"));
170
171  // Different regions within the same language
172  EXPECT_FALSE(
173      LocaleChangeGuard::ShouldShowLocaleChangeNotification("en", "en-au"));
174  EXPECT_FALSE(
175      LocaleChangeGuard::ShouldShowLocaleChangeNotification("en-AU", "en"));
176  EXPECT_FALSE(
177      LocaleChangeGuard::ShouldShowLocaleChangeNotification("en-AU", "en-GB"));
178
179  EXPECT_TRUE(
180      LocaleChangeGuard::ShouldShowLocaleChangeNotification("zh", "zh-CN"));
181  EXPECT_TRUE(
182      LocaleChangeGuard::ShouldShowLocaleChangeNotification("zh-CN", "zh-TW"));
183  EXPECT_TRUE(
184      LocaleChangeGuard::ShouldShowLocaleChangeNotification("es", "es-419"));
185  EXPECT_TRUE(
186      LocaleChangeGuard::ShouldShowLocaleChangeNotification("es", "es-ES"));
187}
188
189TEST(LocaleChangeGuardTest, ShowNotificationLocaleChangedList) {
190  for (size_t i = 0; i < l10n_util::GetAcceptLanguageListSizeForTesting();
191       ++i) {
192    const char* const locale = l10n_util::GetAcceptLanguageListForTesting()[i];
193    const char* const dash = strchr(locale, '-');
194    const std::string language =
195        (dash ? std::string(locale, dash - locale) : std::string(locale));
196
197    const char* const* allowed_begin = kShowNotificationLanguages;
198    const char* const* allowed_end =
199        kShowNotificationLanguages + arraysize(kShowNotificationLanguages);
200    const bool notification_allowed =
201        (std::find(allowed_begin, allowed_end, language) != allowed_end);
202
203    const char* const* skipped_begin =
204        LocaleChangeGuard::GetSkipShowNotificationLanguagesForTesting();
205    const char* const* skipped_end =
206        skipped_begin +
207        LocaleChangeGuard::GetSkipShowNotificationLanguagesSizeForTesting();
208    const bool notification_skipped =
209        (std::find(skipped_begin, skipped_end, language) != skipped_end);
210
211    EXPECT_TRUE(notification_allowed ^ notification_skipped)
212        << "Language '" << language << "' (from locale '" << locale
213        << "') must be in exactly one list: either "
214           "kSkipShowNotificationLanguages (found=" << notification_skipped
215        << ") or kShowNotificationLanguages (found=" << notification_allowed
216        << ").";
217  }
218}
219
220}  // namespace chromeos
221