1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140

content / browser / background_fetch / mock_background_fetch_delegate.h [blame]

// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CONTENT_BROWSER_BACKGROUND_FETCH_MOCK_BACKGROUND_FETCH_DELEGATE_H_
#define CONTENT_BROWSER_BACKGROUND_FETCH_MOCK_BACKGROUND_FETCH_DELEGATE_H_

#include <map>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <vector>

#include "base/files/scoped_temp_dir.h"
#include "content/public/browser/background_fetch_delegate.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "url/gurl.h"

namespace net {
class HttpResponseHeaders;
}  // namespace net

namespace content {

class MockBackgroundFetchDelegate : public BackgroundFetchDelegate {
 public:
  // Structure encapsulating the data for a injected response. Should only be
  // created by the builder, which also defines the ownership semantics.
  struct TestResponse {
    TestResponse();

    TestResponse(const TestResponse&) = delete;
    TestResponse& operator=(const TestResponse&) = delete;

    ~TestResponse();

    bool succeeded = false;
    bool pending = false;
    scoped_refptr<net::HttpResponseHeaders> headers;
    std::string data;
  };

  // Builder for creating a TestResponse object with the given data.
  // MockBackgroundFetchDelegate will respond to the corresponding request based
  // on this.
  class TestResponseBuilder {
   public:
    explicit TestResponseBuilder(int response_code);

    TestResponseBuilder(const TestResponseBuilder&) = delete;
    TestResponseBuilder& operator=(const TestResponseBuilder&) = delete;

    ~TestResponseBuilder();

    TestResponseBuilder& AddResponseHeader(const std::string& name,
                                           const std::string& value);

    TestResponseBuilder& SetResponseData(std::string data);

    TestResponseBuilder& MakeIndefinitelyPending();

    // Finalizes the builder and invalidates the underlying response.
    std::unique_ptr<TestResponse> Build();

   private:
    std::unique_ptr<TestResponse> response_;
  };

  MockBackgroundFetchDelegate();

  MockBackgroundFetchDelegate(const MockBackgroundFetchDelegate&) = delete;
  MockBackgroundFetchDelegate& operator=(const MockBackgroundFetchDelegate&) =
      delete;

  ~MockBackgroundFetchDelegate() override;

  // BackgroundFetchDelegate implementation:
  void GetIconDisplaySize(
      BackgroundFetchDelegate::GetIconDisplaySizeCallback callback) override;
  void CreateDownloadJob(
      base::WeakPtr<Client> client,
      std::unique_ptr<BackgroundFetchDescription> fetch_description) override;
  void DownloadUrl(const std::string& job_unique_id,
                   const std::string& guid,
                   const std::string& method,
                   const GURL& url,
                   ::network::mojom::CredentialsMode credentials_mode,
                   const net::NetworkTrafficAnnotationTag& traffic_annotation,
                   const net::HttpRequestHeaders& headers,
                   bool has_request_body) override;
  void Abort(const std::string& job_unique_id) override;
  void MarkJobComplete(const std::string& job_unique_id) override;
  void UpdateUI(const std::string& job_unique_id,
                const std::optional<std::string>& title,
                const std::optional<SkBitmap>& icon) override;

  void RegisterResponse(const GURL& url,
                        std::unique_ptr<TestResponse> response);

  const std::set<std::string>& completed_jobs() const {
    return completed_jobs_;
  }

 private:
  // Posts (to the default task runner) a callback that is only run if the job
  // indicated by |job_unique_id| has not been aborted.
  void PostAbortCheckingTask(const std::string& job_unique_id,
                             base::OnceCallback<void()> callback);

  // Immediately runs the callback if the job indicated by |job_unique_id| has
  // not been aborted.
  void RunAbortCheckingTask(const std::string& job_unique_id,
                            base::OnceCallback<void()> callback);

  // Single-use responses registered for specific URLs.
  std::map<const GURL, std::unique_ptr<TestResponse>> url_responses_;

  // GUIDs that have been registered via DownloadUrl and thus cannot be reused.
  std::set<std::string> seen_guids_;

  // Temporary directory in which successfully downloaded files will be stored.
  base::ScopedTempDir temp_directory_;

  // Set of unique job ids that have been aborted.
  std::set<std::string> aborted_jobs_;

  // Set of unique job ids that have been completed.
  std::set<std::string> completed_jobs_;

  // Map from download GUIDs to unique job ids.
  std::map<std::string, std::string> download_guid_to_job_id_map_;

  // Map from job GUIDs to Clients.
  std::map<std::string, base::WeakPtr<Client>> job_id_to_client_map_;
};

}  // namespace content

#endif  // CONTENT_BROWSER_BACKGROUND_FETCH_MOCK_BACKGROUND_FETCH_DELEGATE_H_