Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / ios / web / webui / crw_web_ui_page_builder_unittest.mm
blob7d7968a6968e775c789c9b4174c9be25d017b548
1 // Copyright 2015 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 "ios/web/webui/crw_web_ui_page_builder.h"
7 #import <Foundation/Foundation.h>
9 #include "base/logging.h"
10 #import "base/mac/scoped_nsobject.h"
11 #include "base/strings/sys_string_conversions.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "testing/gtest_mac.h"
14 #include "testing/platform_test.h"
15 #include "url/gurl.h"
17 namespace {
19 // HTML page template.
20 NSString* const kPageTemplate = @"<html><head>%@</head></html>";
22 // URL for BuildSimplePage.
23 const char* kSimplePageUrl("http://simplepage");
24 // URL for BuildPageWithJSSubresource.
25 const char* kJsPageUrl("http://javascriptpage");
26 // URL for BuildPageWithCSSSubresource.
27 const char* kCssPageUrl("http://csspage");
28 // URL for BuildPageWithMultipleSubresources.
29 const char* kMultipleResourcesPageUrl("http://multipleresourcespage");
30 // URL for BuildPageWithCSSNestedSubresources.
31 const char* kCssImportPageUrl("http://csspagewithimport");
32 // URL for BuildPageWithRelativeSubresource.
33 const char* kCssRelativePageUrl("http://css/csspage.html");
34 // URL for BuildPageWithWebUIJS.
35 const char* kCoreJsPageUrl("http://corejs");
37 // URL for JS resource.
38 const char* kJsResourceUrl("http://javascriptpage/resources/javascript.js");
39 // URL for CSS resource.
40 const char* kCssResourceUrl("http://csspage/resources/stylesheet.css");
41 // URL for CSS resource with import.
42 const char* kCssImportResourceUrl("http://csspage/resources/import.css");
43 // Chrome URL for messaging JavaScript.
44 const char* kCoreJsResourceUrl("chrome://resources/js/ios/web_ui.js");
45 // String for relative resource URL.
46 const char* kRelativeCssString("myresource.css");
48 // Template for JS tag with URL.
49 NSString* const kJsTagTemplate = @"<script src=\"%@\"></script>";
50 // Template for inlined JS tag.
51 NSString* const kJsInlinedTemplate = @"<script>%@</script>";
52 // Template for CSS tag with URL.
53 NSString* const kCssTagTemplate = @"<link rel=\"stylesheet\" href=\"%@\">";
54 // Template for inlined CSS tag.
55 NSString* const kCssInlinedTemplate = @"<style>%@</style>";
56 // Template for CSS with import statement.
57 NSString* const kCssImportTemplate = @"@import url(%@); b {diplay:block;}";
59 // Content for JS resource.
60 NSString* const kJsContent = @"console.log('This is JavaScript');";
61 // Content for CSS resource.
62 NSString* const kCssContent = @"html {height:100%;}";
63 // Content for relative CSS resource.
64 NSString* const kRelativeCssContent = @"mytag {someprop:1}";
65 // Dummy content for WebUI messaging JavaScript.
66 NSString* kCoreJsContent = @"console.log('messaging javascript');";
68 // Returns HTML string containing tag formed with tag_template and content.
69 NSString* PageForTagTemplateAndContent(NSString* tag_template,
70                                        NSString* content) {
71   NSString* tag = [NSString stringWithFormat:tag_template, content];
72   return [NSString stringWithFormat:kPageTemplate, tag];
75 }  // namespace
77 // Mock subclass of CRWWebUIPageBuilder for testing.
78 @interface MockCRWWebUIPageBuilder : CRWWebUIPageBuilder
79 // Stub out webUIJavaScript method so resource bundle access is not needed.
80 - (NSString*)webUIJavaScript;
81 @end
83 @implementation MockCRWWebUIPageBuilder
84 - (NSString*)webUIJavaScript {
85   return kCoreJsContent;
87 @end
89 // Mock CRWWebUIPageBuilderDelegate to serve responses for resource requests.
90 @interface MockPageBuilderDelegate : NSObject<CRWWebUIPageBuilderDelegate>
91 // Returns HTML page containing tag formed from tagTemplate and URL.
92 - (NSString*)pageWithTagTemplate:(NSString*)tagTemplate URL:(const char*)URL;
93 // Returns resource string for resourceURL.
94 - (NSString*)resourceForURL:(const GURL&)resourceURL;
95 @end
97 @implementation MockPageBuilderDelegate
99 - (void)webUIPageBuilder:(CRWWebUIPageBuilder*)webUIPageBuilder
100     fetchResourceWithURL:(const GURL&)resourceURL
101        completionHandler:(web::WebUIDelegateCompletion)completionHandler {
102   completionHandler([self resourceForURL:resourceURL], resourceURL);
105 - (NSString*)resourceForURL:(const GURL&)resourceURL {
106   // Resource for BuildSimplePage.
107   if (resourceURL == GURL(kSimplePageUrl))
108     return [NSString stringWithFormat:kPageTemplate, @""];
109   // Resources for BuildPageWithJSSubresource.
110   if (resourceURL == GURL(kJsPageUrl))
111     return [self pageWithTagTemplate:kJsTagTemplate URL:kJsResourceUrl];
112   if (resourceURL == GURL(kJsResourceUrl))
113     return kJsContent;
114   // Resources for BuildPageWithCSSSubresource.
115   if (resourceURL == GURL(kCssPageUrl))
116     return [self pageWithTagTemplate:kCssTagTemplate URL:kCssResourceUrl];
117   if (resourceURL == GURL(kCssResourceUrl))
118     return kCssContent;
119   // Resource for BuildPageWithMultipleSubresources.
120   if (resourceURL == GURL(kMultipleResourcesPageUrl)) {
121     NSString* JSTag =
122         [NSString stringWithFormat:kJsTagTemplate,
123                                    base::SysUTF8ToNSString(kJsResourceUrl)];
124     NSString* CSSTag =
125         [NSString stringWithFormat:kCssTagTemplate,
126                                    base::SysUTF8ToNSString(kCssResourceUrl)];
127     NSString* CoreJSTag =
128         [NSString stringWithFormat:kJsTagTemplate,
129                                    base::SysUTF8ToNSString(kCoreJsResourceUrl)];
130     NSString* tags = [[JSTag stringByAppendingString:CSSTag]
131         stringByAppendingString:CoreJSTag];
132     return [NSString stringWithFormat:kPageTemplate, tags];
133   }
134   // Resources for BuildPageWithCSSNestedSubresource.
135   if (resourceURL == GURL(kCssImportPageUrl)) {
136     return [self pageWithTagTemplate:kCssTagTemplate URL:kCssImportResourceUrl];
137   }
138   if (resourceURL == GURL(kCssImportResourceUrl)) {
139     return [NSString stringWithFormat:kCssImportTemplate,
140                                       base::SysUTF8ToNSString(kCssResourceUrl)];
141   }
142   // Resources for BuildPageWithRelativeSubresource.
143   GURL relativePageURL(kCssRelativePageUrl);
144   GURL cssRelativeResourceURL = relativePageURL.Resolve(kRelativeCssString);
145   if (resourceURL == relativePageURL) {
146     return [self pageWithTagTemplate:kCssTagTemplate URL:kRelativeCssString];
147   }
148   if (resourceURL == cssRelativeResourceURL)
149     return kRelativeCssContent;
150   // Resource for BuildPageWithWebUIJS.
151   if (resourceURL == GURL(kCoreJsPageUrl))
152     return [self pageWithTagTemplate:kJsTagTemplate URL:kCoreJsResourceUrl];
154   NOTREACHED();
155   return nil;
158 - (NSString*)pageWithTagTemplate:(NSString*)tagTemplate URL:(const char*)URL {
159   NSString* URLString = base::SysUTF8ToNSString(URL);
160   NSString* tag = [NSString stringWithFormat:tagTemplate, URLString];
161   return [NSString stringWithFormat:kPageTemplate, tag];
164 @end
166 namespace web {
168 class CRWWebUIPageBuilderTest : public PlatformTest {
169  protected:
170   void SetUp() override {
171     PlatformTest::SetUp();
172     delegate_.reset([[MockPageBuilderDelegate alloc] init]);
173     web_ui_page_builder_.reset(
174         [[MockCRWWebUIPageBuilder alloc] initWithDelegate:delegate_]);
175   }
176   // CRWWebUIPageBuilder for testing.
177   base::scoped_nsobject<MockCRWWebUIPageBuilder> web_ui_page_builder_;
178   // Delegate for test CRWWebUIPageBuilder.
179   base::scoped_nsobject<MockPageBuilderDelegate> delegate_;
182 // Tests that a page without imports is passed to completion handler unchanged.
183 TEST_F(CRWWebUIPageBuilderTest, BuildSimplePage) {
184   NSString* simple_page_html = [NSString stringWithFormat:kPageTemplate, @""];
185   [web_ui_page_builder_ buildWebUIPageForURL:GURL(kSimplePageUrl)
186                            completionHandler:^(NSString* result) {
187                              EXPECT_NSEQ(simple_page_html, result);
188                            }];
191 // Tests that a page with a JavaScript subresource is passed to the completion
192 // handler with the resource inlined properly, i.e. <script
193 // src="http://somejs.js"></script> becomes <script>some javascript;</script>.
194 TEST_F(CRWWebUIPageBuilderTest, BuildPageWithJSSubresource) {
195   NSString* js_page_html =
196       PageForTagTemplateAndContent(kJsInlinedTemplate, kJsContent);
197   web::WebUIPageCompletion completionHandler = ^(NSString* result) {
198     EXPECT_NSEQ(js_page_html, result);
199   };
200   [web_ui_page_builder_ buildWebUIPageForURL:GURL(kJsPageUrl)
201                            completionHandler:completionHandler];
204 // Tests that a page with a CSS subresource is passed to the completion handler
205 // with the resource inlined properly, i.e. <link rel="stylesheet"
206 // href="http://somecss.css"/> becomes <style>some css</style>.
207 TEST_F(CRWWebUIPageBuilderTest, BuildPageWithCSSSubresource) {
208   NSString* css_page_html =
209       PageForTagTemplateAndContent(kCssInlinedTemplate, kCssContent);
210   [web_ui_page_builder_ buildWebUIPageForURL:GURL(kCssPageUrl)
211                            completionHandler:^(NSString* result) {
212                              EXPECT_NSEQ(css_page_html, result);
213                            }];
216 TEST_F(CRWWebUIPageBuilderTest, BuildPageWithMultipleSubresources) {
217   NSString* js_tag = [NSString stringWithFormat:kJsInlinedTemplate, kJsContent];
218   NSString* css_tag =
219       [NSString stringWithFormat:kCssInlinedTemplate, kCssContent];
220   NSString* core_js_tag =
221       [NSString stringWithFormat:kJsInlinedTemplate, kCoreJsContent];
222   NSString* tags = [[js_tag stringByAppendingString:css_tag]
223       stringByAppendingString:core_js_tag];
224   NSString* multiple_resources_html =
225       [NSString stringWithFormat:kPageTemplate, tags];
226   [web_ui_page_builder_ buildWebUIPageForURL:GURL(kMultipleResourcesPageUrl)
227                            completionHandler:^(NSString* result) {
228                              EXPECT_NSEQ(multiple_resources_html, result);
229                            }];
232 // Tests that a page with a CSS subresource that contains an @import statement
233 // for another CSS subresource is passed to the completion handler with the
234 // resource inlined properly, i.e. if somecss.css from above has the statement
235 // @import url(morecss.css), the original tag becomes <style>contents of
236 // morecss</style><style>some css</style>.
237 TEST_F(CRWWebUIPageBuilderTest, BuildPageWithCSSNestedSubresource) {
238   NSString* css_inlined_tag =
239       [NSString stringWithFormat:kCssInlinedTemplate, kCssContent];
240   NSString* css_inlined_content =
241       [NSString stringWithFormat:kCssImportTemplate,
242                                  base::SysUTF8ToNSString(kCssResourceUrl)];
243   NSString* css_import_inlined_tag =
244       [NSString stringWithFormat:kCssInlinedTemplate, css_inlined_content];
245   NSString* tags =
246       [css_inlined_tag stringByAppendingString:css_import_inlined_tag];
247   NSString* css_import_page_html =
248       [NSString stringWithFormat:kPageTemplate, tags];
249   [web_ui_page_builder_ buildWebUIPageForURL:GURL(kCssImportPageUrl)
250                            completionHandler:^(NSString* result) {
251                              EXPECT_NSEQ(css_import_page_html, result);
252                            }];
255 // Tests that a page with a relative subresource is properly resolved.
256 TEST_F(CRWWebUIPageBuilderTest, BuildPageWithRelativeSubresource) {
257   NSString* css_page_html =
258       PageForTagTemplateAndContent(kCssInlinedTemplate, kRelativeCssContent);
259   [web_ui_page_builder_ buildWebUIPageForURL:GURL(kCssRelativePageUrl)
260                            completionHandler:^(NSString* result) {
261                              EXPECT_NSEQ(css_page_html, result);
262                            }];
265 // Tests that the JavaScript for connecting WebUI messaging to web controller
266 // messaging is properly inlined.
267 TEST_F(CRWWebUIPageBuilderTest, BuildPageWithWebUIJS) {
268   NSString* core_js_html =
269       PageForTagTemplateAndContent(kJsInlinedTemplate, kCoreJsContent);
270   [web_ui_page_builder_ buildWebUIPageForURL:GURL(kCoreJsPageUrl)
271                            completionHandler:^(NSString* result) {
272                              EXPECT_NSEQ(core_js_html, result);
273                            }];
276 }  //  namespace web