blob: dfa592db8aa3bf26e7fb0ff4f97798d817163e25 [file] [log] [blame]
/*
* Copyright 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Author: atulvasu@google.com (Atul Vasu)
#include "net/instaweb/rewriter/public/js_defer_disabled_filter.h"
#include "net/instaweb/rewriter/public/rewrite_driver.h"
#include "net/instaweb/rewriter/public/rewrite_options.h"
#include "net/instaweb/rewriter/public/rewrite_test_base.h"
#include "net/instaweb/rewriter/public/server_context.h"
#include "net/instaweb/rewriter/public/static_asset_manager.h"
#include "pagespeed/kernel/base/gtest.h"
#include "pagespeed/kernel/base/scoped_ptr.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/base/string_util.h"
#include "pagespeed/kernel/http/user_agent_matcher_test_base.h"
namespace net_instaweb {
const char * kDeferJsCodeNonGStatic = "<script type=\"text/javascript\" "
"src=\"/psajs/js_defer.0.js\"></script>";
class JsDeferDisabledFilterTest : public RewriteTestBase {
protected:
// TODO(matterbury): Delete this method as it should be redundant.
virtual void SetUp() {
RewriteTestBase::SetUp();
SetHtmlMimetype(); // Prevent insertion of CDATA tags to static JS.
}
virtual void InitJsDeferDisabledFilter(bool debug) {
if (debug) {
options()->EnableFilter(RewriteOptions::kDebug);
}
js_defer_disabled_filter_.reset(
new JsDeferDisabledFilter(rewrite_driver()));
rewrite_driver()->AddFilter(js_defer_disabled_filter_.get());
}
virtual bool AddHtmlTags() const { return false; }
virtual bool AddBody() const { return false; }
scoped_ptr<JsDeferDisabledFilter> js_defer_disabled_filter_;
};
TEST_F(JsDeferDisabledFilterTest, DeferScript) {
InitJsDeferDisabledFilter(false);
ValidateExpected("defer_script",
"<html><head>"
"<script type='text/psajs' "
"src='http://www.google.com/javascript/ajax_apis.js'></script>"
"<script type='text/psajs'"
"> func();</script>"
"</head><body>Hello, world!</body></html>",
StrCat("<html><head>"
"<script type='text/psajs' "
"src='http://www.google.com/javascript/ajax_apis.js'></script>"
"<script type='text/psajs'"
"> func();</script>"
"</head><body>Hello, world!",
kDeferJsCodeNonGStatic,
"</body></html>"));
}
TEST_F(JsDeferDisabledFilterTest, JsDeferPreserveURLsOn) {
// Make sure that we don't defer when preserve urls is on.
options()->set_js_preserve_urls(true);
options()->set_support_noscript_enabled(false);
options()->SoftEnableFilterForTesting(RewriteOptions::kDeferJavascript);
rewrite_driver()->AddFilters();
GoogleString before = "<head>"
"<script type='text/psajs' "
"src='http://www.google.com/javascript/ajax_apis.js'></script>"
"<script type='text/psajs'"
"> func();</script>"
"</head><body>Hello, world!</body>";
ValidateNoChanges("js_defer_preserve_urls_on", before);
}
TEST_F(JsDeferDisabledFilterTest, DeferScriptMultiBody) {
InitJsDeferDisabledFilter(false);
ValidateExpected("defer_script_multi_body",
"<html><head>"
"<script type='text/psajs' "
"src='http://www.google.com/javascript/ajax_apis.js'></script>"
"<script type='text/psajs'> func(); </script>"
"</head><body>Hello, world!</body><body>"
"<script type='text/psajs'> func2(); </script></body></html>",
StrCat("<html><head>"
"<script type='text/psajs' "
"src='http://www.google.com/javascript/ajax_apis.js'></script>"
"<script type='text/psajs'> func(); </script>"
"</head><body>Hello, world!"
"</body><body><script type='text/psajs'> func2(); "
"</script>",
kDeferJsCodeNonGStatic,
"</body></html>"));
}
TEST_F(JsDeferDisabledFilterTest, DeferScriptOptimized) {
InitJsDeferDisabledFilter(false);
Parse("optimized",
"<body><script type='text/psajs' src='foo.js'></script></body>");
EXPECT_NE(GoogleString::npos, output_buffer_.find("js_defer.0.js"))
<< "js_defer.js should have been included";
}
TEST_F(JsDeferDisabledFilterTest, DeferScriptDebug) {
InitJsDeferDisabledFilter(true);
Parse("optimized",
"<head></head><body><script type='text/psajs' src='foo.js'>"
"</script></body>");
EXPECT_NE(GoogleString::npos, output_buffer_.find("js_defer_debug.0.js"))
<< "js_defer_debug.js should have been included";
}
TEST_F(JsDeferDisabledFilterTest, InvalidUserAgent) {
InitJsDeferDisabledFilter(false);
SetCurrentUserAgent("BlackListUserAgent");
const char script[] = "<head>"
"<script type='text/psajs' "
"src='http://www.google.com/javascript/ajax_apis.js'></script>"
"<script type='text/psajs'"
"> func();</script>"
"</head><body>Hello, world!</body>";
ValidateNoChanges("defer_script", script);
}
TEST_F(JsDeferDisabledFilterTest, AllowMobileUserAgent) {
InitJsDeferDisabledFilter(false);
SetCurrentUserAgent(UserAgentMatcherTestBase::kIPhone4Safari);
const char script[] = "<head>"
"<script type='text/psajs' "
"src='http://www.google.com/javascript/ajax_apis.js'></script>"
"<script type='text/psajs'"
"> func();</script>"
"</head><body>Hello, world!</body>";
GoogleString expected = StrCat("<head>"
"<script type='text/psajs' "
"src='http://www.google.com/javascript/ajax_apis.js'></script>"
"<script type='text/psajs'"
"> func();</script></head><body>"
"Hello, world!",
kDeferJsCodeNonGStatic,
"</body>");
ValidateExpected("defer_script", script, expected);
}
TEST_F(JsDeferDisabledFilterTest, DisAllowMobileUserAgent) {
InitJsDeferDisabledFilter(false);
options_->ClearSignatureForTesting();
options_->set_enable_aggressive_rewriters_for_mobile(false);
SetCurrentUserAgent(UserAgentMatcherTestBase::kIPhone4Safari);
const char script[] = "<head>"
"<script type='text/psajs' "
"src='http://www.google.com/javascript/ajax_apis.js'></script>"
"<script type='text/psajs'"
"> func();</script>"
"</head><body>Hello, world!</body>";
ValidateNoChanges("defer_script", script);
}
TEST_F(JsDeferDisabledFilterTest, TestDeferJsUrlFromGStatic) {
StaticAssetManager static_asset_manager("",
server_context()->thread_system(),
server_context()->hasher(),
server_context()->message_handler());
static_asset_manager.ServeAssetsFromGStatic(StaticAssetManager::kGStaticBase);
static_asset_manager.SetGStaticHashForTest(StaticAssetEnum::DEFER_JS, "1");
server_context()->set_static_asset_manager(&static_asset_manager);
InitJsDeferDisabledFilter(false);
ValidateExpected(
"defer_script_url",
"<html><body>Hello, world!</body><body>"
"<script type='text/psajs'> func2(); </script></body></html>",
"<html><body>Hello, world!"
"</body><body><script type='text/psajs'> func2(); "
"</script>"
"<script type=\"text/javascript\" "
"src=\"//www.gstatic.com/psa/static/1-js_defer.js\">"
"</script></body></html>");
}
TEST_F(JsDeferDisabledFilterTest, TestDeferJsUrlFromNonGStatic) {
InitJsDeferDisabledFilter(false);
ValidateExpected(
"defer_script_url",
"<html><body>Hello, world!</body><body>"
"<script type='text/psajs'> func2(); </script></body></html>",
StrCat("<html><body>Hello, world!",
"</body><body><script type='text/psajs'> func2(); "
"</script>",
kDeferJsCodeNonGStatic,
"</body></html>"));
}
} // namespace net_instaweb