// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "base/strings/stringprintf.h"
#include "base/test/test_simple_task_runner.h"
#include "base/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "chrome/browser/safe_browsing/chunk.pb.h"
#include "chrome/browser/safe_browsing/protocol_manager.h"
#include "chrome/browser/safe_browsing/safe_browsing_util.h"
#include "google_apis/google_api_keys.h"
#include "net/base/escape.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/url_request/test_url_fetcher_factory.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gmock_mutant.h"
#include "testing/gtest/include/gtest/gtest.h"

using base::Time;
using base::TimeDelta;
using testing::_;
using testing::Invoke;

namespace {

const char kUrlPrefix[] = "https://prefix.com/foo";
const char kBackupConnectUrlPrefix[] = "https://alt1-prefix.com/foo";
const char kBackupHttpUrlPrefix[] = "https://alt2-prefix.com/foo";
const char kBackupNetworkUrlPrefix[] = "https://alt3-prefix.com/foo";
const char kClient[] = "unittest";
const char kAppVer[] = "1.0";
const char kAdditionalQuery[] = "additional_query";

#if defined(OS_ANDROID)
const char kDefaultPhishList[] = "goog-mobilephish-shavar";
const char kDefaultMalwareList[] = "goog-mobilemalware-shavar";
#else
const char kDefaultPhishList[] = "goog-phish-shavar";
const char kDefaultMalwareList[] = "goog-malware-shavar";
#endif

// Add-prefix chunk with single prefix.
const char kRawChunkPayload1[] = {
  '\0', '\0', '\0', '\x08',  // 32-bit payload length in network byte order.
  '\x08',                    // field 1, wire format varint
  '\x03',                    // chunk_number varint 3
  '\x22',                    // field 4, wire format length-delimited
  '\x04',                    // varint 4 length
  'a', 'b', 'c', 'd'         // 4-byte prefix
};
const std::string kChunkPayload1(kRawChunkPayload1, sizeof(kRawChunkPayload1));

// Add-prefix chunk_number 5 with single prefix.
const char kRawChunkPayload2[] = {
  '\0', '\0', '\0', '\x08',  // 32-bit payload length in network byte order.
  '\x08',                    // field 1, wire format varint
  '\x05',                    // chunk_number varint 5
  '\x22',                    // field 4, wire format length-delimited
  '\x04',                    // varint length 4
  'e', 'f', 'g', 'h'         // 4-byte prefix
};
const std::string kChunkPayload2(kRawChunkPayload2, sizeof(kRawChunkPayload2));

}  // namespace

class SafeBrowsingProtocolManagerTest : public testing::Test {
 protected:
  std::string key_param_;

  void SetUp() override {
    std::string key = google_apis::GetAPIKey();
    if (!key.empty()) {
      key_param_ = base::StringPrintf(
          "&key=%s",
          net::EscapeQueryParamValue(key, true).c_str());
    }
  }

  scoped_ptr<SafeBrowsingProtocolManager> CreateProtocolManager(
      SafeBrowsingProtocolManagerDelegate* delegate) {
    SafeBrowsingProtocolConfig config;
    config.client_name = kClient;
    config.url_prefix = kUrlPrefix;
    config.backup_connect_error_url_prefix = kBackupConnectUrlPrefix;
    config.backup_http_error_url_prefix = kBackupHttpUrlPrefix;
    config.backup_network_error_url_prefix = kBackupNetworkUrlPrefix;
    config.version = kAppVer;
#if defined(OS_ANDROID)
    config.disable_connection_check = true;
#endif
    return scoped_ptr<SafeBrowsingProtocolManager>(
        SafeBrowsingProtocolManager::Create(delegate, NULL, config));
  }

  void ValidateUpdateFetcherRequest(
      const net::TestURLFetcher* url_fetcher,
      const std::string& expected_prefix) {
    ASSERT_TRUE(url_fetcher);
    EXPECT_EQ(net::LOAD_DISABLE_CACHE, url_fetcher->GetLoadFlags());

    std::string expected_lists(base::StringPrintf("%s;\n%s;\n",
                                                  kDefaultPhishList,
                                                  kDefaultMalwareList));
    EXPECT_EQ(expected_lists, url_fetcher->upload_data());
    EXPECT_EQ(GURL(expected_prefix + "/downloads?client=unittest&appver=1.0"
                   "&pver=3.0" + key_param_),
              url_fetcher->GetOriginalURL());
  }

  void ValidateUpdateFetcherRequest(const net::TestURLFetcher* url_fetcher) {
    ValidateUpdateFetcherRequest(url_fetcher, kUrlPrefix);
  }

  void ValidateRedirectFetcherRequest(const net::TestURLFetcher* url_fetcher,
                                      const std::string& expected_url) {
    ASSERT_TRUE(url_fetcher);
    EXPECT_EQ(net::LOAD_DISABLE_CACHE, url_fetcher->GetLoadFlags());
    EXPECT_EQ("", url_fetcher->upload_data());
    EXPECT_EQ(GURL(expected_url), url_fetcher->GetOriginalURL());
  }
};

// Ensure that we respect section 5 of the SafeBrowsing protocol specification.
TEST_F(SafeBrowsingProtocolManagerTest, TestBackOffTimes) {
  scoped_ptr<SafeBrowsingProtocolManager> pm(CreateProtocolManager(NULL));

  pm->next_update_interval_ = TimeDelta::FromSeconds(1800);
  ASSERT_TRUE(pm->back_off_fuzz_ >= 0.0 && pm->back_off_fuzz_ <= 1.0);

  TimeDelta next;

  // No errors received so far.
  next = pm->GetNextUpdateInterval(false);
  EXPECT_EQ(next, TimeDelta::FromSeconds(1800));

  // 1 error.
  next = pm->GetNextUpdateInterval(true);
  EXPECT_EQ(next, TimeDelta::FromSeconds(60));

  // 2 errors.
  next = pm->GetNextUpdateInterval(true);
  EXPECT_TRUE(next >= TimeDelta::FromMinutes(30) &&
              next <= TimeDelta::FromMinutes(60));

  // 3 errors.
  next = pm->GetNextUpdateInterval(true);
  EXPECT_TRUE(next >= TimeDelta::FromMinutes(60) &&
              next <= TimeDelta::FromMinutes(120));

  // 4 errors.
  next = pm->GetNextUpdateInterval(true);
  EXPECT_TRUE(next >= TimeDelta::FromMinutes(120) &&
              next <= TimeDelta::FromMinutes(240));

  // 5 errors.
  next = pm->GetNextUpdateInterval(true);
  EXPECT_TRUE(next >= TimeDelta::FromMinutes(240) &&
              next <= TimeDelta::FromMinutes(480));

  // 6 errors, reached max backoff.
  next = pm->GetNextUpdateInterval(true);
  EXPECT_EQ(next, TimeDelta::FromMinutes(480));

  // 7 errors.
  next = pm->GetNextUpdateInterval(true);
  EXPECT_EQ(next, TimeDelta::FromMinutes(480));

  // Received a successful response.
  next = pm->GetNextUpdateInterval(false);
  EXPECT_EQ(next, TimeDelta::FromSeconds(1800));
}

TEST_F(SafeBrowsingProtocolManagerTest, TestChunkStrings) {
  scoped_ptr<SafeBrowsingProtocolManager> pm(CreateProtocolManager(NULL));

  // Add and Sub chunks.
  SBListChunkRanges phish(kDefaultPhishList);
  phish.adds = "1,4,6,8-20,99";
  phish.subs = "16,32,64-96";
  EXPECT_EQ(base::StringPrintf("%s;a:1,4,6,8-20,99:s:16,32,64-96\n",
                               kDefaultPhishList),
            safe_browsing::FormatList(phish));

  // Add chunks only.
  phish.subs = "";
  EXPECT_EQ(base::StringPrintf("%s;a:1,4,6,8-20,99\n",
                               kDefaultPhishList),
            safe_browsing::FormatList(phish));

  // Sub chunks only.
  phish.adds = "";
  phish.subs = "16,32,64-96";
  EXPECT_EQ(base::StringPrintf("%s;s:16,32,64-96\n",
                               kDefaultPhishList),
            safe_browsing::FormatList(phish));

  // No chunks of either type.
  phish.adds = "";
  phish.subs = "";
  EXPECT_EQ(base::StringPrintf("%s;\n", kDefaultPhishList),
            safe_browsing::FormatList(phish));
}

TEST_F(SafeBrowsingProtocolManagerTest, TestGetHashBackOffTimes) {
  scoped_ptr<SafeBrowsingProtocolManager> pm(CreateProtocolManager(NULL));

  // No errors or back off time yet.
  EXPECT_EQ(0U, pm->gethash_error_count_);
  EXPECT_TRUE(pm->next_gethash_time_.is_null());

  Time now = Time::Now();

  // 1 error.
  pm->HandleGetHashError(now);
  EXPECT_EQ(1U, pm->gethash_error_count_);
  TimeDelta margin = TimeDelta::FromSeconds(5);  // Fudge factor.
  Time future = now + TimeDelta::FromMinutes(1);
  EXPECT_TRUE(pm->next_gethash_time_ >= future - margin &&
              pm->next_gethash_time_ <= future + margin);

  // 2 errors.
  pm->HandleGetHashError(now);
  EXPECT_EQ(2U, pm->gethash_error_count_);
  EXPECT_TRUE(pm->next_gethash_time_ >= now + TimeDelta::FromMinutes(30));
  EXPECT_TRUE(pm->next_gethash_time_ <= now + TimeDelta::FromMinutes(60));

  // 3 errors.
  pm->HandleGetHashError(now);
  EXPECT_EQ(3U, pm->gethash_error_count_);
  EXPECT_TRUE(pm->next_gethash_time_ >= now + TimeDelta::FromMinutes(60));
  EXPECT_TRUE(pm->next_gethash_time_ <= now + TimeDelta::FromMinutes(120));

  // 4 errors.
  pm->HandleGetHashError(now);
  EXPECT_EQ(4U, pm->gethash_error_count_);
  EXPECT_TRUE(pm->next_gethash_time_ >= now + TimeDelta::FromMinutes(120));
  EXPECT_TRUE(pm->next_gethash_time_ <= now + TimeDelta::FromMinutes(240));

  // 5 errors.
  pm->HandleGetHashError(now);
  EXPECT_EQ(5U, pm->gethash_error_count_);
  EXPECT_TRUE(pm->next_gethash_time_ >= now + TimeDelta::FromMinutes(240));
  EXPECT_TRUE(pm->next_gethash_time_ <= now + TimeDelta::FromMinutes(480));

  // 6 errors, reached max backoff.
  pm->HandleGetHashError(now);
  EXPECT_EQ(6U, pm->gethash_error_count_);
  EXPECT_TRUE(pm->next_gethash_time_ == now + TimeDelta::FromMinutes(480));

  // 7 errors.
  pm->HandleGetHashError(now);
  EXPECT_EQ(7U, pm->gethash_error_count_);
  EXPECT_TRUE(pm->next_gethash_time_== now + TimeDelta::FromMinutes(480));
}

TEST_F(SafeBrowsingProtocolManagerTest, TestGetHashUrl) {
  scoped_ptr<SafeBrowsingProtocolManager> pm(CreateProtocolManager(NULL));

  EXPECT_EQ("https://prefix.com/foo/gethash?client=unittest&appver=1.0&"
            "pver=3.0" + key_param_, pm->GetHashUrl().spec());

  pm->set_additional_query(kAdditionalQuery);
  EXPECT_EQ("https://prefix.com/foo/gethash?client=unittest&appver=1.0&"
            "pver=3.0" + key_param_ + "&additional_query",
            pm->GetHashUrl().spec());
}

TEST_F(SafeBrowsingProtocolManagerTest, TestUpdateUrl) {
  scoped_ptr<SafeBrowsingProtocolManager> pm(CreateProtocolManager(NULL));

  EXPECT_EQ("https://prefix.com/foo/downloads?client=unittest&appver=1.0&"
            "pver=3.0" + key_param_, pm->UpdateUrl().spec());

  pm->set_additional_query(kAdditionalQuery);
  EXPECT_EQ("https://prefix.com/foo/downloads?client=unittest&appver=1.0&"
            "pver=3.0" + key_param_ + "&additional_query",
            pm->UpdateUrl().spec());
}

TEST_F(SafeBrowsingProtocolManagerTest, TestNextChunkUrl) {
  scoped_ptr<SafeBrowsingProtocolManager> pm(CreateProtocolManager(NULL));

  std::string url_partial = "localhost:1234/foo/bar?foo";
  std::string url_http_full = "http://localhost:1234/foo/bar?foo";
  std::string url_https_full = "https://localhost:1234/foo/bar?foo";
  std::string url_https_no_query = "https://localhost:1234/foo/bar";

  EXPECT_EQ("https://localhost:1234/foo/bar?foo",
            pm->NextChunkUrl(url_partial).spec());
  EXPECT_EQ("http://localhost:1234/foo/bar?foo",
            pm->NextChunkUrl(url_http_full).spec());
  EXPECT_EQ("https://localhost:1234/foo/bar?foo",
            pm->NextChunkUrl(url_https_full).spec());
  EXPECT_EQ("https://localhost:1234/foo/bar",
            pm->NextChunkUrl(url_https_no_query).spec());

  pm->set_additional_query(kAdditionalQuery);
  EXPECT_EQ("https://localhost:1234/foo/bar?foo&additional_query",
            pm->NextChunkUrl(url_partial).spec());
  EXPECT_EQ("http://localhost:1234/foo/bar?foo&additional_query",
            pm->NextChunkUrl(url_http_full).spec());
  EXPECT_EQ("https://localhost:1234/foo/bar?foo&additional_query",
            pm->NextChunkUrl(url_https_full).spec());
  EXPECT_EQ("https://localhost:1234/foo/bar?additional_query",
            pm->NextChunkUrl(url_https_no_query).spec());
}

namespace {

class MockProtocolDelegate : public SafeBrowsingProtocolManagerDelegate {
 public:
  MockProtocolDelegate() {}
  ~MockProtocolDelegate() override {}

  MOCK_METHOD0(UpdateStarted, void());
  MOCK_METHOD1(UpdateFinished, void(bool));
  MOCK_METHOD0(ResetDatabase, void());
  MOCK_METHOD1(GetChunks, void(GetChunksCallback));

  // gmock does not work with scoped_ptr<> at this time.  Add a local method to
  // mock, then call that from an override.  Beware of object ownership when
  // making changes here.
  MOCK_METHOD3(AddChunksRaw, void(const std::string& lists,
                                  const ScopedVector<SBChunkData>& chunks,
                                  AddChunksCallback));
  void AddChunks(const std::string& list,
                 scoped_ptr<ScopedVector<SBChunkData>> chunks,
                 AddChunksCallback callback) override {
    AddChunksRaw(list, *chunks, callback);
  }

  // TODO(shess): Actually test this case somewhere.
  MOCK_METHOD1(DeleteChunksRaw,
               void(const std::vector<SBChunkDelete>& chunk_deletes));
  void DeleteChunks(
      scoped_ptr<std::vector<SBChunkDelete>> chunk_deletes) override {
    DeleteChunksRaw(*chunk_deletes);
  }
};

// |InvokeGetChunksCallback| is required because GMock's InvokeArgument action
// expects to use operator(), and a Callback only provides Run().
// TODO(cbentzel): Use ACTION or ACTION_TEMPLATE instead?
void InvokeGetChunksCallback(
    const std::vector<SBListChunkRanges>& ranges,
    bool database_error,
    SafeBrowsingProtocolManagerDelegate::GetChunksCallback callback) {
  callback.Run(ranges, database_error);
}

// |HandleAddChunks| deletes the chunks and asynchronously invokes
// |callback| since SafeBrowsingProtocolManager is not re-entrant at the time
// this is called. This guarantee is part of the
// SafeBrowsingProtocolManagerDelegate contract.
void HandleAddChunks(
    const std::string& unused_list,
    const ScopedVector<SBChunkData>& chunks,
    SafeBrowsingProtocolManagerDelegate::AddChunksCallback callback) {
  scoped_refptr<base::SingleThreadTaskRunner> task_runner(
      base::ThreadTaskRunnerHandle::Get());
  if (!task_runner.get())
    return;
  task_runner->PostTask(FROM_HERE, callback);
}

}  // namespace

// Tests that the Update protocol will be skipped if there are problems
// accessing the database.
TEST_F(SafeBrowsingProtocolManagerTest, ProblemAccessingDatabase) {
  scoped_refptr<base::TestSimpleTaskRunner> runner(
      new base::TestSimpleTaskRunner());
  base::ThreadTaskRunnerHandle runner_handler(runner);

  testing::StrictMock<MockProtocolDelegate> test_delegate;
  EXPECT_CALL(test_delegate, UpdateStarted()).Times(1);
  EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce(
      Invoke(testing::CreateFunctor(InvokeGetChunksCallback,
                                    std::vector<SBListChunkRanges>(),
                                    true)));
  EXPECT_CALL(test_delegate, UpdateFinished(false)).Times(1);

  scoped_ptr<SafeBrowsingProtocolManager> pm(
      CreateProtocolManager(&test_delegate));

  pm->ForceScheduleNextUpdate(TimeDelta());
  runner->RunPendingTasks();

  EXPECT_TRUE(pm->IsUpdateScheduled());
}

// Tests the contents of the POST body when there are contents in the
// local database. This is not exhaustive, as the actual list formatting
// is covered by SafeBrowsingProtocolManagerTest.TestChunkStrings.
TEST_F(SafeBrowsingProtocolManagerTest, ExistingDatabase) {
  scoped_refptr<base::TestSimpleTaskRunner> runner(
      new base::TestSimpleTaskRunner());
  base::ThreadTaskRunnerHandle runner_handler(runner);
  net::TestURLFetcherFactory url_fetcher_factory;

  std::vector<SBListChunkRanges> ranges;
  SBListChunkRanges range_phish(safe_browsing_util::kPhishingList);
  range_phish.adds = "adds_phish";
  range_phish.subs = "subs_phish";
  ranges.push_back(range_phish);

  SBListChunkRanges range_unknown("unknown_list");
  range_unknown.adds = "adds_unknown";
  range_unknown.subs = "subs_unknown";
  ranges.push_back(range_unknown);

  testing::StrictMock<MockProtocolDelegate> test_delegate;
  EXPECT_CALL(test_delegate, UpdateStarted()).Times(1);
  EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce(
      Invoke(testing::CreateFunctor(InvokeGetChunksCallback,
                                    ranges,
                                    false)));
  EXPECT_CALL(test_delegate, UpdateFinished(true)).Times(1);

  scoped_ptr<SafeBrowsingProtocolManager> pm(
      CreateProtocolManager(&test_delegate));

  // Kick off initialization. This returns chunks from the DB synchronously.
  pm->ForceScheduleNextUpdate(TimeDelta());
  runner->RunPendingTasks();

  // We should have an URLFetcher at this point in time.
  net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0);
  ASSERT_TRUE(url_fetcher);
  EXPECT_EQ(net::LOAD_DISABLE_CACHE, url_fetcher->GetLoadFlags());
  EXPECT_EQ(base::StringPrintf("%s;a:adds_phish:s:subs_phish\n"
                               "unknown_list;a:adds_unknown:s:subs_unknown\n"
                               "%s;\n",
                               kDefaultPhishList, kDefaultMalwareList),
            url_fetcher->upload_data());
  EXPECT_EQ(GURL("https://prefix.com/foo/downloads?client=unittest&appver=1.0"
                 "&pver=3.0" + key_param_),
            url_fetcher->GetOriginalURL());

  url_fetcher->set_status(net::URLRequestStatus());
  url_fetcher->set_response_code(200);
  url_fetcher->SetResponseString(std::string());
  url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);

  EXPECT_TRUE(pm->IsUpdateScheduled());
}

TEST_F(SafeBrowsingProtocolManagerTest, UpdateResponseBadBodyBackupSuccess) {
  scoped_refptr<base::TestSimpleTaskRunner> runner(
      new base::TestSimpleTaskRunner());
  base::ThreadTaskRunnerHandle runner_handler(runner);
  net::TestURLFetcherFactory url_fetcher_factory;

  testing::StrictMock<MockProtocolDelegate> test_delegate;
  EXPECT_CALL(test_delegate, UpdateStarted()).Times(1);
  EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce(
      Invoke(testing::CreateFunctor(InvokeGetChunksCallback,
                                    std::vector<SBListChunkRanges>(),
                                    false)));
  EXPECT_CALL(test_delegate, UpdateFinished(true)).Times(1);

  scoped_ptr<SafeBrowsingProtocolManager> pm(
      CreateProtocolManager(&test_delegate));

  // Kick off initialization. This returns chunks from the DB synchronously.
  pm->ForceScheduleNextUpdate(TimeDelta());
  runner->RunPendingTasks();

  // We should have an URLFetcher at this point in time.
  net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0);
  ValidateUpdateFetcherRequest(url_fetcher);

  // The update response is successful, but an invalid body.
  url_fetcher->set_status(net::URLRequestStatus());
  url_fetcher->set_response_code(200);
  url_fetcher->SetResponseString("THIS_IS_A_BAD_RESPONSE");
  url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);

  // There should now be a backup request.
  net::TestURLFetcher* backup_url_fetcher =
      url_fetcher_factory.GetFetcherByID(1);
  ValidateUpdateFetcherRequest(backup_url_fetcher,
                               kBackupHttpUrlPrefix);

  // Respond to the backup successfully.
  backup_url_fetcher->set_status(net::URLRequestStatus());
  backup_url_fetcher->set_response_code(200);
  backup_url_fetcher->SetResponseString(std::string());
  backup_url_fetcher->delegate()->OnURLFetchComplete(backup_url_fetcher);

  EXPECT_TRUE(pm->IsUpdateScheduled());
}

// Tests what happens when there is an HTTP error response to the update
// request, as well as an error response to the backup update request.
TEST_F(SafeBrowsingProtocolManagerTest, UpdateResponseHttpErrorBackupError) {
  scoped_refptr<base::TestSimpleTaskRunner> runner(
      new base::TestSimpleTaskRunner());
  base::ThreadTaskRunnerHandle runner_handler(runner);
  net::TestURLFetcherFactory url_fetcher_factory;

  testing::StrictMock<MockProtocolDelegate> test_delegate;
  EXPECT_CALL(test_delegate, UpdateStarted()).Times(1);
  EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce(
      Invoke(testing::CreateFunctor(InvokeGetChunksCallback,
                                    std::vector<SBListChunkRanges>(),
                                    false)));
  EXPECT_CALL(test_delegate, UpdateFinished(false)).Times(1);

  scoped_ptr<SafeBrowsingProtocolManager> pm(
      CreateProtocolManager(&test_delegate));

  // Kick off initialization. This returns chunks from the DB synchronously.
  pm->ForceScheduleNextUpdate(TimeDelta());
  runner->RunPendingTasks();

  // We should have an URLFetcher at this point in time.
  net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0);
  ValidateUpdateFetcherRequest(url_fetcher);

  // Go ahead and respond to it.
  url_fetcher->set_status(net::URLRequestStatus());
  url_fetcher->set_response_code(404);
  url_fetcher->SetResponseString(std::string());
  url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);

  // There should now be a backup request.
  net::TestURLFetcher* backup_url_fetcher =
      url_fetcher_factory.GetFetcherByID(1);
  ValidateUpdateFetcherRequest(backup_url_fetcher, kBackupHttpUrlPrefix);

  // Respond to the backup unsuccessfully.
  backup_url_fetcher->set_status(net::URLRequestStatus());
  backup_url_fetcher->set_response_code(404);
  backup_url_fetcher->SetResponseString(std::string());
  backup_url_fetcher->delegate()->OnURLFetchComplete(backup_url_fetcher);

  EXPECT_TRUE(pm->IsUpdateScheduled());
}

// Tests what happens when there is an HTTP error response to the update
// request, followed by a successful response to the backup update request.
TEST_F(SafeBrowsingProtocolManagerTest, UpdateResponseHttpErrorBackupSuccess) {
  scoped_refptr<base::TestSimpleTaskRunner> runner(
      new base::TestSimpleTaskRunner());
  base::ThreadTaskRunnerHandle runner_handler(runner);
  net::TestURLFetcherFactory url_fetcher_factory;

  testing::StrictMock<MockProtocolDelegate> test_delegate;
  EXPECT_CALL(test_delegate, UpdateStarted()).Times(1);
  EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce(
      Invoke(testing::CreateFunctor(InvokeGetChunksCallback,
                                    std::vector<SBListChunkRanges>(),
                                    false)));
  EXPECT_CALL(test_delegate, UpdateFinished(true)).Times(1);

  scoped_ptr<SafeBrowsingProtocolManager> pm(
      CreateProtocolManager(&test_delegate));

  // Kick off initialization. This returns chunks from the DB synchronously.
  pm->ForceScheduleNextUpdate(TimeDelta());
  runner->RunPendingTasks();

  // We should have an URLFetcher at this point in time.
  net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0);
  ValidateUpdateFetcherRequest(url_fetcher);

  // Go ahead and respond to it.
  url_fetcher->set_status(net::URLRequestStatus());
  url_fetcher->set_response_code(404);
  url_fetcher->SetResponseString(std::string());
  url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);

  // There should now be a backup request.
  net::TestURLFetcher* backup_url_fetcher =
      url_fetcher_factory.GetFetcherByID(1);
  ValidateUpdateFetcherRequest(backup_url_fetcher,
                               kBackupHttpUrlPrefix);

  // Respond to the backup successfully.
  backup_url_fetcher->set_status(net::URLRequestStatus());
  backup_url_fetcher->set_response_code(200);
  backup_url_fetcher->SetResponseString(std::string());
  backup_url_fetcher->delegate()->OnURLFetchComplete(backup_url_fetcher);

  EXPECT_TRUE(pm->IsUpdateScheduled());
}

// Tests what happens when there is an HTTP error response to the update
// request, and a timeout on the backup update request.
TEST_F(SafeBrowsingProtocolManagerTest, UpdateResponseHttpErrorBackupTimeout) {
  scoped_refptr<base::TestSimpleTaskRunner> runner(
      new base::TestSimpleTaskRunner());
  base::ThreadTaskRunnerHandle runner_handler(runner);
  net::TestURLFetcherFactory url_fetcher_factory;

  testing::StrictMock<MockProtocolDelegate> test_delegate;
  EXPECT_CALL(test_delegate, UpdateStarted()).Times(1);
  EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce(
      Invoke(testing::CreateFunctor(InvokeGetChunksCallback,
                                    std::vector<SBListChunkRanges>(),
                                    false)));
  EXPECT_CALL(test_delegate, UpdateFinished(false)).Times(1);

  scoped_ptr<SafeBrowsingProtocolManager> pm(
      CreateProtocolManager(&test_delegate));

  // Kick off initialization. This returns chunks from the DB synchronously.
  pm->ForceScheduleNextUpdate(TimeDelta());
  runner->RunPendingTasks();

  // We should have an URLFetcher at this point in time.
  net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0);
  ValidateUpdateFetcherRequest(url_fetcher);

  // Go ahead and respond to it.
  url_fetcher->set_status(net::URLRequestStatus());
  url_fetcher->set_response_code(404);
  url_fetcher->SetResponseString(std::string());
  url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);

  // There should now be a backup request.
  net::TestURLFetcher* backup_url_fetcher =
      url_fetcher_factory.GetFetcherByID(1);
  ValidateUpdateFetcherRequest(backup_url_fetcher, kBackupHttpUrlPrefix);

  // Either one or two calls to RunPendingTasks are needed here. The first run
  // of RunPendingTasks will run the canceled timeout task associated with
  // the first Update request. Depending on timing, this will either directly
  // call the timeout task from the backup request, or schedule another task
  // to run that in the future.
  // TODO(cbentzel): Less fragile approach.
  runner->RunPendingTasks();
  if (!pm->IsUpdateScheduled())
    runner->RunPendingTasks();
  EXPECT_TRUE(pm->IsUpdateScheduled());
}

// Tests what happens when there is a connection error when issuing the update
// request, and an error with the backup update request.
TEST_F(SafeBrowsingProtocolManagerTest,
       UpdateResponseConnectionErrorBackupError) {
  scoped_refptr<base::TestSimpleTaskRunner> runner(
      new base::TestSimpleTaskRunner());
  base::ThreadTaskRunnerHandle runner_handler(runner);
  net::TestURLFetcherFactory url_fetcher_factory;

  testing::StrictMock<MockProtocolDelegate> test_delegate;
  EXPECT_CALL(test_delegate, UpdateStarted()).Times(1);
  EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce(
      Invoke(testing::CreateFunctor(InvokeGetChunksCallback,
                                    std::vector<SBListChunkRanges>(),
                                    false)));
  EXPECT_CALL(test_delegate, UpdateFinished(false)).Times(1);

  scoped_ptr<SafeBrowsingProtocolManager> pm(
      CreateProtocolManager(&test_delegate));

  // Kick off initialization. This returns chunks from the DB synchronously.
  pm->ForceScheduleNextUpdate(TimeDelta());
  runner->RunPendingTasks();

  // We should have an URLFetcher at this point in time.
  net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0);
  ValidateUpdateFetcherRequest(url_fetcher);

  // Go ahead and respond to it.
  url_fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::FAILED,
                                                net::ERR_CONNECTION_RESET));
  url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);

  // There should be a backup URLFetcher now.
  net::TestURLFetcher* backup_url_fetcher =
      url_fetcher_factory.GetFetcherByID(1);
  ValidateUpdateFetcherRequest(backup_url_fetcher,
                               kBackupConnectUrlPrefix);

  // Respond to the backup unsuccessfully.
  backup_url_fetcher->set_status(net::URLRequestStatus());
  backup_url_fetcher->set_response_code(404);
  backup_url_fetcher->SetResponseString(std::string());
  backup_url_fetcher->delegate()->OnURLFetchComplete(backup_url_fetcher);

  EXPECT_TRUE(pm->IsUpdateScheduled());
}

// Tests what happens when there is a connection error when issuing the update
// request, and a successful response to the backup update request.
TEST_F(SafeBrowsingProtocolManagerTest,
       UpdateResponseConnectionErrorBackupSuccess) {
  scoped_refptr<base::TestSimpleTaskRunner> runner(
      new base::TestSimpleTaskRunner());
  base::ThreadTaskRunnerHandle runner_handler(runner);
  net::TestURLFetcherFactory url_fetcher_factory;

  testing::StrictMock<MockProtocolDelegate> test_delegate;
  EXPECT_CALL(test_delegate, UpdateStarted()).Times(1);
  EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce(
      Invoke(testing::CreateFunctor(InvokeGetChunksCallback,
                                    std::vector<SBListChunkRanges>(),
                                    false)));
  EXPECT_CALL(test_delegate, UpdateFinished(true)).Times(1);

  scoped_ptr<SafeBrowsingProtocolManager> pm(
      CreateProtocolManager(&test_delegate));

  // Kick off initialization. This returns chunks from the DB synchronously.
  pm->ForceScheduleNextUpdate(TimeDelta());
  runner->RunPendingTasks();

  // We should have an URLFetcher at this point in time.
  net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0);
  ValidateUpdateFetcherRequest(url_fetcher);

  // Go ahead and respond to it.
  url_fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::FAILED,
                                                net::ERR_CONNECTION_RESET));
  url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);

  // There should be a backup URLFetcher now.
  net::TestURLFetcher* backup_url_fetcher =
      url_fetcher_factory.GetFetcherByID(1);
  ValidateUpdateFetcherRequest(backup_url_fetcher,
                               kBackupConnectUrlPrefix);

  // Respond to the backup unsuccessfully.
  backup_url_fetcher->set_status(net::URLRequestStatus());
  backup_url_fetcher->set_response_code(200);
  backup_url_fetcher->SetResponseString(std::string());
  backup_url_fetcher->delegate()->OnURLFetchComplete(backup_url_fetcher);

  EXPECT_TRUE(pm->IsUpdateScheduled());
}
// Tests what happens when there is a network state error when issuing the
// update request, and an error with the backup update request.
TEST_F(SafeBrowsingProtocolManagerTest,
       UpdateResponseNetworkErrorBackupError) {
  scoped_refptr<base::TestSimpleTaskRunner> runner(
      new base::TestSimpleTaskRunner());
  base::ThreadTaskRunnerHandle runner_handler(runner);
  net::TestURLFetcherFactory url_fetcher_factory;

  testing::StrictMock<MockProtocolDelegate> test_delegate;
  EXPECT_CALL(test_delegate, UpdateStarted()).Times(1);
  EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce(
      Invoke(testing::CreateFunctor(InvokeGetChunksCallback,
                                    std::vector<SBListChunkRanges>(),
                                    false)));
  EXPECT_CALL(test_delegate, UpdateFinished(false)).Times(1);

  scoped_ptr<SafeBrowsingProtocolManager> pm(
      CreateProtocolManager(&test_delegate));

  // Kick off initialization. This returns chunks from the DB synchronously.
  pm->ForceScheduleNextUpdate(TimeDelta());
  runner->RunPendingTasks();

  // We should have an URLFetcher at this point in time.
  net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0);
  ValidateUpdateFetcherRequest(url_fetcher);

  // Go ahead and respond to it.
  url_fetcher->set_status(
      net::URLRequestStatus(net::URLRequestStatus::FAILED,
                            net::ERR_INTERNET_DISCONNECTED));
  url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);

  // There should be a backup URLFetcher now.
  net::TestURLFetcher* backup_url_fetcher =
      url_fetcher_factory.GetFetcherByID(1);
  ValidateUpdateFetcherRequest(backup_url_fetcher,
                               kBackupNetworkUrlPrefix);

  // Respond to the backup unsuccessfully.
  backup_url_fetcher->set_status(net::URLRequestStatus());
  backup_url_fetcher->set_response_code(404);
  backup_url_fetcher->SetResponseString(std::string());
  backup_url_fetcher->delegate()->OnURLFetchComplete(backup_url_fetcher);

  EXPECT_TRUE(pm->IsUpdateScheduled());
}

// Tests what happens when there is a network state error when issuing the
// update request, and a successful response to the backup update request.
TEST_F(SafeBrowsingProtocolManagerTest,
       UpdateResponseNetworkErrorBackupSuccess) {
  scoped_refptr<base::TestSimpleTaskRunner> runner(
      new base::TestSimpleTaskRunner());
  base::ThreadTaskRunnerHandle runner_handler(runner);
  net::TestURLFetcherFactory url_fetcher_factory;

  testing::StrictMock<MockProtocolDelegate> test_delegate;
  EXPECT_CALL(test_delegate, UpdateStarted()).Times(1);
  EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce(
      Invoke(testing::CreateFunctor(InvokeGetChunksCallback,
                                    std::vector<SBListChunkRanges>(),
                                    false)));
  EXPECT_CALL(test_delegate, UpdateFinished(true)).Times(1);

  scoped_ptr<SafeBrowsingProtocolManager> pm(
      CreateProtocolManager(&test_delegate));

  // Kick off initialization. This returns chunks from the DB synchronously.
  pm->ForceScheduleNextUpdate(TimeDelta());
  runner->RunPendingTasks();

  // We should have an URLFetcher at this point in time.
  net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0);
  ValidateUpdateFetcherRequest(url_fetcher);

  // Go ahead and respond to it.
  url_fetcher->set_status(
      net::URLRequestStatus(net::URLRequestStatus::FAILED,
                            net::ERR_INTERNET_DISCONNECTED));
  url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);

  // There should be a backup URLFetcher now.
  net::TestURLFetcher* backup_url_fetcher =
      url_fetcher_factory.GetFetcherByID(1);
  ValidateUpdateFetcherRequest(backup_url_fetcher,
                               kBackupNetworkUrlPrefix);

  // Respond to the backup unsuccessfully.
  backup_url_fetcher->set_status(net::URLRequestStatus());
  backup_url_fetcher->set_response_code(200);
  backup_url_fetcher->SetResponseString(std::string());
  backup_url_fetcher->delegate()->OnURLFetchComplete(backup_url_fetcher);

  EXPECT_TRUE(pm->IsUpdateScheduled());
}

// Tests what happens when there is a timeout before an update response.
TEST_F(SafeBrowsingProtocolManagerTest, UpdateResponseTimeoutBackupSuccess) {
  scoped_refptr<base::TestSimpleTaskRunner> runner(
      new base::TestSimpleTaskRunner());
  base::ThreadTaskRunnerHandle runner_handler(runner);
  net::TestURLFetcherFactory url_fetcher_factory;

  testing::StrictMock<MockProtocolDelegate> test_delegate;
  EXPECT_CALL(test_delegate, UpdateStarted()).Times(1);
  EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce(
      Invoke(testing::CreateFunctor(InvokeGetChunksCallback,
                                    std::vector<SBListChunkRanges>(),
                                    false)));
  EXPECT_CALL(test_delegate, UpdateFinished(true)).Times(1);

  scoped_ptr<SafeBrowsingProtocolManager> pm(
      CreateProtocolManager(&test_delegate));

  // Kick off initialization. This returns chunks from the DB synchronously.
  pm->ForceScheduleNextUpdate(TimeDelta());
  runner->RunPendingTasks();

  // We should have an URLFetcher at this point in time.
  net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0);
  ValidateUpdateFetcherRequest(url_fetcher);

  // The first time RunPendingTasks is called above, the update timeout timer is
  // not handled. This call of RunPendingTasks will handle the update.
  runner->RunPendingTasks();

  // There should be a backup URLFetcher now.
  net::TestURLFetcher* backup_url_fetcher =
      url_fetcher_factory.GetFetcherByID(1);
  ValidateUpdateFetcherRequest(backup_url_fetcher,
                               kBackupConnectUrlPrefix);

  // Respond to the backup unsuccessfully.
  backup_url_fetcher->set_status(net::URLRequestStatus());
  backup_url_fetcher->set_response_code(200);
  backup_url_fetcher->SetResponseString(std::string());
  backup_url_fetcher->delegate()->OnURLFetchComplete(backup_url_fetcher);

  EXPECT_TRUE(pm->IsUpdateScheduled());
}

// Tests what happens when there is a reset command in the response.
TEST_F(SafeBrowsingProtocolManagerTest, UpdateResponseReset) {
  scoped_refptr<base::TestSimpleTaskRunner> runner(
      new base::TestSimpleTaskRunner());
  base::ThreadTaskRunnerHandle runner_handler(runner);
  net::TestURLFetcherFactory url_fetcher_factory;

  testing::StrictMock<MockProtocolDelegate> test_delegate;
  EXPECT_CALL(test_delegate, UpdateStarted()).Times(1);
  EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce(
      Invoke(testing::CreateFunctor(InvokeGetChunksCallback,
                                    std::vector<SBListChunkRanges>(),
                                    false)));
  EXPECT_CALL(test_delegate, ResetDatabase()).Times(1);
  EXPECT_CALL(test_delegate, UpdateFinished(true)).Times(1);

  scoped_ptr<SafeBrowsingProtocolManager> pm(
      CreateProtocolManager(&test_delegate));

  // Kick off initialization. This returns chunks from the DB synchronously.
  pm->ForceScheduleNextUpdate(TimeDelta());
  runner->RunPendingTasks();

  net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0);
  ValidateUpdateFetcherRequest(url_fetcher);

  // The update response is successful, and has a reset command.
  url_fetcher->set_status(net::URLRequestStatus());
  url_fetcher->set_response_code(200);
  url_fetcher->SetResponseString("r:pleasereset\n");
  url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);

  EXPECT_TRUE(pm->IsUpdateScheduled());
}

// Tests a single valid update response, followed by a single redirect response
// that has an valid, but empty body.
TEST_F(SafeBrowsingProtocolManagerTest, EmptyRedirectResponse) {
  scoped_refptr<base::TestSimpleTaskRunner> runner(
      new base::TestSimpleTaskRunner());
  base::ThreadTaskRunnerHandle runner_handler(runner);
  net::TestURLFetcherFactory url_fetcher_factory;

  testing::StrictMock<MockProtocolDelegate> test_delegate;
  EXPECT_CALL(test_delegate, UpdateStarted()).Times(1);
  EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce(
      Invoke(testing::CreateFunctor(InvokeGetChunksCallback,
                                    std::vector<SBListChunkRanges>(),
                                    false)));
  EXPECT_CALL(test_delegate, UpdateFinished(true)).Times(1);

  scoped_ptr<SafeBrowsingProtocolManager> pm(
      CreateProtocolManager(&test_delegate));

  // Kick off initialization. This returns chunks from the DB synchronously.
  pm->ForceScheduleNextUpdate(TimeDelta());
  runner->RunPendingTasks();

  // The update response contains a single redirect command.
  net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0);
  ValidateUpdateFetcherRequest(url_fetcher);
  url_fetcher->set_status(net::URLRequestStatus());
  url_fetcher->set_response_code(200);
  url_fetcher->SetResponseString(
      base::StringPrintf("i:%s\n"
                         "u:redirect-server.example.com/path\n",
                         kDefaultPhishList));
  url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);

  // The redirect response contains an empty body.
  net::TestURLFetcher* chunk_url_fetcher =
      url_fetcher_factory.GetFetcherByID(1);
  ValidateRedirectFetcherRequest(
      chunk_url_fetcher, "https://redirect-server.example.com/path");
  chunk_url_fetcher->set_status(net::URLRequestStatus());
  chunk_url_fetcher->set_response_code(200);
  chunk_url_fetcher->SetResponseString(std::string());
  chunk_url_fetcher->delegate()->OnURLFetchComplete(chunk_url_fetcher);

  EXPECT_TRUE(pm->IsUpdateScheduled());
}

// Tests a single valid update response, followed by a single redirect response
// that has an invalid body.
TEST_F(SafeBrowsingProtocolManagerTest, InvalidRedirectResponse) {
  scoped_refptr<base::TestSimpleTaskRunner> runner(
      new base::TestSimpleTaskRunner());
  base::ThreadTaskRunnerHandle runner_handler(runner);
  net::TestURLFetcherFactory url_fetcher_factory;

  testing::StrictMock<MockProtocolDelegate> test_delegate;
  EXPECT_CALL(test_delegate, UpdateStarted()).Times(1);
  EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce(
      Invoke(testing::CreateFunctor(InvokeGetChunksCallback,
                                    std::vector<SBListChunkRanges>(),
                                    false)));
  EXPECT_CALL(test_delegate, UpdateFinished(false)).Times(1);

  scoped_ptr<SafeBrowsingProtocolManager> pm(
      CreateProtocolManager(&test_delegate));

  // Kick off initialization. This returns chunks from the DB synchronously.
  pm->ForceScheduleNextUpdate(TimeDelta());
  runner->RunPendingTasks();

  // The update response contains a single redirect command.
  net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0);
  ValidateUpdateFetcherRequest(url_fetcher);
  url_fetcher->set_status(net::URLRequestStatus());
  url_fetcher->set_response_code(200);
  url_fetcher->SetResponseString(
      base::StringPrintf("i:%s\n"
                         "u:redirect-server.example.com/path\n",
                         kDefaultPhishList));
  url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);

  // The redirect response contains an invalid body.
  net::TestURLFetcher* chunk_url_fetcher =
      url_fetcher_factory.GetFetcherByID(1);
  ValidateRedirectFetcherRequest(
      chunk_url_fetcher, "https://redirect-server.example.com/path");
  chunk_url_fetcher->set_status(net::URLRequestStatus());
  chunk_url_fetcher->set_response_code(200);
  chunk_url_fetcher->SetResponseString("THIS IS AN INVALID RESPONSE");
  chunk_url_fetcher->delegate()->OnURLFetchComplete(chunk_url_fetcher);

  EXPECT_TRUE(pm->IsUpdateScheduled());
}

// Tests a single valid update response, followed by a single redirect response
// containing chunks.
TEST_F(SafeBrowsingProtocolManagerTest, SingleRedirectResponseWithChunks) {
  scoped_refptr<base::TestSimpleTaskRunner> runner(
      new base::TestSimpleTaskRunner());
  base::ThreadTaskRunnerHandle runner_handler(runner);
  net::TestURLFetcherFactory url_fetcher_factory;

  testing::StrictMock<MockProtocolDelegate> test_delegate;
  EXPECT_CALL(test_delegate, UpdateStarted()).Times(1);
  EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce(
      Invoke(testing::CreateFunctor(InvokeGetChunksCallback,
                                    std::vector<SBListChunkRanges>(),
                                    false)));
  EXPECT_CALL(test_delegate, AddChunksRaw(kDefaultPhishList, _, _)).WillOnce(
      Invoke(HandleAddChunks));
  EXPECT_CALL(test_delegate, UpdateFinished(true)).Times(1);

  scoped_ptr<SafeBrowsingProtocolManager> pm(
      CreateProtocolManager(&test_delegate));

  // Kick off initialization. This returns chunks from the DB synchronously.
  pm->ForceScheduleNextUpdate(TimeDelta());
  runner->RunPendingTasks();

  // The update response contains a single redirect command.
  net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0);
  ValidateUpdateFetcherRequest(url_fetcher);
  url_fetcher->set_status(net::URLRequestStatus());
  url_fetcher->set_response_code(200);
  url_fetcher->SetResponseString(
      base::StringPrintf("i:%s\n"
                         "u:redirect-server.example.com/path\n",
                         kDefaultPhishList));
  url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);

  // The redirect response contains a single chunk.
  net::TestURLFetcher* chunk_url_fetcher =
      url_fetcher_factory.GetFetcherByID(1);
  ValidateRedirectFetcherRequest(
      chunk_url_fetcher, "https://redirect-server.example.com/path");
  chunk_url_fetcher->set_status(net::URLRequestStatus());
  chunk_url_fetcher->set_response_code(200);
  chunk_url_fetcher->SetResponseString(kChunkPayload1);
  chunk_url_fetcher->delegate()->OnURLFetchComplete(chunk_url_fetcher);

  EXPECT_FALSE(pm->IsUpdateScheduled());

  // The AddChunksCallback needs to be invoked.
  runner->RunPendingTasks();

  EXPECT_TRUE(pm->IsUpdateScheduled());
}

// Tests a single valid update response, followed by multiple redirect responses
// containing chunks.
TEST_F(SafeBrowsingProtocolManagerTest, MultipleRedirectResponsesWithChunks) {
  scoped_refptr<base::TestSimpleTaskRunner> runner(
      new base::TestSimpleTaskRunner());
  base::ThreadTaskRunnerHandle runner_handler(runner);
  net::TestURLFetcherFactory url_fetcher_factory;

  testing::StrictMock<MockProtocolDelegate> test_delegate;
  EXPECT_CALL(test_delegate, UpdateStarted()).Times(1);
  EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce(
      Invoke(testing::CreateFunctor(InvokeGetChunksCallback,
                                    std::vector<SBListChunkRanges>(),
                                    false)));
  EXPECT_CALL(test_delegate, AddChunksRaw(kDefaultPhishList, _, _)).
      WillRepeatedly(Invoke(HandleAddChunks));
  EXPECT_CALL(test_delegate, UpdateFinished(true)).Times(1);

  scoped_ptr<SafeBrowsingProtocolManager> pm(
      CreateProtocolManager(&test_delegate));

  // Kick off initialization. This returns chunks from the DB synchronously.
  pm->ForceScheduleNextUpdate(TimeDelta());
  runner->RunPendingTasks();

  // The update response contains multiple redirect commands.
  net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0);
  ValidateUpdateFetcherRequest(url_fetcher);
  url_fetcher->set_status(net::URLRequestStatus());
  url_fetcher->set_response_code(200);
  url_fetcher->SetResponseString(
      base::StringPrintf("i:%s\n"
                         "u:redirect-server.example.com/one\n"
                         "u:redirect-server.example.com/two\n",
                         kDefaultPhishList));
  url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);

  // The first redirect response contains a single chunk.
  net::TestURLFetcher* first_chunk_url_fetcher =
      url_fetcher_factory.GetFetcherByID(1);
  ValidateRedirectFetcherRequest(
      first_chunk_url_fetcher, "https://redirect-server.example.com/one");
  first_chunk_url_fetcher->set_status(net::URLRequestStatus());
  first_chunk_url_fetcher->set_response_code(200);
  first_chunk_url_fetcher->SetResponseString(kChunkPayload1);
  first_chunk_url_fetcher->delegate()->OnURLFetchComplete(
      first_chunk_url_fetcher);

  // Invoke the AddChunksCallback to trigger the second request.
  runner->RunPendingTasks();

  EXPECT_FALSE(pm->IsUpdateScheduled());

  // The second redirect response contains a single chunk.
  net::TestURLFetcher* second_chunk_url_fetcher =
      url_fetcher_factory.GetFetcherByID(2);
  ValidateRedirectFetcherRequest(
      second_chunk_url_fetcher, "https://redirect-server.example.com/two");
  second_chunk_url_fetcher->set_status(net::URLRequestStatus());
  second_chunk_url_fetcher->set_response_code(200);
  second_chunk_url_fetcher->SetResponseString(kChunkPayload2);
  second_chunk_url_fetcher->delegate()->OnURLFetchComplete(
      second_chunk_url_fetcher);

  EXPECT_FALSE(pm->IsUpdateScheduled());

  // Invoke the AddChunksCallback to finish the update.
  runner->RunPendingTasks();

  EXPECT_TRUE(pm->IsUpdateScheduled());
}
