/*
 * 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: abliss@google.com (Adam Bliss)

// Unit-test the server context

#include "net/instaweb/rewriter/public/server_context.h"

#include <cstddef>                     // for size_t

#include "base/logging.h"
#include "net/instaweb/http/public/async_fetch.h"
#include "net/instaweb/http/public/counting_url_async_fetcher.h"
#include "net/instaweb/http/public/http_cache.h"
#include "net/instaweb/http/public/http_cache_failure.h"
#include "net/instaweb/http/public/http_value.h"
#include "net/instaweb/http/public/mock_url_fetcher.h"
#include "net/instaweb/rewriter/input_info.pb.h"
#include "net/instaweb/rewriter/public/beacon_critical_images_finder.h"
#include "net/instaweb/rewriter/public/critical_finder_support_util.h"
#include "net/instaweb/rewriter/public/critical_images_finder.h"
#include "net/instaweb/rewriter/public/critical_selector_finder.h"
#include "net/instaweb/rewriter/public/css_outline_filter.h"
#include "net/instaweb/rewriter/public/domain_lawyer.h"
#include "net/instaweb/rewriter/public/file_load_policy.h"
#include "net/instaweb/rewriter/public/mock_resource_callback.h"
#include "net/instaweb/rewriter/public/output_resource.h"
#include "net/instaweb/rewriter/public/output_resource_kind.h"
#include "net/instaweb/rewriter/public/resource.h"
#include "net/instaweb/rewriter/public/resource_namer.h"
#include "net/instaweb/rewriter/public/rewrite_driver.h"
#include "net/instaweb/rewriter/public/rewrite_filter.h"
#include "net/instaweb/rewriter/public/rewrite_options.h"
#include "net/instaweb/rewriter/public/rewrite_query.h"
#include "net/instaweb/rewriter/public/rewrite_test_base.h"
#include "net/instaweb/rewriter/public/test_rewrite_driver_factory.h"
#include "net/instaweb/rewriter/rendered_image.pb.h"
#include "net/instaweb/util/public/mock_property_page.h"
#include "net/instaweb/util/public/property_cache.h"
#include "pagespeed/kernel/base/basictypes.h"
#include "pagespeed/kernel/base/gtest.h"
#include "pagespeed/kernel/base/mock_message_handler.h"
#include "pagespeed/kernel/base/mock_timer.h"
#include "pagespeed/kernel/base/ref_counted_ptr.h"
#include "pagespeed/kernel/base/scoped_ptr.h"
#include "pagespeed/kernel/base/statistics.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/base/string_hash.h"
#include "pagespeed/kernel/base/string_util.h"
#include "pagespeed/kernel/base/timer.h"
#include "pagespeed/kernel/cache/lru_cache.h"
#include "pagespeed/kernel/html/html_element.h"
#include "pagespeed/kernel/html/html_parse_test_base.h"
#include "pagespeed/kernel/http/content_type.h"
#include "pagespeed/kernel/http/google_url.h"
#include "pagespeed/kernel/http/http_names.h"
#include "pagespeed/kernel/http/request_headers.h"
#include "pagespeed/kernel/http/response_headers.h"
#include "pagespeed/kernel/http/user_agent_matcher.h"
#include "pagespeed/kernel/http/user_agent_matcher_test_base.h"
#include "pagespeed/kernel/util/url_escaper.h"

namespace {

const char kResourceUrl[] = "http://example.com/image.png";
const char kResourceUrlBase[] = "http://example.com";
const char kResourceUrlPath[] = "/image.png";
const char kOptionsHash[] = "1234";

const char kUrlPrefix[] = "http://www.example.com/";
const size_t kUrlPrefixLength = STATIC_STRLEN(kUrlPrefix);

}  // namespace

namespace net_instaweb {

class VerifyContentsCallback : public Resource::AsyncCallback {
 public:
  VerifyContentsCallback(const ResourcePtr& resource,
                         const GoogleString& contents) :
      Resource::AsyncCallback(resource),
      contents_(contents),
      called_(false) {
  }
  VerifyContentsCallback(const OutputResourcePtr& resource,
                         const GoogleString& contents) :
      Resource::AsyncCallback(ResourcePtr(resource)),
      contents_(contents),
      called_(false) {
  }
  virtual void Done(bool lock_failure, bool resource_ok) {
    EXPECT_FALSE(lock_failure);
    EXPECT_STREQ(contents_, resource()->ExtractUncompressedContents());
    called_ = true;
  }
  void AssertCalled() {
    EXPECT_TRUE(called_);
  }
  GoogleString contents_;
  bool called_;
};

class ServerContextTest : public RewriteTestBase {
 protected:
  // Fetches data (which is expected to exist) for given resource,
  // but making sure to go through the path that checks for its
  // non-existence and potentially doing locking, too.
  // Note: resource must have hash set.
  bool FetchExtantOutputResourceHelper(const OutputResourcePtr& resource,
                                       StringAsyncFetch* async_fetch) {
    async_fetch->set_response_headers(resource->response_headers());
    RewriteFilter* null_filter = NULL;  // We want to test the cache only.
    EXPECT_TRUE(rewrite_driver()->FetchOutputResource(resource, null_filter,
                                                      async_fetch));
    rewrite_driver()->WaitForCompletion();
    EXPECT_TRUE(async_fetch->done());
    return async_fetch->success();
  }

  // Helper for testing of FetchOutputResource. Assumes that output_resource
  // is to be handled by the filter with 2-letter code filter_id, and
  // verifies result to match expect_success and expect_content.
  void TestFetchOutputResource(const OutputResourcePtr& output_resource,
                               const char* filter_id,
                               bool expect_success,
                               StringPiece expect_content) {
    ASSERT_TRUE(output_resource.get());
    RewriteFilter* filter = rewrite_driver()->FindFilter(filter_id);
    ASSERT_TRUE(filter != NULL);
    StringAsyncFetch fetch_result(CreateRequestContext());
    EXPECT_TRUE(rewrite_driver()->FetchOutputResource(
        output_resource, filter, &fetch_result));
    rewrite_driver()->WaitForCompletion();
    EXPECT_TRUE(fetch_result.done());
    EXPECT_EQ(expect_success, fetch_result.success());
    EXPECT_EQ(expect_content, fetch_result.buffer());
  }

  GoogleString GetOutputResource(const OutputResourcePtr& resource) {
    StringAsyncFetch fetch(RequestContext::NewTestRequestContext(
        server_context()->thread_system()));
    EXPECT_TRUE(FetchExtantOutputResourceHelper(resource, &fetch));
    return fetch.buffer();
  }

  // Returns whether there was an existing copy of data for the resource.
  // If not, makes sure the resource is wrapped.
  bool TryFetchExtantOutputResource(const OutputResourcePtr& resource) {
    StringAsyncFetch dummy_fetch(CreateRequestContext());
    return FetchExtantOutputResourceHelper(resource, &dummy_fetch);
  }

  // Asserts that the given url starts with an appropriate prefix;
  // then cuts off that prefix.
  virtual void RemoveUrlPrefix(const GoogleString& prefix, GoogleString* url) {
    EXPECT_TRUE(StringPiece(*url).starts_with(prefix));
    url->erase(0, prefix.length());
  }

  OutputResourcePtr CreateOutputResourceForFetch(const StringPiece& url) {
    RewriteFilter* dummy;
    rewrite_driver()->SetBaseUrlForFetch(url);
    GoogleUrl gurl(url);
    return rewrite_driver()->DecodeOutputResource(gurl, &dummy);
  }

  ResourcePtr CreateInputResourceAndReadIfCached(const StringPiece& url) {
    rewrite_driver()->SetBaseUrlForFetch(url);
    GoogleUrl resource_url(url);
    bool unused;
    ResourcePtr resource(rewrite_driver()->CreateInputResource(
        resource_url, RewriteDriver::InputRole::kUnknown, &unused));
    if ((resource.get() != NULL) && !ReadIfCached(resource)) {
      resource.clear();
    }
    return resource;
  }

  // Tests for the lifecycle and various flows of a named output resource.
  void TestNamed() {
    const char* filter_prefix = RewriteOptions::kCssFilterId;
    const char* name = "I.name";  // valid name for CSS filter.
    const char* contents = "contents";
    GoogleString failure_reason;
    OutputResourcePtr output(
        rewrite_driver()->CreateOutputResourceWithPath(
            kUrlPrefix, filter_prefix, name, kRewrittenResource,
            &failure_reason));
    ASSERT_TRUE(output.get() != NULL);
    EXPECT_EQ("", failure_reason);
    // Check name_key against url_prefix/fp.name
    GoogleString name_key = output->name_key();
    RemoveUrlPrefix(kUrlPrefix, &name_key);
    EXPECT_EQ(output->full_name().EncodeIdName(), name_key);
    // Make sure the resource hasn't already been created. We do need to give it
    // a hash for fetching to do anything.
    output->SetHash("42");
    EXPECT_FALSE(TryFetchExtantOutputResource(output));
    EXPECT_FALSE(output->IsWritten());

    {
      // Check that a non-blocking attempt to create another resource
      // with the same name returns quickly. We don't need a hash in this
      // case since we're just trying to create the resource, not fetch it.
      OutputResourcePtr output1(
          rewrite_driver()->CreateOutputResourceWithPath(
              kUrlPrefix, filter_prefix, name, kRewrittenResource,
              &failure_reason));
      ASSERT_TRUE(output1.get() != NULL);
      EXPECT_EQ("", failure_reason);
      EXPECT_FALSE(output1->IsWritten());
    }

    {
      // Here we attempt to create the object with the hash and fetch it.
      // The fetch fails as there is no active filter to resolve it.
      ResourceNamer namer;
      namer.CopyFrom(output->full_name());
      namer.set_hash("0");
      namer.set_ext("txt");
      GoogleString name = StrCat(kUrlPrefix, namer.Encode());
      OutputResourcePtr output1(CreateOutputResourceForFetch(name));
      ASSERT_TRUE(output1.get() != NULL);

      // blocking but stealing
      EXPECT_FALSE(TryFetchExtantOutputResource(output1));
    }

    // Write some data
    ASSERT_TRUE(output->has_hash());
    EXPECT_EQ(kRewrittenResource, output->kind());
    EXPECT_TRUE(rewrite_driver()->Write(
        ResourceVector(), contents, &kContentTypeText, "utf-8", output.get()));
    EXPECT_TRUE(output->IsWritten());
    // Check that hash and ext are correct.
    EXPECT_EQ("0", output->hash());
    EXPECT_EQ("txt", output->extension());
    EXPECT_STREQ("utf-8", output->charset());

    // With the URL (which contains the hash), we can retrieve it
    // from the http_cache.
    OutputResourcePtr output4(CreateOutputResourceForFetch(output->url()));
    EXPECT_EQ(output->url(), output4->url());
    EXPECT_EQ(contents, GetOutputResource(output4));
  }

  bool ResourceIsCached() {
    ResourcePtr resource(CreateResource(kResourceUrlBase, kResourceUrlPath));
    return ReadIfCached(resource);
  }

  void StartRead() {
    ResourcePtr resource(CreateResource(kResourceUrlBase, kResourceUrlPath));
    InitiateResourceRead(resource);
  }

  GoogleString MakeEvilUrl(const StringPiece& host, const StringPiece& name) {
    GoogleString escaped_abs;
    UrlEscaper::EncodeToUrlSegment(name, &escaped_abs);
    // Do not use Encode, which will make the URL non-evil.
    // TODO(matterbury):  Rewrite this for a non-standard UrlNamer?
    return StrCat("http://", host, "/dir/123/", escaped_abs,
                  ".pagespeed.jm.0.js");
  }

  // Accessor for ServerContext field; also cleans up
  // deferred_release_rewrite_drivers_.
  void EnableRewriteDriverCleanupMode(bool s) {
    server_context()->trying_to_cleanup_rewrite_drivers_ = s;
    server_context()->deferred_release_rewrite_drivers_.clear();
  }

  // Creates a response with given ttl and extra cache control under given URL.
  void SetCustomCachingResponse(const StringPiece& url,
                                int ttl_ms,
                                const StringPiece& extra_cache_control) {
    ResponseHeaders response_headers;
    DefaultResponseHeaders(kContentTypeCss, ttl_ms, &response_headers);
    response_headers.SetDateAndCaching(
        http_cache()->timer()->NowMs(), ttl_ms * Timer::kSecondMs,
        extra_cache_control);
    response_headers.ComputeCaching();
    SetFetchResponse(AbsolutifyUrl(url), response_headers, "payload");
  }

  // Creates a resource with given ttl and extra cache control under given URL.
  ResourcePtr CreateCustomCachingResource(
      const StringPiece& url, int ttl_ms,
      const StringPiece& extra_cache_control) {
    SetCustomCachingResponse(url, ttl_ms, extra_cache_control);
    GoogleUrl gurl(AbsolutifyUrl(url));
    rewrite_driver()->SetBaseUrlForFetch(kTestDomain);
    bool unused;
    ResourcePtr resource(rewrite_driver()->CreateInputResource(
        gurl, RewriteDriver::InputRole::kUnknown, &unused));
    VerifyContentsCallback callback(resource, "payload");
    resource->LoadAsync(Resource::kLoadEvenIfNotCacheable,
                        rewrite_driver()->request_context(),
                        &callback);
    callback.AssertCalled();
    return resource;
  }

  void RefererTest(const RequestHeaders* headers,
                   bool is_background_fetch) {
    GoogleString url = "test.jpg";
    rewrite_driver()->SetBaseUrlForFetch(kTestDomain);
    SetCustomCachingResponse(url, 100, "foo");
    GoogleUrl gurl(AbsolutifyUrl(url));
    bool unused;
    ResourcePtr resource(rewrite_driver()->CreateInputResource(
        gurl, RewriteDriver::InputRole::kImg, &unused));
    if (!is_background_fetch) {
      rewrite_driver()->SetRequestHeaders(*headers);
    }
    resource->set_is_background_fetch(is_background_fetch);
    VerifyContentsCallback callback(resource, "payload");
    resource->LoadAsync(Resource::kLoadEvenIfNotCacheable,
                        rewrite_driver()->request_context(),
                        &callback);
    callback.AssertCalled();
  }

  void DefaultHeaders(ResponseHeaders* headers) {
    SetDefaultLongCacheHeaders(&kContentTypeCss, headers);
  }

  const RewriteDriver* decoding_driver() {
    return server_context()->decoding_driver_;
  }

  RewriteOptions* GetCustomOptions(const StringPiece& url,
                                   RequestHeaders* request_headers,
                                   RewriteOptions* domain_options) {
    // The default url_namer does not yield any name-derived options, and we
    // have not specified any URL params or request-headers, so there will be
    // no custom options, and no errors.
    GoogleUrl gurl(url);
    RewriteOptions* copy_options = domain_options != NULL ?
        domain_options->Clone() : NULL;
    RewriteQuery rewrite_query;
    RequestContextPtr null_request_context;
    EXPECT_TRUE(server_context()->GetQueryOptions(
        null_request_context, NULL, &gurl, request_headers, NULL,
        &rewrite_query));
    RewriteOptions* options =
        server_context()->GetCustomOptions(request_headers, copy_options,
                                           rewrite_query.ReleaseOptions());
    return options;
  }

  void CheckExtendCache(RewriteOptions* options, bool x) {
    EXPECT_EQ(x, options->Enabled(RewriteOptions::kExtendCacheCss));
    EXPECT_EQ(x, options->Enabled(RewriteOptions::kExtendCacheImages));
    EXPECT_EQ(x, options->Enabled(RewriteOptions::kExtendCacheScripts));
  }
};

TEST_F(ServerContextTest, CustomOptionsWithNoUrlNamerOptions) {
  // The default url_namer does not yield any name-derived options, and we
  // have not specified any URL params or request-headers, so there will be
  // no custom options, and no errors.
  RequestHeaders request_headers;
  scoped_ptr<RewriteOptions> options(
      GetCustomOptions("http://example.com/", &request_headers, NULL));
  ASSERT_TRUE(options.get() == NULL);

  // Now put a query-param in, just turning on PageSpeed.  The core filters
  // should be enabled.
  options.reset(GetCustomOptions(
      "http://example.com/?PageSpeed=on",
      &request_headers, NULL));
  ASSERT_TRUE(options.get() != NULL);
  EXPECT_TRUE(options->enabled());
  CheckExtendCache(options.get(), true);
  EXPECT_TRUE(options->Enabled(RewriteOptions::kCombineCss));
  EXPECT_FALSE(options->Enabled(RewriteOptions::kDeferJavascript));

  // Now explicitly enable a filter, which should disable others.
  options.reset(GetCustomOptions(
      "http://example.com/?PageSpeedFilters=extend_cache",
      &request_headers, NULL));
  ASSERT_TRUE(options.get() != NULL);
  CheckExtendCache(options.get(), true);
  EXPECT_FALSE(options->Enabled(RewriteOptions::kCombineCss));
  EXPECT_FALSE(options->Enabled(RewriteOptions::kDeferJavascript));

  // Now put a request-header in, turning off pagespeed.  request-headers get
  // priority over query-params.
  request_headers.Add("PageSpeed", "off");
  options.reset(GetCustomOptions(
      "http://example.com/?PageSpeed=on",
      &request_headers, NULL));
  ASSERT_TRUE(options.get() != NULL);
  EXPECT_FALSE(options->enabled());

  // Now explicitly enable a bogus filter, which should will cause the
  // options to be uncomputable.
  GoogleUrl gurl("http://example.com/?PageSpeedFilters=bogus_filter");
  RewriteQuery rewrite_query;
  RequestContextPtr null_request_context;
  EXPECT_FALSE(server_context()->GetQueryOptions(
      null_request_context, options.get(), &gurl, &request_headers, NULL,
      &rewrite_query));

  // The default url_namer does not yield any name-derived options, and we
  // have not specified any URL params or request-headers, and kXRequestedWith
  // header is set with bogus value, so there will be no custom options, and no
  // errors.
  request_headers.Add(
      HttpAttributes::kXRequestedWith, "bogus");
  options.reset(
      GetCustomOptions("http://example.com/", &request_headers, NULL));
  ASSERT_TRUE(options.get() == NULL);

  // The default url_namer does not yield any name-derived options, and we
  // have not specified any URL params or request-headers, but kXRequestedWith
  // header is set to 'XmlHttpRequest', so there will be custom options with
  // all js inserting filters disabled.
  request_headers.RemoveAll(HttpAttributes::kXRequestedWith);
  request_headers.Add(
      HttpAttributes::kXRequestedWith, HttpAttributes::kXmlHttpRequest);
  options.reset(
      GetCustomOptions("http://example.com/", &request_headers, NULL));
  // Disable DelayImages for XmlHttpRequests.
  ASSERT_TRUE(options.get() != NULL);
  EXPECT_TRUE(options->enabled());
  EXPECT_FALSE(options->Enabled(RewriteOptions::kDelayImages));
  // As kDelayImages filter is present in the disabled list, so it will not get
  // enabled even if it is enabled via EnableFilter().
  options->EnableFilter(RewriteOptions::kDelayImages);
  EXPECT_FALSE(options->Enabled(RewriteOptions::kDelayImages));

  options->EnableFilter(RewriteOptions::kCachePartialHtmlDeprecated);
  EXPECT_FALSE(options->Enabled(RewriteOptions::kCachePartialHtmlDeprecated));
  options->EnableFilter(RewriteOptions::kDeferIframe);
  EXPECT_FALSE(options->Enabled(RewriteOptions::kDeferIframe));
  options->EnableFilter(RewriteOptions::kDeferJavascript);
  EXPECT_FALSE(options->Enabled(RewriteOptions::kDeferJavascript));
  options->EnableFilter(RewriteOptions::kFlushSubresources);
  EXPECT_FALSE(options->Enabled(RewriteOptions::kFlushSubresources));
  options->EnableFilter(RewriteOptions::kLazyloadImages);
  EXPECT_FALSE(options->Enabled(RewriteOptions::kLazyloadImages));
  options->EnableFilter(RewriteOptions::kLocalStorageCache);
  EXPECT_FALSE(options->Enabled(RewriteOptions::kLocalStorageCache));
  options->EnableFilter(RewriteOptions::kPrioritizeCriticalCss);
  EXPECT_FALSE(options->Enabled(RewriteOptions::kPrioritizeCriticalCss));
}

TEST_F(ServerContextTest, CustomOptionsWithUrlNamerOptions) {
  // Inject a url-namer that will establish a domain configuration.
  RewriteOptions namer_options(factory()->thread_system());
  namer_options.EnableFilter(RewriteOptions::kCombineJavascript);
  namer_options.EnableFilter(RewriteOptions::kDelayImages);

  RequestHeaders request_headers;
  scoped_ptr<RewriteOptions> options(
      GetCustomOptions("http://example.com/", &request_headers,
                       &namer_options));
  // Even with no query-params or request-headers, we get the custom
  // options as domain options provided as argument.
  ASSERT_TRUE(options.get() != NULL);
  EXPECT_TRUE(options->enabled());
  CheckExtendCache(options.get(), false);
  EXPECT_FALSE(options->Enabled(RewriteOptions::kCombineCss));
  EXPECT_TRUE(options->Enabled(RewriteOptions::kCombineJavascript));
  EXPECT_TRUE(options->Enabled(RewriteOptions::kDelayImages));

  // Now combine with query params, which turns core-filters on.
  options.reset(GetCustomOptions(
      "http://example.com/?PageSpeed=on",
      &request_headers, &namer_options));
  ASSERT_TRUE(options.get() != NULL);
  EXPECT_TRUE(options->enabled());
  CheckExtendCache(options.get(), true);
  EXPECT_TRUE(options->Enabled(RewriteOptions::kCombineCss));
  EXPECT_TRUE(options->Enabled(RewriteOptions::kCombineJavascript));

  // Explicitly enable a filter in query-params, which will turn off
  // the core filters that have not been explicitly enabled.  Note
  // that explicit filter-setting in query-params overrides completely
  // the options provided as a parameter.
  options.reset(GetCustomOptions(
      "http://example.com/?PageSpeedFilters=combine_css",
      &request_headers, &namer_options));
  ASSERT_TRUE(options.get() != NULL);
  EXPECT_TRUE(options->enabled());
  CheckExtendCache(options.get(), false);
  EXPECT_TRUE(options->Enabled(RewriteOptions::kCombineCss));
  EXPECT_FALSE(options->Enabled(RewriteOptions::kCombineJavascript));

  // Now explicitly enable a bogus filter, which should will cause the
  // options to be uncomputable.
  GoogleUrl gurl("http://example.com/?PageSpeedFilters=bogus_filter");
  RewriteQuery rewrite_query;
  RequestContextPtr null_request_context;
  EXPECT_FALSE(server_context()->GetQueryOptions(
      null_request_context, options.get(), &gurl, &request_headers, NULL,
      &rewrite_query));

  request_headers.Add(
      HttpAttributes::kXRequestedWith, "bogus");
  options.reset(
      GetCustomOptions("http://example.com/", &request_headers,
                       &namer_options));
  // Don't disable DelayImages for Non-XmlHttpRequests.
  ASSERT_TRUE(options.get() != NULL);
  EXPECT_TRUE(options->enabled());
  CheckExtendCache(options.get(), false);
  EXPECT_FALSE(options->Enabled(RewriteOptions::kCombineCss));
  EXPECT_TRUE(options->Enabled(RewriteOptions::kCombineJavascript));
  EXPECT_TRUE(options->Enabled(RewriteOptions::kDelayImages));

  request_headers.RemoveAll(HttpAttributes::kXRequestedWith);
  request_headers.Add(
      HttpAttributes::kXRequestedWith, HttpAttributes::kXmlHttpRequest);
  options.reset(
      GetCustomOptions("http://example.com/", &request_headers,
                       &namer_options));
  // Disable DelayImages for XmlHttpRequests.
  ASSERT_TRUE(options.get() != NULL);
  EXPECT_TRUE(options->enabled());
  CheckExtendCache(options.get(), false);
  EXPECT_FALSE(options->Enabled(RewriteOptions::kCombineCss));
  EXPECT_TRUE(options->Enabled(RewriteOptions::kCombineJavascript));
  EXPECT_FALSE(options->Enabled(RewriteOptions::kDelayImages));
}

TEST_F(ServerContextTest, QueryOptionsWithInvalidUrl) {
  RequestHeaders request_headers;
  GoogleUrl gurl("bogus");
  ASSERT_FALSE(gurl.IsWebValid());
  RewriteQuery rewrite_query;
  RequestContextPtr null_request_context;
  EXPECT_FALSE(server_context()->GetQueryOptions(
      null_request_context, options(), &gurl, &request_headers, NULL,
      &rewrite_query));
}

TEST_F(ServerContextTest, TestNamed) {
  TestNamed();
}

TEST_F(ServerContextTest, TestOutputInputUrl) {
  options()->EnableFilter(RewriteOptions::kRewriteJavascriptExternal);
  rewrite_driver()->AddFilters();

  GoogleString url = Encode("http://example.com/dir/123/",
                            RewriteOptions::kJavascriptMinId,
                            "0", "orig", "js");
  SetResponseWithDefaultHeaders(
      "http://example.com/dir/123/orig", kContentTypeJavascript,
      "foo() /*comment */;", 100);

  OutputResourcePtr output_resource(CreateOutputResourceForFetch(url));
  TestFetchOutputResource(output_resource, RewriteOptions::kJavascriptMinId,
                          true, "foo();");
}

// Test to make sure we do not let a crafted output resource URL to get us to
// fetch and host things from a non-lawyer permitted external host; which could
// lead to XSS vulnerabilities or a firewall bypass.
TEST_F(ServerContextTest, TestOutputInputUrlEvil) {
  options()->EnableFilter(RewriteOptions::kRewriteJavascriptExternal);
  rewrite_driver()->AddFilters();

  GoogleString url = MakeEvilUrl("example.com", "http://www.evil.com");
  SetResponseWithDefaultHeaders(
      "http://www.evil.com/", kContentTypeJavascript,
      "foo() /*comment */;", 100);

  OutputResourcePtr output_resource(CreateOutputResourceForFetch(url));
  TestFetchOutputResource(output_resource, RewriteOptions::kJavascriptMinId,
                          false, "");
}

TEST_F(ServerContextTest, TestOutputInputUrlBusy) {
  EXPECT_TRUE(options()->WriteableDomainLawyer()->AddOriginDomainMapping(
      "www.busy.com", "example.com", "", message_handler()));
  options()->EnableFilter(RewriteOptions::kRewriteJavascriptExternal);
  rewrite_driver()->AddFilters();

  GoogleString url = MakeEvilUrl("example.com", "http://www.busy.com");
  SetResponseWithDefaultHeaders(
      "http://www.busy.com/", kContentTypeJavascript,
      "foo() /*comment */;", 100);

  OutputResourcePtr output_resource(CreateOutputResourceForFetch(url));
  TestFetchOutputResource(output_resource, RewriteOptions::kJavascriptMinId,
                          false, "");
}

// Check that we can origin-map a domain referenced from an HTML file
// to 'localhost', but rewrite-map it to 'cdn.com'.  This was not working
// earlier because RewriteDriver::CreateInputResource was mapping to the
// rewrite domain, preventing us from finding the origin-mapping when
// fetching the URL.
TEST_F(ServerContextTest, TestMapRewriteAndOrigin) {
  ASSERT_TRUE(options()->WriteableDomainLawyer()->AddOriginDomainMapping(
      "localhost", kTestDomain, "", message_handler()));
  EXPECT_TRUE(options()->WriteableDomainLawyer()->AddRewriteDomainMapping(
      "cdn.com", kTestDomain, message_handler()));

  ResourcePtr input(CreateResource(StrCat(kTestDomain, "index.html"),
                                   "style.css"));
  ASSERT_TRUE(input.get() != NULL);
  EXPECT_EQ(StrCat(kTestDomain, "style.css"), input->url());

  // The absolute input URL is in test.com, but we will only be
  // able to serve it from localhost, per the origin mapping above.
  static const char kStyleContent[] = "style content";
  const int kOriginTtlSec = 300;
  SetResponseWithDefaultHeaders("http://localhost/style.css", kContentTypeCss,
                                kStyleContent, kOriginTtlSec);
  EXPECT_TRUE(ReadIfCached(input));

  // When we rewrite the resource as an ouptut, it will show up in the
  // CDN per the rewrite mapping.
  GoogleString failure_reason;
  OutputResourcePtr output(
      rewrite_driver()->CreateOutputResourceFromResource(
          RewriteOptions::kCacheExtenderId, rewrite_driver()->default_encoder(),
          NULL, input, kRewrittenResource,
          &failure_reason));
  ASSERT_TRUE(output.get() != NULL);
  EXPECT_EQ("", failure_reason);

  // We need to 'Write' an output resource before we can determine its
  // URL.
  rewrite_driver()->Write(
      ResourceVector(), StringPiece(kStyleContent), &kContentTypeCss,
      StringPiece(), output.get());
  EXPECT_EQ(Encode("http://cdn.com/", "ce", "0", "style.css", "css"),
            output->url());
}

class MockRewriteFilter : public RewriteFilter {
 public:
  explicit MockRewriteFilter(RewriteDriver* driver)
      : RewriteFilter(driver) {}
  virtual ~MockRewriteFilter() {}
  virtual const char* id() const { return "mk"; }
  virtual const char* Name() const { return "mock_filter"; }
  virtual void StartDocumentImpl() {}
  virtual void StartElementImpl(HtmlElement* element) {}
  virtual void EndElementImpl(HtmlElement* element) {}

 private:
  DISALLOW_COPY_AND_ASSIGN(MockRewriteFilter);
};

class CreateMockRewriterCallback
    : public TestRewriteDriverFactory::CreateRewriterCallback {
 public:
  CreateMockRewriterCallback() {}
  virtual ~CreateMockRewriterCallback() {}
  virtual RewriteFilter* Done(RewriteDriver* driver) {
    return new MockRewriteFilter(driver);
  }
 private:
  DISALLOW_COPY_AND_ASSIGN(CreateMockRewriterCallback);
};

class MockPlatformConfigCallback
    : public TestRewriteDriverFactory::PlatformSpecificConfigurationCallback {
 public:
  explicit MockPlatformConfigCallback(RewriteDriver** result_ptr)
      : result_ptr_(result_ptr) {
  }

  virtual void Done(RewriteDriver* driver) {
    *result_ptr_ = driver;
  }

 private:
  RewriteDriver** result_ptr_;
  DISALLOW_COPY_AND_ASSIGN(MockPlatformConfigCallback);
};

// Tests that platform-specific configuration hook runs for various
// factory methods.
TEST_F(ServerContextTest, TestPlatformSpecificConfiguration) {
  RewriteDriver* rec_normal_driver = NULL;
  RewriteDriver* rec_custom_driver = NULL;

  MockPlatformConfigCallback normal_callback(&rec_normal_driver);
  MockPlatformConfigCallback custom_callback(&rec_custom_driver);

  factory()->AddPlatformSpecificConfigurationCallback(&normal_callback);
  RewriteDriver* normal_driver = server_context()->NewRewriteDriver(
      RequestContext::NewTestRequestContext(server_context()->thread_system()));
  EXPECT_EQ(normal_driver, rec_normal_driver);
  factory()->ClearPlatformSpecificConfigurationCallback();
  normal_driver->Cleanup();

  factory()->AddPlatformSpecificConfigurationCallback(&custom_callback);
  RewriteDriver* custom_driver =
      server_context()->NewCustomRewriteDriver(
          new RewriteOptions(factory()->thread_system()),
          RequestContext::NewTestRequestContext(
              server_context()->thread_system()));
  EXPECT_EQ(custom_driver, rec_custom_driver);
  custom_driver->Cleanup();
}

// Tests that platform-specific rewriters are used for decoding fetches.
TEST_F(ServerContextTest, TestPlatformSpecificRewritersDecoding) {
  GoogleString url = Encode("http://example.com/dir/123/",
                            "mk", "0", "orig", "js");
  GoogleUrl gurl(url);
  RewriteFilter* dummy;

  // Without the mock rewriter enabled, this URL should not be decoded.
  OutputResourcePtr bad_output(
      decoding_driver()->DecodeOutputResource(gurl, &dummy));
  ASSERT_TRUE(bad_output.get() == NULL);

  // With the mock rewriter enabled, this URL should be decoded.
  CreateMockRewriterCallback callback;
  factory()->AddCreateRewriterCallback(&callback);
  factory()->set_add_platform_specific_decoding_passes(true);
  factory()->RebuildDecodingDriverForTests(server_context());
  // TODO(sligocki): Do we still want to expose decoding_driver() for
  // platform-specific rewriters? Or should we just use IsPagespeedResource()
  // in these tests?
  OutputResourcePtr good_output(
      decoding_driver()->DecodeOutputResource(gurl, &dummy));
  ASSERT_TRUE(good_output.get() != NULL);
  EXPECT_EQ(url, good_output->url());
}

// Tests that platform-specific rewriters are used for decoding fetches even
// if they are only added in AddPlatformSpecificRewritePasses, not
// AddPlatformSpecificDecodingPasses.  Required for backwards compatibility.
TEST_F(ServerContextTest, TestPlatformSpecificRewritersImplicitDecoding) {
  GoogleString url = Encode("http://example.com/dir/123/",
                            "mk", "0", "orig", "js");
  GoogleUrl gurl(url);
  RewriteFilter* dummy;

  // The URL should be decoded even if AddPlatformSpecificDecodingPasses is
  // suppressed.
  CreateMockRewriterCallback callback;
  factory()->AddCreateRewriterCallback(&callback);
  factory()->set_add_platform_specific_decoding_passes(false);
  factory()->RebuildDecodingDriverForTests(server_context());
  OutputResourcePtr good_output(
      decoding_driver()->DecodeOutputResource(gurl, &dummy));
  ASSERT_TRUE(good_output.get() != NULL);
  EXPECT_EQ(url, good_output->url());
}

// DecodeOutputResource should drop query
TEST_F(ServerContextTest, TestOutputResourceFetchQuery) {
  GoogleString url = Encode("http://example.com/dir/123/",
                            "jm", "0", "orig", "js");
  RewriteFilter* dummy;
  GoogleUrl gurl(StrCat(url, "?query"));
  OutputResourcePtr output_resource(
      rewrite_driver()->DecodeOutputResource(gurl, &dummy));
  ASSERT_TRUE(output_resource.get() != NULL);
  EXPECT_EQ(url, output_resource->url());
}

// Input resources and corresponding output resources should keep queries
TEST_F(ServerContextTest, TestInputResourceQuery) {
  const char kUrl[] = "test?param";
  ResourcePtr resource(CreateResource(kResourceUrlBase, kUrl));
  ASSERT_TRUE(resource.get() != NULL);
  EXPECT_EQ(StrCat(GoogleString(kResourceUrlBase), "/", kUrl), resource->url());
  GoogleString failure_reason;
  OutputResourcePtr output(rewrite_driver()->CreateOutputResourceFromResource(
      "sf", rewrite_driver()->default_encoder(), NULL, resource,
      kRewrittenResource, &failure_reason));
  ASSERT_TRUE(output.get() != NULL);
  EXPECT_EQ("", failure_reason);

  GoogleString included_name;
  EXPECT_TRUE(UrlEscaper::DecodeFromUrlSegment(output->name(), &included_name));
  EXPECT_EQ(GoogleString(kUrl), included_name);
}

TEST_F(ServerContextTest, TestRemember404) {
  // Make sure our resources remember that a page 404'd, for limited time.
  http_cache()->set_failure_caching_ttl_sec(
      kFetchStatusUncacheableError, 10000);
  http_cache()->set_failure_caching_ttl_sec(kFetchStatus4xxError, 100);

  ResponseHeaders not_found;
  SetDefaultLongCacheHeaders(&kContentTypeHtml, &not_found);
  not_found.SetStatusAndReason(HttpStatus::kNotFound);
  SetFetchResponse("http://example.com/404", not_found, "");

  ResourcePtr resource(
      CreateInputResourceAndReadIfCached("http://example.com/404"));
  EXPECT_EQ(NULL, resource.get());

  HTTPValue value_out;
  ResponseHeaders headers_out;
  EXPECT_EQ(
      HTTPCache::FindResult(HTTPCache::kRecentFailure, kFetchStatus4xxError),
      HttpBlockingFind(
          "http://example.com/404", http_cache(), &value_out, &headers_out));
  AdvanceTimeMs(150 * Timer::kSecondMs);

  EXPECT_EQ(kNotFoundResult, HttpBlockingFind(
      "http://example.com/404", http_cache(), &value_out, &headers_out));
}

TEST_F(ServerContextTest, TestRememberDropped) {
  // Fake resource being dropped by adding the appropriate header to the
  // resource proper.
  ResponseHeaders not_found;
  SetDefaultLongCacheHeaders(&kContentTypeHtml, &not_found);
  not_found.SetStatusAndReason(HttpStatus::kNotFound);
  not_found.Add(HttpAttributes::kXPsaLoadShed, "1");
  SetFetchResponse("http://example.com/404", not_found, "");

  ResourcePtr resource(
      CreateInputResourceAndReadIfCached("http://example.com/404"));
  EXPECT_EQ(NULL, resource.get());

  HTTPValue value_out;
  ResponseHeaders headers_out;
  EXPECT_EQ(
      HTTPCache::FindResult(HTTPCache::kRecentFailure, kFetchStatusDropped),
      HttpBlockingFind(
          "http://example.com/404", http_cache(), &value_out, &headers_out));

  AdvanceTimeMs(11 * Timer::kSecondMs);
  EXPECT_EQ(kNotFoundResult, HttpBlockingFind(
      "http://example.com/404", http_cache(), &value_out, &headers_out));
}

TEST_F(ServerContextTest, TestNonCacheable) {
  const char kContents[] = "ok";

  // Make sure that when we get non-cacheable resources
  // we mark the fetch as not cacheable in the cache.
  ResponseHeaders no_cache;
  SetDefaultLongCacheHeaders(&kContentTypeHtml, &no_cache);
  no_cache.Replace(HttpAttributes::kCacheControl, "no-cache");
  no_cache.ComputeCaching();
  SetFetchResponse("http://example.com/", no_cache, kContents);

  ResourcePtr resource(CreateResource("http://example.com/", "/"));
  ASSERT_TRUE(resource.get() != NULL);

  VerifyContentsCallback callback(resource, kContents);
  resource->LoadAsync(Resource::kReportFailureIfNotCacheable,
                      rewrite_driver()->request_context(),
                      &callback);
  callback.AssertCalled();

  HTTPValue value_out;
  ResponseHeaders headers_out;
  EXPECT_EQ(
      HTTPCache::FindResult(HTTPCache::kRecentFailure,
                            kFetchStatusUncacheable200),
      HttpBlockingFind(
          "http://example.com/", http_cache(), &value_out, &headers_out));
}

TEST_F(ServerContextTest, TestNonCacheableReadResultPolicy) {
  // Make sure we report the success/failure for non-cacheable resources
  // depending on the policy. (TestNonCacheable also covers the value).

  ResponseHeaders no_cache;
  SetDefaultLongCacheHeaders(&kContentTypeHtml, &no_cache);
  no_cache.Replace(HttpAttributes::kCacheControl, "no-cache");
  no_cache.ComputeCaching();
  SetFetchResponse("http://example.com/", no_cache, "stuff");

  ResourcePtr resource1(CreateResource("http://example.com/", "/"));
  ASSERT_TRUE(resource1.get() != NULL);
  MockResourceCallback callback1(resource1, factory()->thread_system());
  resource1->LoadAsync(Resource::kReportFailureIfNotCacheable,
                       rewrite_driver()->request_context(),
                       &callback1);
  EXPECT_TRUE(callback1.done());
  EXPECT_FALSE(callback1.success());

  ResourcePtr resource2(CreateResource("http://example.com/", "/"));
  ASSERT_TRUE(resource2.get() != NULL);
  MockResourceCallback callback2(resource2, factory()->thread_system());
  resource2->LoadAsync(Resource::kLoadEvenIfNotCacheable,
                       rewrite_driver()->request_context(),
                       &callback2);
  EXPECT_TRUE(callback2.done());
  EXPECT_TRUE(callback2.success());
}

TEST_F(ServerContextTest, TestRememberEmpty) {
  // Make sure our resources remember that a page is empty, for limited time.
  http_cache()->set_failure_caching_ttl_sec(kFetchStatusEmpty, 100);

  ResponseHeaders headers;
  SetDefaultLongCacheHeaders(&kContentTypeHtml, &headers);
  headers.SetStatusAndReason(HttpStatus::kOK);
  static const char kUrl[] = "http://example.com/empty.html";
  SetFetchResponse(kUrl, headers, "");

  ResourcePtr resource(CreateInputResourceAndReadIfCached(kUrl));
  EXPECT_EQ(NULL, resource.get());

  HTTPValue value_out;
  ResponseHeaders headers_out;
  EXPECT_EQ(HTTPCache::FindResult(HTTPCache::kRecentFailure,
                                  kFetchStatusEmpty),
            HttpBlockingFind(kUrl, http_cache(), &value_out, &headers_out));

  AdvanceTimeMs(150 * Timer::kSecondMs);
  EXPECT_EQ(kNotFoundResult,
            HttpBlockingFind(kUrl, http_cache(), &value_out, &headers_out));
}

TEST_F(ServerContextTest, TestNotRememberEmptyRedirect) {
  // Parallel to TestRememberEmpty for empty 301 redirect.
  http_cache()->set_failure_caching_ttl_sec(kFetchStatusEmpty, 100);

  ResponseHeaders headers;
  SetDefaultLongCacheHeaders(&kContentTypeHtml, &headers);
  headers.SetStatusAndReason(HttpStatus::kMovedPermanently);
  headers.Add(HttpAttributes::kLocation, "http://example.com/destination.html");
  static const char kUrl[] = "http://example.com/redirect.html";
  SetFetchResponse(kUrl, headers, "");

  ResourcePtr resource(CreateInputResourceAndReadIfCached(kUrl));
  EXPECT_EQ(NULL, resource.get());

  HTTPValue value_out;
  ResponseHeaders headers_out;
  // Currently we are remembering 301 as not cacheable, but in the future if
  // that changes the important thing here is that we don't remember non-200
  // as empty (and thus fail to use them.
  EXPECT_NE(HTTPCache::FindResult(HTTPCache::kRecentFailure,
                                  kFetchStatusEmpty),
            HttpBlockingFind(kUrl, http_cache(), &value_out, &headers_out));

  AdvanceTimeMs(150 * Timer::kSecondMs);
  EXPECT_NE(HTTPCache::FindResult(HTTPCache::kRecentFailure,
                                  kFetchStatusEmpty),
            HttpBlockingFind(kUrl, http_cache(), &value_out, &headers_out));
}

TEST_F(ServerContextTest, TestVaryOption) {
  // Make sure that when we get non-cacheable resources
  // we mark the fetch as not-cacheable in the cache.
  options()->set_respect_vary(true);
  ResponseHeaders no_cache;
  const char kContents[] = "ok";
  SetDefaultLongCacheHeaders(&kContentTypeHtml, &no_cache);
  no_cache.Add(HttpAttributes::kVary, HttpAttributes::kAcceptEncoding);
  no_cache.Add(HttpAttributes::kVary, HttpAttributes::kUserAgent);
  no_cache.ComputeCaching();
  SetFetchResponse("http://example.com/", no_cache, kContents);

  ResourcePtr resource(CreateResource("http://example.com/", "/"));
  ASSERT_TRUE(resource.get() != NULL);

  VerifyContentsCallback callback(resource, kContents);
  resource->LoadAsync(Resource::kReportFailureIfNotCacheable,
                      rewrite_driver()->request_context(),
                      &callback);
  callback.AssertCalled();
  EXPECT_FALSE(resource->IsValidAndCacheable());

  HTTPValue valueOut;
  ResponseHeaders headersOut;
  EXPECT_EQ(
      HTTPCache::FindResult(HTTPCache::kRecentFailure,
                            kFetchStatusUncacheable200),
      HttpBlockingFind(
          "http://example.com/", http_cache(), &valueOut, &headersOut));
}

TEST_F(ServerContextTest, TestOutlined) {
  // Outliner resources should not produce extra cache traffic
  // due to rname/ entries we can't use anyway.
  EXPECT_EQ(0, lru_cache()->num_hits());
  EXPECT_EQ(0, lru_cache()->num_misses());
  EXPECT_EQ(0, lru_cache()->num_inserts());
  EXPECT_EQ(0, lru_cache()->num_identical_reinserts());
  GoogleString failure_reason;
  OutputResourcePtr output_resource(
      rewrite_driver()->CreateOutputResourceWithPath(
          kUrlPrefix, CssOutlineFilter::kFilterId, "_", kOutlinedResource,
          &failure_reason));
  ASSERT_TRUE(output_resource.get() != NULL);
  EXPECT_EQ("", failure_reason);
  EXPECT_EQ(NULL, output_resource->cached_result());
  EXPECT_EQ(0, lru_cache()->num_hits());
  EXPECT_EQ(0, lru_cache()->num_misses());
  EXPECT_EQ(0, lru_cache()->num_inserts());
  EXPECT_EQ(0, lru_cache()->num_identical_reinserts());

  rewrite_driver()->Write(
      ResourceVector(), "foo", &kContentTypeCss, StringPiece(),
      output_resource.get());
  EXPECT_EQ(NULL, output_resource->cached_result());
  EXPECT_EQ(0, lru_cache()->num_hits());
  EXPECT_EQ(0, lru_cache()->num_misses());
  EXPECT_EQ(1, lru_cache()->num_inserts());
  EXPECT_EQ(0, lru_cache()->num_identical_reinserts());

  // Now try fetching again. It should not get a cached_result either.
  output_resource.reset(
      rewrite_driver()->CreateOutputResourceWithPath(
          kUrlPrefix, CssOutlineFilter::kFilterId, "_", kOutlinedResource,
          &failure_reason));
  ASSERT_TRUE(output_resource.get() != NULL);
  EXPECT_EQ("", failure_reason);
  EXPECT_EQ(NULL, output_resource->cached_result());
  EXPECT_EQ(0, lru_cache()->num_hits());
  EXPECT_EQ(0, lru_cache()->num_misses());
  EXPECT_EQ(1, lru_cache()->num_inserts());
  EXPECT_EQ(0, lru_cache()->num_identical_reinserts());
}

TEST_F(ServerContextTest, TestOnTheFly) {
  // Test to make sure that an on-fly insert does not insert the data,
  // just the rname/

  // For derived resources we can and should use the rewrite
  // summary/metadata cache
  EXPECT_EQ(0, lru_cache()->num_hits());
  EXPECT_EQ(0, lru_cache()->num_misses());
  EXPECT_EQ(0, lru_cache()->num_inserts());
  EXPECT_EQ(0, lru_cache()->num_identical_reinserts());
  GoogleString failure_reason;
  OutputResourcePtr output_resource(
      rewrite_driver()->CreateOutputResourceWithPath(
          kUrlPrefix, RewriteOptions::kCssFilterId, "_", kOnTheFlyResource,
          &failure_reason));
  ASSERT_TRUE(output_resource.get() != NULL);
  EXPECT_EQ("", failure_reason);
  EXPECT_EQ(NULL, output_resource->cached_result());
  EXPECT_EQ(0, lru_cache()->num_hits());
  EXPECT_EQ(0, lru_cache()->num_misses());
  EXPECT_EQ(0, lru_cache()->num_inserts());
  EXPECT_EQ(0, lru_cache()->num_identical_reinserts());

  rewrite_driver()->Write(
      ResourceVector(), "foo", &kContentTypeCss, StringPiece(),
      output_resource.get());
  EXPECT_TRUE(output_resource->cached_result() != NULL);
  EXPECT_EQ(0, lru_cache()->num_hits());
  EXPECT_EQ(0, lru_cache()->num_misses());
  EXPECT_EQ(0, lru_cache()->num_inserts());
  EXPECT_EQ(0, lru_cache()->num_identical_reinserts());
}

TEST_F(ServerContextTest, TestNotGenerated) {
  // For derived resources we can and should use the rewrite
  // summary/metadata cache
  EXPECT_EQ(0, lru_cache()->num_hits());
  EXPECT_EQ(0, lru_cache()->num_misses());
  EXPECT_EQ(0, lru_cache()->num_inserts());
  EXPECT_EQ(0, lru_cache()->num_identical_reinserts());
  GoogleString failure_reason;
  OutputResourcePtr output_resource(
      rewrite_driver()->CreateOutputResourceWithPath(
          kUrlPrefix, RewriteOptions::kCssFilterId, "_", kRewrittenResource,
          &failure_reason));
  ASSERT_TRUE(output_resource.get() != NULL);
  EXPECT_EQ("", failure_reason);
  EXPECT_EQ(NULL, output_resource->cached_result());
  EXPECT_EQ(0, lru_cache()->num_hits());
  EXPECT_EQ(0, lru_cache()->num_misses());
  EXPECT_EQ(0, lru_cache()->num_inserts());
  EXPECT_EQ(0, lru_cache()->num_identical_reinserts());

  rewrite_driver()->Write(
      ResourceVector(), "foo", &kContentTypeCss, StringPiece(),
      output_resource.get());
  EXPECT_TRUE(output_resource->cached_result() != NULL);
  EXPECT_EQ(0, lru_cache()->num_hits());
  EXPECT_EQ(0, lru_cache()->num_misses());
  EXPECT_EQ(1, lru_cache()->num_inserts());
  EXPECT_EQ(0, lru_cache()->num_identical_reinserts());
}

TEST_F(ServerContextTest, TestHandleBeaconNoLoadParam) {
  EXPECT_FALSE(server_context()->HandleBeacon(
      "", UserAgentMatcherTestBase::kChromeUserAgent,
      CreateRequestContext()));
}

TEST_F(ServerContextTest, TestHandleBeaconInvalidLoadParam) {
  EXPECT_FALSE(server_context()->HandleBeacon(
      "ets=asd", UserAgentMatcherTestBase::kChromeUserAgent,
      CreateRequestContext()));
}

TEST_F(ServerContextTest, TestHandleBeaconNoUrl) {
  EXPECT_FALSE(server_context()->HandleBeacon(
      "ets=load:34", UserAgentMatcherTestBase::kChromeUserAgent,
      CreateRequestContext()));
}

TEST_F(ServerContextTest, TestHandleBeaconInvalidUrl) {
  EXPECT_FALSE(server_context()->HandleBeacon(
      "url=%2f%2finvalidurl&ets=load:34",
      UserAgentMatcherTestBase::kChromeUserAgent, CreateRequestContext()));
}

TEST_F(ServerContextTest, TestHandleBeaconMissingValue) {
  EXPECT_FALSE(server_context()->HandleBeacon(
      "url=http%3A%2F%2Flocalhost%3A8080%2Findex.html&ets=load:",
      UserAgentMatcherTestBase::kChromeUserAgent, CreateRequestContext()));
}

TEST_F(ServerContextTest, TestHandleBeacon) {
  EXPECT_TRUE(server_context()->HandleBeacon(
      "url=http%3A%2F%2Flocalhost%3A8080%2Findex.html&ets=load:34",
      UserAgentMatcherTestBase::kChromeUserAgent, CreateRequestContext()));
}

class BeaconTest : public ServerContextTest {
 protected:
  BeaconTest() : property_cache_(NULL) { }
  virtual ~BeaconTest() { }

  virtual void SetUp() {
    ServerContextTest::SetUp();

    property_cache_ = server_context()->page_property_cache();
    property_cache_->set_enabled(true);
    const PropertyCache::Cohort* beacon_cohort =
        SetupCohort(property_cache_, RewriteDriver::kBeaconCohort);
    server_context()->set_beacon_cohort(beacon_cohort);
    server_context()->set_critical_images_finder(
        new BeaconCriticalImagesFinder(
            beacon_cohort, factory()->nonce_generator(), statistics()));
    server_context()->set_critical_selector_finder(
        new BeaconCriticalSelectorFinder(beacon_cohort,
                                         factory()->nonce_generator(),
                                         statistics()));
    ResetDriver();
    candidates_.insert("#foo");
    candidates_.insert(".bar");
    candidates_.insert("img");
  }

  void ResetDriver() {
    rewrite_driver()->Clear();
    SetDriverRequestHeaders();
  }

  MockPropertyPage* MockPageForUA(StringPiece user_agent) {
    UserAgentMatcher::DeviceType device_type =
        server_context()->user_agent_matcher()->GetDeviceTypeForUA(
            user_agent);
    MockPropertyPage* page = NewMockPage(
        kUrlPrefix, kOptionsHash, device_type);
    property_cache_->Read(page);
    return page;
  }

  void InsertCssBeacon(StringPiece user_agent) {
    // Simulate effects on pcache of CSS beacon insertion.
    rewrite_driver()->set_property_page(MockPageForUA(user_agent));
    factory()->mock_timer()->AdvanceMs(
        options()->beacon_reinstrument_time_sec() * Timer::kSecondMs);
    last_beacon_metadata_ =
        server_context()->critical_selector_finder()->
            PrepareForBeaconInsertion(candidates_, rewrite_driver());
    ASSERT_EQ(kBeaconWithNonce, last_beacon_metadata_.status);
    ASSERT_FALSE(last_beacon_metadata_.nonce.empty());
    rewrite_driver()->property_page()->WriteCohort(
        server_context()->beacon_cohort());
  }

  void InsertImageBeacon(StringPiece user_agent) {
    // Simulate effects on pcache of image beacon insertion.
    rewrite_driver()->set_property_page(MockPageForUA(user_agent));
    // Some of the critical image tests send enough beacons with the same set of
    // images that we can go into low frequency beaconing mode, so advance time
    // by the low frequency rebeacon interval.
    factory()->mock_timer()->AdvanceMs(
        options()->beacon_reinstrument_time_sec() * Timer::kSecondMs *
        kLowFreqBeaconMult);
    last_beacon_metadata_ =
        server_context()->critical_images_finder()->
            PrepareForBeaconInsertion(rewrite_driver());
    ASSERT_EQ(kBeaconWithNonce, last_beacon_metadata_.status);
    ASSERT_FALSE(last_beacon_metadata_.nonce.empty());
    rewrite_driver()->property_page()->WriteCohort(
        server_context()->beacon_cohort());
  }

  // Send a beacon through ServerContext::HandleBeacon and verify that the
  // property cache entries for critical images, critical selectors and rendered
  // dimensions of images were updated correctly.
  void TestBeacon(const StringSet* critical_image_hashes,
                  const StringSet* critical_css_selectors,
                  const GoogleString* rendered_images_json_map,
                  StringPiece user_agent) {
    ASSERT_EQ(kBeaconWithNonce, last_beacon_metadata_.status)
        << "Remember to insert a beacon!";
    // Setup the beacon_url and pass to HandleBeacon.
    GoogleString beacon_url = StrCat(
        "url=http%3A%2F%2Fwww.example.com"
        "&oh=", kOptionsHash, "&n=", last_beacon_metadata_.nonce);
    if (critical_image_hashes != NULL) {
      StrAppend(&beacon_url, "&ci=");
      AppendJoinCollection(&beacon_url, *critical_image_hashes, ",");
    }
    if (critical_css_selectors != NULL) {
      StrAppend(&beacon_url, "&cs=");
      AppendJoinCollection(&beacon_url, *critical_css_selectors, ",");
    }
    if (rendered_images_json_map != NULL) {
      StrAppend(&beacon_url, "&rd=", *rendered_images_json_map);
    }
    EXPECT_TRUE(server_context()->HandleBeacon(
        beacon_url, user_agent, CreateRequestContext()));

    // Read the property cache value for critical images, and verify that it has
    // the expected value.
    ResetDriver();
    scoped_ptr<MockPropertyPage> page(MockPageForUA(user_agent));
    rewrite_driver()->set_property_page(page.release());
    if (critical_image_hashes != NULL) {
      critical_html_images_ = server_context()->critical_images_finder()->
          GetHtmlCriticalImages(rewrite_driver());
    }
    if (critical_css_selectors != NULL) {
      critical_css_selectors_ = server_context()->critical_selector_finder()->
          GetCriticalSelectors(rewrite_driver());
    }

    if (rendered_images_json_map != NULL) {
      rendered_images_.reset(server_context()->critical_images_finder()->
                             ExtractRenderedImageDimensionsFromCache(
                                 rewrite_driver()));
    }
  }

  PropertyCache* property_cache_;
  // These fields hold data deserialized from the pcache after TestBeacon.
  StringSet critical_html_images_;
  StringSet critical_css_selectors_;
  // This field holds the data deserialized from pcache after a BeaconTest call.
  scoped_ptr<RenderedImages> rendered_images_;
  // This field holds candidate critical css selectors.
  StringSet candidates_;
  BeaconMetadata last_beacon_metadata_;
};

TEST_F(BeaconTest, BasicPcacheSetup) {
  const PropertyCache::Cohort* cohort = property_cache_->GetCohort(
      RewriteDriver::kBeaconCohort);
  UserAgentMatcher::DeviceType device_type =
      server_context()->user_agent_matcher()->GetDeviceTypeForUA(
          UserAgentMatcherTestBase::kChromeUserAgent);
  scoped_ptr<MockPropertyPage> page(
      NewMockPage(kUrlPrefix, kOptionsHash, device_type));
  property_cache_->Read(page.get());
  PropertyValue* property = page->GetProperty(cohort, "critical_images");
  EXPECT_FALSE(property->has_value());
}

TEST_F(BeaconTest, HandleBeaconRenderedDimensionsofImages) {
  GoogleString img1 = "http://www.example.com/img1.png";
  GoogleString hash1 = IntegerToString(
      HashString<CasePreserve, unsigned>(img1.c_str(), img1.size()));
  options()->EnableFilter(RewriteOptions::kResizeToRenderedImageDimensions);
  RenderedImages rendered_images;
  RenderedImages_Image* images = rendered_images.add_image();
  images->set_src(hash1);
  images->set_rendered_width(40);
  images->set_rendered_height(50);
  GoogleString json_map_rendered_dimensions = StrCat(
      "{\"", hash1, "\":{\"rw\":40,", "\"rh\":50,\"ow\":160,\"oh\":200}}");
  InsertImageBeacon(UserAgentMatcherTestBase::kChromeUserAgent);
  TestBeacon(NULL, NULL, &json_map_rendered_dimensions,
              UserAgentMatcherTestBase::kChromeUserAgent);
  ASSERT_FALSE(rendered_images_.get() == NULL);
  EXPECT_EQ(1, rendered_images_->image_size());
  EXPECT_STREQ(hash1, rendered_images_->image(0).src());
  EXPECT_EQ(40, rendered_images_->image(0).rendered_width());
  EXPECT_EQ(50, rendered_images_->image(0).rendered_height());
}

TEST_F(BeaconTest, HandleBeaconCritImages) {
  GoogleString img1 = "http://www.example.com/img1.png";
  GoogleString img2 = "http://www.example.com/img2.png";
  GoogleString hash1 = IntegerToString(
      HashString<CasePreserve, unsigned>(img1.c_str(), img1.size()));
  GoogleString hash2 = IntegerToString(
      HashString<CasePreserve, unsigned>(img2.c_str(), img2.size()));

  StringSet critical_image_hashes;
  critical_image_hashes.insert(hash1);
  InsertImageBeacon(UserAgentMatcherTestBase::kChromeUserAgent);
  TestBeacon(&critical_image_hashes, NULL, NULL,
             UserAgentMatcherTestBase::kChromeUserAgent);
  EXPECT_STREQ(hash1, JoinCollection(critical_html_images_, ","));

  // Beacon both images as critical.  Since we require 80% support, img2 won't
  // show as critical until we've beaconed four times.  It doesn't require five
  // beacon results because we weight recent beacon values more heavily and
  // beacon support decays over time.
  critical_image_hashes.insert(hash2);
  for (int i = 0; i < 3; ++i) {
    InsertImageBeacon(UserAgentMatcherTestBase::kChromeUserAgent);
    TestBeacon(&critical_image_hashes, NULL, NULL,
               UserAgentMatcherTestBase::kChromeUserAgent);
    EXPECT_STREQ(hash1, JoinCollection(critical_html_images_, ","));
  }
  GoogleString expected = StrCat(hash1, ",", hash2);
  InsertImageBeacon(UserAgentMatcherTestBase::kChromeUserAgent);
  TestBeacon(&critical_image_hashes, NULL, NULL,
             UserAgentMatcherTestBase::kChromeUserAgent);
  EXPECT_STREQ(expected, JoinCollection(critical_html_images_, ","));

  // Test with a different user agent, providing support only for img1.
  critical_image_hashes.clear();
  critical_image_hashes.insert(hash1);
  InsertImageBeacon(UserAgentMatcherTestBase::kIPhoneUserAgent);
  TestBeacon(&critical_image_hashes, NULL, NULL,
             UserAgentMatcherTestBase::kIPhoneUserAgent);
  EXPECT_STREQ(hash1, JoinCollection(critical_html_images_, ","));

  // Beacon once more with the original user agent and with only img1; img2
  // loses 80% support again.
  InsertImageBeacon(UserAgentMatcherTestBase::kChromeUserAgent);
  TestBeacon(&critical_image_hashes, NULL, NULL,
             UserAgentMatcherTestBase::kChromeUserAgent);
  EXPECT_STREQ(hash1, JoinCollection(critical_html_images_, ","));
}

TEST_F(BeaconTest, HandleBeaconCriticalCss) {
  InsertCssBeacon(UserAgentMatcherTestBase::kChromeUserAgent);
  StringSet critical_css_selector;
  critical_css_selector.insert("%23foo");
  critical_css_selector.insert(".bar");
  critical_css_selector.insert("%23noncandidate");
  TestBeacon(NULL, &critical_css_selector, NULL,
             UserAgentMatcherTestBase::kChromeUserAgent);
  EXPECT_STREQ("#foo,.bar",
               JoinCollection(critical_css_selectors_, ","));

  // Send another beacon response, and make sure we are storing a history of
  // responses.
  InsertCssBeacon(UserAgentMatcherTestBase::kChromeUserAgent);
  critical_css_selector.clear();
  critical_css_selector.insert(".bar");
  critical_css_selector.insert("img");
  critical_css_selector.insert("%23noncandidate");
  TestBeacon(NULL, &critical_css_selector, NULL,
             UserAgentMatcherTestBase::kChromeUserAgent);
  EXPECT_STREQ("#foo,.bar,img",
               JoinCollection(critical_css_selectors_, ","));
}

TEST_F(BeaconTest, EmptyCriticalCss) {
  InsertCssBeacon(UserAgentMatcherTestBase::kChromeUserAgent);
  StringSet empty_critical_selectors;
  TestBeacon(NULL, &empty_critical_selectors, NULL,
             UserAgentMatcherTestBase::kChromeUserAgent);
  EXPECT_TRUE(critical_css_selectors_.empty());
}

class ResourceFreshenTest : public ServerContextTest {
 protected:
  virtual void SetUp() {
    ServerContextTest::SetUp();
    HTTPCache::InitStats(statistics());
    expirations_ = statistics()->GetVariable(HTTPCache::kCacheExpirations);
    CHECK(expirations_ != NULL);
    SetDefaultLongCacheHeaders(&kContentTypePng, &response_headers_);
    response_headers_.SetStatusAndReason(HttpStatus::kOK);
    response_headers_.RemoveAll(HttpAttributes::kCacheControl);
    response_headers_.RemoveAll(HttpAttributes::kExpires);
  }

  Variable* expirations_;
  ResponseHeaders response_headers_;
};

// Many resources expire in 5 minutes, because that is our default for
// when caching headers are not present.  This test ensures that iff
// we ask for the resource when there's just a minute left, we proactively
// fetch it rather than allowing it to expire.
TEST_F(ResourceFreshenTest, TestFreshenImminentlyExpiringResources) {
  SetupWaitFetcher();
  FetcherUpdateDateHeaders();

  // Make sure we don't try to insert non-cacheable resources
  // into the cache wastefully, but still fetch them well.
  int max_age_sec =
      RewriteOptions::kDefaultImplicitCacheTtlMs / Timer::kSecondMs;
  response_headers_.Add(HttpAttributes::kCacheControl,
                       StringPrintf("max-age=%d", max_age_sec));
  SetFetchResponse(kResourceUrl, response_headers_, "foo");

  // The test here is not that the ReadIfCached will succeed, because
  // it's a fake url fetcher.
  StartRead();
  CallFetcherCallbacks();
  EXPECT_TRUE(ResourceIsCached());

  // Now let the time expire with no intervening fetches to freshen the cache.
  // This is because we do not proactively initiate refreshes for all resources;
  // only the ones that are actually asked for on a regular basis.  So a
  // completely inactive site will not see its resources freshened.
  AdvanceTimeMs((max_age_sec + 1) * Timer::kSecondMs);
  expirations_->Clear();
  StartRead();
  EXPECT_EQ(1, expirations_->Get());
  expirations_->Clear();
  CallFetcherCallbacks();
  EXPECT_TRUE(ResourceIsCached());

  // But if we have just a little bit of traffic then when we get a request
  // for a soon-to-expire resource it will auto-freshen.
  AdvanceTimeMs((1 + (max_age_sec * 4) / 5) * Timer::kSecondMs);
  EXPECT_TRUE(ResourceIsCached());
  CallFetcherCallbacks();  // freshens cache.
  AdvanceTimeMs((max_age_sec / 5) * Timer::kSecondMs);
  EXPECT_TRUE(ResourceIsCached());  // Yay, no cache misses after 301 seconds
  EXPECT_EQ(0, expirations_->Get());
}

// Tests that freshining will not be performed when we have caching
// forced.  Nothing will ever be evicted due to time, so there is no
// need to freshen.
TEST_F(ResourceFreshenTest, NoFreshenOfForcedCachedResources) {
  http_cache()->set_force_caching(true);
  FetcherUpdateDateHeaders();

  response_headers_.Add(HttpAttributes::kCacheControl, "max-age=0");
  SetFetchResponse(kResourceUrl, response_headers_, "foo");

  // We should get just 1 fetch.  If we were aggressively freshening
  // we would get 2.
  EXPECT_TRUE(ResourceIsCached());
  EXPECT_EQ(1, counting_url_async_fetcher()->fetch_count());

  // There should be no extra fetches required because our cache is
  // still active.  We shouldn't have needed an extra fetch to freshen,
  // either, because the cache expiration time is irrelevant -- we are
  // forcing caching so we consider the resource to always be fresh.
  // So even after an hour we should have no expirations.
  AdvanceTimeMs(1 * Timer::kHourMs);
  EXPECT_TRUE(ResourceIsCached());
  EXPECT_EQ(1, counting_url_async_fetcher()->fetch_count());

  // Nothing expires with force-caching on.
  EXPECT_EQ(0, expirations_->Get());
}

// Tests that freshining will not occur for short-lived resources,
// which could impact the performance of the server.
TEST_F(ResourceFreshenTest, NoFreshenOfShortLivedResources) {
  FetcherUpdateDateHeaders();

  int max_age_sec =
      RewriteOptions::kDefaultImplicitCacheTtlMs / Timer::kSecondMs - 1;
  response_headers_.Add(HttpAttributes::kCacheControl,
                       StringPrintf("max-age=%d", max_age_sec));
  SetFetchResponse(kResourceUrl, response_headers_, "foo");

  EXPECT_TRUE(ResourceIsCached());
  EXPECT_EQ(1, counting_url_async_fetcher()->fetch_count());

  // There should be no extra fetches required because our cache is
  // still active.  We shouldn't have needed an extra fetch to freshen,
  // either.
  AdvanceTimeMs((max_age_sec - 1) * Timer::kSecondMs);
  EXPECT_TRUE(ResourceIsCached());
  EXPECT_EQ(1, counting_url_async_fetcher()->fetch_count());
  EXPECT_EQ(0, expirations_->Get());

  // Now let the resource expire.  We'll need another fetch since we did not
  // freshen.
  AdvanceTimeMs(2 * Timer::kSecondMs);
  EXPECT_TRUE(ResourceIsCached());
  EXPECT_EQ(2, counting_url_async_fetcher()->fetch_count());
  EXPECT_EQ(1, expirations_->Get());
}

class ServerContextShardedTest : public ServerContextTest {
 protected:
  virtual void SetUp() {
    ServerContextTest::SetUp();
    EXPECT_TRUE(options()->WriteableDomainLawyer()->AddShard(
        "example.com", "shard0.com,shard1.com", message_handler()));
  }
};

TEST_F(ServerContextShardedTest, TestNamed) {
  GoogleString url = Encode("http://example.com/dir/123/",
                            "jm", "0", "orig", "js");
  GoogleString failure_reason;
  OutputResourcePtr output_resource(
      rewrite_driver()->CreateOutputResourceWithPath(
          "http://example.com/dir/",
          "jm",
          "orig.js",
          kRewrittenResource,
          &failure_reason));
  ASSERT_TRUE(output_resource.get());
  EXPECT_EQ("", failure_reason);
  ASSERT_TRUE(rewrite_driver()->Write(ResourceVector(),
                                      "alert('hello');",
                                      &kContentTypeJavascript,
                                      StringPiece(),
                                      output_resource.get()));

  // This always gets mapped to shard0 because we are using the mock
  // hasher for the content hash.  Note that the sharding sensitivity
  // to the hash value is tested in DomainLawyerTest.Shard, and will
  // also be covered in a system test.
  EXPECT_EQ(Encode("http://shard0.com/dir/", "jm", "0", "orig.js", "js"),
            output_resource->url());
}

TEST_F(ServerContextTest, TestMergeNonCachingResponseHeaders) {
  ResponseHeaders input, output;
  input.Add("X-Extra-Header", "Extra Value");  // should be copied to output
  input.Add(HttpAttributes::kCacheControl, "max-age=300");  // should not be
  server_context()->MergeNonCachingResponseHeaders(input, &output);
  ConstStringStarVector v;
  EXPECT_FALSE(output.Lookup(HttpAttributes::kCacheControl, &v));
  ASSERT_TRUE(output.Lookup("X-Extra-Header", &v));
  ASSERT_EQ(1, v.size());
  EXPECT_EQ("Extra Value", *v[0]);
}

class ServerContextCacheControlTest : public ServerContextTest {
 protected:
  void SetUp() override {
    ServerContextTest::SetUp();
    implicit_public_100_ = CreateCustomCachingResource("ipub_100", 100, "");
    implicit_public_200_ = CreateCustomCachingResource("ipub_200", 200, "");
    explicit_public_200_ = CreateCustomCachingResource(
        "epub_200", 200, ",public");
    private_300_ = CreateCustomCachingResource("pri_300", 300, ",private");
    private_400_ = CreateCustomCachingResource("pri_400", 400, ",private");
    no_cache_150_ = CreateCustomCachingResource("noc_150", 400, ",no-cache");
    no_store_200_ = CreateCustomCachingResource("nos_200", 200, ",no-store");
    DefaultHeaders(&response_headers_);
  }

  GoogleString LongCacheTtl() const {
    return StrCat(
        "max-age=",
        Integer64ToString(ServerContext::kGeneratedMaxAgeMs /
                          Timer::kSecondMs));
  }

  bool HasCacheControl(StringPiece value) {
    return response_headers_.HasValue(HttpAttributes::kCacheControl, value);
  }

  ResourcePtr implicit_public_100_;
  ResourcePtr implicit_public_200_;
  ResourcePtr explicit_public_200_;
  ResourcePtr private_300_;
  ResourcePtr private_400_;
  ResourcePtr no_cache_150_;
  ResourcePtr no_store_200_;
  ResourceVector resources_;
  ResponseHeaders response_headers_;
};

TEST_F(ServerContextCacheControlTest, ImplicitPublic) {
  // If we feed in just implicitly public resources, we should get
  // something with ultra-long TTL, regardless of how soon they
  // expire.
  resources_.push_back(implicit_public_100_);
  resources_.push_back(implicit_public_200_);
  server_context()->ApplyInputCacheControl(resources_, &response_headers_);
  EXPECT_STREQ(LongCacheTtl(),
               response_headers_.Lookup1(HttpAttributes::kCacheControl));
}

TEST_F(ServerContextCacheControlTest, ExplicitPublic) {
  // An explicit 'public' gets reflected in the output.
  resources_.push_back(explicit_public_200_);
  server_context()->ApplyInputCacheControl(resources_, &response_headers_);
  EXPECT_TRUE(HasCacheControl("public"));
  EXPECT_FALSE(HasCacheControl("private"));
  EXPECT_TRUE(HasCacheControl(LongCacheTtl()));
}

TEST_F(ServerContextCacheControlTest, Private) {
  // If an input is private, however, we must mark output appropriately
  // and not cache-extend.
  resources_.push_back(implicit_public_100_);
  resources_.push_back(private_300_);
  resources_.push_back(private_400_);
  server_context()->ApplyInputCacheControl(resources_, &response_headers_);
  EXPECT_FALSE(HasCacheControl("public"));
  EXPECT_TRUE(HasCacheControl("private"));
  EXPECT_TRUE(HasCacheControl("max-age=100"));
}

TEST_F(ServerContextCacheControlTest, NoCache) {
  // Similarly no-cache should be incorporated --- but then we also need
  // to have 0 ttl.
  resources_.push_back(implicit_public_100_);
  resources_.push_back(private_300_);
  resources_.push_back(private_400_);
  resources_.push_back(no_cache_150_);
  server_context()->ApplyInputCacheControl(resources_, &response_headers_);
  EXPECT_FALSE(HasCacheControl("public"));
  EXPECT_TRUE(HasCacheControl("no-cache"));
  EXPECT_TRUE(HasCacheControl("max-age=0"));
}

TEST_F(ServerContextCacheControlTest, NoStore) {
  // Make sure we save no-store as well.
  resources_.push_back(implicit_public_100_);
  resources_.push_back(private_300_);
  resources_.push_back(private_400_);
  resources_.push_back(no_cache_150_);
  resources_.push_back(no_store_200_);
  server_context()->ApplyInputCacheControl(resources_, &response_headers_);
  EXPECT_FALSE(HasCacheControl("public"));
  EXPECT_TRUE(HasCacheControl("no-cache"));
  EXPECT_TRUE(HasCacheControl("no-store"));
  EXPECT_TRUE(HasCacheControl("max-age=0"));
}

TEST_F(ServerContextTest, WriteChecksInputVector) {
  // Make sure ->Write incorporates the cache control info from inputs,
  // and doesn't cache a private resource improperly. Also make sure
  // we get the charset right (including quoting).
  ResourcePtr private_400(
      CreateCustomCachingResource("pri_400", 400, ",private"));
  // Should have the 'it's not cacheable!' entry here; see also below.
  EXPECT_EQ(1, http_cache()->cache_inserts()->Get());
  GoogleString failure_reason;
  OutputResourcePtr output_resource(
      rewrite_driver()->CreateOutputResourceFromResource(
          "cf", rewrite_driver()->default_encoder(), NULL /* no context*/,
          private_400, kRewrittenResource, &failure_reason));
  ASSERT_TRUE(output_resource.get() != NULL);
  EXPECT_EQ("", failure_reason);

  rewrite_driver()->Write(ResourceVector(1, private_400),
                          "boo!",
                          &kContentTypeText,
                          "\"\\koi8-r\"",  // covers escaping behavior, too.
                          output_resource.get());
  ResponseHeaders* headers = output_resource->response_headers();
  EXPECT_FALSE(headers->HasValue(HttpAttributes::kCacheControl, "public"));
  EXPECT_TRUE(headers->HasValue(HttpAttributes::kCacheControl, "private"));
  EXPECT_TRUE(headers->HasValue(HttpAttributes::kCacheControl, "max-age=400"));
  EXPECT_STREQ("text/plain; charset=\"\\koi8-r\"",
               headers->Lookup1(HttpAttributes::kContentType));

  // Make sure nothing extra in the cache at this point.
  EXPECT_EQ(1, http_cache()->cache_inserts()->Get());
}

TEST_F(ServerContextTest, IsPagespeedResource) {
  GoogleUrl rewritten(Encode("http://shard0.com/dir/", "jm", "0",
                             "orig.js", "js"));
  EXPECT_TRUE(server_context()->IsPagespeedResource(rewritten));

  GoogleUrl normal("http://jqueryui.com/jquery-1.6.2.js");
  EXPECT_FALSE(server_context()->IsPagespeedResource(normal));
}

TEST_F(ServerContextTest, PartlyFailedFetch) {
  // Regression test for invalid Resource state when the fetch physically
  // succeeds but does not get added to cache due to invalid cacheability.
  // In that case, we would end up with headers claiming successful fetch,
  // but an HTTPValue without headers set (which would also crash on
  // access if no data was emitted by fetcher via Write).
  static const char kCssName[] = "a.css";
  GoogleString abs_url = AbsolutifyUrl(kCssName);
  ResponseHeaders non_cacheable;
  SetDefaultLongCacheHeaders(&kContentTypeCss, &non_cacheable);
  non_cacheable.SetDateAndCaching(start_time_ms() /* date */, 0 /* ttl */,
                                  "private, no-cache");
  non_cacheable.ComputeCaching();
  SetFetchResponse(abs_url, non_cacheable, "foo");

  // We tell the fetcher to quash the zero-bytes writes, as that behavior
  // (which Serf has) made the bug more severe, with not only
  // loaded() and HttpStatusOk() lying, but also contents() crashing.
  mock_url_fetcher()->set_omit_empty_writes(true);

  // We tell the fetcher to output the headers and then immediately fail.
  mock_url_fetcher()->set_fail_after_headers(true);

  GoogleUrl gurl(abs_url);
  SetBaseUrlForFetch(abs_url);
  bool is_authorized;
  ResourcePtr resource = rewrite_driver()->CreateInputResource(
      gurl, RewriteDriver::InputRole::kStyle, &is_authorized);
  ASSERT_TRUE(resource.get() != NULL);
  EXPECT_TRUE(is_authorized);
  MockResourceCallback callback(resource, factory()->thread_system());
  resource->LoadAsync(Resource::kReportFailureIfNotCacheable,
                      rewrite_driver()->request_context(),
                      &callback);
  EXPECT_TRUE(callback.done());
  EXPECT_FALSE(callback.success());
  EXPECT_FALSE(resource->IsValidAndCacheable());
  EXPECT_FALSE(resource->loaded());
  EXPECT_FALSE(resource->HttpStatusOk())
      << " Unexpectedly got access to resource contents:"
      << resource->ExtractUncompressedContents();
}

TEST_F(ServerContextTest, LoadFromFileReadAsync) {
  // This reads a resource twice, to make sure that there is no misbehavior
  // (read: check failures or crashes) when cache invalidation logic tries to
  // deal with FileInputResource.
  const char kContents[] = "lots of bits of data";
  options()->file_load_policy()->Associate("http://test.com/", "/test/");

  GoogleUrl test_url("http://test.com/a.css");

  // Init file resources.
  WriteFile("/test/a.css", kContents);

  SetBaseUrlForFetch("http://test.com");
  bool unused;
  ResourcePtr resource(rewrite_driver()->CreateInputResource(
      test_url, RewriteDriver::InputRole::kStyle, &unused));
  VerifyContentsCallback callback(resource, kContents);
  resource->LoadAsync(Resource::kReportFailureIfNotCacheable,
                      rewrite_driver()->request_context(),
                      &callback);
  callback.AssertCalled();

  resource = rewrite_driver()->CreateInputResource(
      test_url, RewriteDriver::InputRole::kStyle, &unused);
  VerifyContentsCallback callback2(resource, kContents);
  resource->LoadAsync(Resource::kReportFailureIfNotCacheable,
                      rewrite_driver()->request_context(),
                      &callback2);
  callback2.AssertCalled();
}

namespace {

void CheckMatchesHeaders(const ResponseHeaders& headers,
                         const InputInfo& input) {
  ASSERT_TRUE(input.has_type());
  EXPECT_EQ(InputInfo::CACHED, input.type());

  EXPECT_EQ(headers.has_last_modified_time_ms(),
            input.has_last_modified_time_ms());
  EXPECT_EQ(headers.last_modified_time_ms(), input.last_modified_time_ms());

  ASSERT_TRUE(input.has_expiration_time_ms());
  EXPECT_EQ(headers.CacheExpirationTimeMs(), input.expiration_time_ms());

  ASSERT_TRUE(input.has_date_ms());
  EXPECT_EQ(headers.date_ms(), input.date_ms());
}

}  // namespace

TEST_F(ServerContextTest, FillInPartitionInputInfo) {
  // Test for Resource::FillInPartitionInputInfo.
  const char kUrl[] = "http://example.com/page.html";
  const char kContents[] = "bits";
  SetBaseUrlForFetch("http://example.com/");

  ResponseHeaders headers;
  SetDefaultLongCacheHeaders(&kContentTypeHtml, &headers);
  headers.ComputeCaching();
  SetFetchResponse(kUrl, headers, kContents);
  GoogleUrl gurl(kUrl);
  bool unused;
  ResourcePtr resource(rewrite_driver()->CreateInputResource(
      gurl, RewriteDriver::InputRole::kUnknown, &unused));
  VerifyContentsCallback callback(resource, kContents);
  resource->LoadAsync(Resource::kReportFailureIfNotCacheable,
                      rewrite_driver()->request_context(),
                      &callback);
  callback.AssertCalled();

  InputInfo with_hash, without_hash;
  resource->FillInPartitionInputInfo(Resource::kIncludeInputHash, &with_hash);
  resource->FillInPartitionInputInfo(Resource::kOmitInputHash, &without_hash);

  CheckMatchesHeaders(headers, with_hash);
  CheckMatchesHeaders(headers, without_hash);
  ASSERT_TRUE(with_hash.has_input_content_hash());
  EXPECT_STREQ("zEEebBNnDlISRim4rIP30", with_hash.input_content_hash());
  EXPECT_FALSE(without_hash.has_input_content_hash());

  resource->response_headers()->RemoveAll(HttpAttributes::kLastModified);
  resource->response_headers()->ComputeCaching();
  EXPECT_FALSE(resource->response_headers()->has_last_modified_time_ms());
  InputInfo without_last_modified;
  resource->FillInPartitionInputInfo(Resource::kOmitInputHash,
                                     &without_last_modified);
  CheckMatchesHeaders(*resource->response_headers(), without_last_modified);
}

// Test of referer for BackgroundFetch: When the resource fetching request
// header misses referer, we set the driver base url as its referer.
TEST_F(ServerContextTest, TestRefererBackgroundFetch) {
  RefererTest(NULL, true);
  EXPECT_EQ(rewrite_driver()->base_url().Spec(),
            mock_url_fetcher()->last_referer());
}

// Test of referer for NonBackgroundFetch: When the resource fetching request
// header misses referer and the original request referer header misses, no
// referer would be added.
TEST_F(ServerContextTest, TestRefererNonBackgroundFetch) {
  RequestHeaders headers;
  RefererTest(&headers, false);
  EXPECT_EQ("", mock_url_fetcher()->last_referer());
}

// Test of referer for NonBackgroundFetch: When the resource fetching request
// header misses referer but the original request header has referer set, we set
// this referer as the referer of resource fetching request.
TEST_F(ServerContextTest, TestRefererNonBackgroundFetchWithDriverRefer) {
  RequestHeaders headers;
  const char kReferer[] = "http://other.com/";
  headers.Add(HttpAttributes::kReferer, kReferer);
  RefererTest(&headers, false);
  EXPECT_EQ(kReferer, mock_url_fetcher()->last_referer());
}

// Regression test for RewriteTestBase::DefaultResponseHeaders, which is based
// on ServerContext methods. It used to not set 'Expires' correctly.
TEST_F(ServerContextTest, RewriteTestBaseDefaultResponseHeaders) {
  ResponseHeaders headers;
  DefaultResponseHeaders(kContentTypeCss, 100 /* ttl_sec */, &headers);
  int64 expire_time_ms = 0;
  ASSERT_TRUE(
      headers.ParseDateHeader(HttpAttributes::kExpires, &expire_time_ms));
  EXPECT_EQ(timer()->NowMs() + 100 * Timer::kSecondMs, expire_time_ms);
}

}  // namespace net_instaweb
