/*
 * Copyright (c) 2014, Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h"

#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_context.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h"
#include "third_party/blink/renderer/platform/loader/fetch/raw_resource.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_request.h"
#include "third_party/blink/renderer/platform/loader/testing/mock_fetch_context.h"
#include "third_party/blink/renderer/platform/loader/testing/mock_resource.h"
#include "third_party/blink/renderer/platform/loader/testing/test_resource_fetcher_properties.h"
#include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h"

namespace blink {

namespace {

// An URL for the original request.
constexpr char kResourceURL[] = "http://resource.com/";

// The origin time of our first request.
constexpr char kOriginalRequestDateAsString[] = "Thu, 25 May 1977 18:30:00 GMT";
constexpr char kOneDayBeforeOriginalRequest[] = "Wed, 24 May 1977 18:30:00 GMT";
constexpr char kOneDayAfterOriginalRequest[] = "Fri, 26 May 1977 18:30:00 GMT";

}  // namespace

class MemoryCacheCorrectnessTest : public testing::Test {
 protected:
  MockResource* ResourceFromResourceResponse(ResourceResponse response) {
    if (response.CurrentRequestUrl().IsNull())
      response.SetCurrentRequestUrl(KURL(kResourceURL));
    ResourceRequest request(response.CurrentRequestUrl());
    request.SetRequestorOrigin(GetSecurityOrigin());
    MockResource* resource = MockResource::Create(request);
    resource->SetResponse(response);
    resource->FinishForTest();
    AddResourceToMemoryCache(resource);

    return resource;
  }
  MockResource* ResourceFromResourceRequest(ResourceRequest request) {
    if (request.Url().IsNull())
      request.SetURL(KURL(kResourceURL));
    request.SetFetchCredentialsMode(
        network::mojom::FetchCredentialsMode::kOmit);
    MockResource* resource = MockResource::Create(request);
    ResourceResponse response(KURL{kResourceURL});
    response.SetMimeType("text/html");
    resource->SetResponse(response);
    resource->FinishForTest();
    AddResourceToMemoryCache(resource);

    return resource;
  }
  void AddResourceToMemoryCache(Resource* resource) {
    GetMemoryCache()->Add(resource);
  }
  // TODO(toyoshim): Consider to use MockResource for all tests instead of
  // RawResource.
  RawResource* FetchRawResource() {
    ResourceRequest resource_request{KURL(kResourceURL)};
    resource_request.SetRequestContext(mojom::RequestContextType::INTERNAL);
    resource_request.SetRequestorOrigin(GetSecurityOrigin());
    FetchParameters fetch_params(resource_request);
    return RawResource::Fetch(fetch_params, Fetcher(), nullptr);
  }
  MockResource* FetchMockResource() {
    ResourceRequest resource_request{KURL(kResourceURL)};
    resource_request.SetRequestorOrigin(GetSecurityOrigin());
    FetchParameters fetch_params(resource_request);
    return MockResource::Fetch(fetch_params, Fetcher(), nullptr);
  }
  ResourceFetcher* Fetcher() const { return fetcher_.Get(); }
  void AdvanceClock(double seconds) { platform_->AdvanceClockSeconds(seconds); }
  scoped_refptr<const SecurityOrigin> GetSecurityOrigin() const {
    return security_origin_;
  }

 private:
  // Overrides testing::Test.
  void SetUp() override {
    // Save the global memory cache to restore it upon teardown.
    global_memory_cache_ = ReplaceMemoryCacheForTesting(
        MemoryCache::Create(platform_->test_task_runner()));

    security_origin_ = SecurityOrigin::CreateUniqueOpaque();
    MockFetchContext* context =
        MakeGarbageCollected<MockFetchContext>(nullptr, security_origin_);
    auto* properties = MakeGarbageCollected<TestResourceFetcherProperties>();
    properties->SetShouldBlockLoadingMainResource(true);
    properties->SetShouldBlockLoadingSubResource(true);
    fetcher_ = MakeGarbageCollected<ResourceFetcher>(*properties, context);
  }
  void TearDown() override {
    GetMemoryCache()->EvictResources();

    // Yield the ownership of the global memory cache back.
    ReplaceMemoryCacheForTesting(global_memory_cache_.Release());
  }

  Persistent<MemoryCache> global_memory_cache_;
  scoped_refptr<const SecurityOrigin> security_origin_;
  Persistent<ResourceFetcher> fetcher_;
  ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
      platform_;
};

TEST_F(MemoryCacheCorrectnessTest, FreshFromLastModified) {
  ResourceResponse fresh200_response;
  fresh200_response.SetHTTPStatusCode(200);
  fresh200_response.SetHTTPHeaderField("Date", kOriginalRequestDateAsString);
  fresh200_response.SetHTTPHeaderField("Last-Modified",
                                       kOneDayBeforeOriginalRequest);

  MockResource* fresh200 = ResourceFromResourceResponse(fresh200_response);

  // Advance the clock within the implicit freshness period of this resource
  // before we make a request.
  AdvanceClock(600.);

  MockResource* fetched = FetchMockResource();
  EXPECT_EQ(fresh200, fetched);
}

TEST_F(MemoryCacheCorrectnessTest, FreshFromExpires) {
  ResourceResponse fresh200_response;
  fresh200_response.SetHTTPStatusCode(200);
  fresh200_response.SetHTTPHeaderField("Date", kOriginalRequestDateAsString);
  fresh200_response.SetHTTPHeaderField("Expires", kOneDayAfterOriginalRequest);

  MockResource* fresh200 = ResourceFromResourceResponse(fresh200_response);

  // Advance the clock within the freshness period of this resource before we
  // make a request.
  AdvanceClock(24. * 60. * 60. - 15.);

  MockResource* fetched = FetchMockResource();
  EXPECT_EQ(fresh200, fetched);
}

TEST_F(MemoryCacheCorrectnessTest, FreshFromMaxAge) {
  ResourceResponse fresh200_response;
  fresh200_response.SetHTTPStatusCode(200);
  fresh200_response.SetHTTPHeaderField("Date", kOriginalRequestDateAsString);
  fresh200_response.SetHTTPHeaderField("Cache-Control", "max-age=600");

  MockResource* fresh200 = ResourceFromResourceResponse(fresh200_response);

  // Advance the clock within the freshness period of this resource before we
  // make a request.
  AdvanceClock(500.);

  MockResource* fetched = FetchMockResource();
  EXPECT_EQ(fresh200, fetched);
}

// The strong validator causes a revalidation to be launched, and the proxy and
// original resources leak because of their reference loop.
TEST_F(MemoryCacheCorrectnessTest, DISABLED_ExpiredFromLastModified) {
  ResourceResponse expired200_response;
  expired200_response.SetHTTPStatusCode(200);
  expired200_response.SetHTTPHeaderField("Date", kOriginalRequestDateAsString);
  expired200_response.SetHTTPHeaderField("Last-Modified",
                                         kOneDayBeforeOriginalRequest);

  MockResource* expired200 = ResourceFromResourceResponse(expired200_response);

  // Advance the clock beyond the implicit freshness period.
  AdvanceClock(24. * 60. * 60. * 0.2);

  MockResource* fetched = FetchMockResource();
  EXPECT_NE(expired200, fetched);
}

TEST_F(MemoryCacheCorrectnessTest, ExpiredFromExpires) {
  ResourceResponse expired200_response;
  expired200_response.SetHTTPStatusCode(200);
  expired200_response.SetHTTPHeaderField("Date", kOriginalRequestDateAsString);
  expired200_response.SetHTTPHeaderField("Expires",
                                         kOneDayAfterOriginalRequest);

  MockResource* expired200 = ResourceFromResourceResponse(expired200_response);

  // Advance the clock within the expiredness period of this resource before we
  // make a request.
  AdvanceClock(24. * 60. * 60. + 15.);

  MockResource* fetched = FetchMockResource();
  EXPECT_NE(expired200, fetched);
}

// If the resource hasn't been loaded in this "document" before, then it
// shouldn't have list of available resources logic.
TEST_F(MemoryCacheCorrectnessTest, NewMockResourceExpiredFromExpires) {
  ResourceResponse expired200_response;
  expired200_response.SetHTTPStatusCode(200);
  expired200_response.SetHTTPHeaderField("Date", kOriginalRequestDateAsString);
  expired200_response.SetHTTPHeaderField("Expires",
                                         kOneDayAfterOriginalRequest);

  MockResource* expired200 = ResourceFromResourceResponse(expired200_response);

  // Advance the clock within the expiredness period of this resource before we
  // make a request.
  AdvanceClock(24. * 60. * 60. + 15.);

  MockResource* fetched = FetchMockResource();
  EXPECT_NE(expired200, fetched);
}

// If the resource has been loaded in this "document" before, then it should
// have list of available resources logic, and so normal cache testing should be
// bypassed.
TEST_F(MemoryCacheCorrectnessTest, ReuseMockResourceExpiredFromExpires) {
  ResourceResponse expired200_response;
  expired200_response.SetHTTPStatusCode(200);
  expired200_response.SetHTTPHeaderField("Date", kOriginalRequestDateAsString);
  expired200_response.SetHTTPHeaderField("Expires",
                                         kOneDayAfterOriginalRequest);

  MockResource* expired200 = ResourceFromResourceResponse(expired200_response);

  // Advance the clock within the freshness period, and make a request to add
  // this resource to the document resources.
  AdvanceClock(15.);
  MockResource* first_fetched = FetchMockResource();
  EXPECT_EQ(expired200, first_fetched);

  // Advance the clock within the expiredness period of this resource before we
  // make a request.
  AdvanceClock(24. * 60. * 60. + 15.);

  MockResource* fetched = FetchMockResource();
  EXPECT_EQ(expired200, fetched);
}

TEST_F(MemoryCacheCorrectnessTest, ExpiredFromMaxAge) {
  ResourceResponse expired200_response;
  expired200_response.SetHTTPStatusCode(200);
  expired200_response.SetHTTPHeaderField("Date", kOriginalRequestDateAsString);
  expired200_response.SetHTTPHeaderField("Cache-Control", "max-age=600");

  MockResource* expired200 = ResourceFromResourceResponse(expired200_response);

  // Advance the clock within the expiredness period of this resource before we
  // make a request.
  AdvanceClock(700.);

  MockResource* fetched = FetchMockResource();
  EXPECT_NE(expired200, fetched);
}

TEST_F(MemoryCacheCorrectnessTest, FreshButNoCache) {
  ResourceResponse fresh200_nocache_response;
  fresh200_nocache_response.SetHTTPStatusCode(200);
  fresh200_nocache_response.SetHTTPHeaderField(http_names::kDate,
                                               kOriginalRequestDateAsString);
  fresh200_nocache_response.SetHTTPHeaderField(http_names::kExpires,
                                               kOneDayAfterOriginalRequest);
  fresh200_nocache_response.SetHTTPHeaderField(http_names::kCacheControl,
                                               "no-cache");

  MockResource* fresh200_nocache =
      ResourceFromResourceResponse(fresh200_nocache_response);

  // Advance the clock within the freshness period of this resource before we
  // make a request.
  AdvanceClock(24. * 60. * 60. - 15.);

  MockResource* fetched = FetchMockResource();
  EXPECT_NE(fresh200_nocache, fetched);
}

TEST_F(MemoryCacheCorrectnessTest, RequestWithNoCache) {
  ResourceRequest no_cache_request;
  no_cache_request.SetHTTPHeaderField(http_names::kCacheControl, "no-cache");
  no_cache_request.SetRequestorOrigin(GetSecurityOrigin());
  MockResource* no_cache_resource =
      ResourceFromResourceRequest(no_cache_request);
  MockResource* fetched = FetchMockResource();
  EXPECT_NE(no_cache_resource, fetched);
}

TEST_F(MemoryCacheCorrectnessTest, FreshButNoStore) {
  ResourceResponse fresh200_nostore_response;
  fresh200_nostore_response.SetHTTPStatusCode(200);
  fresh200_nostore_response.SetHTTPHeaderField(http_names::kDate,
                                               kOriginalRequestDateAsString);
  fresh200_nostore_response.SetHTTPHeaderField(http_names::kExpires,
                                               kOneDayAfterOriginalRequest);
  fresh200_nostore_response.SetHTTPHeaderField(http_names::kCacheControl,
                                               "no-store");

  MockResource* fresh200_nostore =
      ResourceFromResourceResponse(fresh200_nostore_response);

  // Advance the clock within the freshness period of this resource before we
  // make a request.
  AdvanceClock(24. * 60. * 60. - 15.);

  MockResource* fetched = FetchMockResource();
  EXPECT_NE(fresh200_nostore, fetched);
}

TEST_F(MemoryCacheCorrectnessTest, RequestWithNoStore) {
  ResourceRequest no_store_request;
  no_store_request.SetHTTPHeaderField(http_names::kCacheControl, "no-store");
  no_store_request.SetRequestorOrigin(GetSecurityOrigin());
  MockResource* no_store_resource =
      ResourceFromResourceRequest(no_store_request);
  MockResource* fetched = FetchMockResource();
  EXPECT_NE(no_store_resource, fetched);
}

// FIXME: Determine if ignoring must-revalidate for blink is correct behaviour.
// See crbug.com/340088 .
TEST_F(MemoryCacheCorrectnessTest, DISABLED_FreshButMustRevalidate) {
  ResourceResponse fresh200_must_revalidate_response;
  fresh200_must_revalidate_response.SetHTTPStatusCode(200);
  fresh200_must_revalidate_response.SetHTTPHeaderField(
      http_names::kDate, kOriginalRequestDateAsString);
  fresh200_must_revalidate_response.SetHTTPHeaderField(
      http_names::kExpires, kOneDayAfterOriginalRequest);
  fresh200_must_revalidate_response.SetHTTPHeaderField(
      http_names::kCacheControl, "must-revalidate");

  MockResource* fresh200_must_revalidate =
      ResourceFromResourceResponse(fresh200_must_revalidate_response);

  // Advance the clock within the freshness period of this resource before we
  // make a request.
  AdvanceClock(24. * 60. * 60. - 15.);

  MockResource* fetched = FetchMockResource();
  EXPECT_NE(fresh200_must_revalidate, fetched);
}

TEST_F(MemoryCacheCorrectnessTest, FreshWithFreshRedirect) {
  KURL redirect_url(kResourceURL);
  const char kRedirectTargetUrlString[] = "http://redirect-target.com";
  KURL redirect_target_url(kRedirectTargetUrlString);

  ResourceRequest request(redirect_url);
  request.SetRequestorOrigin(GetSecurityOrigin());
  MockResource* first_resource = MockResource::Create(request);

  ResourceResponse fresh301_response(redirect_url);
  fresh301_response.SetHTTPStatusCode(301);
  fresh301_response.SetHTTPHeaderField(http_names::kDate,
                                       kOriginalRequestDateAsString);
  fresh301_response.SetHTTPHeaderField(http_names::kLocation,
                                       kRedirectTargetUrlString);
  fresh301_response.SetHTTPHeaderField(http_names::kCacheControl,
                                       "max-age=600");

  // Add the redirect to our request.
  ResourceRequest redirect_request = ResourceRequest(redirect_target_url);
  redirect_request.SetRequestorOrigin(GetSecurityOrigin());
  first_resource->WillFollowRedirect(redirect_request, fresh301_response);

  // Add the final response to our request.
  ResourceResponse fresh200_response(redirect_target_url);
  fresh200_response.SetHTTPStatusCode(200);
  fresh200_response.SetHTTPHeaderField(http_names::kDate,
                                       kOriginalRequestDateAsString);
  fresh200_response.SetHTTPHeaderField(http_names::kExpires,
                                       kOneDayAfterOriginalRequest);

  first_resource->SetResponse(fresh200_response);
  first_resource->FinishForTest();
  AddResourceToMemoryCache(first_resource);

  AdvanceClock(500.);

  MockResource* fetched = FetchMockResource();
  EXPECT_EQ(first_resource, fetched);
}

TEST_F(MemoryCacheCorrectnessTest, FreshWithStaleRedirect) {
  KURL redirect_url(kResourceURL);
  const char kRedirectTargetUrlString[] = "http://redirect-target.com";
  KURL redirect_target_url(kRedirectTargetUrlString);

  ResourceRequest request(redirect_url);
  request.SetRequestorOrigin(GetSecurityOrigin());
  request.SetFetchCredentialsMode(network::mojom::FetchCredentialsMode::kOmit);
  MockResource* first_resource = MockResource::Create(request);

  ResourceResponse stale301_response(redirect_url);
  stale301_response.SetHTTPStatusCode(301);
  stale301_response.SetHTTPHeaderField(http_names::kDate,
                                       kOriginalRequestDateAsString);
  stale301_response.SetHTTPHeaderField(http_names::kLocation,
                                       kRedirectTargetUrlString);

  // Add the redirect to our request.
  ResourceRequest redirect_request = ResourceRequest(redirect_target_url);
  redirect_request.SetRequestorOrigin(GetSecurityOrigin());
  first_resource->WillFollowRedirect(redirect_request, stale301_response);

  // Add the final response to our request.
  ResourceResponse fresh200_response(redirect_target_url);
  fresh200_response.SetHTTPStatusCode(200);
  fresh200_response.SetHTTPHeaderField(http_names::kDate,
                                       kOriginalRequestDateAsString);
  fresh200_response.SetHTTPHeaderField(http_names::kExpires,
                                       kOneDayAfterOriginalRequest);

  first_resource->SetResponse(fresh200_response);
  first_resource->FinishForTest();
  AddResourceToMemoryCache(first_resource);

  AdvanceClock(500.);

  MockResource* fetched = FetchMockResource();
  EXPECT_NE(first_resource, fetched);
}

TEST_F(MemoryCacheCorrectnessTest, PostToSameURLTwice) {
  ResourceRequest request1{KURL(kResourceURL)};
  request1.SetHTTPMethod(http_names::kPOST);
  request1.SetRequestorOrigin(GetSecurityOrigin());
  RawResource* resource1 =
      RawResource::CreateForTest(request1, ResourceType::kRaw);
  resource1->SetStatus(ResourceStatus::kPending);
  AddResourceToMemoryCache(resource1);

  ResourceRequest request2{KURL(kResourceURL)};
  request2.SetHTTPMethod(http_names::kPOST);
  request2.SetRequestorOrigin(GetSecurityOrigin());
  FetchParameters fetch2(request2);
  RawResource* resource2 = RawResource::FetchSynchronously(fetch2, Fetcher());
  EXPECT_NE(resource1, resource2);
}

TEST_F(MemoryCacheCorrectnessTest, 302RedirectNotImplicitlyFresh) {
  KURL redirect_url(kResourceURL);
  const char kRedirectTargetUrlString[] = "http://redirect-target.com";
  KURL redirect_target_url(kRedirectTargetUrlString);

  RawResource* first_resource = RawResource::CreateForTest(
      redirect_url, GetSecurityOrigin(), ResourceType::kRaw);

  ResourceResponse fresh302_response(redirect_url);
  fresh302_response.SetHTTPStatusCode(302);
  fresh302_response.SetHTTPHeaderField(http_names::kDate,
                                       kOriginalRequestDateAsString);
  fresh302_response.SetHTTPHeaderField(http_names::kLastModified,
                                       kOneDayBeforeOriginalRequest);
  fresh302_response.SetHTTPHeaderField(http_names::kLocation,
                                       kRedirectTargetUrlString);

  // Add the redirect to our request.
  ResourceRequest redirect_request = ResourceRequest(redirect_target_url);
  redirect_request.SetRequestorOrigin(GetSecurityOrigin());
  first_resource->WillFollowRedirect(redirect_request, fresh302_response);

  // Add the final response to our request.
  ResourceResponse fresh200_response(redirect_target_url);
  fresh200_response.SetHTTPStatusCode(200);
  fresh200_response.SetHTTPHeaderField(http_names::kDate,
                                       kOriginalRequestDateAsString);
  fresh200_response.SetHTTPHeaderField(http_names::kExpires,
                                       kOneDayAfterOriginalRequest);

  first_resource->SetResponse(fresh200_response);
  first_resource->FinishForTest();
  AddResourceToMemoryCache(first_resource);

  AdvanceClock(500.);

  RawResource* fetched = FetchRawResource();
  EXPECT_NE(first_resource, fetched);
}

TEST_F(MemoryCacheCorrectnessTest, 302RedirectExplicitlyFreshMaxAge) {
  KURL redirect_url(kResourceURL);
  const char kRedirectTargetUrlString[] = "http://redirect-target.com";
  KURL redirect_target_url(kRedirectTargetUrlString);

  ResourceRequest request(redirect_url);
  request.SetRequestorOrigin(GetSecurityOrigin());
  MockResource* first_resource = MockResource::Create(request);

  ResourceResponse fresh302_response(redirect_url);
  fresh302_response.SetHTTPStatusCode(302);
  fresh302_response.SetHTTPHeaderField(http_names::kDate,
                                       kOriginalRequestDateAsString);
  fresh302_response.SetHTTPHeaderField(http_names::kCacheControl,
                                       "max-age=600");
  fresh302_response.SetHTTPHeaderField(http_names::kLocation,
                                       kRedirectTargetUrlString);

  // Add the redirect to our request.
  ResourceRequest redirect_request = ResourceRequest(redirect_target_url);
  redirect_request.SetRequestorOrigin(GetSecurityOrigin());
  first_resource->WillFollowRedirect(redirect_request, fresh302_response);

  // Add the final response to our request.
  ResourceResponse fresh200_response(redirect_target_url);
  fresh200_response.SetHTTPStatusCode(200);
  fresh200_response.SetHTTPHeaderField(http_names::kDate,
                                       kOriginalRequestDateAsString);
  fresh200_response.SetHTTPHeaderField(http_names::kExpires,
                                       kOneDayAfterOriginalRequest);

  first_resource->SetResponse(fresh200_response);
  first_resource->FinishForTest();
  AddResourceToMemoryCache(first_resource);

  AdvanceClock(500.);

  MockResource* fetched = FetchMockResource();
  EXPECT_EQ(first_resource, fetched);
}

TEST_F(MemoryCacheCorrectnessTest, 302RedirectExplicitlyFreshExpires) {
  KURL redirect_url(kResourceURL);
  const char kRedirectTargetUrlString[] = "http://redirect-target.com";
  KURL redirect_target_url(kRedirectTargetUrlString);

  ResourceRequest request(redirect_url);
  request.SetRequestorOrigin(GetSecurityOrigin());
  MockResource* first_resource = MockResource::Create(request);

  ResourceResponse fresh302_response(redirect_url);
  fresh302_response.SetHTTPStatusCode(302);
  fresh302_response.SetHTTPHeaderField(http_names::kDate,
                                       kOriginalRequestDateAsString);
  fresh302_response.SetHTTPHeaderField(http_names::kExpires,
                                       kOneDayAfterOriginalRequest);
  fresh302_response.SetHTTPHeaderField(http_names::kLocation,
                                       kRedirectTargetUrlString);

  // Add the redirect to our request.
  ResourceRequest redirect_request = ResourceRequest(redirect_target_url);
  first_resource->WillFollowRedirect(redirect_request, fresh302_response);

  // Add the final response to our request.
  ResourceResponse fresh200_response(redirect_target_url);
  fresh200_response.SetHTTPStatusCode(200);
  fresh200_response.SetHTTPHeaderField(http_names::kDate,
                                       kOriginalRequestDateAsString);
  fresh200_response.SetHTTPHeaderField(http_names::kExpires,
                                       kOneDayAfterOriginalRequest);

  first_resource->SetResponse(fresh200_response);
  first_resource->FinishForTest();
  AddResourceToMemoryCache(first_resource);

  AdvanceClock(500.);

  MockResource* fetched = FetchMockResource();
  EXPECT_EQ(first_resource, fetched);
}

}  // namespace blink
