1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <gtest/gtest.h>
17 #include "locale_config.h"
18 #include "utils.h"
19 #include "zone_util.h"
20 
21 using namespace OHOS::Global::I18n;
22 using testing::ext::TestSize;
23 using namespace std;
24 
25 namespace OHOS {
26 namespace Global {
27 namespace I18n {
28 class ZoneUtilTest : public testing::Test {
29 public:
30     static void SetUpTestCase(void);
31     static void TearDownTestCase(void);
32     void SetUp();
33     void TearDown();
34 };
35 
SetUpTestCase(void)36 void ZoneUtilTest::SetUpTestCase(void)
37 {}
38 
TearDownTestCase(void)39 void ZoneUtilTest::TearDownTestCase(void)
40 {}
41 
SetUp(void)42 void ZoneUtilTest::SetUp(void)
43 {
44 }
45 
TearDown(void)46 void ZoneUtilTest::TearDown(void)
47 {}
48 
49 /**
50  * @tc.name: ZoneUtilFuncTest001
51  * @tc.desc: Test ZoneUtil GetDefaultZone
52  * @tc.type: FUNC
53  */
54 HWTEST_F(ZoneUtilTest,  ZoneUtilFuncTest001, TestSize.Level1)
55 {
56     string expects[] = { "Asia/Shanghai", "America/New_York", "Asia/Shanghai", "America/New_York", "", "" };
57     string countries[] = { "CN", "US", "cn", "us", "fake", "GB" };
58     ZoneUtil util;
59     int count = 4;
60     for (int i = 0; i < count; ++i) {
61         string out = util.GetDefaultZone(countries[i].c_str());
62         EXPECT_EQ(out, expects[i]);
63     }
64 }
65 
66 /**
67  * @tc.name: ZoneUtilFuncTest002
68  * @tc.desc: Test ZoneUtil GetDefaultZone with offset
69  * @tc.type: FUNC
70  */
71 HWTEST_F(ZoneUtilTest,  ZoneUtilFuncTest002, TestSize.Level1)
72 {
73     string expects[] = { "Asia/Shanghai", "America/Detroit", "" };
74     int32_t offsets[] = { 3600 * 1000 * 8, -3600 * 1000 * 5, 1234 * 789 * 7 };
75     string countries[] = { "CN", "US", "fake" };
76     int count = 2;
77     ZoneUtil util;
78     for (int i = 0; i < count; ++i) {
79         string out = util.GetDefaultZone(countries[i].c_str(), offsets[i]);
80         EXPECT_EQ(out, expects[i]);
81     }
82 }
83 
84 /**
85  * @tc.name: ZoneUtilFuncTest003
86  * @tc.desc: Test ZoneUtil GetDefaultZoneList for CN
87  * @tc.type: FUNC
88  */
89 HWTEST_F(ZoneUtilTest,  ZoneUtilFuncTest003, TestSize.Level1)
90 {
91     vector<string> expects = { "Asia/Shanghai", "Asia/Urumqi"};
92     string country = "CN";
93     vector<string> out;
94     ZoneUtil util;
95     util.GetZoneList(country, out);
96     EXPECT_EQ(expects.size(), out.size());
97     if (expects.size() == out.size()) {
98         for (decltype(expects.size()) i = 0; i < expects.size(); ++i) {
99             EXPECT_EQ(expects[i], out[i]);
100         }
101     }
102 
103     country = "fake";
104     out.clear();
105     util.GetZoneList(country, out);
106     EXPECT_EQ(out.size(), 0);
107 }
108 
109 /**
110  * @tc.name: ZoneUtilFuncTest004
111  * @tc.desc: Test ZoneUtil GetDefaultZoneList for GB
112  * @tc.type: FUNC
113  */
114 HWTEST_F(ZoneUtilTest,  ZoneUtilFuncTest004, TestSize.Level1)
115 {
116     vector<string> expects = { "Europe/London" };
117     string country = "GB";
118     vector<string> out;
119     ZoneUtil util;
120     util.GetZoneList(country, out);
121     EXPECT_EQ(expects.size(), out.size());
122     if (expects.size() == out.size()) {
123         for (decltype(expects.size()) i = 0; i < expects.size(); ++i) {
124             EXPECT_EQ(expects[i], out[i]);
125         }
126     }
127 }
128 
129 /**
130  * @tc.name: ZoneUtilFuncTest003
131  * @tc.desc: Test ZoneUtil GetDefaultZoneList for de
132  * @tc.type: FUNC
133  */
134 HWTEST_F(ZoneUtilTest,  ZoneUtilFuncTest005, TestSize.Level1)
135 {
136     vector<string> expects = { "Europe/Berlin", "Europe/Busingen" };
137     string country = "DE";
138     vector<string> out;
139     ZoneUtil util;
140     util.GetZoneList(country, out);
141     EXPECT_EQ(expects.size(), out.size());
142     if (expects.size() == out.size()) {
143         for (decltype(expects.size()) i = 0; i < expects.size(); ++i) {
144             EXPECT_EQ(expects[i], out[i]);
145         }
146     }
147 }
148 
149 /**
150  * @tc.name: ZoneUtilFuncTest006
151  * @tc.desc: Test ZoneUtil GetDefaultZoneList for CN with offset 8 hours
152  * @tc.type: FUNC
153  */
154 HWTEST_F(ZoneUtilTest,  ZoneUtilFuncTest006, TestSize.Level1)
155 {
156     vector<string> expects = { "Asia/Shanghai" };
157     string country = "CN";
158     vector<string> out;
159     ZoneUtil util;
160     util.GetZoneList(country, 3600 * 1000 * 8, out);
161     EXPECT_EQ(expects.size(), out.size());
162     if (expects.size() == out.size()) {
163         for (decltype(expects.size()) i = 0; i < expects.size(); ++i) {
164             EXPECT_EQ(expects[i], out[i]);
165         }
166     }
167 
168     country = "fake";
169     out.clear();
170     util.GetZoneList(country, 1234 * 789 * 9, out);
171     EXPECT_EQ(out.size(), 0);
172 }
173 
174 /**
175  * @tc.name: ZoneUtilFuncTest007
176  * @tc.desc: Test ZoneUtil GetDefaultZoneList for 86 with offset 8 hours
177  * @tc.type: FUNC
178  */
179 HWTEST_F(ZoneUtilTest, ZoneUtilFuncTest007, TestSize.Level1)
180 {
181     vector<string> expects = { "Asia/Shanghai" };
182     int32_t number = 86;
183     ZoneUtil util;
184     string out = util.GetDefaultZone(number);
185     EXPECT_EQ(expects[0], out);
186     int32_t fakeNum = 2233;
187     out = util.GetDefaultZone(fakeNum);
188     EXPECT_EQ("", out);
189 }
190 
191 /**
192  * @tc.name: ZoneUtilFuncTest008
193  * @tc.desc: Test ZoneUtil GetDefaultZoneList for 86 with offset 8 hours
194  * @tc.type: FUNC
195  */
196 HWTEST_F(ZoneUtilTest, ZoneUtilFuncTest008, TestSize.Level1)
197 {
198     vector<string> expects = { "Asia/Shanghai" };
199     int32_t number = 86;
200     ZoneUtil util;
201     string out = util.GetDefaultZone(number, 8 * 3600 * 1000);
202     EXPECT_EQ(expects[0], out);
203     int32_t fakeNum = 2233;
204     out = util.GetDefaultZone(fakeNum, 8 * 3600 * 1000);
205     EXPECT_EQ("", out);
206 }
207 
208 /**
209  * @tc.name: ZoneUtilFuncTest009
210  * @tc.desc: Test ZoneUtil LookupTimezoneByCountryAndNITZ
211  * @tc.type: FUNC
212  */
213 HWTEST_F(ZoneUtilTest, ZoneUtilFuncTest009, TestSize.Level1)
214 {
215     ZoneUtil util;
216     std::string region = "CN";
217     NITZData nitzData = { 0, 28800000, 1679969021999 };
218     CountryResult result = util.LookupTimezoneByCountryAndNITZ(region, nitzData);
219     EXPECT_TRUE(result.isOnlyMatch);
220     EXPECT_EQ(result.timezoneId, "Asia/Shanghai");
221 
222     NITZData nitzData2 = { 0, 21600000, 1679969021999 };
223     CountryResult result2 = util.LookupTimezoneByCountryAndNITZ(region, nitzData2);
224     EXPECT_TRUE(result2.isOnlyMatch);
225     EXPECT_EQ(result2.timezoneId, "Asia/Urumqi");
226 }
227 
228 /**
229  * @tc.name: ZoneUtilFuncTest010
230  * @tc.desc: Test ZoneUtil LookupTimezoneByNITZ
231  * @tc.type: FUNC
232  */
233 HWTEST_F(ZoneUtilTest, ZoneUtilFuncTest010, TestSize.Level1)
234 {
235     ZoneUtil util;
236 
237     NITZData nitzData = { 0, 28800000, 1679969021999 };
238     CountryResult result = util.LookupTimezoneByNITZ(nitzData);
239     EXPECT_FALSE(result.isOnlyMatch);
240     unordered_set<std::string> possibleTimeZones = {"Asia/Shanghai", "Asia/Urumqi", "Antarctica/Casey", "Asia/Brunei",
241         "Asia/Choibalsan", "Asia/Hong_Kong", "Asia/Irkutsk", "Asia/Kuala_Lumpur", "Asia/Kuching", "Asia/Macau",
242         "Asia/Makassar", "Asia/Manila", "Asia/Shanghai", "Asia/Singapore", "Asia/Taipei", "Asia/Ulaanbaatar",
243         "Australia/Perth"};
244     EXPECT_TRUE(possibleTimeZones.find(result.timezoneId) != possibleTimeZones.end());
245 
246     NITZData nitzData2 = { 1, 10800000, 1679969021999 };
247     CountryResult result2 = util.LookupTimezoneByNITZ(nitzData2);
248     EXPECT_FALSE(result2.isOnlyMatch);
249     possibleTimeZones = {"Asia/Beirut", "Asia/Famagusta", "Asia/Jerusalem", "Asia/Nicosia", "EET",
250         "Europe/Athens", "Europe/Bucharest", "Europe/Chisinau", "Europe/Helsinki", "Europe/Kiev", "Europe/Mariehamn",
251         "Europe/Nicosia", "Europe/Riga", "Europe/Sofia", "Europe/Tallinn", "Europe/Uzhgorod", "Europe/Vilnius",
252         "Europe/Zaporozhye"};
253     EXPECT_TRUE(possibleTimeZones.find(result2.timezoneId) != possibleTimeZones.end());
254 
255     NITZData nitzData3 = { 1, 37800000, 1679969021999 };
256     CountryResult result3 = util.LookupTimezoneByNITZ(nitzData3);
257     EXPECT_FALSE(result3.isOnlyMatch);
258     possibleTimeZones = {"Australia/Adelaide", "Australia/Broken_Hill"};
259     EXPECT_TRUE(possibleTimeZones.find(result3.timezoneId) != possibleTimeZones.end());
260 
261     NITZData nitzData4 = { 0, 12345678, 1679969021999 };
262     CountryResult result4 = util.LookupTimezoneByNITZ(nitzData4);
263     EXPECT_TRUE(result4.isOnlyMatch);
264     EXPECT_EQ(result4.timezoneId, "");
265 
266     NITZData nitzData5 = { -1, 12345678, 1679969021999 };
267     CountryResult result5 = util.LookupTimezoneByNITZ(nitzData5);
268     EXPECT_TRUE(result5.isOnlyMatch);
269     EXPECT_EQ(result5.timezoneId, "");
270 }
271 
272 /**
273  * @tc.name: ZoneUtilFuncTest011
274  * @tc.desc: Test ZoneUtil LookupTimezoneByCountry
275  * @tc.type: FUNC
276  */
277 HWTEST_F(ZoneUtilTest, ZoneUtilFuncTest011, TestSize.Level1)
278 {
279     ZoneUtil util;
280     std::string region = "AQ";
281     int64_t currentMillis = 1679969021999;
282     CountryResult result = util.LookupTimezoneByCountry(region, currentMillis);
283     EXPECT_EQ(result.timezoneId, "Antarctica/McMurdo");
284     EXPECT_EQ(result.quality, MatchQuality::MULTIPLE_ZONES_DIFFERENT_OFFSET);
285 
286     region = "fake Region";
287     CountryResult result2 = util.LookupTimezoneByCountry(region, currentMillis);
288     EXPECT_EQ(result2.timezoneId, "");
289     EXPECT_EQ(result2.quality, 3);
290 
291     region = "AR";
292     CountryResult result3 = util.LookupTimezoneByCountry(region, currentMillis);
293     EXPECT_EQ(result3.timezoneId, "America/Argentina/Buenos_Aires");
294     EXPECT_TRUE(result3.quality == 0 || result3.quality == 2);
295 
296     region = "AM";
297     CountryResult result4 = util.LookupTimezoneByCountry(region, currentMillis);
298     EXPECT_EQ(result4.timezoneId, "Asia/Yerevan");
299     EXPECT_EQ(result4.quality, 1);
300 
301     region = "CY";
302     CountryResult result5 = util.LookupTimezoneByCountry(region, currentMillis);
303     EXPECT_EQ(result5.timezoneId, "Asia/Nicosia");
304     EXPECT_EQ(result5.quality, 2);
305 }
306 
307 /**
308  * @tc.name: ZoneUtilFuncTest0012
309  * @tc.desc: Test ZoneUtil GetDefaultZone
310  * @tc.type: FUNC
311  */
312 HWTEST_F(ZoneUtilTest, ZoneUtilFuncTest0012, TestSize.Level1)
313 {
314     ZoneUtil util;
315     I18nErrorCode errorCode = I18nErrorCode::SUCCESS;
316     std::set<std::string> timeZoneList = GetTimeZoneAvailableIDs(errorCode);
317     std::vector<std::string> vec;
318     LocaleConfig::GetSystemCountries(vec);
319     for (size_t i = 0; i < vec.size(); ++i) {
320         std::string timeZoneId = util.GetDefaultZone(vec[i]);
321         EXPECT_TRUE(timeZoneList.find(timeZoneId) != timeZoneList.end());
322         if (timeZoneList.find(timeZoneId) == timeZoneList.end()) {
323             EXPECT_EQ(vec[i], "");
324             EXPECT_EQ(timeZoneId, "");
325         }
326     }
327 }
328 } // namespace I18n
329 } // namespace Global
330 } // namespace OHOS