Index: ios/web/webui/crw_web_ui_page_builder_unittest.mm |
diff --git a/ios/web/webui/crw_web_ui_page_builder_unittest.mm b/ios/web/webui/crw_web_ui_page_builder_unittest.mm |
new file mode 100644 |
index 0000000000000000000000000000000000000000..fdefc3f40c6ac02c4662e39dcec1ba1408a795db |
--- /dev/null |
+++ b/ios/web/webui/crw_web_ui_page_builder_unittest.mm |
@@ -0,0 +1,276 @@ |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "ios/web/webui/crw_web_ui_page_builder.h" |
+ |
+#import <Foundation/Foundation.h> |
+ |
+#include "base/logging.h" |
+#import "base/mac/scoped_nsobject.h" |
+#include "base/strings/sys_string_conversions.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+#include "testing/gtest_mac.h" |
+#include "testing/platform_test.h" |
+#include "url/gurl.h" |
+ |
+namespace { |
+ |
+// HTML page template. |
+NSString* const kPageTemplate = @"<html><head>%@</head></html>"; |
+ |
+// URL for BuildSimplePage. |
+const char* kSimplePageUrl("http://simplepage"); |
+// URL for BuildPageWithJSSubresource. |
+const char* kJsPageUrl("http://javascriptpage"); |
+// URL for BuildPageWithCSSSubresource. |
+const char* kCssPageUrl("http://csspage"); |
+// URL for BuildPageWithMultipleSubresources. |
+const char* kMultipleResourcesPageUrl("http://multipleresourcespage"); |
+// URL for BuildPageWithCSSNestedSubresources. |
+const char* kCssImportPageUrl("http://csspagewithimport"); |
+// URL for BuildPageWithRelativeSubresource. |
+const char* kCssRelativePageUrl("http://css/csspage.html"); |
+// URL for BuildPageWithWebUIJS. |
+const char* kCoreJsPageUrl("http://corejs"); |
+ |
+// URL for JS resource. |
+const char* kJsResourceUrl("http://javascriptpage/resources/javascript.js"); |
+// URL for CSS resource. |
+const char* kCssResourceUrl("http://csspage/resources/stylesheet.css"); |
+// URL for CSS resource with import. |
+const char* kCssImportResourceUrl("http://csspage/resources/import.css"); |
+// Chrome URL for messaging JavaScript. |
+const char* kCoreJsResourceUrl("chrome://resources/js/ios/core.js"); |
+// String for relative resource URL. |
+const char* kRelativeCssString("myresource.css"); |
+ |
+// Template for JS tag with URL. |
+NSString* const kJsTagTemplate = @"<script src=\"%@\"></script>"; |
+// Template for inlined JS tag. |
+NSString* const kJsInlinedTemplate = @"<script>%@</script>"; |
+// Template for CSS tag with URL. |
+NSString* const kCssTagTemplate = @"<link rel=\"stylesheet\" href=\"%@\">"; |
+// Template for inlined CSS tag. |
+NSString* const kCssInlinedTemplate = @"<style>%@</style>"; |
+// Template for CSS with import statement. |
+NSString* const kCssImportTemplate = @"@import url(%@); b {diplay:block;}"; |
+ |
+// Content for JS resource. |
+NSString* const kJsContent = @"console.log('This is JavaScript');"; |
+// Content for CSS resource. |
+NSString* const kCssContent = @"html {height:100%;}"; |
+// Content for relative CSS resource. |
+NSString* const kRelativeCssContent = @"mytag {someprop:1}"; |
+// Dummy content for WebUI messaging JavaScript. |
+NSString* kCoreJsContent = @"console.log('messaging javascript');"; |
+ |
+// Returns HTML string containing tag formed with tag_template and content. |
+NSString* PageForTagTemplateAndContent(NSString* tag_template, |
+ NSString* content) { |
+ NSString* tag = [NSString stringWithFormat:tag_template, content]; |
+ return [NSString stringWithFormat:kPageTemplate, tag]; |
+} |
+ |
+} // namespace |
+ |
+// Mock subclass of CRWWebUIPageBuilder for testing. |
+@interface MockCRWWebUIPageBuilder : CRWWebUIPageBuilder |
+// Stub out webUIJavaScript method so resource bundle access is not needed. |
+- (NSString*)webUIJavaScript; |
+@end |
+ |
+@implementation MockCRWWebUIPageBuilder |
+- (NSString*)webUIJavaScript { |
+ return kCoreJsContent; |
+} |
+@end |
+ |
+// Mock CRWWebUIPageBuilderDelegate to serve responses for resource requests. |
+@interface MockPageBuilderDelegate : NSObject<CRWWebUIPageBuilderDelegate> |
+// Returns HTML page containing tag formed from tagTemplate and URL. |
+- (NSString*)pageWithTagTemplate:(NSString*)tagTemplate URL:(const char*)URL; |
+// Returns resource string for resourceURL. |
+- (NSString*)resourceForURL:(const GURL&)resourceURL; |
+@end |
+ |
+@implementation MockPageBuilderDelegate |
+ |
+- (void)webUIPageBuilder:(CRWWebUIPageBuilder*)webUIPageBuilder |
+ fetchResourceWithURL:(const GURL&)resourceURL |
+ completionHandler:(web::WebUIDelegateCompletion)completionHandler { |
+ completionHandler([self resourceForURL:resourceURL], resourceURL); |
+} |
+ |
+- (NSString*)resourceForURL:(const GURL&)resourceURL { |
+ // Resource for BuildSimplePage. |
+ if (resourceURL == GURL(kSimplePageUrl)) |
+ return [NSString stringWithFormat:kPageTemplate, @""]; |
+ // Resources for BuildPageWithJSSubresource. |
+ if (resourceURL == GURL(kJsPageUrl)) |
+ return [self pageWithTagTemplate:kJsTagTemplate URL:kJsResourceUrl]; |
+ if (resourceURL == GURL(kJsResourceUrl)) |
+ return kJsContent; |
+ // Resources for BuildPageWithCSSSubresource. |
+ if (resourceURL == GURL(kCssPageUrl)) |
+ return [self pageWithTagTemplate:kCssTagTemplate URL:kCssResourceUrl]; |
+ if (resourceURL == GURL(kCssResourceUrl)) |
+ return kCssContent; |
+ // Resource for BuildPageWithMultipleSubresources. |
+ if (resourceURL == GURL(kMultipleResourcesPageUrl)) { |
+ NSString* JSTag = |
+ [NSString stringWithFormat:kJsTagTemplate, |
+ base::SysUTF8ToNSString(kJsResourceUrl)]; |
+ NSString* CSSTag = |
+ [NSString stringWithFormat:kCssTagTemplate, |
+ base::SysUTF8ToNSString(kCssResourceUrl)]; |
+ NSString* CoreJSTag = |
+ [NSString stringWithFormat:kJsTagTemplate, |
+ base::SysUTF8ToNSString(kCoreJsResourceUrl)]; |
+ NSString* tags = [[JSTag stringByAppendingString:CSSTag] |
+ stringByAppendingString:CoreJSTag]; |
+ return [NSString stringWithFormat:kPageTemplate, tags]; |
+ } |
+ // Resources for BuildPageWithCSSNestedSubresource. |
+ if (resourceURL == GURL(kCssImportPageUrl)) { |
+ return [self pageWithTagTemplate:kCssTagTemplate URL:kCssImportResourceUrl]; |
+ } |
+ if (resourceURL == GURL(kCssImportResourceUrl)) { |
+ return [NSString stringWithFormat:kCssImportTemplate, |
+ base::SysUTF8ToNSString(kCssResourceUrl)]; |
+ } |
+ // Resources for BuildPageWithRelativeSubresource. |
+ GURL relativePageURL(kCssRelativePageUrl); |
+ GURL cssRelativeResourceURL = relativePageURL.Resolve(kRelativeCssString); |
+ if (resourceURL == relativePageURL) { |
+ return [self pageWithTagTemplate:kCssTagTemplate URL:kRelativeCssString]; |
+ } |
+ if (resourceURL == cssRelativeResourceURL) |
+ return kRelativeCssContent; |
+ // Resource for BuildPageWithWebUIJS. |
+ if (resourceURL == GURL(kCoreJsPageUrl)) |
+ return [self pageWithTagTemplate:kJsTagTemplate URL:kCoreJsResourceUrl]; |
+ |
+ NOTREACHED(); |
+ return nil; |
+} |
+ |
+- (NSString*)pageWithTagTemplate:(NSString*)tagTemplate URL:(const char*)URL { |
+ NSString* URLString = base::SysUTF8ToNSString(URL); |
+ NSString* tag = [NSString stringWithFormat:tagTemplate, URLString]; |
+ return [NSString stringWithFormat:kPageTemplate, tag]; |
+} |
+ |
+@end |
+ |
+namespace web { |
+ |
+class CRWWebUIPageBuilderTest : public PlatformTest { |
+ protected: |
+ void SetUp() override { |
+ PlatformTest::SetUp(); |
+ delegate_.reset([[MockPageBuilderDelegate alloc] init]); |
+ web_ui_page_builder_.reset( |
+ [[MockCRWWebUIPageBuilder alloc] initWithDelegate:delegate_]); |
+ } |
+ // CRWWebUIPageBuilder for testing. |
+ base::scoped_nsobject<MockCRWWebUIPageBuilder> web_ui_page_builder_; |
+ // Delegate for test CRWWebUIPageBuilder. |
+ base::scoped_nsobject<MockPageBuilderDelegate> delegate_; |
+}; |
+ |
+// Tests that a page without imports is passed to completion handler unchanged. |
+TEST_F(CRWWebUIPageBuilderTest, BuildSimplePage) { |
+ NSString* simple_page_html = [NSString stringWithFormat:kPageTemplate, @""]; |
+ [web_ui_page_builder_ buildWebUIPageForURL:GURL(kSimplePageUrl) |
+ completionHandler:^(NSString* result) { |
+ EXPECT_NSEQ(simple_page_html, result); |
+ }]; |
+} |
+ |
+// Tests that a page with a JavaScript subresource is passed to the completion |
+// handler with the resource inlined properly, i.e. <script |
+// src="http://somejs.js"></script> becomes <script>some javascript;</script>. |
+TEST_F(CRWWebUIPageBuilderTest, BuildPageWithJSSubresource) { |
+ NSString* js_page_html = |
+ PageForTagTemplateAndContent(kJsInlinedTemplate, kJsContent); |
+ web::WebUIPageCompletion completionHandler = ^(NSString* result) { |
+ EXPECT_NSEQ(js_page_html, result); |
+ }; |
+ [web_ui_page_builder_ buildWebUIPageForURL:GURL(kJsPageUrl) |
+ completionHandler:completionHandler]; |
+} |
+ |
+// Tests that a page with a CSS subresource is passed to the completion handler |
+// with the resource inlined properly, i.e. <link rel="stylesheet" |
+// href="http://somecss.css"/> becomes <style>some css</style>. |
+TEST_F(CRWWebUIPageBuilderTest, BuildPageWithCSSSubresource) { |
+ NSString* css_page_html = |
+ PageForTagTemplateAndContent(kCssInlinedTemplate, kCssContent); |
+ [web_ui_page_builder_ buildWebUIPageForURL:GURL(kCssPageUrl) |
+ completionHandler:^(NSString* result) { |
+ EXPECT_NSEQ(css_page_html, result); |
+ }]; |
+} |
+ |
+TEST_F(CRWWebUIPageBuilderTest, BuildPageWithMultipleSubresources) { |
+ NSString* js_tag = [NSString stringWithFormat:kJsInlinedTemplate, kJsContent]; |
+ NSString* css_tag = |
+ [NSString stringWithFormat:kCssInlinedTemplate, kCssContent]; |
+ NSString* core_js_tag = |
+ [NSString stringWithFormat:kJsInlinedTemplate, kCoreJsContent]; |
+ NSString* tags = [[js_tag stringByAppendingString:css_tag] |
+ stringByAppendingString:core_js_tag]; |
+ NSString* multiple_resources_html = |
+ [NSString stringWithFormat:kPageTemplate, tags]; |
+ [web_ui_page_builder_ buildWebUIPageForURL:GURL(kMultipleResourcesPageUrl) |
+ completionHandler:^(NSString* result) { |
+ EXPECT_NSEQ(multiple_resources_html, result); |
+ }]; |
+} |
+ |
+// Tests that a page with a CSS subresource that contains an @import statement |
+// for another CSS subresource is passed to the completion handler with the |
+// resource inlined properly, i.e. if somecss.css from above has the statement |
+// @import url(morecss.css), the original tag becomes <style>contents of |
+// morecss</style><style>some css</style>. |
+TEST_F(CRWWebUIPageBuilderTest, BuildPageWithCSSNestedSubresource) { |
+ NSString* css_inlined_tag = |
+ [NSString stringWithFormat:kCssInlinedTemplate, kCssContent]; |
+ NSString* css_inlined_content = |
+ [NSString stringWithFormat:kCssImportTemplate, |
+ base::SysUTF8ToNSString(kCssResourceUrl)]; |
+ NSString* css_import_inlined_tag = |
+ [NSString stringWithFormat:kCssInlinedTemplate, css_inlined_content]; |
+ NSString* tags = |
+ [css_inlined_tag stringByAppendingString:css_import_inlined_tag]; |
+ NSString* css_import_page_html = |
+ [NSString stringWithFormat:kPageTemplate, tags]; |
+ [web_ui_page_builder_ buildWebUIPageForURL:GURL(kCssImportPageUrl) |
+ completionHandler:^(NSString* result) { |
+ EXPECT_NSEQ(css_import_page_html, result); |
+ }]; |
+} |
+ |
+// Tests that a page with a relative subresource is properly resolved. |
+TEST_F(CRWWebUIPageBuilderTest, BuildPageWithRelativeSubresource) { |
+ NSString* css_page_html = |
+ PageForTagTemplateAndContent(kCssInlinedTemplate, kRelativeCssContent); |
+ [web_ui_page_builder_ buildWebUIPageForURL:GURL(kCssRelativePageUrl) |
+ completionHandler:^(NSString* result) { |
+ EXPECT_NSEQ(css_page_html, result); |
+ }]; |
+} |
+ |
+// Tests that the JavaScript for connecting WebUI messaging to web controller |
+// messaging is properly inlined. |
+TEST_F(CRWWebUIPageBuilderTest, BuildPageWithWebUIJS) { |
+ NSString* core_js_html = |
+ PageForTagTemplateAndContent(kJsInlinedTemplate, kCoreJsContent); |
+ [web_ui_page_builder_ buildWebUIPageForURL:GURL(kCoreJsPageUrl) |
+ completionHandler:^(NSString* result) { |
+ EXPECT_NSEQ(core_js_html, result); |
+ }]; |
+} |
+ |
+} // namespace web |