WebCore on Mac ignores the user's preferred region (country) while getting the language
[WebKit.git] / Tools / TestWebKitAPI / Tests / mac / NavigatorLanguage.mm
1 /*
2  * Copyright (C) 2015 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #import "config.h"
27 #import "PlatformUtilities.h"
28 #import <WebKit/WebViewPrivate.h>
29 #import <WebKit/DOM.h>
30 #import <wtf/RetainPtr.h>
31
32 @interface NavigatorLanguageDelegate : NSObject <WebFrameLoadDelegate> {
33 }
34 @end
35
36 static bool didFinishLoad;
37
38 @implementation NavigatorLanguageDelegate
39
40 - (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame
41 {
42     didFinishLoad = true;
43 }
44
45 @end
46
47 namespace TestWebKitAPI {
48
49 void overrideAppleLanguages(NSString *primaryLanguage)
50 {
51     RetainPtr<NSMutableDictionary> argumentDomain = adoptNS([[[NSUserDefaults standardUserDefaults] volatileDomainForName:NSArgumentDomain] mutableCopy]);
52     if (!argumentDomain)
53         argumentDomain = adoptNS([[NSMutableDictionary alloc] init]);
54     
55     [argumentDomain addEntriesFromDictionary:@{
56         @"AppleLanguages": @[primaryLanguage]
57     }];
58     [[NSUserDefaults standardUserDefaults] setVolatileDomain:argumentDomain.get() forName:NSArgumentDomain];
59
60     [[NSDistributedNotificationCenter defaultCenter] postNotificationName:@"AppleLanguagePreferencesChangedNotification" object:nil userInfo:nil options:NSNotificationDeliverImmediately];
61
62     [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
63 }
64
65 static NSString *languageForSystemLanguage(WebView* webView, NSString *systemLanguage)
66 {
67     overrideAppleLanguages(systemLanguage);
68     return [webView stringByEvaluatingJavaScriptFromString:@"navigator.language"];
69 }
70
71 // These tests document current behavior. Some of the current results may not be right. Note that
72 // this oddly assumes that the user has set their language to something possibly-foreign but still
73 // left their region as US. Hence the "-us" variants.
74 // FIXME: These tests should also set the region to see how WebKit will handle that.
75 // https://bugs.webkit.org/show_bug.cgi?id=157039
76 NSArray *tests = @[
77     @[@"ru", @"ru-us"], // This does not match other browsers or CFNetwork's Accept-Language, which all use "ru".
78     @[@"en", @"en-us"],
79     @[@"en-GB", @"en-gb"],
80     @[@"en-US", @"en-us"],
81     @[@"ja", @"ja-us"],
82     @[@"hi", @"hi-us"],
83     @[@"zh-TW", @"zh-tw"], // This should not map to the generic zh-hant, see rdar://problem/21395180.
84     @[@"zh-HK", @"zh-tw"],
85     @[@"es", @"es-us"],
86     @[@"es-MX", @"es-xl"],
87     @[@"es-ES", @"es-es"],
88     @[@"es-419", @"es-xl"],
89     @[@"zh-Hans", @"zh-cn"],
90     @[@"zh-Hant", @"zh-tw"],
91     @[@"pt-BR", @"pt-br"],
92     @[@"pt-PT", @"pt-pt"],
93     @[@"fr", @"fr-us"],
94     @[@"fr-CA", @"fr-ca"],
95 ];
96
97 TEST(WebKit1, NavigatorLanguage)
98 {
99     RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:NSZeroRect frameName:nil groupName:nil]);
100     RetainPtr<NavigatorLanguageDelegate> frameLoadDelegate = adoptNS([NavigatorLanguageDelegate new]);
101
102     webView.get().frameLoadDelegate = frameLoadDelegate.get();
103     [[webView.get() mainFrame] loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"about:blank"]]];
104
105     Util::run(&didFinishLoad);
106     for (NSArray *test in tests)
107         EXPECT_WK_STREQ([test objectAtIndex:1], languageForSystemLanguage(webView.get(), [test objectAtIndex:0]));
108 }
109
110 #if WK_API_ENABLED
111
112 TEST(WKWebView, NavigatorLanguage)
113 {
114     RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
115
116     NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"about:blank"]];
117     [webView loadRequest:request];
118     __block bool isDone = false;
119
120     __block void (^runTest)(NSUInteger) = ^(NSUInteger index) {
121         NSArray *test = [tests objectAtIndex:index];
122         overrideAppleLanguages([test objectAtIndex:0]);
123         [webView evaluateJavaScript:@"navigator.language" completionHandler:^(id result, NSError *) {
124             EXPECT_WK_STREQ([test objectAtIndex:1], result);
125             if (index + 1 < [tests count])
126                 runTest(index + 1);
127             else
128                 isDone = true;
129         }];
130     };
131
132     runTest(0);
133
134     TestWebKitAPI::Util::run(&isDone);
135 }
136
137 #endif
138
139 } // namespace TestWebKitAPI