// Copyright 2016 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 "pdf/document_loader_impl.h"

#include <algorithm>
#include <memory>
#include <string>
#include <vector>

#include "base/check.h"
#include "pdf/url_loader_wrapper.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/range/range.h"

using ::testing::_;
using ::testing::Mock;
using ::testing::Sequence;
using ::testing::NiceMock;
using ::testing::Return;

namespace chrome_pdf {

namespace {

constexpr uint32_t kDefaultRequestSize =
    DocumentLoaderImpl::kDefaultRequestSize;

class TestURLLoader : public URLLoaderWrapper {
 public:
  class LoaderData {
   public:
    LoaderData() = default;
    ~LoaderData() {
      // We should call callbacks to prevent memory leaks.
      // The callbacks don't do anything, because the objects that created the
      // callbacks have been destroyed.
      if (IsWaitRead())
        CallReadCallback(-1);
      if (IsWaitOpen())
        CallOpenCallback(-1);
    }

    int content_length() const { return content_length_; }
    void set_content_length(int content_length) {
      content_length_ = content_length;
    }
    bool accept_ranges_bytes() const { return accept_ranges_bytes_; }
    void set_accept_ranges_bytes(bool accept_ranges_bytes) {
      accept_ranges_bytes_ = accept_ranges_bytes;
    }
    bool content_encoded() const { return content_encoded_; }
    void set_content_encoded(bool content_encoded) {
      content_encoded_ = content_encoded;
    }
    const std::string& content_type() const { return content_type_; }
    void set_content_type(const std::string& content_type) {
      content_type_ = content_type;
    }
    const std::string& content_disposition() const {
      return content_disposition_;
    }
    void set_content_disposition(const std::string& content_disposition) {
      content_disposition_ = content_disposition;
    }
    const std::string& multipart_boundary() const {
      return multipart_boundary_;
    }
    void set_multipart_boundary(const std::string& multipart_boundary) {
      multipart_boundary_ = multipart_boundary;
    }
    const gfx::Range& byte_range() const { return byte_range_; }
    void set_byte_range(const gfx::Range& byte_range) {
      byte_range_ = byte_range;
    }
    bool is_multipart() const { return is_multipart_; }
    void set_is_multipart(bool is_multipart) { is_multipart_ = is_multipart; }
    int status_code() const { return status_code_; }
    void set_status_code(int status_code) { status_code_ = status_code; }
    bool closed() const { return closed_; }
    void set_closed(bool closed) { closed_ = closed; }
    const gfx::Range& open_byte_range() const { return open_byte_range_; }
    void set_open_byte_range(const gfx::Range& open_byte_range) {
      open_byte_range_ = open_byte_range;
    }

    bool IsWaitRead() const { return !did_read_callback_.IsOptional(); }
    bool IsWaitOpen() const { return !did_open_callback_.IsOptional(); }
    char* buffer() const { return buffer_; }
    int buffer_size() const { return buffer_size_; }

    void SetReadCallback(const pp::CompletionCallback& read_callback,
                         char* buffer,
                         int buffer_size) {
      did_read_callback_ = read_callback;
      buffer_ = buffer;
      buffer_size_ = buffer_size;
    }

    void SetOpenCallback(const pp::CompletionCallback& open_callback,
                         gfx::Range req_byte_range) {
      did_open_callback_ = open_callback;
      set_open_byte_range(req_byte_range);
    }

    void CallOpenCallback(int result) {
      DCHECK(IsWaitOpen());
      did_open_callback_.RunAndClear(result);
    }

    void CallReadCallback(int result) {
      DCHECK(IsWaitRead());
      did_read_callback_.RunAndClear(result);
    }

   private:
    pp::CompletionCallback did_open_callback_;
    pp::CompletionCallback did_read_callback_;
    char* buffer_ = nullptr;
    int buffer_size_ = 0;

    int content_length_ = -1;
    bool accept_ranges_bytes_ = false;
    bool content_encoded_ = false;
    std::string content_type_;
    std::string content_disposition_;
    std::string multipart_boundary_;
    gfx::Range byte_range_ = gfx::Range::InvalidRange();
    bool is_multipart_ = false;
    int status_code_ = 0;
    bool closed_ = true;
    gfx::Range open_byte_range_ = gfx::Range::InvalidRange();

    DISALLOW_COPY_AND_ASSIGN(LoaderData);
  };

  explicit TestURLLoader(LoaderData* data) : data_(data) {
    data_->set_closed(false);
  }

  ~TestURLLoader() override { Close(); }

  int GetContentLength() const override { return data_->content_length(); }

  bool IsAcceptRangesBytes() const override {
    return data_->accept_ranges_bytes();
  }

  bool IsContentEncoded() const override { return data_->content_encoded(); }

  std::string GetContentType() const override { return data_->content_type(); }

  std::string GetContentDisposition() const override {
    return data_->content_disposition();
  }

  int GetStatusCode() const override { return data_->status_code(); }

  bool IsMultipart() const override { return data_->is_multipart(); }

  bool GetByteRangeStart(int* start) const override {
    *start = data_->byte_range().start();
    return data_->byte_range().IsValid();
  }

  void Close() override { data_->set_closed(true); }

  void OpenRange(const std::string& url,
                 const std::string& referrer_url,
                 uint32_t position,
                 uint32_t size,
                 const pp::CompletionCallback& cc) override {
    data_->SetOpenCallback(cc, gfx::Range(position, position + size));
  }

  void ReadResponseBody(char* buffer,
                        int buffer_size,
                        const pp::CompletionCallback& cc) override {
    data_->SetReadCallback(cc, buffer, buffer_size);
  }

  bool GetDownloadProgress(int64_t* bytes_received,
                           int64_t* total_bytes_to_be_received) const override {
    return false;
  }

 private:
  LoaderData* data_;

  DISALLOW_COPY_AND_ASSIGN(TestURLLoader);
};

class TestClient : public DocumentLoader::Client {
 public:
  TestClient() { full_page_loader_data()->set_content_type("application/pdf"); }
  ~TestClient() override = default;

  // DocumentLoader::Client overrides:
  pp::Instance* GetPluginInstance() override { return nullptr; }
  std::unique_ptr<URLLoaderWrapper> CreateURLLoader() override {
    return std::unique_ptr<URLLoaderWrapper>(
        new TestURLLoader(partial_loader_data()));
  }
  void OnPendingRequestComplete() override {}
  void OnNewDataReceived() override {}
  void OnDocumentComplete() override {}
  void OnDocumentCanceled() override {}

  std::unique_ptr<URLLoaderWrapper> CreateFullPageLoader() {
    return std::unique_ptr<URLLoaderWrapper>(
        new TestURLLoader(full_page_loader_data()));
  }

  TestURLLoader::LoaderData* full_page_loader_data() {
    return &full_page_loader_data_;
  }
  TestURLLoader::LoaderData* partial_loader_data() {
    return &partial_loader_data_;
  }

  void SetCanUsePartialLoading() {
    full_page_loader_data()->set_content_length(10 * 1024 * 1024);
    full_page_loader_data()->set_content_encoded(false);
    full_page_loader_data()->set_accept_ranges_bytes(true);
  }

  void SendAllPartialData() {
    partial_loader_data_.set_byte_range(partial_loader_data_.open_byte_range());
    partial_loader_data_.CallOpenCallback(0);
    uint32_t length = partial_loader_data_.byte_range().length();
    while (length > 0) {
      constexpr uint32_t max_part_len = kDefaultRequestSize;
      const uint32_t part_len = std::min(length, max_part_len);
      partial_loader_data_.CallReadCallback(part_len);
      length -= part_len;
    }
    if (partial_loader_data_.IsWaitRead()) {
      partial_loader_data_.CallReadCallback(0);
    }
  }

 private:
  TestURLLoader::LoaderData full_page_loader_data_;
  TestURLLoader::LoaderData partial_loader_data_;

  DISALLOW_COPY_AND_ASSIGN(TestClient);
};

class MockClient : public TestClient {
 public:
  MockClient() = default;

  MOCK_METHOD0(OnPendingRequestComplete, void());
  MOCK_METHOD0(OnNewDataReceived, void());
  MOCK_METHOD0(OnDocumentComplete, void());
  MOCK_METHOD0(OnDocumentCanceled, void());

 private:
  DISALLOW_COPY_AND_ASSIGN(MockClient);
};

}  // namespace

using DocumentLoaderImplTest = ::testing::Test;

TEST_F(DocumentLoaderImplTest, PartialLoadingEnabled) {
  TestClient client;
  client.SetCanUsePartialLoading();
  DocumentLoaderImpl loader(&client);
  loader.Init(client.CreateFullPageLoader(), "http://url.com");
  loader.RequestData(1000000, 1);
  EXPECT_FALSE(loader.is_partial_loader_active());
  // Always send initial data from FullPageLoader.
  client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  EXPECT_TRUE(loader.is_partial_loader_active());
}

TEST_F(DocumentLoaderImplTest, PartialLoadingDisabledOnSmallFiles) {
  TestClient client;
  client.SetCanUsePartialLoading();
  client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 2);
  DocumentLoaderImpl loader(&client);
  loader.Init(client.CreateFullPageLoader(), "http://url.com");
  loader.RequestData(1000000, 1);
  EXPECT_FALSE(loader.is_partial_loader_active());
  // Always send initial data from FullPageLoader.
  client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  EXPECT_FALSE(loader.is_partial_loader_active());
}

TEST_F(DocumentLoaderImplTest, PartialLoadingDisabledIfContentEncoded) {
  TestClient client;
  client.SetCanUsePartialLoading();
  client.full_page_loader_data()->set_content_encoded(true);
  DocumentLoaderImpl loader(&client);
  loader.Init(client.CreateFullPageLoader(), "http://url.com");
  loader.RequestData(1000000, 1);
  EXPECT_FALSE(loader.is_partial_loader_active());
  // Always send initial data from FullPageLoader.
  client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  EXPECT_FALSE(loader.is_partial_loader_active());
}

TEST_F(DocumentLoaderImplTest, PartialLoadingDisabledNoAcceptRangeBytes) {
  TestClient client;
  client.SetCanUsePartialLoading();
  client.full_page_loader_data()->set_accept_ranges_bytes(false);
  DocumentLoaderImpl loader(&client);
  loader.Init(client.CreateFullPageLoader(), "http://url.com");
  loader.RequestData(1000000, 1);
  EXPECT_FALSE(loader.is_partial_loader_active());
  // Always send initial data from FullPageLoader.
  client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  EXPECT_FALSE(loader.is_partial_loader_active());
}

TEST_F(DocumentLoaderImplTest, PartialLoadingReallyDisabledRequestFromBegin) {
  TestClient client;
  DocumentLoaderImpl loader(&client);
  client.SetCanUsePartialLoading();
  loader.SetPartialLoadingEnabled(false);
  loader.Init(client.CreateFullPageLoader(), "http://url.com");
  // We should not start partial loading if requested data is beside full page
  // loading position.
  loader.RequestData(kDefaultRequestSize, 1);
  EXPECT_FALSE(loader.is_partial_loader_active());
  // Always send initial data from FullPageLoader.
  client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  EXPECT_FALSE(loader.is_partial_loader_active());
}

TEST_F(DocumentLoaderImplTest, PartialLoadingReallyDisabledRequestFromMiddle) {
  TestClient client;
  client.SetCanUsePartialLoading();
  DocumentLoaderImpl loader(&client);
  loader.SetPartialLoadingEnabled(false);
  loader.Init(client.CreateFullPageLoader(), "http://url.com");
  loader.RequestData(1000000, 1);
  EXPECT_FALSE(loader.is_partial_loader_active());
  // Always send initial data from FullPageLoader.
  client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  EXPECT_FALSE(loader.is_partial_loader_active());
}

TEST_F(DocumentLoaderImplTest, PartialLoadingSimple) {
  TestClient client;
  client.SetCanUsePartialLoading();

  DocumentLoaderImpl loader(&client);
  loader.Init(client.CreateFullPageLoader(), "http://url.com");

  // While we have no requests, we should not start partial loading.
  EXPECT_FALSE(loader.is_partial_loader_active());

  loader.RequestData(5000000, 1);

  EXPECT_FALSE(client.partial_loader_data()->IsWaitOpen());
  EXPECT_FALSE(loader.is_partial_loader_active());

  // Always send initial data from FullPageLoader.
  client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);

  // Partial loader should request headers.
  EXPECT_TRUE(client.partial_loader_data()->IsWaitOpen());
  EXPECT_TRUE(loader.is_partial_loader_active());
  // Loader should be stopped.
  EXPECT_TRUE(client.full_page_loader_data()->closed());

  EXPECT_EQ("{4980736,10485760}",
            client.partial_loader_data()->open_byte_range().ToString());
}

TEST_F(DocumentLoaderImplTest, PartialLoadingBackOrder) {
  TestClient client;
  client.SetCanUsePartialLoading();

  DocumentLoaderImpl loader(&client);
  loader.Init(client.CreateFullPageLoader(), "http://url.com");

  // While we have no requests, we should not start partial loading.
  EXPECT_FALSE(loader.is_partial_loader_active());

  loader.RequestData(client.full_page_loader_data()->content_length() - 1, 1);

  EXPECT_FALSE(client.partial_loader_data()->IsWaitOpen());
  EXPECT_FALSE(loader.is_partial_loader_active());

  // Always send initial data from FullPageLoader.
  client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);

  // Partial loader should request headers.
  EXPECT_TRUE(client.partial_loader_data()->IsWaitOpen());
  EXPECT_TRUE(loader.is_partial_loader_active());
  // Loader should be stopped.
  EXPECT_TRUE(client.full_page_loader_data()->closed());

  // Requested range should be enlarged.
  EXPECT_GT(client.partial_loader_data()->open_byte_range().length(), 1u);
  EXPECT_EQ("{9830400,10485760}",
            client.partial_loader_data()->open_byte_range().ToString());
}

TEST_F(DocumentLoaderImplTest, CompleteWithoutPartial) {
  TestClient client;
  client.SetCanUsePartialLoading();
  DocumentLoaderImpl loader(&client);
  loader.Init(client.CreateFullPageLoader(), "http://url.com");
  EXPECT_FALSE(client.full_page_loader_data()->closed());
  while (client.full_page_loader_data()->IsWaitRead()) {
    client.full_page_loader_data()->CallReadCallback(1000);
  }
  EXPECT_TRUE(loader.IsDocumentComplete());
  EXPECT_TRUE(client.full_page_loader_data()->closed());
}

TEST_F(DocumentLoaderImplTest, ErrorDownloadFullDocument) {
  TestClient client;
  client.SetCanUsePartialLoading();
  DocumentLoaderImpl loader(&client);
  loader.Init(client.CreateFullPageLoader(), "http://url.com");
  EXPECT_TRUE(client.full_page_loader_data()->IsWaitRead());
  EXPECT_FALSE(client.full_page_loader_data()->closed());
  client.full_page_loader_data()->CallReadCallback(-3);
  EXPECT_TRUE(client.full_page_loader_data()->closed());
  EXPECT_FALSE(loader.IsDocumentComplete());
}

TEST_F(DocumentLoaderImplTest, CompleteNoContentLength) {
  TestClient client;
  DocumentLoaderImpl loader(&client);
  loader.Init(client.CreateFullPageLoader(), "http://url.com");
  EXPECT_FALSE(client.full_page_loader_data()->closed());
  for (int i = 0; i < 10; ++i) {
    EXPECT_TRUE(client.full_page_loader_data()->IsWaitRead());
    client.full_page_loader_data()->CallReadCallback(1000);
  }
  EXPECT_TRUE(client.full_page_loader_data()->IsWaitRead());
  client.full_page_loader_data()->CallReadCallback(0);
  EXPECT_EQ(10000ul, loader.GetDocumentSize());
  EXPECT_TRUE(loader.IsDocumentComplete());
  EXPECT_TRUE(client.full_page_loader_data()->closed());
}

TEST_F(DocumentLoaderImplTest, CompleteWithPartial) {
  TestClient client;
  client.SetCanUsePartialLoading();
  client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 20);
  DocumentLoaderImpl loader(&client);
  loader.Init(client.CreateFullPageLoader(), "http://url.com");
  loader.RequestData(19 * kDefaultRequestSize, kDefaultRequestSize);
  EXPECT_FALSE(client.full_page_loader_data()->closed());
  EXPECT_FALSE(client.partial_loader_data()->IsWaitRead());
  EXPECT_FALSE(client.partial_loader_data()->IsWaitOpen());

  // Always send initial data from FullPageLoader.
  client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  EXPECT_TRUE(client.full_page_loader_data()->closed());
  EXPECT_FALSE(client.partial_loader_data()->closed());

  client.SendAllPartialData();
  // Now we should send other document data.
  client.SendAllPartialData();
  EXPECT_TRUE(client.full_page_loader_data()->closed());
  EXPECT_TRUE(client.partial_loader_data()->closed());
}

TEST_F(DocumentLoaderImplTest, PartialRequestLastChunk) {
  constexpr uint32_t kLastChunkSize = 300;
  TestClient client;
  client.SetCanUsePartialLoading();
  client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 20 +
                                                     kLastChunkSize);
  DocumentLoaderImpl loader(&client);
  loader.Init(client.CreateFullPageLoader(), "http://url.com");
  loader.RequestData(20 * kDefaultRequestSize, 1);

  // Always send initial data from FullPageLoader.
  client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);

  EXPECT_TRUE(client.partial_loader_data()->IsWaitOpen());
  EXPECT_EQ(
      static_cast<int>(client.partial_loader_data()->open_byte_range().end()),
      client.full_page_loader_data()->content_length());
  client.partial_loader_data()->set_byte_range(
      client.partial_loader_data()->open_byte_range());
  client.partial_loader_data()->CallOpenCallback(0);
  uint32_t data_length = client.partial_loader_data()->byte_range().length();
  while (data_length > kDefaultRequestSize) {
    client.partial_loader_data()->CallReadCallback(kDefaultRequestSize);
    data_length -= kDefaultRequestSize;
  }
  EXPECT_EQ(kLastChunkSize, data_length);
  client.partial_loader_data()->CallReadCallback(kLastChunkSize);
  EXPECT_TRUE(loader.IsDataAvailable(kDefaultRequestSize * 20, kLastChunkSize));
}

TEST_F(DocumentLoaderImplTest, DocumentSize) {
  TestClient client;
  client.SetCanUsePartialLoading();
  client.full_page_loader_data()->set_content_length(123456789);
  DocumentLoaderImpl loader(&client);
  loader.Init(client.CreateFullPageLoader(), "http://url.com");
  EXPECT_EQ(static_cast<int>(loader.GetDocumentSize()),
            client.full_page_loader_data()->content_length());
}

TEST_F(DocumentLoaderImplTest, DocumentSizeNoContentLength) {
  TestClient client;
  DocumentLoaderImpl loader(&client);
  loader.Init(client.CreateFullPageLoader(), "http://url.com");
  EXPECT_EQ(0ul, loader.GetDocumentSize());
  client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  client.full_page_loader_data()->CallReadCallback(1000);
  client.full_page_loader_data()->CallReadCallback(500);
  client.full_page_loader_data()->CallReadCallback(0);
  EXPECT_EQ(kDefaultRequestSize + 1000ul + 500ul, loader.GetDocumentSize());
  EXPECT_TRUE(loader.IsDocumentComplete());
}

TEST_F(DocumentLoaderImplTest, ClearPendingRequests) {
  TestClient client;
  client.SetCanUsePartialLoading();
  client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 100 +
                                                     58383);
  DocumentLoaderImpl loader(&client);
  loader.Init(client.CreateFullPageLoader(), "http://url.com");
  loader.RequestData(17 * kDefaultRequestSize + 100, 10);
  loader.ClearPendingRequests();
  loader.RequestData(15 * kDefaultRequestSize + 200, 20);
  // pending requests are accumulating, and will be processed after initial data
  // load.
  EXPECT_FALSE(client.partial_loader_data()->IsWaitOpen());

  // Send initial data from FullPageLoader.
  client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);

  {
    EXPECT_TRUE(client.partial_loader_data()->IsWaitOpen());
    constexpr gfx::Range range_requested(15 * kDefaultRequestSize,
                                         16 * kDefaultRequestSize);
    EXPECT_EQ(range_requested.start(),
              client.partial_loader_data()->open_byte_range().start());
    EXPECT_LE(range_requested.end(),
              client.partial_loader_data()->open_byte_range().end());
    client.partial_loader_data()->set_byte_range(
        client.partial_loader_data()->open_byte_range());
  }
  // clear requests before Open callback.
  loader.ClearPendingRequests();
  // Current request should continue loading.
  EXPECT_TRUE(client.partial_loader_data()->IsWaitOpen());
  client.partial_loader_data()->CallOpenCallback(0);
  client.partial_loader_data()->CallReadCallback(kDefaultRequestSize);
  EXPECT_FALSE(client.partial_loader_data()->closed());
  // Current request should continue loading, because no other request queued.

  loader.RequestData(18 * kDefaultRequestSize + 200, 20);
  // Requests queue is processed only on receiving data.
  client.partial_loader_data()->CallReadCallback(kDefaultRequestSize);
  // New request within close distance from the one currently loading. Loading
  // isn't restarted.
  EXPECT_FALSE(client.partial_loader_data()->IsWaitOpen());

  loader.ClearPendingRequests();
  // request again two.
  loader.RequestData(60 * kDefaultRequestSize + 100, 10);
  loader.RequestData(35 * kDefaultRequestSize + 200, 20);
  // Requests queue is processed only on receiving data.
  client.partial_loader_data()->CallReadCallback(kDefaultRequestSize);
  {
    // new requset not with in close distance from current loading.
    // Loading should be restarted.
    EXPECT_TRUE(client.partial_loader_data()->IsWaitOpen());
    // The first requested chunk should be processed.
    constexpr gfx::Range range_requested(35 * kDefaultRequestSize,
                                         36 * kDefaultRequestSize);
    EXPECT_EQ(range_requested.start(),
              client.partial_loader_data()->open_byte_range().start());
    EXPECT_LE(range_requested.end(),
              client.partial_loader_data()->open_byte_range().end());
    client.partial_loader_data()->set_byte_range(
        client.partial_loader_data()->open_byte_range());
  }
  EXPECT_TRUE(client.partial_loader_data()->IsWaitOpen());
  client.partial_loader_data()->CallOpenCallback(0);
  // Override pending requests.
  loader.ClearPendingRequests();
  loader.RequestData(70 * kDefaultRequestSize + 100, 10);

  // Requests queue is processed only on receiving data.
  client.partial_loader_data()->CallReadCallback(kDefaultRequestSize);
  {
    // New requset not with in close distance from current loading.
    // Loading should be restarted .
    EXPECT_TRUE(client.partial_loader_data()->IsWaitOpen());
    // The first requested chunk should be processed.
    constexpr gfx::Range range_requested(70 * kDefaultRequestSize,
                                         71 * kDefaultRequestSize);
    EXPECT_EQ(range_requested.start(),
              client.partial_loader_data()->open_byte_range().start());
    EXPECT_LE(range_requested.end(),
              client.partial_loader_data()->open_byte_range().end());
    client.partial_loader_data()->set_byte_range(
        client.partial_loader_data()->open_byte_range());
  }
  EXPECT_TRUE(client.partial_loader_data()->IsWaitOpen());
}

TEST_F(DocumentLoaderImplTest, GetBlock) {
  std::vector<char> buffer(kDefaultRequestSize);
  TestClient client;
  client.SetCanUsePartialLoading();
  client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 20 +
                                                     58383);
  DocumentLoaderImpl loader(&client);
  loader.Init(client.CreateFullPageLoader(), "http://url.com");
  EXPECT_FALSE(loader.GetBlock(0, 1000, buffer.data()));
  client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  EXPECT_TRUE(loader.GetBlock(0, 1000, buffer.data()));
  EXPECT_FALSE(loader.GetBlock(kDefaultRequestSize, 1500, buffer.data()));
  client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  EXPECT_TRUE(loader.GetBlock(kDefaultRequestSize, 1500, buffer.data()));

  EXPECT_FALSE(loader.GetBlock(17 * kDefaultRequestSize, 3000, buffer.data()));
  loader.RequestData(17 * kDefaultRequestSize + 100, 10);
  EXPECT_FALSE(loader.GetBlock(17 * kDefaultRequestSize, 3000, buffer.data()));

  // Requests queue is processed only on receiving data.
  client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);

  client.SendAllPartialData();
  EXPECT_TRUE(loader.GetBlock(17 * kDefaultRequestSize, 3000, buffer.data()));
}

TEST_F(DocumentLoaderImplTest, IsDataAvailable) {
  TestClient client;
  client.SetCanUsePartialLoading();
  client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 20 +
                                                     58383);
  DocumentLoaderImpl loader(&client);
  loader.Init(client.CreateFullPageLoader(), "http://url.com");
  EXPECT_FALSE(loader.IsDataAvailable(0, 1000));
  client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  EXPECT_TRUE(loader.IsDataAvailable(0, 1000));
  EXPECT_FALSE(loader.IsDataAvailable(kDefaultRequestSize, 1500));
  client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  EXPECT_TRUE(loader.IsDataAvailable(kDefaultRequestSize, 1500));

  EXPECT_FALSE(loader.IsDataAvailable(17 * kDefaultRequestSize, 3000));
  loader.RequestData(17 * kDefaultRequestSize + 100, 10);
  EXPECT_FALSE(loader.IsDataAvailable(17 * kDefaultRequestSize, 3000));

  // Requests queue is processed only on receiving data.
  client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);

  client.SendAllPartialData();
  EXPECT_TRUE(loader.IsDataAvailable(17 * kDefaultRequestSize, 3000));
}

TEST_F(DocumentLoaderImplTest, RequestData) {
  TestClient client;
  client.SetCanUsePartialLoading();
  client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 100 +
                                                     58383);
  DocumentLoaderImpl loader(&client);
  loader.Init(client.CreateFullPageLoader(), "http://url.com");
  loader.RequestData(37 * kDefaultRequestSize + 200, 10);
  loader.RequestData(25 * kDefaultRequestSize + 600, 100);
  loader.RequestData(13 * kDefaultRequestSize + 900, 500);

  // Send initial data from FullPageLoader.
  client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);

  {
    EXPECT_TRUE(client.partial_loader_data()->IsWaitOpen());
    constexpr gfx::Range range_requested(13 * kDefaultRequestSize,
                                         14 * kDefaultRequestSize);
    EXPECT_EQ(range_requested.start(),
              client.partial_loader_data()->open_byte_range().start());
    EXPECT_LE(range_requested.end(),
              client.partial_loader_data()->open_byte_range().end());
    client.partial_loader_data()->set_byte_range(
        client.partial_loader_data()->open_byte_range());
  }
  client.partial_loader_data()->CallOpenCallback(0);
  // Override pending requests.
  loader.ClearPendingRequests();
  loader.RequestData(38 * kDefaultRequestSize + 200, 10);
  loader.RequestData(26 * kDefaultRequestSize + 600, 100);
  // Requests queue is processed only on receiving data.
  client.partial_loader_data()->CallReadCallback(kDefaultRequestSize);
  {
    EXPECT_TRUE(client.partial_loader_data()->IsWaitOpen());
    constexpr gfx::Range range_requested(26 * kDefaultRequestSize,
                                         27 * kDefaultRequestSize);
    EXPECT_EQ(range_requested.start(),
              client.partial_loader_data()->open_byte_range().start());
    EXPECT_LE(range_requested.end(),
              client.partial_loader_data()->open_byte_range().end());
    client.partial_loader_data()->set_byte_range(
        client.partial_loader_data()->open_byte_range());
  }
  client.partial_loader_data()->CallOpenCallback(0);
  // Override pending requests.
  loader.ClearPendingRequests();
  loader.RequestData(39 * kDefaultRequestSize + 200, 10);
  // Requests queue is processed only on receiving data.
  client.partial_loader_data()->CallReadCallback(kDefaultRequestSize);
  {
    EXPECT_TRUE(client.partial_loader_data()->IsWaitOpen());
    constexpr gfx::Range range_requested(39 * kDefaultRequestSize,
                                         40 * kDefaultRequestSize);
    EXPECT_EQ(range_requested.start(),
              client.partial_loader_data()->open_byte_range().start());
    EXPECT_LE(range_requested.end(),
              client.partial_loader_data()->open_byte_range().end());
    client.partial_loader_data()->set_byte_range(
        client.partial_loader_data()->open_byte_range());
  }
  // Fill all gaps.
  while (!loader.IsDocumentComplete()) {
    client.SendAllPartialData();
  }
  EXPECT_TRUE(client.partial_loader_data()->closed());
}

TEST_F(DocumentLoaderImplTest, DoNotLoadAvailablePartialData) {
  TestClient client;
  client.SetCanUsePartialLoading();
  client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 20 +
                                                     58383);
  DocumentLoaderImpl loader(&client);
  loader.Init(client.CreateFullPageLoader(), "http://url.com");
  // Send initial data from FullPageLoader.
  client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);

  // Send more data from FullPageLoader.
  client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);

  loader.RequestData(2 * kDefaultRequestSize + 200, 10);

  // Send more data from FullPageLoader.
  client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);

  // Partial loading should not have started for already available data.
  EXPECT_TRUE(client.partial_loader_data()->closed());
}

TEST_F(DocumentLoaderImplTest, DoNotLoadDataAfterComplete) {
  TestClient client;
  client.SetCanUsePartialLoading();
  client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 20);
  DocumentLoaderImpl loader(&client);
  loader.Init(client.CreateFullPageLoader(), "http://url.com");

  for (int i = 0; i < 20; ++i) {
    client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  }

  EXPECT_TRUE(loader.IsDocumentComplete());

  loader.RequestData(17 * kDefaultRequestSize + 200, 10);

  EXPECT_TRUE(client.partial_loader_data()->closed());
  EXPECT_TRUE(client.full_page_loader_data()->closed());
}

TEST_F(DocumentLoaderImplTest, DoNotLoadPartialDataAboveDocumentSize) {
  TestClient client;
  client.SetCanUsePartialLoading();
  client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 20);
  DocumentLoaderImpl loader(&client);
  loader.Init(client.CreateFullPageLoader(), "http://url.com");

  loader.RequestData(20 * kDefaultRequestSize + 200, 10);

  // Send initial data from FullPageLoader.
  client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);

  EXPECT_TRUE(client.partial_loader_data()->closed());
}

TEST_F(DocumentLoaderImplTest, MergePendingRequests) {
  TestClient client;
  client.SetCanUsePartialLoading();
  client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 50 +
                                                     58383);
  DocumentLoaderImpl loader(&client);
  loader.Init(client.CreateFullPageLoader(), "http://url.com");
  loader.RequestData(17 * kDefaultRequestSize + 200, 10);
  loader.RequestData(16 * kDefaultRequestSize + 600, 100);

  // Send initial data from FullPageLoader.
  client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);

  constexpr gfx::Range range_requested(16 * kDefaultRequestSize,
                                       18 * kDefaultRequestSize);
  EXPECT_EQ(range_requested.start(),
            client.partial_loader_data()->open_byte_range().start());
  EXPECT_LE(range_requested.end(),
            client.partial_loader_data()->open_byte_range().end());

  EXPECT_TRUE(client.partial_loader_data()->IsWaitOpen());

  // Fill all gaps.
  while (!loader.IsDocumentComplete()) {
    client.SendAllPartialData();
  }
  EXPECT_TRUE(client.partial_loader_data()->closed());
}

TEST_F(DocumentLoaderImplTest, PartialStopOnStatusCodeError) {
  TestClient client;
  client.SetCanUsePartialLoading();
  client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 20);
  DocumentLoaderImpl loader(&client);
  loader.Init(client.CreateFullPageLoader(), "http://url.com");

  loader.RequestData(17 * kDefaultRequestSize + 200, 10);

  // Send initial data from FullPageLoader.
  client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);

  EXPECT_TRUE(client.partial_loader_data()->IsWaitOpen());
  client.partial_loader_data()->set_status_code(404);
  client.partial_loader_data()->CallOpenCallback(0);
  EXPECT_TRUE(client.partial_loader_data()->closed());
}

TEST_F(DocumentLoaderImplTest,
       PartialAsFullDocumentLoadingRangeRequestNoRangeField) {
  TestClient client;
  client.SetCanUsePartialLoading();
  client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 20);
  DocumentLoaderImpl loader(&client);
  loader.Init(client.CreateFullPageLoader(), "http://url.com");

  loader.RequestData(17 * kDefaultRequestSize + 200, 10);

  // Send initial data from FullPageLoader.
  client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);

  EXPECT_TRUE(client.partial_loader_data()->IsWaitOpen());
  client.partial_loader_data()->set_byte_range(gfx::Range::InvalidRange());
  client.partial_loader_data()->CallOpenCallback(0);
  EXPECT_FALSE(client.partial_loader_data()->closed());
  // Partial loader is used to load the whole page, like full page loader.
  EXPECT_FALSE(loader.is_partial_loader_active());
}

TEST_F(DocumentLoaderImplTest, PartialMultiPart) {
  TestClient client;
  client.SetCanUsePartialLoading();
  client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 20);
  DocumentLoaderImpl loader(&client);
  loader.Init(client.CreateFullPageLoader(), "http://url.com");

  loader.RequestData(17 * kDefaultRequestSize + 200, 10);

  // Send initial data from FullPageLoader.
  client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);

  EXPECT_TRUE(client.partial_loader_data()->IsWaitOpen());
  client.partial_loader_data()->set_is_multipart(true);
  client.partial_loader_data()->CallOpenCallback(0);
  client.partial_loader_data()->set_byte_range(
      gfx::Range(17 * kDefaultRequestSize, 18 * kDefaultRequestSize));
  client.partial_loader_data()->CallReadCallback(kDefaultRequestSize);
  EXPECT_TRUE(
      loader.IsDataAvailable(17 * kDefaultRequestSize, kDefaultRequestSize));
}

TEST_F(DocumentLoaderImplTest, PartialMultiPartRangeError) {
  TestClient client;
  client.SetCanUsePartialLoading();
  client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 20);
  DocumentLoaderImpl loader(&client);
  loader.Init(client.CreateFullPageLoader(), "http://url.com");

  loader.RequestData(17 * kDefaultRequestSize + 200, 10);

  // Send initial data from FullPageLoader.
  client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);

  EXPECT_TRUE(client.partial_loader_data()->IsWaitOpen());
  client.partial_loader_data()->set_is_multipart(true);
  client.partial_loader_data()->CallOpenCallback(0);
  client.partial_loader_data()->set_byte_range(gfx::Range::InvalidRange());
  client.partial_loader_data()->CallReadCallback(kDefaultRequestSize);
  EXPECT_FALSE(
      loader.IsDataAvailable(17 * kDefaultRequestSize, kDefaultRequestSize));
  EXPECT_TRUE(client.partial_loader_data()->closed());
}

TEST_F(DocumentLoaderImplTest, PartialConnectionErrorOnOpen) {
  TestClient client;
  client.SetCanUsePartialLoading();
  client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 20);
  DocumentLoaderImpl loader(&client);
  loader.Init(client.CreateFullPageLoader(), "http://url.com");

  loader.RequestData(17 * kDefaultRequestSize + 200, 10);

  // Send initial data from FullPageLoader.
  client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);

  EXPECT_TRUE(client.partial_loader_data()->IsWaitOpen());
  client.partial_loader_data()->CallOpenCallback(-3);
  EXPECT_TRUE(client.partial_loader_data()->closed());

  // Partial loading should not restart after any error.
  loader.RequestData(18 * kDefaultRequestSize + 200, 10);

  EXPECT_FALSE(client.partial_loader_data()->IsWaitOpen());
  EXPECT_TRUE(client.partial_loader_data()->closed());
}

TEST_F(DocumentLoaderImplTest, PartialConnectionErrorOnRead) {
  TestClient client;
  client.SetCanUsePartialLoading();
  client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 20);
  DocumentLoaderImpl loader(&client);
  loader.Init(client.CreateFullPageLoader(), "http://url.com");

  loader.RequestData(17 * kDefaultRequestSize + 200, 10);

  // Send initial data from FullPageLoader.
  client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);

  EXPECT_TRUE(client.partial_loader_data()->IsWaitOpen());
  client.partial_loader_data()->set_byte_range(
      gfx::Range(17 * kDefaultRequestSize, 18 * kDefaultRequestSize));
  client.partial_loader_data()->CallOpenCallback(0);
  EXPECT_TRUE(client.partial_loader_data()->IsWaitRead());
  client.partial_loader_data()->CallReadCallback(-3);
  EXPECT_TRUE(client.partial_loader_data()->closed());

  // Partial loading should not restart after any error.
  loader.RequestData(18 * kDefaultRequestSize + 200, 10);

  EXPECT_FALSE(client.partial_loader_data()->IsWaitOpen());
  EXPECT_TRUE(client.partial_loader_data()->closed());
}

TEST_F(DocumentLoaderImplTest, ClientCompleteCallbacks) {
  MockClient client;
  client.SetCanUsePartialLoading();
  client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 20);
  DocumentLoaderImpl loader(&client);
  loader.Init(client.CreateFullPageLoader(), "http://url.com");

  EXPECT_CALL(client, OnDocumentComplete()).Times(0);
  for (int i = 0; i < 19; ++i)
    client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  Mock::VerifyAndClear(&client);

  EXPECT_CALL(client, OnDocumentComplete()).Times(1);
  client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  Mock::VerifyAndClear(&client);
}

TEST_F(DocumentLoaderImplTest, ClientCompleteCallbacksNoContentLength) {
  MockClient client;
  DocumentLoaderImpl loader(&client);
  loader.Init(client.CreateFullPageLoader(), "http://url.com");

  EXPECT_CALL(client, OnDocumentCanceled()).Times(0);
  EXPECT_CALL(client, OnDocumentComplete()).Times(0);
  for (int i = 0; i < 20; ++i)
    client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  Mock::VerifyAndClear(&client);

  EXPECT_CALL(client, OnDocumentCanceled()).Times(0);
  EXPECT_CALL(client, OnDocumentComplete()).Times(1);
  client.full_page_loader_data()->CallReadCallback(0);
  Mock::VerifyAndClear(&client);
}

TEST_F(DocumentLoaderImplTest, ClientCancelCallback) {
  MockClient client;
  client.SetCanUsePartialLoading();
  client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 20);
  DocumentLoaderImpl loader(&client);
  loader.Init(client.CreateFullPageLoader(), "http://url.com");

  EXPECT_CALL(client, OnDocumentCanceled()).Times(0);
  EXPECT_CALL(client, OnDocumentComplete()).Times(0);
  for (int i = 0; i < 10; ++i)
    client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  Mock::VerifyAndClear(&client);

  EXPECT_CALL(client, OnDocumentComplete()).Times(0);
  EXPECT_CALL(client, OnDocumentCanceled()).Times(1);
  client.full_page_loader_data()->CallReadCallback(-3);
  Mock::VerifyAndClear(&client);
}

TEST_F(DocumentLoaderImplTest, NewDataAvailable) {
  MockClient client;
  client.SetCanUsePartialLoading();
  client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 20);
  DocumentLoaderImpl loader(&client);
  loader.Init(client.CreateFullPageLoader(), "http://url.com");

  EXPECT_CALL(client, OnNewDataReceived()).Times(1);
  client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  Mock::VerifyAndClear(&client);

  EXPECT_CALL(client, OnNewDataReceived()).Times(1);
  client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize - 100);
  Mock::VerifyAndClear(&client);

  EXPECT_CALL(client, OnNewDataReceived()).Times(1);
  client.full_page_loader_data()->CallReadCallback(100);
  Mock::VerifyAndClear(&client);
}

TEST_F(DocumentLoaderImplTest, ClientPendingRequestCompleteFullLoader) {
  MockClient client;
  client.SetCanUsePartialLoading();
  DocumentLoaderImpl loader(&client);
  loader.Init(client.CreateFullPageLoader(), "http://url.com");

  loader.RequestData(1000, 4000);

  EXPECT_CALL(client, OnPendingRequestComplete()).Times(1);
  client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  Mock::VerifyAndClear(&client);
}

TEST_F(DocumentLoaderImplTest, ClientPendingRequestCompletePartialLoader) {
  MockClient client;
  client.SetCanUsePartialLoading();
  DocumentLoaderImpl loader(&client);
  loader.Init(client.CreateFullPageLoader(), "http://url.com");

  EXPECT_CALL(client, OnPendingRequestComplete()).Times(1);
  loader.RequestData(15 * kDefaultRequestSize + 4000, 4000);

  // Always send initial data from FullPageLoader.
  client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);

  client.SendAllPartialData();
  Mock::VerifyAndClear(&client);
}

TEST_F(DocumentLoaderImplTest,
       ClientPendingRequestCompletePartialAndFullLoader) {
  MockClient client;
  client.SetCanUsePartialLoading();
  DocumentLoaderImpl loader(&client);
  loader.Init(client.CreateFullPageLoader(), "http://url.com");

  EXPECT_CALL(client, OnPendingRequestComplete()).Times(1);
  loader.RequestData(16 * kDefaultRequestSize + 4000, 4000);
  loader.RequestData(4 * kDefaultRequestSize + 4000, 4000);

  for (int i = 0; i < 5; ++i)
    client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);

  Mock::VerifyAndClear(&client);

  EXPECT_CALL(client, OnPendingRequestComplete()).Times(1);
  client.SendAllPartialData();
  Mock::VerifyAndClear(&client);
}

TEST_F(DocumentLoaderImplTest, IgnoreDataMoreThanExpectedWithPartial) {
  static constexpr uint32_t kDocSize = kDefaultRequestSize * 80 - 321;
  TestClient client;
  client.SetCanUsePartialLoading();
  client.full_page_loader_data()->set_content_length(kDocSize);
  DocumentLoaderImpl loader(&client);
  loader.Init(client.CreateFullPageLoader(), "http://url.com");
  // Request data at and.
  loader.RequestData(kDocSize - 100, 100);

  // Always send initial data from FullPageLoader.
  client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  EXPECT_TRUE(client.full_page_loader_data()->closed());
  EXPECT_FALSE(client.partial_loader_data()->closed());

  // Request data at middle to continue loading partial, but not all remaining
  // data.
  loader.RequestData(kDocSize / 2, 100);

  // Fill data at the end, the partial loding should be started for second
  // requested data after receive data for first request.
  client.SendAllPartialData();

  ASSERT_TRUE(client.partial_loader_data()->IsWaitOpen());
  // Process second request.
  const uint32_t expected_length =
      client.partial_loader_data()->open_byte_range().length();

  // Send data.
  client.partial_loader_data()->set_byte_range(
      client.partial_loader_data()->open_byte_range());
  client.partial_loader_data()->CallOpenCallback(0);
  uint32_t length = expected_length;
  while (length > 0) {
    constexpr uint32_t max_part_len = kDefaultRequestSize;
    const uint32_t part_len = std::min(length, max_part_len);
    client.partial_loader_data()->CallReadCallback(part_len);
    length -= part_len;
  }

  // The partial loading should be finished for current chunks sequence, if
  // expected range was received, and remaining sequence should start loading.
  EXPECT_FALSE(client.partial_loader_data()->IsWaitRead());
  ASSERT_TRUE(client.partial_loader_data()->IsWaitOpen());

  // Send other document data.
  client.SendAllPartialData();
  // The downloads should be finished.
  EXPECT_TRUE(client.full_page_loader_data()->closed());
  EXPECT_TRUE(client.partial_loader_data()->closed());
}

TEST_F(DocumentLoaderImplTest, IgnoreDataMoreThanExpectedWithPartialAtFileEnd) {
  static constexpr uint32_t kExtraSize = 100;
  static constexpr uint32_t kRealSize = kDefaultRequestSize * 20 - 300;
  static constexpr uint32_t kDocSize = kRealSize - kExtraSize;
  TestClient client;
  client.SetCanUsePartialLoading();
  client.full_page_loader_data()->set_content_length(kDocSize);
  DocumentLoaderImpl loader(&client);
  loader.Init(client.CreateFullPageLoader(), "http://url.com");
  // Request data at middle.
  static constexpr uint32_t kFirstPartial = kDefaultRequestSize * 11;
  loader.RequestData(kFirstPartial, kDefaultRequestSize);

  // Always send initial data from FullPageLoader.
  client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  EXPECT_TRUE(client.full_page_loader_data()->closed());
  EXPECT_FALSE(client.partial_loader_data()->closed());

  // Send data to file end and extra non expected data.
  client.partial_loader_data()->set_byte_range(
      gfx::Range(kFirstPartial, kRealSize));
  client.partial_loader_data()->CallOpenCallback(0);
  uint32_t length = client.partial_loader_data()->byte_range().length();
  while (length > 0) {
    constexpr uint32_t max_part_len = kDefaultRequestSize;
    const uint32_t part_len = std::min(length, max_part_len);
    client.partial_loader_data()->CallReadCallback(part_len);
    length -= part_len;
  }

  // The partial loading should be finished for current chunks sequence, if
  // eof was reached, and remaining sequence should start loading.
  EXPECT_FALSE(client.partial_loader_data()->IsWaitRead());
  EXPECT_EQ(gfx::Range(kDefaultRequestSize, kFirstPartial),
            client.partial_loader_data()->open_byte_range());

  // Send other document data.
  client.SendAllPartialData();
  // The downloads should be finished.
  EXPECT_TRUE(client.full_page_loader_data()->closed());
  EXPECT_TRUE(client.partial_loader_data()->closed());
}

}  // namespace chrome_pdf
