blob: f98c3d021f7e4442545747342bbb3bb02ca9d3b6 [file] [log] [blame]
/**
* Copyright 2010 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: sligocki@google.com (Shawn Ligocki)
#include "net/instaweb/rewriter/public/common_filter.h"
#include "net/instaweb/htmlparse/public/html_parse.h"
#include "net/instaweb/util/public/google_message_handler.h"
#include "net/instaweb/util/public/gtest.h"
namespace net_instaweb {
namespace {
class CountingFilter : public CommonFilter {
public:
CountingFilter(HtmlParse* html_parse) : CommonFilter(html_parse),
start_doc_calls_(0),
start_element_calls_(0),
end_element_calls_(0) {}
virtual void StartDocumentImpl() { ++start_doc_calls_; }
virtual void StartElementImpl(HtmlElement* element) {
++start_element_calls_;
}
virtual void EndElementImpl(HtmlElement* element) { ++end_element_calls_; }
virtual const char* Name() const { return "CommonFilterTest.CountingFilter"; }
int start_doc_calls_;
int start_element_calls_;
int end_element_calls_;
};
class CommonFilterTest : public ::testing::Test {
protected:
CommonFilterTest() : html_parse_(&handler_),
filter_(&html_parse_) {
html_parse_.AddFilter(&filter_);
}
void ExpectUrl(const std::string& expected_url, const GURL& actual_gurl) {
LOG(INFO) << actual_gurl;
EXPECT_EQ(expected_url, GoogleUrl::Spec(actual_gurl));
}
GoogleMessageHandler handler_;
HtmlParse html_parse_;
CountingFilter filter_;
};
TEST_F(CommonFilterTest, DoesCallImpls) {
EXPECT_EQ(0, filter_.start_doc_calls_);
filter_.StartDocument();
EXPECT_EQ(1, filter_.start_doc_calls_);
HtmlElement* element =
html_parse_.NewElement(NULL, html_parse_.Intern("foo"));
EXPECT_EQ(0, filter_.start_element_calls_);
filter_.StartElement(element);
EXPECT_EQ(1, filter_.start_element_calls_);
EXPECT_EQ(0, filter_.end_element_calls_);
filter_.EndElement(element);
EXPECT_EQ(1, filter_.end_element_calls_);
}
TEST_F(CommonFilterTest, StoresCorrectBaseUrl) {
std::string doc_url = "http://www.example.com/";
html_parse_.StartParse(doc_url);
html_parse_.Flush();
// Base URL starts out as document URL.
ExpectUrl(doc_url, html_parse_.gurl());
ExpectUrl(doc_url, filter_.base_gurl());
html_parse_.ParseText("<html><head><link rel='stylesheet' href='foo.css'>");
html_parse_.Flush();
ExpectUrl(doc_url, filter_.base_gurl());
std::string base_url = "http://www.baseurl.com/foo/";
html_parse_.ParseText("<base href='");
html_parse_.ParseText(base_url);
html_parse_.ParseText("' />");
html_parse_.Flush();
// Update to base URL.
ExpectUrl(base_url, filter_.base_gurl());
// Make sure we didn't change the document URL.
ExpectUrl(doc_url, html_parse_.gurl());
html_parse_.ParseText("<link rel='stylesheet' href='foo.css'>");
html_parse_.Flush();
ExpectUrl(base_url, filter_.base_gurl());
std::string new_base_url = "http://www.somewhere-else.com/";
html_parse_.ParseText("<base href='");
html_parse_.ParseText(new_base_url);
html_parse_.ParseText("' />");
html_parse_.Flush();
// Uses new base URL.
ExpectUrl(new_base_url, filter_.base_gurl());
html_parse_.ParseText("</head></html>");
html_parse_.FinishParse();
ExpectUrl(new_base_url, filter_.base_gurl());
ExpectUrl(doc_url, html_parse_.gurl());
}
TEST_F(CommonFilterTest, DetectsNoScriptCorrectly) {
std::string doc_url = "http://www.example.com/";
html_parse_.StartParse(doc_url);
html_parse_.Flush();
EXPECT_TRUE(filter_.noscript_element() == NULL);
html_parse_.ParseText("<html><head><title>Example Site");
html_parse_.Flush();
EXPECT_TRUE(filter_.noscript_element() == NULL);
html_parse_.ParseText("</title><noscript>");
html_parse_.Flush();
EXPECT_TRUE(filter_.noscript_element() != NULL);
// Nested <noscript> elements
html_parse_.ParseText("Blah blah blah <noscript><noscript> do-de-do-do ");
html_parse_.Flush();
EXPECT_TRUE(filter_.noscript_element() != NULL);
html_parse_.ParseText("<link href='style.css'>");
html_parse_.Flush();
EXPECT_TRUE(filter_.noscript_element() != NULL);
// Close inner <noscript>s
html_parse_.ParseText("</noscript></noscript>");
html_parse_.Flush();
EXPECT_TRUE(filter_.noscript_element() != NULL);
// Close outter <noscript>
html_parse_.ParseText("</noscript>");
html_parse_.Flush();
EXPECT_TRUE(filter_.noscript_element() == NULL);
html_parse_.ParseText("</head></html>");
html_parse_.FinishParse();
EXPECT_TRUE(filter_.noscript_element() == NULL);
}
} // namespace
} // namespace net_instaweb