OLD | NEW |
(Empty) | |
| 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. |
| 4 |
| 5 #include "ios/web/webui/crw_web_ui_page_builder.h" |
| 6 |
| 7 #import <Foundation/Foundation.h> |
| 8 |
| 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" |
| 16 |
| 17 namespace { |
| 18 |
| 19 // HTML page template. |
| 20 NSString* const kPageTemplate = @"<html><head>%@</head></html>"; |
| 21 |
| 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"); |
| 36 |
| 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/core.js"); |
| 45 // String for relative resource URL. |
| 46 const char* kRelativeCssString("myresource.css"); |
| 47 |
| 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;}"; |
| 58 |
| 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');"; |
| 67 |
| 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]; |
| 73 } |
| 74 |
| 75 } // namespace |
| 76 |
| 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 |
| 82 |
| 83 @implementation MockCRWWebUIPageBuilder |
| 84 - (NSString*)webUIJavaScript { |
| 85 return kCoreJsContent; |
| 86 } |
| 87 @end |
| 88 |
| 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 |
| 96 |
| 97 @implementation MockPageBuilderDelegate |
| 98 |
| 99 - (void)webUIPageBuilder:(CRWWebUIPageBuilder*)webUIPageBuilder |
| 100 fetchResourceWithURL:(const GURL&)resourceURL |
| 101 completionHandler:(web::WebUIDelegateCompletion)completionHandler { |
| 102 completionHandler([self resourceForURL:resourceURL], resourceURL); |
| 103 } |
| 104 |
| 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]; |
| 153 |
| 154 NOTREACHED(); |
| 155 return nil; |
| 156 } |
| 157 |
| 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]; |
| 162 } |
| 163 |
| 164 @end |
| 165 |
| 166 namespace web { |
| 167 |
| 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_; |
| 180 }; |
| 181 |
| 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 }]; |
| 189 } |
| 190 |
| 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]; |
| 202 } |
| 203 |
| 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 }]; |
| 214 } |
| 215 |
| 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 }]; |
| 230 } |
| 231 |
| 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 }]; |
| 253 } |
| 254 |
| 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 }]; |
| 263 } |
| 264 |
| 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 }]; |
| 274 } |
| 275 |
| 276 } // namespace web |
OLD | NEW |